From 1add949ef0e424e3b144e33d55938c873ac5050e Mon Sep 17 00:00:00 2001
From: Paul Emmerich <paul.emmerich@croit.io>
Date: Thu, 11 Jul 2019 22:23:00 +0200
Subject: [PATCH 001/943] libtest: add --show-output option

this new flag enables printing the captured stdout of successful tests
utilizing the already existing display_output test runner option
---
 src/librustdoc/markdown.rs |  2 +-
 src/librustdoc/test.rs     |  2 +-
 src/libtest/lib.rs         | 16 +++++++++++-----
 src/libtest/tests.rs       | 11 +++++++++++
 4 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 50a647f244db5..21a7c39f72e92 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -154,6 +154,6 @@ pub fn test(mut options: Options, diag: &errors::Handler) -> i32 {
 
     options.test_args.insert(0, "rustdoctest".to_string());
     testing::test_main(&options.test_args, collector.tests,
-                       testing::Options::new().display_output(options.display_warnings));
+                       Some(testing::Options::new().display_output(options.display_warnings)));
     0
 }
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 63545ab45bf64..562d98a4a4327 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -120,7 +120,7 @@ pub fn run(options: Options) -> i32 {
     testing::test_main(
         &test_args,
         tests,
-        testing::Options::new().display_output(display_warnings)
+        Some(testing::Options::new().display_output(display_warnings))
     );
 
     0
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 53bf67bdf671f..a1ce45dad4e9e 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -272,7 +272,7 @@ impl Options {
 
 // The default console test runner. It accepts the command line
 // arguments and a vector of test_descs.
-pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Options) {
+pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Option<Options>) {
     let mut opts = match parse_opts(args) {
         Some(Ok(o)) => o,
         Some(Err(msg)) => {
@@ -281,8 +281,9 @@ pub fn test_main(args: &[String], tests: Vec<TestDescAndFn>, options: Options) {
         }
         None => return,
     };
-
-    opts.options = options;
+    if let Some(options) = options {
+        opts.options = options;
+    }
     if opts.list {
         if let Err(e) = list_tests_console(&opts, tests) {
             eprintln!("error: io error when listing tests: {:?}", e);
@@ -323,7 +324,7 @@ pub fn test_main_static(tests: &[&TestDescAndFn]) {
             _ => panic!("non-static tests passed to test::test_main_static"),
         })
         .collect();
-    test_main(&args, owned_tests, Options::new())
+    test_main(&args, owned_tests, None)
 }
 
 /// Invoked when unit tests terminate. Should panic if the unit
@@ -468,6 +469,11 @@ fn optgroups() -> getopts::Options {
             json   = Output a json document",
             "pretty|terse|json",
         )
+        .optflag(
+            "",
+            "show-output",
+            "Show captured stdout of successful tests"
+        )
         .optopt(
             "Z",
             "",
@@ -667,7 +673,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
         format,
         test_threads,
         skip: matches.opt_strs("skip"),
-        options: Options::new(),
+        options: Options::new().display_output(matches.opt_present("show-output")),
     };
 
     Some(Ok(test_opts))
diff --git a/src/libtest/tests.rs b/src/libtest/tests.rs
index d8734d8caa03e..5956526e89403 100644
--- a/src/libtest/tests.rs
+++ b/src/libtest/tests.rs
@@ -160,6 +160,17 @@ fn parse_ignored_flag() {
     assert_eq!(opts.run_ignored, RunIgnored::Only);
 }
 
+#[test]
+fn parse_show_output_flag() {
+    let args = vec![
+        "progname".to_string(),
+        "filter".to_string(),
+        "--show-output".to_string(),
+    ];
+    let opts = parse_opts(&args).unwrap().unwrap();
+    assert!(opts.options.display_output);
+}
+
 #[test]
 fn parse_include_ignored_flag() {
     let args = vec![

From 409a41dc24fe72e6d8bf3c2252efb13c94d921c5 Mon Sep 17 00:00:00 2001
From: Paul Emmerich <paul.emmerich@croit.io>
Date: Fri, 12 Jul 2019 01:56:43 +0200
Subject: [PATCH 002/943] libtest: support display_output in JSON formatter

---
 src/libtest/formatters/json.rs                | 71 +++++++++++--------
 src/libtest/formatters/mod.rs                 |  1 +
 src/libtest/formatters/pretty.rs              |  8 ++-
 src/libtest/formatters/terse.rs               |  8 ++-
 src/libtest/lib.rs                            |  2 +-
 .../run-make-fulldeps/libtest-json/Makefile   | 12 ++--
 src/test/run-make-fulldeps/libtest-json/f.rs  |  3 +-
 .../{output.json => output-default.json}      |  2 +-
 .../libtest-json/output-stdout-success.json   | 10 +++
 9 files changed, 77 insertions(+), 40 deletions(-)
 rename src/test/run-make-fulldeps/libtest-json/{output.json => output-default.json} (91%)
 create mode 100644 src/test/run-make-fulldeps/libtest-json/output-stdout-success.json

diff --git a/src/libtest/formatters/json.rs b/src/libtest/formatters/json.rs
index a06497f98626a..e0bea4ce54530 100644
--- a/src/libtest/formatters/json.rs
+++ b/src/libtest/formatters/json.rs
@@ -9,44 +9,57 @@ impl<T: Write> JsonFormatter<T> {
         Self { out }
     }
 
-    fn write_message(&mut self, s: &str) -> io::Result<()> {
+    fn writeln_message(&mut self, s: &str) -> io::Result<()> {
         assert!(!s.contains('\n'));
 
         self.out.write_all(s.as_ref())?;
         self.out.write_all(b"\n")
     }
 
+    fn write_message(&mut self, s: &str) -> io::Result<()> {
+        assert!(!s.contains('\n'));
+
+        self.out.write_all(s.as_ref())
+    }
+
     fn write_event(
         &mut self,
         ty: &str,
         name: &str,
         evt: &str,
-        extra: Option<String>,
+        stdout: Option<Cow<'_, str>>,
+        extra: Option<&str>,
     ) -> io::Result<()> {
-        if let Some(extras) = extra {
+        self.write_message(&*format!(
+            r#"{{ "type": "{}", "name": "{}", "event": "{}""#,
+            ty, name, evt
+        ))?;
+        if let Some(stdout) = stdout {
             self.write_message(&*format!(
-                r#"{{ "type": "{}", "name": "{}", "event": "{}", {} }}"#,
-                ty, name, evt, extras
-            ))
-        } else {
+                r#", "stdout": "{}""#,
+                EscapedString(stdout)
+            ))?;
+        }
+        if let Some(extra) = extra {
             self.write_message(&*format!(
-                r#"{{ "type": "{}", "name": "{}", "event": "{}" }}"#,
-                ty, name, evt
-            ))
+                r#", {}"#,
+                extra
+            ))?;
         }
+        self.writeln_message(" }")
     }
 }
 
 impl<T: Write> OutputFormatter for JsonFormatter<T> {
     fn write_run_start(&mut self, test_count: usize) -> io::Result<()> {
-        self.write_message(&*format!(
+        self.writeln_message(&*format!(
             r#"{{ "type": "suite", "event": "started", "test_count": {} }}"#,
             test_count
         ))
     }
 
     fn write_test_start(&mut self, desc: &TestDesc) -> io::Result<()> {
-        self.write_message(&*format!(
+        self.writeln_message(&*format!(
             r#"{{ "type": "test", "event": "started", "name": "{}" }}"#,
             desc.name
         ))
@@ -57,34 +70,30 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
         desc: &TestDesc,
         result: &TestResult,
         stdout: &[u8],
+        state: &ConsoleTestState,
     ) -> io::Result<()> {
+        let stdout = if (state.options.display_output || *result != TrOk) && stdout.len() > 0 {
+            Some(String::from_utf8_lossy(stdout))
+        } else {
+            None
+        };
         match *result {
-            TrOk => self.write_event("test", desc.name.as_slice(), "ok", None),
-
-            TrFailed => {
-                let extra_data = if stdout.len() > 0 {
-                    Some(format!(
-                        r#""stdout": "{}""#,
-                        EscapedString(String::from_utf8_lossy(stdout))
-                    ))
-                } else {
-                    None
-                };
+            TrOk => self.write_event("test", desc.name.as_slice(), "ok", stdout, None),
 
-                self.write_event("test", desc.name.as_slice(), "failed", extra_data)
-            }
+            TrFailed => self.write_event("test", desc.name.as_slice(), "failed", stdout, None),
 
             TrFailedMsg(ref m) => self.write_event(
                 "test",
                 desc.name.as_slice(),
                 "failed",
-                Some(format!(r#""message": "{}""#, EscapedString(m))),
+                stdout,
+                Some(&*format!(r#""message": "{}""#, EscapedString(m))),
             ),
 
-            TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", None),
+            TrIgnored => self.write_event("test", desc.name.as_slice(), "ignored", stdout, None),
 
             TrAllowedFail => {
-                self.write_event("test", desc.name.as_slice(), "allowed_failure", None)
+                self.write_event("test", desc.name.as_slice(), "allowed_failure", stdout, None)
             }
 
             TrBench(ref bs) => {
@@ -105,20 +114,20 @@ impl<T: Write> OutputFormatter for JsonFormatter<T> {
                     desc.name, median, deviation, mbps
                 );
 
-                self.write_message(&*line)
+                self.writeln_message(&*line)
             }
         }
     }
 
     fn write_timeout(&mut self, desc: &TestDesc) -> io::Result<()> {
-        self.write_message(&*format!(
+        self.writeln_message(&*format!(
             r#"{{ "type": "test", "event": "timeout", "name": "{}" }}"#,
             desc.name
         ))
     }
 
     fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
-        self.write_message(&*format!(
+        self.writeln_message(&*format!(
             "{{ \"type\": \"suite\", \
              \"event\": \"{}\", \
              \"passed\": {}, \
diff --git a/src/libtest/formatters/mod.rs b/src/libtest/formatters/mod.rs
index be5f6a65039b7..cc30b06e5ec38 100644
--- a/src/libtest/formatters/mod.rs
+++ b/src/libtest/formatters/mod.rs
@@ -17,6 +17,7 @@ pub(crate) trait OutputFormatter {
         desc: &TestDesc,
         result: &TestResult,
         stdout: &[u8],
+        state: &ConsoleTestState,
     ) -> io::Result<()>;
     fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool>;
 }
diff --git a/src/libtest/formatters/pretty.rs b/src/libtest/formatters/pretty.rs
index 4af00428ca87e..88331406a64d0 100644
--- a/src/libtest/formatters/pretty.rs
+++ b/src/libtest/formatters/pretty.rs
@@ -162,7 +162,13 @@ impl<T: Write> OutputFormatter for PrettyFormatter<T> {
         Ok(())
     }
 
-    fn write_result(&mut self, desc: &TestDesc, result: &TestResult, _: &[u8]) -> io::Result<()> {
+    fn write_result(
+        &mut self,
+        desc: &TestDesc,
+        result: &TestResult,
+        _: &[u8],
+        _: &ConsoleTestState,
+    ) -> io::Result<()> {
         if self.is_multithreaded {
             self.write_test_name(desc)?;
         }
diff --git a/src/libtest/formatters/terse.rs b/src/libtest/formatters/terse.rs
index 1400fba5d6092..d10b0c5807d57 100644
--- a/src/libtest/formatters/terse.rs
+++ b/src/libtest/formatters/terse.rs
@@ -170,7 +170,13 @@ impl<T: Write> OutputFormatter for TerseFormatter<T> {
         Ok(())
     }
 
-    fn write_result(&mut self, desc: &TestDesc, result: &TestResult, _: &[u8]) -> io::Result<()> {
+    fn write_result(
+        &mut self,
+        desc: &TestDesc,
+        result: &TestResult,
+        _: &[u8],
+        _: &ConsoleTestState,
+    ) -> io::Result<()> {
         match *result {
             TrOk => self.write_ok(),
             TrFailed | TrFailedMsg(_) => self.write_failed(),
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index a1ce45dad4e9e..6e00e02b3c809 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -906,7 +906,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
             TeTimeout(ref test) => out.write_timeout(test),
             TeResult(test, result, stdout) => {
                 st.write_log_result(&test, &result)?;
-                out.write_result(&test, &result, &*stdout)?;
+                out.write_result(&test, &result, &*stdout, &st)?;
                 match result {
                     TrOk => {
                         st.passed += 1;
diff --git a/src/test/run-make-fulldeps/libtest-json/Makefile b/src/test/run-make-fulldeps/libtest-json/Makefile
index a0bc8cf6688bc..8339e230bbe92 100644
--- a/src/test/run-make-fulldeps/libtest-json/Makefile
+++ b/src/test/run-make-fulldeps/libtest-json/Makefile
@@ -2,13 +2,17 @@
 
 # Test expected libtest's JSON output
 
-OUTPUT_FILE := $(TMPDIR)/libtest-json-output.json
+OUTPUT_FILE_DEFAULT := $(TMPDIR)/libtest-json-output-default.json
+OUTPUT_FILE_STDOUT_SUCCESS := $(TMPDIR)/libtest-json-output-stdout-success.json
 
 all:
 	$(RUSTC) --test f.rs
-	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json > $(OUTPUT_FILE) || true
+	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json > $(OUTPUT_FILE_DEFAULT) || true
+	RUST_BACKTRACE=0 $(call RUN,f) -Z unstable-options --test-threads=1 --format=json --show-output > $(OUTPUT_FILE_STDOUT_SUCCESS) || true
 
-	cat $(OUTPUT_FILE) | "$(PYTHON)" validate_json.py
+	cat $(OUTPUT_FILE_DEFAULT) | "$(PYTHON)" validate_json.py
+	cat $(OUTPUT_FILE_STDOUT_SUCCESS) | "$(PYTHON)" validate_json.py
 
 	# Compare to output file
-	diff output.json $(OUTPUT_FILE)
+	diff output-default.json $(OUTPUT_FILE_DEFAULT)
+	diff output-stdout-success.json $(OUTPUT_FILE_STDOUT_SUCCESS)
diff --git a/src/test/run-make-fulldeps/libtest-json/f.rs b/src/test/run-make-fulldeps/libtest-json/f.rs
index f5e44c2c24407..95ff36bd764ec 100644
--- a/src/test/run-make-fulldeps/libtest-json/f.rs
+++ b/src/test/run-make-fulldeps/libtest-json/f.rs
@@ -1,11 +1,12 @@
 #[test]
 fn a() {
+    println!("print from successful test");
     // Should pass
 }
 
 #[test]
 fn b() {
-    assert!(false)
+    assert!(false);
 }
 
 #[test]
diff --git a/src/test/run-make-fulldeps/libtest-json/output.json b/src/test/run-make-fulldeps/libtest-json/output-default.json
similarity index 91%
rename from src/test/run-make-fulldeps/libtest-json/output.json
rename to src/test/run-make-fulldeps/libtest-json/output-default.json
index 0caf268aa007f..8046d72221703 100644
--- a/src/test/run-make-fulldeps/libtest-json/output.json
+++ b/src/test/run-make-fulldeps/libtest-json/output-default.json
@@ -2,7 +2,7 @@
 { "type": "test", "event": "started", "name": "a" }
 { "type": "test", "name": "a", "event": "ok" }
 { "type": "test", "event": "started", "name": "b" }
-{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:8:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" }
+{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" }
 { "type": "test", "event": "started", "name": "c" }
 { "type": "test", "name": "c", "event": "ok" }
 { "type": "test", "event": "started", "name": "d" }
diff --git a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json
new file mode 100644
index 0000000000000..303316278d8ab
--- /dev/null
+++ b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json
@@ -0,0 +1,10 @@
+{ "type": "suite", "event": "started", "test_count": 4 }
+{ "type": "test", "event": "started", "name": "a" }
+{ "type": "test", "name": "a", "event": "ok", "stdout": "print from successful test\n" }
+{ "type": "test", "event": "started", "name": "b" }
+{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" }
+{ "type": "test", "event": "started", "name": "c" }
+{ "type": "test", "name": "c", "event": "ok", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:15:5\n" }
+{ "type": "test", "event": "started", "name": "d" }
+{ "type": "test", "name": "d", "event": "ignored" }
+{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "allowed_fail": 0, "ignored": 1, "measured": 0, "filtered_out": 0 }

From cb873c5a87a70661ba4c9a6575374a738dd59481 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Tue, 16 Jul 2019 18:29:50 +0200
Subject: [PATCH 003/943] code formatting

---
 src/librustdoc/html/render.rs      | 18 ++++++++++--------
 src/librustdoc/html/static/main.js |  2 +-
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 3cd520fd4b50b..9813c36397e2e 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2575,13 +2575,14 @@ fn document(w: &mut fmt::Formatter<'_>, cx: &Context, item: &clean::Item) -> fmt
 }
 
 /// Render md_text as markdown.
-fn render_markdown(w: &mut fmt::Formatter<'_>,
-                   cx: &Context,
-                   md_text: &str,
-                   links: Vec<(String, String)>,
-                   prefix: &str,
-                   is_hidden: bool)
-                   -> fmt::Result {
+fn render_markdown(
+    w: &mut fmt::Formatter<'_>,
+    cx: &Context,
+    md_text: &str,
+    links: Vec<(String, String)>,
+    prefix: &str,
+    is_hidden: bool,
+) -> fmt::Result {
     let mut ids = cx.id_map.borrow_mut();
     write!(w, "<div class='docblock{}'>{}{}</div>",
            if is_hidden { " hidden" } else { "" },
@@ -2595,7 +2596,8 @@ fn document_short(
     cx: &Context,
     item: &clean::Item,
     link: AssocItemLink<'_>,
-    prefix: &str, is_hidden: bool
+    prefix: &str,
+    is_hidden: bool,
 ) -> fmt::Result {
     if let Some(s) = item.doc_value() {
         let markdown = if s.contains('\n') {
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 82d2c11b2497b..bc49d34b15bb3 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -3,7 +3,7 @@
 
 // Local js definitions:
 /* global addClass, getCurrentValue, hasClass */
-/* global isHidden onEach, removeClass, updateLocalStorage */
+/* global isHidden, onEach, removeClass, updateLocalStorage */
 
 if (!String.prototype.startsWith) {
     String.prototype.startsWith = function(searchString, position) {

From 145ae1b26375b8e003d39df402dbff24030fa774 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Tue, 16 Jul 2019 18:32:14 +0200
Subject: [PATCH 004/943] hide default trait methods by default

---
 src/librustdoc/html/render.rs | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 9813c36397e2e..b8d774dac2f64 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -4250,9 +4250,10 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
             RenderMode::ForDeref { mut_: deref_mut_ } => should_render_item(&item, deref_mut_),
         };
 
-        let (is_hidden, extra_class) = if trait_.is_none() ||
-                                          item.doc_value().is_some() ||
-                                          item.inner.is_associated() {
+        let (is_hidden, extra_class) = if (trait_.is_none() ||
+                                           item.doc_value().is_some() ||
+                                           item.inner.is_associated()) &&
+                                          !is_default_item {
             (false, "")
         } else {
             (true, " hidden")

From f7656b65764bf2134ffdd605bc182263c79fc508 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Tue, 16 Jul 2019 23:24:10 +0200
Subject: [PATCH 005/943] Update tests

---
 src/test/rustdoc/assoc-consts.rs                          | 2 +-
 src/test/rustdoc/inline_cross/assoc-items.rs              | 6 +++---
 .../rustdoc/inline_cross/impl-inline-without-trait.rs     | 2 +-
 src/test/rustdoc/manual_impl.rs                           | 8 ++++----
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/test/rustdoc/assoc-consts.rs b/src/test/rustdoc/assoc-consts.rs
index ee622e74a08dc..bb6af7995a0ad 100644
--- a/src/test/rustdoc/assoc-consts.rs
+++ b/src/test/rustdoc/assoc-consts.rs
@@ -95,5 +95,5 @@ impl Qux for Bar {
     /// Docs for QUX_DEFAULT1 in impl.
     const QUX_DEFAULT1: i16 = 7;
     // @has - '//*[@id="associatedconstant.QUX_DEFAULT2"]' 'const QUX_DEFAULT2: u32'
-    // @has - '//*[@class="docblock"]' "Docs for QUX_DEFAULT2 in trait."
+    // @has - '//*[@class="docblock hidden"]' "Docs for QUX_DEFAULT2 in trait."
 }
diff --git a/src/test/rustdoc/inline_cross/assoc-items.rs b/src/test/rustdoc/inline_cross/assoc-items.rs
index d4f05bab5cabf..7eb3e43cb114e 100644
--- a/src/test/rustdoc/inline_cross/assoc-items.rs
+++ b/src/test/rustdoc/inline_cross/assoc-items.rs
@@ -16,15 +16,15 @@ extern crate assoc_items;
 // @has - '//*[@id="associatedconstant.ConstNoDefault"]' 'const ConstNoDefault: i16'
 // @has - '//*[@class="docblock"]' 'dox for ConstNoDefault'
 // @has - '//*[@id="associatedconstant.ConstWithDefault"]' 'const ConstWithDefault: u16'
-// @has - '//*[@class="docblock"]' 'docs for ConstWithDefault'
+// @has - '//*[@class="docblock hidden"]' 'docs for ConstWithDefault'
 // @has - '//*[@id="associatedtype.TypeNoDefault"]' 'type TypeNoDefault = i32'
 // @has - '//*[@class="docblock"]' 'dox for TypeNoDefault'
 // @has - '//*[@id="associatedtype.TypeWithDefault"]' 'type TypeWithDefault = u32'
-// @has - '//*[@class="docblock"]' 'docs for TypeWithDefault'
+// @has - '//*[@class="docblock hidden"]' 'docs for TypeWithDefault'
 // @has - '//*[@id="method.method_no_default"]' 'fn method_no_default()'
 // @has - '//*[@class="docblock"]' 'dox for method_no_default'
 // @has - '//*[@id="method.method_with_default"]' 'fn method_with_default()'
-// @has - '//*[@class="docblock"]' 'docs for method_with_default'
+// @has - '//*[@class="docblock hidden"]' 'docs for method_with_default'
 pub use assoc_items::MyStruct;
 
 // @has foo/trait.MyTrait.html
diff --git a/src/test/rustdoc/inline_cross/impl-inline-without-trait.rs b/src/test/rustdoc/inline_cross/impl-inline-without-trait.rs
index cadeccb60c817..4591bb526ae77 100644
--- a/src/test/rustdoc/inline_cross/impl-inline-without-trait.rs
+++ b/src/test/rustdoc/inline_cross/impl-inline-without-trait.rs
@@ -8,5 +8,5 @@ extern crate impl_inline_without_trait;
 
 // @has 'foo/struct.MyStruct.html'
 // @has - '//*[@id="method.my_trait_method"]' 'fn my_trait_method()'
-// @has - '//*[@class="docblock"]' 'docs for my_trait_method'
+// @has - '//*[@class="docblock hidden"]' 'docs for my_trait_method'
 pub use impl_inline_without_trait::MyStruct;
diff --git a/src/test/rustdoc/manual_impl.rs b/src/test/rustdoc/manual_impl.rs
index c9e4f4e0d3037..11ddab5f7ff26 100644
--- a/src/test/rustdoc/manual_impl.rs
+++ b/src/test/rustdoc/manual_impl.rs
@@ -24,10 +24,10 @@ pub trait T {
 // @has  - '//*[@class="docblock"]' 'Docs associated with the S1 trait implementation.'
 // @has  - '//*[@class="docblock"]' 'Docs associated with the S1 trait a_method implementation.'
 // @!has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.'
-// @has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.'
-// @has - '//*[@class="docblock"]' 'Docs associated with the trait c_method definition.'
+// @has - '//*[@class="docblock hidden"]' 'Docs associated with the trait b_method definition.'
+// @has - '//*[@class="docblock hidden"]' 'Docs associated with the trait c_method definition.'
 // @!has - '//*[@class="docblock"]' 'There is another line'
-// @has - '//*[@class="docblock"]' 'Read more'
+// @has - '//*[@class="docblock hidden"]' 'Read more'
 pub struct S1(usize);
 
 /// Docs associated with the S1 trait implementation.
@@ -44,7 +44,7 @@ impl T for S1 {
 // @has  - '//*[@class="docblock"]' 'Docs associated with the S2 trait c_method implementation.'
 // @!has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.'
 // @!has - '//*[@class="docblock"]' 'Docs associated with the trait c_method definition.'
-// @has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.'
+// @has - '//*[@class="docblock hidden"]' 'Docs associated with the trait b_method definition.'
 pub struct S2(usize);
 
 /// Docs associated with the S2 trait implementation.

From a0ab5a3651f5cb30efa2f82a3ee15a7df479080a Mon Sep 17 00:00:00 2001
From: ksqsf <i@ksqsf.moe>
Date: Thu, 1 Aug 2019 00:26:47 +0800
Subject: [PATCH 006/943] Add Result::cloned{,_err} and Result::copied{,_err}

---
 src/libcore/result.rs | 160 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 160 insertions(+)

diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 559877ddd5a1c..a8f0f422cb4d7 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -820,6 +820,166 @@ impl<T, E> Result<T, E> {
     }
 }
 
+impl<T: Copy, E> Result<&T, E> {
+    /// Maps a `Result<&T, E>` to a `Result<T, E>` by copying the contents of the
+    /// `Ok` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_copied)]
+    /// let val = 12;
+    /// let x = Ok(&val);
+    /// assert_eq!(x, Ok(&12));
+    /// let copied = x.copied();
+    /// assert_eq!(copied, Ok(12));
+    /// ```
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "XXXXX")]
+    fn copied(self) -> Result<T, E> {
+        self.map(|&t| t)
+    }
+}
+
+impl<T: Copy, E> Result<&mut T, E> {
+    /// Maps a `Result<&mut T, E>` to a `Result<T, E>` by copying the contents of the
+    /// `Ok` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_copied)]
+    /// let val = 12;
+    /// let x = Ok(&mut val);
+    /// assert_eq!(x, Ok(&mut 12));
+    /// let copied = x.copied();
+    /// assert_eq!(copied, Ok(12));
+    /// ```
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "XXXXX")]
+    fn copied(self) -> Result<T, E> {
+        self.map(|&mut t| t)
+    }
+}
+
+impl<T, E: Copy> Result<T, &E> {
+    /// Maps a `Result<T, &E>` to a `Result<T, E>` by copying the contents of the
+    /// `Err` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_copied)]
+    /// let val = 12;
+    /// let x = Err(&val);
+    /// assert_eq!(x, Err(&12));
+    /// let copied = x.copied_err();
+    /// assert_eq!(copied, Err(12));
+    /// ```
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "XXXXX")]
+    fn copied_err(self) -> Result<T, E> {
+        self.map_err(|&e| e)
+    }
+}
+
+impl<T, E: Copy> Result<T, &mut E> {
+    /// Maps a `Result<T, &mut E>` to a `Result<T, E>` by copying the contents of the
+    /// `Err` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_copied)]
+    /// let val = 12;
+    /// let x = Err(&mut val);
+    /// assert_eq!(x, Err(&mut 12));
+    /// let copied = x.copied();
+    /// assert_eq!(cloned, Err(12));
+    /// ```
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "XXXXX")]
+    fn copied_err(self) -> Result<T, E> {
+        self.map_err(|&mut e| e)
+    }
+}
+
+impl<T: Clone, E> Result<&T, E> {
+    /// Maps a `Result<&T, E>` to a `Result<T, E>` by cloning the contents of the
+    /// `Ok` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_cloned)]
+    /// let val = 12;
+    /// let x = Ok(&val);
+    /// assert_eq!(x, Ok(&12));
+    /// let cloned = x.cloned();
+    /// assert_eq!(cloned, Ok(12));
+    /// ```
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "XXXXX")]
+    fn cloned(self) -> Result<T, E> {
+        self.map(|t| t.clone())
+    }
+}
+
+impl<T: Clone, E> Result<&mut T, E> {
+    /// Maps a `Result<&mut T, E>` to a `Result<T, E>` by cloning the contents of the
+    /// `Ok` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_cloned)]
+    /// let val = 12;
+    /// let x = Ok(&mut val);
+    /// assert_eq!(x, Ok(&mut 12));
+    /// let cloned = x.cloned();
+    /// assert_eq!(cloned, Ok(12));
+    /// ```
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "XXXXX")]
+    fn cloned(self) -> Result<T, E> {
+        self.map(|t| t.clone())
+    }
+}
+
+impl<T, E: Clone> Result<T, &mut E> {
+    /// Maps a `Result<T, &E>` to a `Result<T, E>` by cloning the contents of the
+    /// `Err` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_cloned)]
+    /// let val = 12;
+    /// let x = Err(&mut val);
+    /// assert_eq!(x, Err(&mut 12));
+    /// let cloned = x.cloned();
+    /// assert_eq!(cloned, Err(12));
+    /// ```
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "XXXXX")]
+    fn cloned_err(self) -> Result<T, E> {
+        self.map_err(|e| e.clone())
+    }
+}
+
+impl<T, E: Clone> Result<T, &mut E> {
+    /// Maps a `Result<T, &mut E>` to a `Result<T, E>` by cloning the contents of the
+    /// `Err` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_cloned)]
+    /// let val = 12;
+    /// let x = Err(&mut val);
+    /// assert_eq!(x, Err(&mut 12));
+    /// let cloned = x.cloned();
+    /// assert_eq!(cloned, Err(12));
+    /// ```
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "XXXXX")]
+    fn cloned_err(self) -> Result<T, E> {
+        self.map_err(|e| e.clone())
+    }
+}
+
 impl<T, E: fmt::Debug> Result<T, E> {
     /// Unwraps a result, yielding the content of an [`Ok`].
     ///

From c784720f3a2d0b66142da3c9a9fd6039f5d3a036 Mon Sep 17 00:00:00 2001
From: ksqsf <i@ksqsf.moe>
Date: Thu, 1 Aug 2019 00:55:36 +0800
Subject: [PATCH 007/943] Fix issue and impl

---
 src/libcore/result.rs | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index a8f0f422cb4d7..31584972b9f68 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -834,7 +834,7 @@ impl<T: Copy, E> Result<&T, E> {
     /// let copied = x.copied();
     /// assert_eq!(copied, Ok(12));
     /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "XXXXX")]
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
     fn copied(self) -> Result<T, E> {
         self.map(|&t| t)
     }
@@ -854,7 +854,7 @@ impl<T: Copy, E> Result<&mut T, E> {
     /// let copied = x.copied();
     /// assert_eq!(copied, Ok(12));
     /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "XXXXX")]
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
     fn copied(self) -> Result<T, E> {
         self.map(|&mut t| t)
     }
@@ -874,7 +874,7 @@ impl<T, E: Copy> Result<T, &E> {
     /// let copied = x.copied_err();
     /// assert_eq!(copied, Err(12));
     /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "XXXXX")]
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
     fn copied_err(self) -> Result<T, E> {
         self.map_err(|&e| e)
     }
@@ -894,7 +894,7 @@ impl<T, E: Copy> Result<T, &mut E> {
     /// let copied = x.copied();
     /// assert_eq!(cloned, Err(12));
     /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "XXXXX")]
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
     fn copied_err(self) -> Result<T, E> {
         self.map_err(|&mut e| e)
     }
@@ -914,7 +914,7 @@ impl<T: Clone, E> Result<&T, E> {
     /// let cloned = x.cloned();
     /// assert_eq!(cloned, Ok(12));
     /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "XXXXX")]
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
     fn cloned(self) -> Result<T, E> {
         self.map(|t| t.clone())
     }
@@ -934,13 +934,13 @@ impl<T: Clone, E> Result<&mut T, E> {
     /// let cloned = x.cloned();
     /// assert_eq!(cloned, Ok(12));
     /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "XXXXX")]
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
     fn cloned(self) -> Result<T, E> {
         self.map(|t| t.clone())
     }
 }
 
-impl<T, E: Clone> Result<T, &mut E> {
+impl<T, E: Clone> Result<T, &E> {
     /// Maps a `Result<T, &E>` to a `Result<T, E>` by cloning the contents of the
     /// `Err` part.
     ///
@@ -954,7 +954,7 @@ impl<T, E: Clone> Result<T, &mut E> {
     /// let cloned = x.cloned();
     /// assert_eq!(cloned, Err(12));
     /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "XXXXX")]
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
     fn cloned_err(self) -> Result<T, E> {
         self.map_err(|e| e.clone())
     }
@@ -974,7 +974,7 @@ impl<T, E: Clone> Result<T, &mut E> {
     /// let cloned = x.cloned();
     /// assert_eq!(cloned, Err(12));
     /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "XXXXX")]
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
     fn cloned_err(self) -> Result<T, E> {
         self.map_err(|e| e.clone())
     }

From 5a36b0dba1d7a350bba04b1abf256f057b3d1079 Mon Sep 17 00:00:00 2001
From: ksqsf <i@ksqsf.moe>
Date: Thu, 1 Aug 2019 01:09:07 +0800
Subject: [PATCH 008/943] Make these methods public

---
 src/libcore/result.rs | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 31584972b9f68..77cb447b95460 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -835,7 +835,7 @@ impl<T: Copy, E> Result<&T, E> {
     /// assert_eq!(copied, Ok(12));
     /// ```
     #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    fn copied(self) -> Result<T, E> {
+    pub fn copied(self) -> Result<T, E> {
         self.map(|&t| t)
     }
 }
@@ -855,7 +855,7 @@ impl<T: Copy, E> Result<&mut T, E> {
     /// assert_eq!(copied, Ok(12));
     /// ```
     #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    fn copied(self) -> Result<T, E> {
+    pub fn copied(self) -> Result<T, E> {
         self.map(|&mut t| t)
     }
 }
@@ -875,7 +875,7 @@ impl<T, E: Copy> Result<T, &E> {
     /// assert_eq!(copied, Err(12));
     /// ```
     #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    fn copied_err(self) -> Result<T, E> {
+    pub fn copied_err(self) -> Result<T, E> {
         self.map_err(|&e| e)
     }
 }
@@ -895,7 +895,7 @@ impl<T, E: Copy> Result<T, &mut E> {
     /// assert_eq!(cloned, Err(12));
     /// ```
     #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    fn copied_err(self) -> Result<T, E> {
+    pub fn copied_err(self) -> Result<T, E> {
         self.map_err(|&mut e| e)
     }
 }
@@ -915,7 +915,7 @@ impl<T: Clone, E> Result<&T, E> {
     /// assert_eq!(cloned, Ok(12));
     /// ```
     #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    fn cloned(self) -> Result<T, E> {
+    pub fn cloned(self) -> Result<T, E> {
         self.map(|t| t.clone())
     }
 }
@@ -935,7 +935,7 @@ impl<T: Clone, E> Result<&mut T, E> {
     /// assert_eq!(cloned, Ok(12));
     /// ```
     #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    fn cloned(self) -> Result<T, E> {
+    pub fn cloned(self) -> Result<T, E> {
         self.map(|t| t.clone())
     }
 }
@@ -955,7 +955,7 @@ impl<T, E: Clone> Result<T, &E> {
     /// assert_eq!(cloned, Err(12));
     /// ```
     #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    fn cloned_err(self) -> Result<T, E> {
+    pub fn cloned_err(self) -> Result<T, E> {
         self.map_err(|e| e.clone())
     }
 }
@@ -975,7 +975,7 @@ impl<T, E: Clone> Result<T, &mut E> {
     /// assert_eq!(cloned, Err(12));
     /// ```
     #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    fn cloned_err(self) -> Result<T, E> {
+    pub fn cloned_err(self) -> Result<T, E> {
         self.map_err(|e| e.clone())
     }
 }

From 6c130817623426697d8ebdf5d505487bd11ee2f6 Mon Sep 17 00:00:00 2001
From: ksqsf <i@ksqsf.moe>
Date: Thu, 1 Aug 2019 02:35:14 +0800
Subject: [PATCH 009/943] Rename {copied,cloned} to {copied,cloned}_ok, and add
 {copied,cloned} to copy/clone both Ok and Err

---
 src/libcore/result.rs | 144 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 140 insertions(+), 4 deletions(-)

diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 77cb447b95460..0aa8fcb69b9c6 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -835,7 +835,7 @@ impl<T: Copy, E> Result<&T, E> {
     /// assert_eq!(copied, Ok(12));
     /// ```
     #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied(self) -> Result<T, E> {
+    pub fn copied_ok(self) -> Result<T, E> {
         self.map(|&t| t)
     }
 }
@@ -855,7 +855,7 @@ impl<T: Copy, E> Result<&mut T, E> {
     /// assert_eq!(copied, Ok(12));
     /// ```
     #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied(self) -> Result<T, E> {
+    pub fn copied_ok(self) -> Result<T, E> {
         self.map(|&mut t| t)
     }
 }
@@ -900,6 +900,74 @@ impl<T, E: Copy> Result<T, &mut E> {
     }
 }
 
+impl<T: Copy, E: Copy> Result<&T, &E> {
+    /// Maps a `Result<&T, &E>` to a `Result<T, E>` by copying the
+    /// contents of the result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_copied)]
+    /// assert_eq!(Err(&1), Err(1));
+    /// assert_eq!(Ok(&42), Ok(42));
+    /// ```
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
+    pub fn copied(self) -> Result<T, E> {
+        self.copied_ok().copied_err()
+    }
+}
+
+impl<T: Copy, E: Copy> Result<&mut T, &E> {
+    /// Maps a `Result<&mut T, &E>` to a `Result<T, E>` by copying the
+    /// contents of the result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_copied)]
+    /// assert_eq!(Err(&1), Err(1));
+    /// assert_eq!(Ok(&mut 42), Ok(42));
+    /// ```
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
+    pub fn copied(self) -> Result<T, E> {
+        self.copied_ok().copied_err()
+    }
+}
+
+impl<T: Copy, E: Copy> Result<&T, &mut E> {
+    /// Maps a `Result<&T, &mut E>` to a `Result<T, E>` by copying the
+    /// contents of the result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_copied)]
+    /// assert_eq!(Err(&mut 1), Err(1));
+    /// assert_eq!(Ok(&42), Ok(42));
+    /// ```
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
+    pub fn copied(self) -> Result<T, E> {
+        self.copied_ok().copied_err()
+    }
+}
+
+impl<T: Copy, E: Copy> Result<&mut T, &mut E> {
+    /// Maps a `Result<&mut T, &mut E>` to a `Result<T, E>` by copying
+    /// the contents of the result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_copied)]
+    /// assert_eq!(Err(&mut 1), Err(1));
+    /// assert_eq!(Ok(&mut 42), Ok(42));
+    /// ```
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
+    pub fn copied(self) -> Result<T, E> {
+        self.copied_ok().copied_err()
+    }
+}
+
 impl<T: Clone, E> Result<&T, E> {
     /// Maps a `Result<&T, E>` to a `Result<T, E>` by cloning the contents of the
     /// `Ok` part.
@@ -915,7 +983,7 @@ impl<T: Clone, E> Result<&T, E> {
     /// assert_eq!(cloned, Ok(12));
     /// ```
     #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned(self) -> Result<T, E> {
+    pub fn cloned_ok(self) -> Result<T, E> {
         self.map(|t| t.clone())
     }
 }
@@ -935,7 +1003,7 @@ impl<T: Clone, E> Result<&mut T, E> {
     /// assert_eq!(cloned, Ok(12));
     /// ```
     #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned(self) -> Result<T, E> {
+    pub fn cloned_ok(self) -> Result<T, E> {
         self.map(|t| t.clone())
     }
 }
@@ -980,6 +1048,74 @@ impl<T, E: Clone> Result<T, &mut E> {
     }
 }
 
+impl<T: Clone, E: Clone> Result<&T, &E> {
+    /// Maps a `Result<&T, &E>` to a `Result<T, E>` by cloning the contents of the
+    /// result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_cloned)]
+    /// assert_eq!(Err(&1).cloned(), Err(1));
+    /// assert_eq!(Ok(&42).cloned(), Ok(42));
+    /// ```
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
+    pub fn cloned(self) -> Result<T, E> {
+        self.cloned_ok().cloned_err()
+    }
+}
+
+impl<T: Clone, E: Clone> Result<&mut T, &E> {
+    /// Maps a `Result<&mut T, &E>` to a `Result<T, E>` by cloning the
+    /// contents of the result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_cloned)]
+    /// assert_eq!(Err(&1).cloned(), Err(1));
+    /// assert_eq!(Ok(&mut 42).cloned(), Ok(42));
+    /// ```
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
+    pub fn cloned(self) -> Result<T, E> {
+        self.cloned_ok().cloned_err()
+    }
+}
+
+impl<T: Clone, E: Clone> Result<&T, &mut E> {
+    /// Maps a `Result<&T, &mut E>` to a `Result<T, E>` by cloning the
+    /// contents of the result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_cloned)]
+    /// assert_eq!(Err(&mut 1).cloned(), Err(1));
+    /// assert_eq!(Ok(&42).cloned(), Ok(42));
+    /// ```
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
+    pub fn cloned(self) -> Result<T, E> {
+        self.cloned_ok().cloned_err()
+    }
+}
+
+impl<T: Clone, E: Clone> Result<&mut T, &mut E> {
+    /// Maps a `Result<&mut T, &mut E>` to a `Result<T, E>` by cloning
+    /// the contents of the result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_cloned)]
+    /// assert_eq!(Err(&mut 1).cloned(), Err(1));
+    /// assert_eq!(Ok(&mut 42).cloned(), Ok(42));
+    /// ```
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
+    pub fn cloned(self) -> Result<T, E> {
+        self.cloned_ok().cloned_err()
+    }
+}
+
 impl<T, E: fmt::Debug> Result<T, E> {
     /// Unwraps a result, yielding the content of an [`Ok`].
     ///

From 4b2f598986e135f0eb070a9be87a5a963e8ff3d4 Mon Sep 17 00:00:00 2001
From: ksqsf <i@ksqsf.moe>
Date: Thu, 1 Aug 2019 13:38:23 +0800
Subject: [PATCH 010/943] Revert "cloned/copied"

This reverts commit 6c130817623426697d8ebdf5d505487bd11ee2f6.
---
 src/libcore/result.rs | 144 ++----------------------------------------
 1 file changed, 4 insertions(+), 140 deletions(-)

diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 0aa8fcb69b9c6..77cb447b95460 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -835,7 +835,7 @@ impl<T: Copy, E> Result<&T, E> {
     /// assert_eq!(copied, Ok(12));
     /// ```
     #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied_ok(self) -> Result<T, E> {
+    pub fn copied(self) -> Result<T, E> {
         self.map(|&t| t)
     }
 }
@@ -855,7 +855,7 @@ impl<T: Copy, E> Result<&mut T, E> {
     /// assert_eq!(copied, Ok(12));
     /// ```
     #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied_ok(self) -> Result<T, E> {
+    pub fn copied(self) -> Result<T, E> {
         self.map(|&mut t| t)
     }
 }
@@ -900,74 +900,6 @@ impl<T, E: Copy> Result<T, &mut E> {
     }
 }
 
-impl<T: Copy, E: Copy> Result<&T, &E> {
-    /// Maps a `Result<&T, &E>` to a `Result<T, E>` by copying the
-    /// contents of the result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_copied)]
-    /// assert_eq!(Err(&1), Err(1));
-    /// assert_eq!(Ok(&42), Ok(42));
-    /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied(self) -> Result<T, E> {
-        self.copied_ok().copied_err()
-    }
-}
-
-impl<T: Copy, E: Copy> Result<&mut T, &E> {
-    /// Maps a `Result<&mut T, &E>` to a `Result<T, E>` by copying the
-    /// contents of the result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_copied)]
-    /// assert_eq!(Err(&1), Err(1));
-    /// assert_eq!(Ok(&mut 42), Ok(42));
-    /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied(self) -> Result<T, E> {
-        self.copied_ok().copied_err()
-    }
-}
-
-impl<T: Copy, E: Copy> Result<&T, &mut E> {
-    /// Maps a `Result<&T, &mut E>` to a `Result<T, E>` by copying the
-    /// contents of the result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_copied)]
-    /// assert_eq!(Err(&mut 1), Err(1));
-    /// assert_eq!(Ok(&42), Ok(42));
-    /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied(self) -> Result<T, E> {
-        self.copied_ok().copied_err()
-    }
-}
-
-impl<T: Copy, E: Copy> Result<&mut T, &mut E> {
-    /// Maps a `Result<&mut T, &mut E>` to a `Result<T, E>` by copying
-    /// the contents of the result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_copied)]
-    /// assert_eq!(Err(&mut 1), Err(1));
-    /// assert_eq!(Ok(&mut 42), Ok(42));
-    /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied(self) -> Result<T, E> {
-        self.copied_ok().copied_err()
-    }
-}
-
 impl<T: Clone, E> Result<&T, E> {
     /// Maps a `Result<&T, E>` to a `Result<T, E>` by cloning the contents of the
     /// `Ok` part.
@@ -983,7 +915,7 @@ impl<T: Clone, E> Result<&T, E> {
     /// assert_eq!(cloned, Ok(12));
     /// ```
     #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned_ok(self) -> Result<T, E> {
+    pub fn cloned(self) -> Result<T, E> {
         self.map(|t| t.clone())
     }
 }
@@ -1003,7 +935,7 @@ impl<T: Clone, E> Result<&mut T, E> {
     /// assert_eq!(cloned, Ok(12));
     /// ```
     #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned_ok(self) -> Result<T, E> {
+    pub fn cloned(self) -> Result<T, E> {
         self.map(|t| t.clone())
     }
 }
@@ -1048,74 +980,6 @@ impl<T, E: Clone> Result<T, &mut E> {
     }
 }
 
-impl<T: Clone, E: Clone> Result<&T, &E> {
-    /// Maps a `Result<&T, &E>` to a `Result<T, E>` by cloning the contents of the
-    /// result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_cloned)]
-    /// assert_eq!(Err(&1).cloned(), Err(1));
-    /// assert_eq!(Ok(&42).cloned(), Ok(42));
-    /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned(self) -> Result<T, E> {
-        self.cloned_ok().cloned_err()
-    }
-}
-
-impl<T: Clone, E: Clone> Result<&mut T, &E> {
-    /// Maps a `Result<&mut T, &E>` to a `Result<T, E>` by cloning the
-    /// contents of the result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_cloned)]
-    /// assert_eq!(Err(&1).cloned(), Err(1));
-    /// assert_eq!(Ok(&mut 42).cloned(), Ok(42));
-    /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned(self) -> Result<T, E> {
-        self.cloned_ok().cloned_err()
-    }
-}
-
-impl<T: Clone, E: Clone> Result<&T, &mut E> {
-    /// Maps a `Result<&T, &mut E>` to a `Result<T, E>` by cloning the
-    /// contents of the result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_cloned)]
-    /// assert_eq!(Err(&mut 1).cloned(), Err(1));
-    /// assert_eq!(Ok(&42).cloned(), Ok(42));
-    /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned(self) -> Result<T, E> {
-        self.cloned_ok().cloned_err()
-    }
-}
-
-impl<T: Clone, E: Clone> Result<&mut T, &mut E> {
-    /// Maps a `Result<&mut T, &mut E>` to a `Result<T, E>` by cloning
-    /// the contents of the result.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_cloned)]
-    /// assert_eq!(Err(&mut 1).cloned(), Err(1));
-    /// assert_eq!(Ok(&mut 42).cloned(), Ok(42));
-    /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned(self) -> Result<T, E> {
-        self.cloned_ok().cloned_err()
-    }
-}
-
 impl<T, E: fmt::Debug> Result<T, E> {
     /// Unwraps a result, yielding the content of an [`Ok`].
     ///

From 9733f0d16382c728e502c3efb4f38a19270f8202 Mon Sep 17 00:00:00 2001
From: ksqsf <i@ksqsf.moe>
Date: Thu, 1 Aug 2019 17:12:13 +0800
Subject: [PATCH 011/943] Fix doc tests

---
 src/libcore/result.rs | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 77cb447b95460..7b9f6d9ff8a61 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -829,7 +829,7 @@ impl<T: Copy, E> Result<&T, E> {
     /// ```
     /// #![feature(result_copied)]
     /// let val = 12;
-    /// let x = Ok(&val);
+    /// let x: Result<&i32, i32> = Ok(&val);
     /// assert_eq!(x, Ok(&12));
     /// let copied = x.copied();
     /// assert_eq!(copied, Ok(12));
@@ -848,8 +848,8 @@ impl<T: Copy, E> Result<&mut T, E> {
     ///
     /// ```
     /// #![feature(result_copied)]
-    /// let val = 12;
-    /// let x = Ok(&mut val);
+    /// let mut val = 12;
+    /// let x: Result<&mut i32, i32> = Ok(&mut val);
     /// assert_eq!(x, Ok(&mut 12));
     /// let copied = x.copied();
     /// assert_eq!(copied, Ok(12));
@@ -869,7 +869,7 @@ impl<T, E: Copy> Result<T, &E> {
     /// ```
     /// #![feature(result_copied)]
     /// let val = 12;
-    /// let x = Err(&val);
+    /// let x: Result<i32, &i32> = Err(&val);
     /// assert_eq!(x, Err(&12));
     /// let copied = x.copied_err();
     /// assert_eq!(copied, Err(12));
@@ -888,11 +888,11 @@ impl<T, E: Copy> Result<T, &mut E> {
     ///
     /// ```
     /// #![feature(result_copied)]
-    /// let val = 12;
-    /// let x = Err(&mut val);
+    /// let mut val = 12;
+    /// let x: Result<i32, &mut i32> = Err(&mut val);
     /// assert_eq!(x, Err(&mut 12));
-    /// let copied = x.copied();
-    /// assert_eq!(cloned, Err(12));
+    /// let copied = x.copied_err();
+    /// assert_eq!(copied, Err(12));
     /// ```
     #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
     pub fn copied_err(self) -> Result<T, E> {
@@ -909,7 +909,7 @@ impl<T: Clone, E> Result<&T, E> {
     /// ```
     /// #![feature(result_cloned)]
     /// let val = 12;
-    /// let x = Ok(&val);
+    /// let x: Result<&i32, i32> = Ok(&val);
     /// assert_eq!(x, Ok(&12));
     /// let cloned = x.cloned();
     /// assert_eq!(cloned, Ok(12));
@@ -928,8 +928,8 @@ impl<T: Clone, E> Result<&mut T, E> {
     ///
     /// ```
     /// #![feature(result_cloned)]
-    /// let val = 12;
-    /// let x = Ok(&mut val);
+    /// let mut val = 12;
+    /// let x: Result<&mut i32, i32> = Ok(&mut val);
     /// assert_eq!(x, Ok(&mut 12));
     /// let cloned = x.cloned();
     /// assert_eq!(cloned, Ok(12));
@@ -949,9 +949,9 @@ impl<T, E: Clone> Result<T, &E> {
     /// ```
     /// #![feature(result_cloned)]
     /// let val = 12;
-    /// let x = Err(&mut val);
-    /// assert_eq!(x, Err(&mut 12));
-    /// let cloned = x.cloned();
+    /// let x: Result<i32, &i32> = Err(&val);
+    /// assert_eq!(x, Err(&12));
+    /// let cloned = x.cloned_err();
     /// assert_eq!(cloned, Err(12));
     /// ```
     #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
@@ -968,10 +968,10 @@ impl<T, E: Clone> Result<T, &mut E> {
     ///
     /// ```
     /// #![feature(result_cloned)]
-    /// let val = 12;
-    /// let x = Err(&mut val);
+    /// let mut val = 12;
+    /// let x: Result<i32, &mut i32> = Err(&mut val);
     /// assert_eq!(x, Err(&mut 12));
-    /// let cloned = x.cloned();
+    /// let cloned = x.cloned_err();
     /// assert_eq!(cloned, Err(12));
     /// ```
     #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]

From 61e52866352339326600fe694e92373f2e07fd79 Mon Sep 17 00:00:00 2001
From: ksqsf <i@ksqsf.moe>
Date: Fri, 2 Aug 2019 13:58:55 +0800
Subject: [PATCH 012/943] Remove Err variants of cloned and copied

---
 src/libcore/result.rs | 79 -------------------------------------------
 1 file changed, 79 deletions(-)

diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 7b9f6d9ff8a61..935e48574fdf5 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -860,46 +860,6 @@ impl<T: Copy, E> Result<&mut T, E> {
     }
 }
 
-impl<T, E: Copy> Result<T, &E> {
-    /// Maps a `Result<T, &E>` to a `Result<T, E>` by copying the contents of the
-    /// `Err` part.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_copied)]
-    /// let val = 12;
-    /// let x: Result<i32, &i32> = Err(&val);
-    /// assert_eq!(x, Err(&12));
-    /// let copied = x.copied_err();
-    /// assert_eq!(copied, Err(12));
-    /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied_err(self) -> Result<T, E> {
-        self.map_err(|&e| e)
-    }
-}
-
-impl<T, E: Copy> Result<T, &mut E> {
-    /// Maps a `Result<T, &mut E>` to a `Result<T, E>` by copying the contents of the
-    /// `Err` part.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_copied)]
-    /// let mut val = 12;
-    /// let x: Result<i32, &mut i32> = Err(&mut val);
-    /// assert_eq!(x, Err(&mut 12));
-    /// let copied = x.copied_err();
-    /// assert_eq!(copied, Err(12));
-    /// ```
-    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
-    pub fn copied_err(self) -> Result<T, E> {
-        self.map_err(|&mut e| e)
-    }
-}
-
 impl<T: Clone, E> Result<&T, E> {
     /// Maps a `Result<&T, E>` to a `Result<T, E>` by cloning the contents of the
     /// `Ok` part.
@@ -940,45 +900,6 @@ impl<T: Clone, E> Result<&mut T, E> {
     }
 }
 
-impl<T, E: Clone> Result<T, &E> {
-    /// Maps a `Result<T, &E>` to a `Result<T, E>` by cloning the contents of the
-    /// `Err` part.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_cloned)]
-    /// let val = 12;
-    /// let x: Result<i32, &i32> = Err(&val);
-    /// assert_eq!(x, Err(&12));
-    /// let cloned = x.cloned_err();
-    /// assert_eq!(cloned, Err(12));
-    /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned_err(self) -> Result<T, E> {
-        self.map_err(|e| e.clone())
-    }
-}
-
-impl<T, E: Clone> Result<T, &mut E> {
-    /// Maps a `Result<T, &mut E>` to a `Result<T, E>` by cloning the contents of the
-    /// `Err` part.
-    ///
-    /// # Examples
-    ///
-    /// ```
-    /// #![feature(result_cloned)]
-    /// let mut val = 12;
-    /// let x: Result<i32, &mut i32> = Err(&mut val);
-    /// assert_eq!(x, Err(&mut 12));
-    /// let cloned = x.cloned_err();
-    /// assert_eq!(cloned, Err(12));
-    /// ```
-    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
-    pub fn cloned_err(self) -> Result<T, E> {
-        self.map_err(|e| e.clone())
-    }
-}
 
 impl<T, E: fmt::Debug> Result<T, E> {
     /// Unwraps a result, yielding the content of an [`Ok`].

From ae1e7cace3971b2ed7e2e75fca74c554a36fbfd3 Mon Sep 17 00:00:00 2001
From: Stefan Schindler <dns2utf8@estada.ch>
Date: Thu, 25 Jul 2019 00:35:24 +0200
Subject: [PATCH 013/943] Match the loop examples

---
 src/libstd/keyword_docs.rs | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs
index f5018485ef7bc..5ca518358d7d9 100644
--- a/src/libstd/keyword_docs.rs
+++ b/src/libstd/keyword_docs.rs
@@ -681,14 +681,15 @@ mod while_keyword { }
 ///     # break;
 /// }
 ///
-/// let mut i = 0;
+/// let mut i = 1;
 /// loop {
 ///     println!("i is {}", i);
-///     if i > 10 {
+///     if i > 100 {
 ///         break;
 ///     }
-///     i += 1;
+///     i *= 2;
 /// }
+/// assert_eq!(i, 128);
 /// ```
 ///
 /// Unlike the other kinds of loops in Rust (`while`, `while let`, and `for`), loops can be used as

From 7b8273c2e873b814b7c115eabae398d6f11d695b Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Tue, 13 Aug 2019 17:21:45 +0300
Subject: [PATCH 014/943] Re-enable Redox builder (take 2)

---
 Cargo.lock                              | 120 ++++++++++++------------
 src/ci/docker/dist-various-1/Dockerfile |   6 +-
 2 files changed, 62 insertions(+), 64 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index ab6731e4d433d..38dba4f629885 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -92,7 +92,7 @@ name = "atty"
 version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -105,7 +105,7 @@ dependencies = [
  "backtrace-sys 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
@@ -117,7 +117,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
 
@@ -162,7 +162,7 @@ dependencies = [
  "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -269,7 +269,7 @@ dependencies = [
  "jobserver 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "libgit2-sys 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -453,7 +453,7 @@ name = "commoncrypto-sys"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -473,7 +473,7 @@ dependencies = [
  "env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -492,7 +492,7 @@ dependencies = [
  "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -523,7 +523,7 @@ version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -658,7 +658,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "curl-sys 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "schannel 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -672,7 +672,7 @@ version = "0.4.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -780,7 +780,7 @@ version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_users 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -791,7 +791,7 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-std-workspace-core 1.0.0",
 ]
 
@@ -904,7 +904,7 @@ version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -919,7 +919,7 @@ version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "miniz_oxide_c_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -964,7 +964,7 @@ name = "fs2"
 version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1054,7 +1054,7 @@ version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1063,7 +1063,7 @@ version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "libgit2-sys 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1348,7 +1348,7 @@ name = "iovec"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1385,7 +1385,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1393,7 +1393,7 @@ name = "jobserver"
 version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1441,7 +1441,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libc"
-version = "0.2.60"
+version = "0.2.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rustc-std-workspace-core 1.0.0",
@@ -1465,7 +1465,7 @@ version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "libssh2-sys 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1478,7 +1478,7 @@ version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1487,7 +1487,7 @@ version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1500,7 +1500,7 @@ version = "1.0.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1565,7 +1565,7 @@ version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1675,7 +1675,7 @@ name = "memmap"
 version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1725,7 +1725,7 @@ version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1743,7 +1743,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1757,7 +1757,7 @@ dependencies = [
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1782,7 +1782,7 @@ version = "0.6.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1832,7 +1832,7 @@ version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1849,7 +1849,7 @@ version = "0.2.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1892,7 +1892,7 @@ name = "num_cpus"
 version = "1.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1917,7 +1917,7 @@ dependencies = [
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1940,7 +1940,7 @@ version = "0.9.43"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-src 111.3.0+1.1.1c (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1979,7 +1979,7 @@ version = "0.0.0"
 dependencies = [
  "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -1990,7 +1990,7 @@ dependencies = [
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "unwind 0.0.0",
 ]
 
@@ -2008,7 +2008,7 @@ name = "parking_lot_core"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2230,7 +2230,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_chacha 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2247,7 +2247,7 @@ version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "getrandom 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2320,7 +2320,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2778,7 +2778,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2867,7 +2867,7 @@ dependencies = [
  "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)",
  "jobserver 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3372,7 +3372,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -3480,7 +3480,7 @@ version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -3512,7 +3512,7 @@ version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -3535,7 +3535,7 @@ dependencies = [
  "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "hashbrown 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "panic_abort 0.0.0",
  "panic_unwind 0.0.0",
  "profiler_builtins 0.0.0",
@@ -3712,7 +3712,7 @@ version = "0.4.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "filetime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -3723,7 +3723,7 @@ version = "3.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3776,7 +3776,7 @@ name = "termion"
 version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -3796,7 +3796,7 @@ version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -3832,7 +3832,7 @@ name = "time"
 version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -3923,7 +3923,7 @@ version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3955,7 +3955,7 @@ version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "signal-hook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4026,7 +4026,7 @@ dependencies = [
  "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -4160,7 +4160,7 @@ dependencies = [
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "core 0.0.0",
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -4329,7 +4329,7 @@ name = "xattr"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -4482,7 +4482,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
 "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
 "checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
-"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb"
+"checksum libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)" = "c665266eb592905e8503ba3403020f4b8794d26263f412ca33171600eca9a6fa"
 "checksum libflate 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "90c6f86f4b0caa347206f916f8b687b51d77c6ef8ff18d52dd007491fd580529"
 "checksum libgit2-sys 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4c179ed6d19cd3a051e68c177fbbc214e79ac4724fac3a850ec9f3d3eb8a5578"
 "checksum libnghttp2-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d75d7966bda4730b722d1eab8e668df445368a24394bae9fc1e8dc0ab3dbe4f4"
diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile
index ae2ea8ef95a6a..105791194628b 100644
--- a/src/ci/docker/dist-various-1/Dockerfile
+++ b/src/ci/docker/dist-various-1/Dockerfile
@@ -104,9 +104,7 @@ ENV TARGETS=$TARGETS,armv5te-unknown-linux-musleabi
 ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabihf
 ENV TARGETS=$TARGETS,aarch64-unknown-linux-musl
 ENV TARGETS=$TARGETS,sparc64-unknown-linux-gnu
-# FIXME: temporarily disable the redox builder,
-# see: https://github.com/rust-lang/rust/issues/63160
-# ENV TARGETS=$TARGETS,x86_64-unknown-redox
+ENV TARGETS=$TARGETS,x86_64-unknown-redox
 ENV TARGETS=$TARGETS,thumbv6m-none-eabi
 ENV TARGETS=$TARGETS,thumbv7m-none-eabi
 ENV TARGETS=$TARGETS,thumbv7em-none-eabi
@@ -132,7 +130,7 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
     CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \
     AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \
     CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++
-    
+
 ENV RUST_CONFIGURE_ARGS \
       --musl-root-armv5te=/musl-armv5te \
       --musl-root-arm=/musl-arm \

From 070c83d5a96d26240824abdb3c38ecdb860710f5 Mon Sep 17 00:00:00 2001
From: Andre Bogus <bogusandre@gmail.com>
Date: Mon, 5 Aug 2019 11:32:27 +0200
Subject: [PATCH 015/943] add contains benchmarks

---
 .../tiny_list/tests.rs                        | 35 +++++++++++++++----
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git a/src/librustc_data_structures/tiny_list/tests.rs b/src/librustc_data_structures/tiny_list/tests.rs
index 8374659e1e67b..0142631590cc9 100644
--- a/src/librustc_data_structures/tiny_list/tests.rs
+++ b/src/librustc_data_structures/tiny_list/tests.rs
@@ -1,7 +1,7 @@
 use super::*;
 
 extern crate test;
-use test::Bencher;
+use test::{Bencher, black_box};
 
 #[test]
 fn test_contains_and_insert() {
@@ -98,36 +98,59 @@ fn test_remove_single() {
 #[bench]
 fn bench_insert_empty(b: &mut Bencher) {
     b.iter(|| {
-        let mut list = TinyList::new();
+        let mut list = black_box(TinyList::new());
         list.insert(1);
+        list
     })
 }
 
 #[bench]
 fn bench_insert_one(b: &mut Bencher) {
     b.iter(|| {
-        let mut list = TinyList::new_single(0);
+        let mut list = black_box(TinyList::new_single(0));
         list.insert(1);
+        list
     })
 }
 
+#[bench]
+fn bench_contains_empty(b: &mut Bencher) {
+    b.iter(|| {
+        black_box(TinyList::new()).contains(&1)
+    });
+}
+
+#[bench]
+fn bench_contains_unknown(b: &mut Bencher) {
+    b.iter(|| {
+        black_box(TinyList::new_single(0)).contains(&1)
+    });
+}
+
+#[bench]
+fn bench_contains_one(b: &mut Bencher) {
+    b.iter(|| {
+        black_box(TinyList::new_single(1)).contains(&1)
+    });
+}
+
 #[bench]
 fn bench_remove_empty(b: &mut Bencher) {
     b.iter(|| {
-        TinyList::new().remove(&1)
+        black_box(TinyList::new()).remove(&1)
     });
 }
 
 #[bench]
 fn bench_remove_unknown(b: &mut Bencher) {
     b.iter(|| {
-        TinyList::new_single(0).remove(&1)
+        black_box(TinyList::new_single(0)).remove(&1)
     });
 }
 
 #[bench]
 fn bench_remove_one(b: &mut Bencher) {
     b.iter(|| {
-        TinyList::new_single(1).remove(&1)
+        black_box(TinyList::new_single(1)).remove(&1)
     });
 }

From 45f14a8c9026b33dc278000a5fc120e9667806ff Mon Sep 17 00:00:00 2001
From: Andre Bogus <bogusandre@gmail.com>
Date: Wed, 17 Jul 2019 08:19:29 +0200
Subject: [PATCH 016/943] refactor `len` and `contains` to iterate instead of
 recurse

---
 src/librustc_data_structures/tiny_list.rs | 56 +++++++----------------
 1 file changed, 16 insertions(+), 40 deletions(-)

diff --git a/src/librustc_data_structures/tiny_list.rs b/src/librustc_data_structures/tiny_list.rs
index 1c0d9360f2511..ea771d9f20f8b 100644
--- a/src/librustc_data_structures/tiny_list.rs
+++ b/src/librustc_data_structures/tiny_list.rs
@@ -20,7 +20,6 @@ pub struct TinyList<T: PartialEq> {
 }
 
 impl<T: PartialEq> TinyList<T> {
-
     #[inline]
     pub fn new() -> TinyList<T> {
         TinyList {
@@ -60,20 +59,24 @@ impl<T: PartialEq> TinyList<T> {
 
     #[inline]
     pub fn contains(&self, data: &T) -> bool {
-        if let Some(ref head) = self.head {
-            head.contains(data)
-        } else {
-            false
+        let mut elem = self.head.as_ref();
+        while let Some(ref e) = elem {
+            if &e.data == data {
+                return true;
+            }
+            elem = e.next.as_ref().map(|e| &**e);
         }
+        false
     }
 
     #[inline]
     pub fn len(&self) -> usize {
-        if let Some(ref head) = self.head {
-            head.len()
-        } else {
-            0
+        let (mut elem, mut count) = (self.head.as_ref(), 0);
+        while let Some(ref e) = elem {
+            count += 1;
+            elem = e.next.as_ref().map(|e| &**e);
         }
+        count
     }
 }
 
@@ -84,40 +87,13 @@ struct Element<T: PartialEq> {
 }
 
 impl<T: PartialEq> Element<T> {
-
     fn remove_next(&mut self, data: &T) -> bool {
-        let new_next = if let Some(ref mut next) = self.next {
-            if next.data != *data {
-                return next.remove_next(data)
-            } else {
-                next.next.take()
-            }
-        } else {
-            return false
+        let new_next = match self.next {
+            Some(ref mut next) if next.data == *data => next.next.take(),
+            Some(ref mut next) => return next.remove_next(data),
+            None => return false,
         };
-
         self.next = new_next;
-
         true
     }
-
-    fn len(&self) -> usize {
-        if let Some(ref next) = self.next {
-            1 + next.len()
-        } else {
-            1
-        }
-    }
-
-    fn contains(&self, data: &T) -> bool {
-        if self.data == *data {
-            return true
-        }
-
-        if let Some(ref next) = self.next {
-            next.contains(data)
-        } else {
-            false
-        }
-    }
 }

From 9b9eecf964235f781806ce3e026c1522eb35e013 Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Sat, 13 Jul 2019 04:00:06 +0200
Subject: [PATCH 017/943] Store allocation size, make bytes, undef_mask private

Direct access to the bytes was previously a problem (#62931) where
components would read their contents without properly checking
relocations and/or definedness.

Making bytes private instead of purely renaming them also helps in
allowing amendments to their allocation scheme (such as eliding
allocation for undef of constant regions).
---
 src/librustc/ich/impls_ty.rs             |  8 +++++-
 src/librustc/mir/interpret/allocation.rs | 35 ++++++++++++++++++------
 src/librustc/ty/print/pretty.rs          | 10 +++++--
 3 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 0ddc9211f9811..e33991bb1b6f8 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -176,15 +176,21 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
         hasher: &mut StableHasher<W>,
     ) {
         let mir::interpret::Allocation {
-            bytes, relocations, undef_mask, align, mutability,
+            relocations, align, mutability, size,
             extra: _,
+            .. /* private bytes and undef_mask */
         } = self;
+
+        let bytes = self.inspect_with_undef_and_ptr_outside_interpreter(0..self.len());
+        let undef_mask = self.undef_mask();
+
         bytes.hash_stable(hcx, hasher);
         relocations.len().hash_stable(hcx, hasher);
         for reloc in relocations.iter() {
             reloc.hash_stable(hcx, hasher);
         }
         undef_mask.hash_stable(hcx, hasher);
+        size.hash_stable(hcx, hasher);
         align.hash_stable(hcx, hasher);
         mutability.hash_stable(hcx, hasher);
     }
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index ce04cca96e0f9..61b237c0bb395 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -16,15 +16,17 @@ use std::borrow::Cow;
 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
 pub struct Allocation<Tag=(),Extra=()> {
     /// The actual bytes of the allocation.
-    /// Note that the bytes of a pointer represent the offset of the pointer
-    pub bytes: Vec<u8>,
+    /// Note that the bytes of a pointer represent the offset of the pointer.
+    bytes: Vec<u8>,
     /// Maps from byte addresses to extra data for each pointer.
     /// Only the first byte of a pointer is inserted into the map; i.e.,
     /// every entry in this map applies to `pointer_size` consecutive bytes starting
     /// at the given offset.
     pub relocations: Relocations<Tag>,
-    /// Denotes undefined memory. Reading from undefined memory is forbidden in miri
-    pub undef_mask: UndefMask,
+    /// Denotes which part of this allocation is initialized.
+    undef_mask: UndefMask,
+    /// The size of the allocation. Currently, must always equal `bytes.len()`.
+    pub size: Size,
     /// The alignment of the allocation to detect unaligned reads.
     pub align: Align,
     /// Whether the allocation is mutable.
@@ -85,11 +87,12 @@ impl<Tag> Allocation<Tag> {
     /// Creates a read-only allocation initialized by the given bytes
     pub fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, align: Align) -> Self {
         let bytes = slice.into().into_owned();
-        let undef_mask = UndefMask::new(Size::from_bytes(bytes.len() as u64), true);
+        let size = Size::from_bytes(bytes.len() as u64);
         Self {
             bytes,
             relocations: Relocations::new(),
-            undef_mask,
+            undef_mask: UndefMask::new(size, true),
+            size,
             align,
             mutability: Mutability::Immutable,
             extra: (),
@@ -106,6 +109,7 @@ impl<Tag> Allocation<Tag> {
             bytes: vec![0; size.bytes() as usize],
             relocations: Relocations::new(),
             undef_mask: UndefMask::new(size, false),
+            size,
             align,
             mutability: Mutability::Mutable,
             extra: (),
@@ -113,6 +117,21 @@ impl<Tag> Allocation<Tag> {
     }
 }
 
+/// Raw accessors. Provide access to otherwise private bytes.
+impl<Tag, Extra> Allocation<Tag, Extra> {
+    pub fn len(&self) -> usize {
+        self.size.bytes() as usize
+    }
+
+    /// Look at a slice which may describe undefined bytes or describe a relocation. This differs
+    /// from `get_bytes_with_undef_and_ptr` in that it does no relocation checks (even on the
+    /// edges) at all. It further ignores `AllocationExtra` callbacks.
+    /// This must not be used for reads affecting the interpreter execution.
+    pub fn inspect_with_undef_and_ptr_outside_interpreter(&self, range: Range<usize>) -> &[u8] {
+        &self.bytes[range]
+    }
+}
+
 impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Allocation {}
 
 /// Byte accessors
@@ -132,9 +151,9 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         );
         let end = end.bytes() as usize;
         assert!(
-            end <= self.bytes.len(),
+            end <= self.len(),
             "Out-of-bounds access at offset {}, size {} in allocation of size {}",
-            offset.bytes(), size.bytes(), self.bytes.len()
+            offset.bytes(), size.bytes(), self.len()
         );
         (offset.bytes() as usize)..end
     }
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index bf6741dde43b5..a72ecdb5745bb 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -944,10 +944,16 @@ pub trait PrettyPrinter<'tcx>:
                         .get_bytes(&self.tcx(), ptr, Size::from_bytes(n)).unwrap())
                 },
                 (ConstValue::Slice { data, start, end }, ty::Slice(t)) if *t == u8 => {
-                    Some(&data.bytes[start..end])
+                    // The `inspect` here is okay since we checked the bounds, and there are no
+                    // relocations (we have an active slice reference here). We don't use this
+                    // result to affect interpreter execution.
+                    Some(data.inspect_with_undef_and_ptr_outside_interpreter(start..end))
                 },
                 (ConstValue::Slice { data, start, end }, ty::Str) => {
-                    let slice = &data.bytes[start..end];
+                    // The `inspect` here is okay since we checked the bounds, and there are no
+                    // relocations (we have an active `str` reference here). We don't use this
+                    // result to affect interpreter execution.
+                    let slice = data.inspect_with_undef_and_ptr_outside_interpreter(start..end);
                     let s = ::std::str::from_utf8(slice)
                         .expect("non utf8 str from miri");
                     p!(write("{:?}", s));

From 2228b3f08631b5e9b32e6b6c82e758fe4bcbbd60 Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Sat, 17 Aug 2019 19:49:51 +0200
Subject: [PATCH 018/943] Derive HashStable for Allocation

Requires a manual implementation for Relocations since dereferencing to
SortedMap is not always implemented but that one is far more trivial.
Added fields could otherwise be silently forgotten since private fields
make destructing outside the module possible only with `..` pattern
which would then also be applicable to newly added public fields.
---
 src/librustc/ich/impls_ty.rs             | 26 ++++++++----------------
 src/librustc/mir/interpret/allocation.rs | 13 +++++++++++-
 2 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index e33991bb1b6f8..be7669fcad875 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -168,31 +168,21 @@ impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::AllocId {
     }
 }
 
-// Allocations treat their relocations specially
-impl<'a> HashStable<StableHashingContext<'a>> for mir::interpret::Allocation {
+// `Relocations` with default type parameters is a sorted map.
+impl<'a, Tag> HashStable<StableHashingContext<'a>>
+for mir::interpret::Relocations<Tag>
+where
+    Tag: HashStable<StableHashingContext<'a>>,
+{
     fn hash_stable<W: StableHasherResult>(
         &self,
         hcx: &mut StableHashingContext<'a>,
         hasher: &mut StableHasher<W>,
     ) {
-        let mir::interpret::Allocation {
-            relocations, align, mutability, size,
-            extra: _,
-            .. /* private bytes and undef_mask */
-        } = self;
-
-        let bytes = self.inspect_with_undef_and_ptr_outside_interpreter(0..self.len());
-        let undef_mask = self.undef_mask();
-
-        bytes.hash_stable(hcx, hasher);
-        relocations.len().hash_stable(hcx, hasher);
-        for reloc in relocations.iter() {
+        self.len().hash_stable(hcx, hasher);
+        for reloc in self.iter() {
             reloc.hash_stable(hcx, hasher);
         }
-        undef_mask.hash_stable(hcx, hasher);
-        size.hash_stable(hcx, hasher);
-        align.hash_stable(hcx, hasher);
-        mutability.hash_stable(hcx, hasher);
     }
 }
 
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index 61b237c0bb395..363fcaae5b266 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -13,7 +13,18 @@ use rustc_data_structures::sorted_map::SortedMap;
 use rustc_target::abi::HasDataLayout;
 use std::borrow::Cow;
 
-#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(
+    Clone,
+    Debug,
+    Eq,
+    PartialEq,
+    PartialOrd,
+    Ord,
+    Hash,
+    RustcEncodable,
+    RustcDecodable,
+    HashStable,
+)]
 pub struct Allocation<Tag=(),Extra=()> {
     /// The actual bytes of the allocation.
     /// Note that the bytes of a pointer represent the offset of the pointer.

From 98cff6928925256faffbe3e9ce9f14d0dfdbb6c0 Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Tue, 30 Jul 2019 23:38:02 +0200
Subject: [PATCH 019/943] Move copy of undef_mask into allocation

This also means that the compressed representation chosen may be
optimized together with any changes to the undef_mask.
---
 src/librustc/mir/interpret/allocation.rs | 85 ++++++++++++++++++++++++
 src/librustc_mir/interpret/memory.rs     | 58 +---------------
 2 files changed, 88 insertions(+), 55 deletions(-)

diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index 363fcaae5b266..e0ada7e2f11a3 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -566,6 +566,91 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
     }
 }
 
+/// Run-length encoding of the undef mask.
+/// Used to copy parts of a mask multiple times to another allocation.
+pub struct AllocationDefinedness {
+    ranges: smallvec::SmallVec::<[u64; 1]>,
+    first: bool,
+}
+
+/// Transferring the definedness mask to other allocations.
+impl<Tag, Extra> Allocation<Tag, Extra> {
+    /// Creates a run-length encoding of the undef_mask.
+    pub fn compress_defined_range(
+        &self,
+        src: Pointer<Tag>,
+        size: Size,
+    ) -> AllocationDefinedness {
+        // Since we are copying `size` bytes from `src` to `dest + i * size` (`for i in 0..repeat`),
+        // a naive undef mask copying algorithm would repeatedly have to read the undef mask from
+        // the source and write it to the destination. Even if we optimized the memory accesses,
+        // we'd be doing all of this `repeat` times.
+        // Therefor we precompute a compressed version of the undef mask of the source value and
+        // then write it back `repeat` times without computing any more information from the source.
+
+        // a precomputed cache for ranges of defined/undefined bits
+        // 0000010010001110 will become
+        // [5, 1, 2, 1, 3, 3, 1]
+        // where each element toggles the state
+
+        let mut ranges = smallvec::SmallVec::<[u64; 1]>::new();
+        let first = self.undef_mask.get(src.offset);
+        let mut cur_len = 1;
+        let mut cur = first;
+
+        for i in 1..size.bytes() {
+            // FIXME: optimize to bitshift the current undef block's bits and read the top bit
+            if self.undef_mask.get(src.offset + Size::from_bytes(i)) == cur {
+                cur_len += 1;
+            } else {
+                ranges.push(cur_len);
+                cur_len = 1;
+                cur = !cur;
+            }
+        }
+
+        ranges.push(cur_len);
+
+        AllocationDefinedness { ranges, first, }
+    }
+
+    /// Apply multiple instances of the run-length encoding to the undef_mask.
+    pub fn mark_compressed_range(
+        &mut self,
+        defined: &AllocationDefinedness,
+        dest: Pointer<Tag>,
+        size: Size,
+        repeat: u64,
+    ) {
+        // an optimization where we can just overwrite an entire range of definedness bits if
+        // they are going to be uniformly `1` or `0`.
+        if defined.ranges.len() <= 1 {
+            self.undef_mask.set_range_inbounds(
+                dest.offset,
+                dest.offset + size * repeat,
+                defined.first,
+            );
+            return;
+        }
+
+        for mut j in 0..repeat {
+            j *= size.bytes();
+            j += dest.offset.bytes();
+            let mut cur = defined.first;
+            for range in &defined.ranges {
+                let old_j = j;
+                j += range;
+                self.undef_mask.set_range_inbounds(
+                    Size::from_bytes(old_j),
+                    Size::from_bytes(j),
+                    cur,
+                );
+                cur = !cur;
+            }
+        }
+    }
+}
+
 /// Relocations
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct Relocations<Tag=(), Id=AllocId>(SortedMap<Size, (Tag, Id)>);
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index aef09df4537be..f572651f02b56 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -894,65 +894,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // The bits have to be saved locally before writing to dest in case src and dest overlap.
         assert_eq!(size.bytes() as usize as u64, size.bytes());
 
-        let undef_mask = &self.get(src.alloc_id)?.undef_mask;
-
-        // Since we are copying `size` bytes from `src` to `dest + i * size` (`for i in 0..repeat`),
-        // a naive undef mask copying algorithm would repeatedly have to read the undef mask from
-        // the source and write it to the destination. Even if we optimized the memory accesses,
-        // we'd be doing all of this `repeat` times.
-        // Therefor we precompute a compressed version of the undef mask of the source value and
-        // then write it back `repeat` times without computing any more information from the source.
-
-        // a precomputed cache for ranges of defined/undefined bits
-        // 0000010010001110 will become
-        // [5, 1, 2, 1, 3, 3, 1]
-        // where each element toggles the state
-        let mut ranges = smallvec::SmallVec::<[u64; 1]>::new();
-        let first = undef_mask.get(src.offset);
-        let mut cur_len = 1;
-        let mut cur = first;
-        for i in 1..size.bytes() {
-            // FIXME: optimize to bitshift the current undef block's bits and read the top bit
-            if undef_mask.get(src.offset + Size::from_bytes(i)) == cur {
-                cur_len += 1;
-            } else {
-                ranges.push(cur_len);
-                cur_len = 1;
-                cur = !cur;
-            }
-        }
+        let src_alloc = self.get(src.alloc_id)?;
+        let compressed = src_alloc.compress_defined_range(src, size);
 
         // now fill in all the data
         let dest_allocation = self.get_mut(dest.alloc_id)?;
-        // an optimization where we can just overwrite an entire range of definedness bits if
-        // they are going to be uniformly `1` or `0`.
-        if ranges.is_empty() {
-            dest_allocation.undef_mask.set_range_inbounds(
-                dest.offset,
-                dest.offset + size * repeat,
-                first,
-            );
-            return Ok(())
-        }
+        dest_allocation.mark_compressed_range(&compressed, dest, size, repeat);
 
-        // remember to fill in the trailing bits
-        ranges.push(cur_len);
-
-        for mut j in 0..repeat {
-            j *= size.bytes();
-            j += dest.offset.bytes();
-            let mut cur = first;
-            for range in &ranges {
-                let old_j = j;
-                j += range;
-                dest_allocation.undef_mask.set_range_inbounds(
-                    Size::from_bytes(old_j),
-                    Size::from_bytes(j),
-                    cur,
-                );
-                cur = !cur;
-            }
-        }
         Ok(())
     }
 

From 5d75654cce9bb174b874ff7d8eb2ccd70e9b268f Mon Sep 17 00:00:00 2001
From: Artyom Pavlov <newpavlov@gmail.com>
Date: Sat, 17 Aug 2019 19:15:36 +0000
Subject: [PATCH 020/943] fix Cargo.lock

---
 Cargo.lock | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Cargo.lock b/Cargo.lock
index 59571bc7f6d54..c0e85c6487dee 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3529,7 +3529,6 @@ dependencies = [
  "fortanix-sgx-abi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.61 (registry+https://github.com/rust-lang/crates.io-index)",
- "hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "panic_abort 0.0.0",
  "panic_unwind 0.0.0",
  "profiler_builtins 0.0.0",

From e0f73052a93eee54400b7d4f788181b28bb54b4d Mon Sep 17 00:00:00 2001
From: GrayJack <gr41.j4ck@gmail.com>
Date: Sun, 18 Aug 2019 07:13:33 -0300
Subject: [PATCH 021/943] Constify LinkedList new function

---
 src/liballoc/collections/linked_list.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs
index a14a3fe9994ab..816a71f255798 100644
--- a/src/liballoc/collections/linked_list.rs
+++ b/src/liballoc/collections/linked_list.rs
@@ -276,7 +276,7 @@ impl<T> LinkedList<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn new() -> Self {
+    pub const fn new() -> Self {
         LinkedList {
             head: None,
             tail: None,

From 6896ed383dbd3a847ef39b713449fc0393292828 Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 09:47:58 +0300
Subject: [PATCH 022/943] use wasi crate

---
 src/libstd/sys/wasi/args.rs   |  16 +-
 src/libstd/sys/wasi/ext/fs.rs |   8 +-
 src/libstd/sys/wasi/ext/io.rs |   8 +-
 src/libstd/sys/wasi/fd.rs     | 302 +++++++++++-----------------------
 src/libstd/sys/wasi/fs.rs     | 176 +++++++++-----------
 src/libstd/sys/wasi/io.rs     |  11 +-
 src/libstd/sys/wasi/mod.rs    |  31 ++--
 src/libstd/sys/wasi/os.rs     |  29 +---
 src/libstd/sys/wasi/stdio.rs  |  11 +-
 src/libstd/sys/wasi/thread.rs |   4 +-
 src/libstd/sys/wasi/time.rs   |  29 ++--
 11 files changed, 249 insertions(+), 376 deletions(-)

diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs
index 8b4b354d9fc20..679bb1b2cbe30 100644
--- a/src/libstd/sys/wasi/args.rs
+++ b/src/libstd/sys/wasi/args.rs
@@ -27,14 +27,24 @@ pub fn args() -> Args {
     })
 }
 
+fn cvt_wasi(r: u16) -> crate::io::Result<()> {
+    if r != 0 {
+        Err(Error::from_raw_os_error(r as i32))
+    } else {
+        Ok(())
+    }
+}
+
 fn maybe_args() -> io::Result<Args> {
+    // FIXME: replace with safe functions
+    use wasi::wasi_unstable::raw::{__wasi_args_sizes_get, __wasi_args_get};
     unsafe {
         let (mut argc, mut argv_buf_size) = (0, 0);
-        cvt_wasi(libc::__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?;
+        cvt_wasi(__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?;
 
-        let mut argc = vec![core::ptr::null_mut::<libc::c_char>(); argc];
+        let mut argc = vec![core::ptr::null_mut::<u8>(); argc];
         let mut argv_buf = vec![0; argv_buf_size];
-        cvt_wasi(libc::__wasi_args_get(argc.as_mut_ptr(), argv_buf.as_mut_ptr()))?;
+        cvt_wasi(__wasi_args_get(argc.as_mut_ptr(), argv_buf.as_mut_ptr()))?;
 
         let args = argc.into_iter()
             .map(|ptr| CStr::from_ptr(ptr).to_bytes().to_vec())
diff --git a/src/libstd/sys/wasi/ext/fs.rs b/src/libstd/sys/wasi/ext/fs.rs
index 0ec4122f385da..ecd509f01dabd 100644
--- a/src/libstd/sys/wasi/ext/fs.rs
+++ b/src/libstd/sys/wasi/ext/fs.rs
@@ -336,16 +336,16 @@ pub trait FileTypeExt {
 
 impl FileTypeExt for fs::FileType {
     fn is_block_device(&self) -> bool {
-        self.as_inner().bits() == libc::__WASI_FILETYPE_BLOCK_DEVICE
+        self.as_inner().bits() == wasi::FILETYPE_BLOCK_DEVICE
     }
     fn is_character_device(&self) -> bool {
-        self.as_inner().bits() == libc::__WASI_FILETYPE_CHARACTER_DEVICE
+        self.as_inner().bits() == wasi::FILETYPE_CHARACTER_DEVICE
     }
     fn is_socket_dgram(&self) -> bool {
-        self.as_inner().bits() == libc::__WASI_FILETYPE_SOCKET_DGRAM
+        self.as_inner().bits() == wasi::FILETYPE_SOCKET_DGRAM
     }
     fn is_socket_stream(&self) -> bool {
-        self.as_inner().bits() == libc::__WASI_FILETYPE_SOCKET_STREAM
+        self.as_inner().bits() == wasi::FILETYPE_SOCKET_STREAM
     }
 }
 
diff --git a/src/libstd/sys/wasi/ext/io.rs b/src/libstd/sys/wasi/ext/io.rs
index 12afd1d42dc19..c843144f0c406 100644
--- a/src/libstd/sys/wasi/ext/io.rs
+++ b/src/libstd/sys/wasi/ext/io.rs
@@ -8,6 +8,8 @@ use crate::sys;
 use crate::net;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 
+use wasi::wasi_unstable as wasi;
+
 /// Raw file descriptors.
 pub type RawFd = u32;
 
@@ -125,18 +127,18 @@ impl IntoRawFd for fs::File {
 
 impl AsRawFd for io::Stdin {
     fn as_raw_fd(&self) -> RawFd {
-        libc::STDIN_FILENO as u32
+        wasi::STDIN_FD
     }
 }
 
 impl AsRawFd for io::Stdout {
     fn as_raw_fd(&self) -> RawFd {
-        libc::STDOUT_FILENO as u32
+        wasi::STDOUT_FD
     }
 }
 
 impl AsRawFd for io::Stderr {
     fn as_raw_fd(&self) -> RawFd {
-        libc::STDERR_FILENO as u32
+        wasi::STDERR_FD
     }
 }
diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs
index 25692ec086801..93fe8add326c8 100644
--- a/src/libstd/sys/wasi/fd.rs
+++ b/src/libstd/sys/wasi/fd.rs
@@ -3,348 +3,240 @@
 use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem;
 use crate::net::Shutdown;
-use crate::sys::cvt_wasi;
-use libc::{self, c_char, c_void};
+use wasi::wasi_unstable as wasi;
 
 #[derive(Debug)]
 pub struct WasiFd {
-    fd: libc::__wasi_fd_t,
+    fd: wasi::Fd,
 }
 
-// FIXME: these should probably all be fancier structs, builders, enums, etc
-pub type LookupFlags = u32;
-pub type FdFlags = u16;
-pub type Advice = u8;
-pub type Rights = u64;
-pub type Oflags = u16;
-pub type DirCookie = u64;
-pub type Timestamp = u64;
-pub type FstFlags = u16;
-pub type RiFlags = u16;
-pub type RoFlags = u16;
-pub type SiFlags = u16;
-
-fn iovec(a: &mut [IoSliceMut<'_>]) -> (*const libc::__wasi_iovec_t, usize) {
+fn iovec(a: &mut [IoSliceMut<'_>]) -> &[wasi::IoVec] {
     assert_eq!(
         mem::size_of::<IoSliceMut<'_>>(),
-        mem::size_of::<libc::__wasi_iovec_t>()
+        mem::size_of::<wasi::IoVec>()
     );
     assert_eq!(
         mem::align_of::<IoSliceMut<'_>>(),
-        mem::align_of::<libc::__wasi_iovec_t>()
+        mem::align_of::<wasi::IoVec>()
     );
-    (a.as_ptr() as *const libc::__wasi_iovec_t, a.len())
+    /// SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout
+    unsafe { mem::transmute(a) }
 }
 
-fn ciovec(a: &[IoSlice<'_>]) -> (*const libc::__wasi_ciovec_t, usize) {
+fn ciovec(a: &[IoSlice<'_>]) -> &[wasi::CIoVec] {
     assert_eq!(
         mem::size_of::<IoSlice<'_>>(),
-        mem::size_of::<libc::__wasi_ciovec_t>()
+        mem::size_of::<wasi::CIoVec>()
     );
     assert_eq!(
         mem::align_of::<IoSlice<'_>>(),
-        mem::align_of::<libc::__wasi_ciovec_t>()
+        mem::align_of::<wasi::CIoVec>()
     );
-    (a.as_ptr() as *const libc::__wasi_ciovec_t, a.len())
+    /// SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout
+    unsafe { mem::transmute(a) }
 }
 
 impl WasiFd {
-    pub unsafe fn from_raw(fd: libc::__wasi_fd_t) -> WasiFd {
+    pub unsafe fn from_raw(fd: wasi::Fd) -> WasiFd {
         WasiFd { fd }
     }
 
-    pub fn into_raw(self) -> libc::__wasi_fd_t {
+    pub fn into_raw(self) -> wasi::Fd {
         let ret = self.fd;
         mem::forget(self);
         ret
     }
 
-    pub fn as_raw(&self) -> libc::__wasi_fd_t {
+    pub fn as_raw(&self) -> wasi::Fd {
         self.fd
     }
 
     pub fn datasync(&self) -> io::Result<()> {
-        cvt_wasi(unsafe { libc::__wasi_fd_datasync(self.fd) })
+        wasi::fd_datasync(self.fd).map_err(From::from)
     }
 
     pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
-        let mut read = 0;
-        let (ptr, len) = iovec(bufs);
-        cvt_wasi(unsafe { libc::__wasi_fd_pread(self.fd, ptr, len, offset, &mut read) })?;
-        Ok(read)
+        wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(From::from)
     }
 
     pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
-        let mut read = 0;
-        let (ptr, len) = ciovec(bufs);
-        cvt_wasi(unsafe { libc::__wasi_fd_pwrite(self.fd, ptr, len, offset, &mut read) })?;
-        Ok(read)
+        wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(From::from)
     }
 
     pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        let mut read = 0;
-        let (ptr, len) = iovec(bufs);
-        cvt_wasi(unsafe { libc::__wasi_fd_read(self.fd, ptr, len, &mut read) })?;
-        Ok(read)
+        wasi::fd_read(self.fd, iovec(bufs)).map_err(From::from)
     }
 
     pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        let mut read = 0;
-        let (ptr, len) = ciovec(bufs);
-        cvt_wasi(unsafe { libc::__wasi_fd_write(self.fd, ptr, len, &mut read) })?;
-        Ok(read)
+        wasi::fd_write(self.fd, ciovec(bufs)).map_err(From::from)
     }
 
     pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
         let (whence, offset) = match pos {
-            SeekFrom::Start(pos) => (libc::__WASI_WHENCE_SET, pos as i64),
-            SeekFrom::End(pos) => (libc::__WASI_WHENCE_END, pos),
-            SeekFrom::Current(pos) => (libc::__WASI_WHENCE_CUR, pos),
+            SeekFrom::Start(pos) => (wasi::WHENCE_SET, pos as i64),
+            SeekFrom::End(pos) => (wasi::WHENCE_END, pos),
+            SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos),
         };
-        let mut pos = 0;
-        cvt_wasi(unsafe { libc::__wasi_fd_seek(self.fd, offset, whence, &mut pos) })?;
-        Ok(pos)
+        wasi::fd_seek(self.fd, offset, whence).map_err(From::from)
     }
 
     pub fn tell(&self) -> io::Result<u64> {
-        let mut pos = 0;
-        cvt_wasi(unsafe { libc::__wasi_fd_tell(self.fd, &mut pos) })?;
-        Ok(pos)
+        wasi::fd_tell(self.fd).map_err(From::from)
     }
 
     // FIXME: __wasi_fd_fdstat_get
 
-    pub fn set_flags(&self, flags: FdFlags) -> io::Result<()> {
-        cvt_wasi(unsafe { libc::__wasi_fd_fdstat_set_flags(self.fd, flags) })
+    pub fn set_flags(&self, flags: wasi::FdFlags) -> io::Result<()> {
+        wasi::fd_fdstat_set_flags(self.fd, flags).map_err(From::from)
     }
 
-    pub fn set_rights(&self, base: Rights, inheriting: Rights) -> io::Result<()> {
-        cvt_wasi(unsafe { libc::__wasi_fd_fdstat_set_rights(self.fd, base, inheriting) })
+    pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> {
+        wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(From::from)
     }
 
     pub fn sync(&self) -> io::Result<()> {
-        cvt_wasi(unsafe { libc::__wasi_fd_sync(self.fd) })
+        wasi::fd_sync(self.fd).map_err(From::from)
     }
 
-    pub fn advise(&self, offset: u64, len: u64, advice: Advice) -> io::Result<()> {
-        cvt_wasi(unsafe { libc::__wasi_fd_advise(self.fd, offset, len, advice as u8) })
+    pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
+        wasi::fd_advise(self.fd, offset, len, advice).map_err(From::from)
     }
 
     pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> {
-        cvt_wasi(unsafe { libc::__wasi_fd_allocate(self.fd, offset, len) })
+        wasi::fd_allocate(self.fd, offset, len).map_err(From::from)
     }
 
     pub fn create_directory(&self, path: &[u8]) -> io::Result<()> {
-        cvt_wasi(unsafe {
-            libc::__wasi_path_create_directory(self.fd, path.as_ptr() as *const c_char, path.len())
-        })
+        wasi::path_create_directory(self.fd, path).map_err(From::from)
     }
 
     pub fn link(
         &self,
-        old_flags: LookupFlags,
+        old_flags: wasi::LookupFlags,
         old_path: &[u8],
         new_fd: &WasiFd,
         new_path: &[u8],
     ) -> io::Result<()> {
-        cvt_wasi(unsafe {
-            libc::__wasi_path_link(
-                self.fd,
-                old_flags,
-                old_path.as_ptr() as *const c_char,
-                old_path.len(),
-                new_fd.fd,
-                new_path.as_ptr() as *const c_char,
-                new_path.len(),
-            )
-        })
+        wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path)
+            .map_err(From::from)
     }
 
     pub fn open(
         &self,
-        dirflags: LookupFlags,
+        dirflags: wasi::LookupFlags,
         path: &[u8],
-        oflags: Oflags,
-        fs_rights_base: Rights,
-        fs_rights_inheriting: Rights,
-        fs_flags: FdFlags,
+        oflags: wasi::OFlags,
+        fs_rights_base: wasi::Rights,
+        fs_rights_inheriting: wasi::Rights,
+        fs_flags: wasi::FdFlags,
     ) -> io::Result<WasiFd> {
-        unsafe {
-            let mut fd = 0;
-            cvt_wasi(libc::__wasi_path_open(
-                self.fd,
-                dirflags,
-                path.as_ptr() as *const c_char,
-                path.len(),
-                oflags,
-                fs_rights_base,
-                fs_rights_inheriting,
-                fs_flags,
-                &mut fd,
-            ))?;
-            Ok(WasiFd::from_raw(fd))
-        }
-    }
-
-    pub fn readdir(&self, buf: &mut [u8], cookie: DirCookie) -> io::Result<usize> {
-        let mut used = 0;
-        cvt_wasi(unsafe {
-            libc::__wasi_fd_readdir(
-                self.fd,
-                buf.as_mut_ptr() as *mut c_void,
-                buf.len(),
-                cookie,
-                &mut used,
-            )
-        })?;
-        Ok(used)
+        let fd = wasi_path_open(
+            self.fd,
+            dirflags,
+            path,
+            oflags,
+            fs_rights_base,
+            fs_rights_inheriting,
+            fs_flags,
+        )?;
+        Ok(WasiFd::from_raw(fd))
+    }
+
+    pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result<usize> {
+        wasi::fd_readdir(self.fd, buf, cookie).map_err(From::from)
     }
 
     pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result<usize> {
-        let mut used = 0;
-        cvt_wasi(unsafe {
-            libc::__wasi_path_readlink(
-                self.fd,
-                path.as_ptr() as *const c_char,
-                path.len(),
-                buf.as_mut_ptr() as *mut c_char,
-                buf.len(),
-                &mut used,
-            )
-        })?;
-        Ok(used)
+        wasi::path_readlink(self.fd, path, buf).map_err(From::from)
     }
 
     pub fn rename(&self, old_path: &[u8], new_fd: &WasiFd, new_path: &[u8]) -> io::Result<()> {
-        cvt_wasi(unsafe {
-            libc::__wasi_path_rename(
-                self.fd,
-                old_path.as_ptr() as *const c_char,
-                old_path.len(),
-                new_fd.fd,
-                new_path.as_ptr() as *const c_char,
-                new_path.len(),
-            )
-        })
+        wasi::path_rename(self.fd, old_path, new_fd.fd, new_path)
+            .map_err(From::from)
     }
 
-    pub fn filestat_get(&self, buf: *mut libc::__wasi_filestat_t) -> io::Result<()> {
-        cvt_wasi(unsafe { libc::__wasi_fd_filestat_get(self.fd, buf) })
+    pub fn filestat_get(&self) -> io::Result<wasi::Filestat> {
+        wasi::fd_filestat_get(self.fd, buf).map_err(From::from)
     }
 
     pub fn filestat_set_times(
         &self,
-        atim: Timestamp,
-        mtim: Timestamp,
-        fstflags: FstFlags,
+        atim: wasi::Timestamp,
+        mtim: wasi::Timestamp,
+        fstflags: wasi::FstFlags,
     ) -> io::Result<()> {
-        cvt_wasi(unsafe { libc::__wasi_fd_filestat_set_times(self.fd, atim, mtim, fstflags) })
+        wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags)
+            .map_err(From::from)
     }
 
     pub fn filestat_set_size(&self, size: u64) -> io::Result<()> {
-        cvt_wasi(unsafe { libc::__wasi_fd_filestat_set_size(self.fd, size) })
+        wasi::fd_filestat_set_size(self.fd, size).map_err(From::from)
     }
 
     pub fn path_filestat_get(
         &self,
-        flags: LookupFlags,
+        flags: wasi::LookupFlags,
         path: &[u8],
-        buf: *mut libc::__wasi_filestat_t,
-    ) -> io::Result<()> {
-        cvt_wasi(unsafe {
-            libc::__wasi_path_filestat_get(
-                self.fd,
-                flags,
-                path.as_ptr() as *const c_char,
-                path.len(),
-                buf,
-            )
-        })
+    ) -> io::Result<wasi::FileStat> {
+        wasi::path_filestat_get(self.fd, flags, path).map_err(From::from)
     }
 
     pub fn path_filestat_set_times(
         &self,
-        flags: LookupFlags,
+        flags: wasi::LookupFlags,
         path: &[u8],
-        atim: Timestamp,
-        mtim: Timestamp,
-        fstflags: FstFlags,
+        atim: wasi::Timestamp,
+        mtim: wasi::Timestamp,
+        fstflags: wasi::FstFlags,
     ) -> io::Result<()> {
-        cvt_wasi(unsafe {
-            libc::__wasi_path_filestat_set_times(
-                self.fd,
-                flags,
-                path.as_ptr() as *const c_char,
-                path.len(),
-                atim,
-                mtim,
-                fstflags,
-            )
-        })
+        wasi::path_filestat_set_times(
+            self.fd,
+            flags,
+            path,
+            atim,
+            mtim,
+            fstflags,
+        ).map_err(From::from)
     }
 
     pub fn symlink(&self, old_path: &[u8], new_path: &[u8]) -> io::Result<()> {
-        cvt_wasi(unsafe {
-            libc::__wasi_path_symlink(
-                old_path.as_ptr() as *const c_char,
-                old_path.len(),
-                self.fd,
-                new_path.as_ptr() as *const c_char,
-                new_path.len(),
-            )
-        })
+        wasi::path_symlink(old_path, self.fd, new_path).map_err(From::from)
     }
 
     pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> {
-        cvt_wasi(unsafe {
-            libc::__wasi_path_unlink_file(self.fd, path.as_ptr() as *const c_char, path.len())
-        })
+        wasi::path_unlink_file(self.fd, path).map_err(From::from)
     }
 
     pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> {
-        cvt_wasi(unsafe {
-            libc::__wasi_path_remove_directory(self.fd, path.as_ptr() as *const c_char, path.len())
-        })
+        wasi::path_remove_directory(self.fd, path).map_err(From::from)
     }
 
     pub fn sock_recv(
         &self,
         ri_data: &mut [IoSliceMut<'_>],
-        ri_flags: RiFlags,
-    ) -> io::Result<(usize, RoFlags)> {
-        let mut ro_datalen = 0;
-        let mut ro_flags = 0;
-        let (ptr, len) = iovec(ri_data);
-        cvt_wasi(unsafe {
-            libc::__wasi_sock_recv(self.fd, ptr, len, ri_flags, &mut ro_datalen, &mut ro_flags)
-        })?;
-        Ok((ro_datalen, ro_flags))
+        ri_flags: wasi::RiFlags,
+    ) -> io::Result<(usize, wasi::RoFlags)> {
+        wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(From::from)
     }
 
-    pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: SiFlags) -> io::Result<usize> {
-        let mut so_datalen = 0;
-        let (ptr, len) = ciovec(si_data);
-        cvt_wasi(unsafe { libc::__wasi_sock_send(self.fd, ptr, len, si_flags, &mut so_datalen) })?;
-        Ok(so_datalen)
+    pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::SiFlags) -> io::Result<usize> {
+        wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(From::from)
     }
 
     pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
         let how = match how {
-            Shutdown::Read => libc::__WASI_SHUT_RD,
-            Shutdown::Write => libc::__WASI_SHUT_WR,
-            Shutdown::Both => libc::__WASI_SHUT_WR | libc::__WASI_SHUT_RD,
+            Shutdown::Read => WASI::SHUT_RD,
+            Shutdown::Write => WASI::SHUT_WR,
+            Shutdown::Both => WASI::SHUT_WR | WASI::SHUT_RD,
         };
-        cvt_wasi(unsafe { libc::__wasi_sock_shutdown(self.fd, how) })?;
-        Ok(())
+        wasi::sock_shutdown(self.fd, how).map_err(From::from)
     }
 }
 
 impl Drop for WasiFd {
     fn drop(&mut self) {
-        unsafe {
-            // FIXME: can we handle the return code here even though we can't on
-            // unix?
-            libc::__wasi_fd_close(self.fd);
-        }
+        // FIXME: can we handle the return code here even though we can't on
+        // unix?
+        let _ = wasi::fd_close(self.fd);
     }
 }
diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs
index 172c60385b317..f23ecfc2bcd22 100644
--- a/src/libstd/sys/wasi/fs.rs
+++ b/src/libstd/sys/wasi/fs.rs
@@ -15,13 +15,15 @@ use crate::sys_common::FromInner;
 pub use crate::sys_common::fs::copy;
 pub use crate::sys_common::fs::remove_dir_all;
 
+use wasi::wasi_unstable as wasi;
+
 pub struct File {
     fd: WasiFd,
 }
 
 #[derive(Clone)]
 pub struct FileAttr {
-    meta: libc::__wasi_filestat_t,
+    meta: wasi::FileStat,
 }
 
 pub struct ReadDir {
@@ -38,7 +40,7 @@ struct ReadDirInner {
 }
 
 pub struct DirEntry {
-    meta: libc::__wasi_dirent_t,
+    meta: wasi::Dirent,
     name: Vec<u8>,
     inner: Arc<ReadDirInner>,
 }
@@ -47,11 +49,11 @@ pub struct DirEntry {
 pub struct OpenOptions {
     read: bool,
     write: bool,
-    dirflags: libc::__wasi_lookupflags_t,
-    fdflags: libc::__wasi_fdflags_t,
-    oflags: libc::__wasi_oflags_t,
-    rights_base: Option<libc::__wasi_rights_t>,
-    rights_inheriting: Option<libc::__wasi_rights_t>,
+    dirflags: wasi::LookupFlags,
+    fdflags: wasi::FdFlags,
+    oflags: wasi::OFlags,
+    rights_base: Option<wasi::Rights>,
+    rights_inheriting: Option<wasi::Rights>,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug)]
@@ -61,7 +63,7 @@ pub struct FilePermissions {
 
 #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
 pub struct FileType {
-    bits: libc::__wasi_filetype_t,
+    bits: wasi::FileType,
 }
 
 #[derive(Debug)]
@@ -101,7 +103,7 @@ impl FileAttr {
         Ok(SystemTime::from_wasi_timestamp(self.meta.st_ctim))
     }
 
-    pub fn as_wasi(&self) -> &libc::__wasi_filestat_t {
+    pub fn as_wasi(&self) -> &wasi::FileStat {
         &self.meta
     }
 }
@@ -118,18 +120,18 @@ impl FilePermissions {
 
 impl FileType {
     pub fn is_dir(&self) -> bool {
-        self.bits == libc::__WASI_FILETYPE_DIRECTORY
+        self.bits == wasi::FILETYPE_DIRECTORY
     }
 
     pub fn is_file(&self) -> bool {
-        self.bits == libc::__WASI_FILETYPE_REGULAR_FILE
+        self.bits == wasi::FILETYPE_REGULAR_FILE
     }
 
     pub fn is_symlink(&self) -> bool {
-        self.bits == libc::__WASI_FILETYPE_SYMBOLIC_LINK
+        self.bits == wasi::FILETYPE_SYMBOLIC_LINK
     }
 
-    pub fn bits(&self) -> libc::__wasi_filetype_t {
+    pub fn bits(&self) -> wasi::FileType {
         self.bits
     }
 }
@@ -173,7 +175,7 @@ impl Iterator for ReadDir {
             // must have been truncated at the end of the buffer, so reset our
             // offset so we can go back and reread into the buffer, picking up
             // where we last left off.
-            let dirent_size = mem::size_of::<libc::__wasi_dirent_t>();
+            let dirent_size = mem::size_of::<wasi::Dirent>();
             if data.len() < dirent_size {
                 assert!(self.cookie.is_some());
                 assert!(self.buf.len() >= dirent_size);
@@ -182,7 +184,7 @@ impl Iterator for ReadDir {
             }
             let (dirent, data) = data.split_at(dirent_size);
             let dirent =
-                unsafe { ptr::read_unaligned(dirent.as_ptr() as *const libc::__wasi_dirent_t) };
+                unsafe { ptr::read_unaligned(dirent.as_ptr() as *const wasi::Dirent) };
 
             // If the file name was truncated, then we need to reinvoke
             // `readdir` so we truncate our buffer to start over and reread this
@@ -241,7 +243,7 @@ impl DirEntry {
         })
     }
 
-    pub fn ino(&self) -> libc::__wasi_inode_t {
+    pub fn ino(&self) -> wasi::Inode {
         self.meta.d_ino
     }
 }
@@ -249,7 +251,7 @@ impl DirEntry {
 impl OpenOptions {
     pub fn new() -> OpenOptions {
         let mut base = OpenOptions::default();
-        base.dirflags = libc::__WASI_LOOKUP_SYMLINK_FOLLOW;
+        base.dirflags = wasi::LOOKUP_SYMLINK_FOLLOW;
         return base;
     }
 
@@ -262,23 +264,23 @@ impl OpenOptions {
     }
 
     pub fn truncate(&mut self, truncate: bool) {
-        self.oflag(libc::__WASI_O_TRUNC, truncate);
+        self.oflag(wasi::O_TRUNC, truncate);
     }
 
     pub fn create(&mut self, create: bool) {
-        self.oflag(libc::__WASI_O_CREAT, create);
+        self.oflag(wasi::O_CREAT, create);
     }
 
     pub fn create_new(&mut self, create_new: bool) {
-        self.oflag(libc::__WASI_O_EXCL, create_new);
-        self.oflag(libc::__WASI_O_CREAT, create_new);
+        self.oflag(wasi::O_EXCL, create_new);
+        self.oflag(wasi::O_CREAT, create_new);
     }
 
     pub fn directory(&mut self, directory: bool) {
-        self.oflag(libc::__WASI_O_DIRECTORY, directory);
+        self.oflag(wasi::O_DIRECTORY, directory);
     }
 
-    fn oflag(&mut self, bit: libc::__wasi_oflags_t, set: bool) {
+    fn oflag(&mut self, bit: wasi::OFlags, set: bool) {
         if set {
             self.oflags |= bit;
         } else {
@@ -287,26 +289,26 @@ impl OpenOptions {
     }
 
     pub fn append(&mut self, set: bool) {
-        self.fdflag(libc::__WASI_FDFLAG_APPEND, set);
+        self.fdflag(wasi::FDFLAG_APPEND, set);
     }
 
     pub fn dsync(&mut self, set: bool) {
-        self.fdflag(libc::__WASI_FDFLAG_DSYNC, set);
+        self.fdflag(wasi::FDFLAG_DSYNC, set);
     }
 
     pub fn nonblock(&mut self, set: bool) {
-        self.fdflag(libc::__WASI_FDFLAG_NONBLOCK, set);
+        self.fdflag(wasi::FDFLAG_NONBLOCK, set);
     }
 
     pub fn rsync(&mut self, set: bool) {
-        self.fdflag(libc::__WASI_FDFLAG_RSYNC, set);
+        self.fdflag(wasi::FDFLAG_RSYNC, set);
     }
 
     pub fn sync(&mut self, set: bool) {
-        self.fdflag(libc::__WASI_FDFLAG_SYNC, set);
+        self.fdflag(wasi::FDFLAG_SYNC, set);
     }
 
-    fn fdflag(&mut self, bit: libc::__wasi_fdflags_t, set: bool) {
+    fn fdflag(&mut self, bit: wasi::FdFlags, set: bool) {
         if set {
             self.fdflags |= bit;
         } else {
@@ -314,15 +316,15 @@ impl OpenOptions {
         }
     }
 
-    pub fn fs_rights_base(&mut self, rights: libc::__wasi_rights_t) {
+    pub fn fs_rights_base(&mut self, rights: wasi::Rights) {
         self.rights_base = Some(rights);
     }
 
-    pub fn fs_rights_inheriting(&mut self, rights: libc::__wasi_rights_t) {
+    pub fn fs_rights_inheriting(&mut self, rights: wasi::Rights) {
         self.rights_inheriting = Some(rights);
     }
 
-    fn rights_base(&self) -> libc::__wasi_rights_t {
+    fn rights_base(&self) -> wasi::Rights {
         if let Some(rights) = self.rights_base {
             return rights;
         }
@@ -334,52 +336,52 @@ impl OpenOptions {
         // based on that.
         let mut base = 0;
         if self.read {
-            base |= libc::__WASI_RIGHT_FD_READ;
-            base |= libc::__WASI_RIGHT_FD_READDIR;
+            base |= wasi::RIGHT_FD_READ;
+            base |= wasi::RIGHT_FD_READDIR;
         }
         if self.write {
-            base |= libc::__WASI_RIGHT_FD_WRITE;
-            base |= libc::__WASI_RIGHT_FD_DATASYNC;
-            base |= libc::__WASI_RIGHT_FD_ALLOCATE;
-            base |= libc::__WASI_RIGHT_FD_FILESTAT_SET_SIZE;
+            base |= wasi::RIGHT_FD_WRITE;
+            base |= wasi::RIGHT_FD_DATASYNC;
+            base |= wasi::RIGHT_FD_ALLOCATE;
+            base |= wasi::RIGHT_FD_FILESTAT_SET_SIZE;
         }
 
         // FIXME: some of these should probably be read-only or write-only...
-        base |= libc::__WASI_RIGHT_FD_ADVISE;
-        base |= libc::__WASI_RIGHT_FD_FDSTAT_SET_FLAGS;
-        base |= libc::__WASI_RIGHT_FD_FILESTAT_SET_TIMES;
-        base |= libc::__WASI_RIGHT_FD_SEEK;
-        base |= libc::__WASI_RIGHT_FD_SYNC;
-        base |= libc::__WASI_RIGHT_FD_TELL;
-        base |= libc::__WASI_RIGHT_PATH_CREATE_DIRECTORY;
-        base |= libc::__WASI_RIGHT_PATH_CREATE_FILE;
-        base |= libc::__WASI_RIGHT_PATH_FILESTAT_GET;
-        base |= libc::__WASI_RIGHT_PATH_LINK_SOURCE;
-        base |= libc::__WASI_RIGHT_PATH_LINK_TARGET;
-        base |= libc::__WASI_RIGHT_PATH_OPEN;
-        base |= libc::__WASI_RIGHT_PATH_READLINK;
-        base |= libc::__WASI_RIGHT_PATH_REMOVE_DIRECTORY;
-        base |= libc::__WASI_RIGHT_PATH_RENAME_SOURCE;
-        base |= libc::__WASI_RIGHT_PATH_RENAME_TARGET;
-        base |= libc::__WASI_RIGHT_PATH_SYMLINK;
-        base |= libc::__WASI_RIGHT_PATH_UNLINK_FILE;
-        base |= libc::__WASI_RIGHT_POLL_FD_READWRITE;
+        base |= wasi::RIGHT_FD_ADVISE;
+        base |= wasi::RIGHT_FD_FDSTAT_SET_FLAGS;
+        base |= wasi::RIGHT_FD_FILESTAT_SET_TIMES;
+        base |= wasi::RIGHT_FD_SEEK;
+        base |= wasi::RIGHT_FD_SYNC;
+        base |= wasi::RIGHT_FD_TELL;
+        base |= wasi::RIGHT_PATH_CREATE_DIRECTORY;
+        base |= wasi::RIGHT_PATH_CREATE_FILE;
+        base |= wasi::RIGHT_PATH_FILESTAT_GET;
+        base |= wasi::RIGHT_PATH_LINK_SOURCE;
+        base |= wasi::RIGHT_PATH_LINK_TARGET;
+        base |= wasi::RIGHT_PATH_OPEN;
+        base |= wasi::RIGHT_PATH_READLINK;
+        base |= wasi::RIGHT_PATH_REMOVE_DIRECTORY;
+        base |= wasi::RIGHT_PATH_RENAME_SOURCE;
+        base |= wasi::RIGHT_PATH_RENAME_TARGET;
+        base |= wasi::RIGHT_PATH_SYMLINK;
+        base |= wasi::RIGHT_PATH_UNLINK_FILE;
+        base |= wasi::RIGHT_POLL_FD_READWRITE;
 
         return base;
     }
 
-    fn rights_inheriting(&self) -> libc::__wasi_rights_t {
+    fn rights_inheriting(&self) -> wasi::Rights {
         self.rights_inheriting.unwrap_or_else(|| self.rights_base())
     }
 
-    pub fn lookup_flags(&mut self, flags: libc::__wasi_lookupflags_t) {
+    pub fn lookup_flags(&mut self, flags: wasi::LookupFlags) {
         self.dirflags = flags;
     }
 }
 
 impl File {
     pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
-        let (dir, file) = open_parent(path, libc::__WASI_RIGHT_PATH_OPEN)?;
+        let (dir, file) = open_parent(path, wasi::RIGHT_PATH_OPEN)?;
         open_at(&dir, &file, opts)
     }
 
@@ -388,14 +390,12 @@ impl File {
     }
 
     pub fn file_attr(&self) -> io::Result<FileAttr> {
-        let mut ret = FileAttr::zero();
-        self.fd.filestat_get(&mut ret.meta)?;
-        Ok(ret)
+        self.fd.filestat_get().map_ok(|meta| FileAttr { meta })
     }
 
     pub fn metadata_at(
         &self,
-        flags: libc::__wasi_lookupflags_t,
+        flags: wasi::LookupFlags,
         path: &Path,
     ) -> io::Result<FileAttr> {
         metadata_at(&self.fd, flags, path)
@@ -477,7 +477,7 @@ impl DirBuilder {
     }
 
     pub fn mkdir(&self, p: &Path) -> io::Result<()> {
-        let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_CREATE_DIRECTORY)?;
+        let (dir, file) = open_parent(p, wasi::RIGHT_PATH_CREATE_DIRECTORY)?;
         dir.create_directory(file.as_os_str().as_bytes())
     }
 }
@@ -508,13 +508,13 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
 }
 
 pub fn unlink(p: &Path) -> io::Result<()> {
-    let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_UNLINK_FILE)?;
+    let (dir, file) = open_parent(p, wasi::RIGHT_PATH_UNLINK_FILE)?;
     dir.unlink_file(file.as_os_str().as_bytes())
 }
 
 pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
-    let (old, old_file) = open_parent(old, libc::__WASI_RIGHT_PATH_RENAME_SOURCE)?;
-    let (new, new_file) = open_parent(new, libc::__WASI_RIGHT_PATH_RENAME_TARGET)?;
+    let (old, old_file) = open_parent(old, wasi::RIGHT_PATH_RENAME_SOURCE)?;
+    let (new, new_file) = open_parent(new, wasi::RIGHT_PATH_RENAME_TARGET)?;
     old.rename(
         old_file.as_os_str().as_bytes(),
         &new,
@@ -529,12 +529,12 @@ pub fn set_perm(_p: &Path, _perm: FilePermissions) -> io::Result<()> {
 }
 
 pub fn rmdir(p: &Path) -> io::Result<()> {
-    let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_REMOVE_DIRECTORY)?;
+    let (dir, file) = open_parent(p, wasi::RIGHT_PATH_REMOVE_DIRECTORY)?;
     dir.remove_directory(file.as_os_str().as_bytes())
 }
 
 pub fn readlink(p: &Path) -> io::Result<PathBuf> {
-    let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_READLINK)?;
+    let (dir, file) = open_parent(p, wasi::RIGHT_PATH_READLINK)?;
     read_link(&dir, &file)
 }
 
@@ -570,15 +570,15 @@ fn read_link(fd: &WasiFd, file: &Path) -> io::Result<PathBuf> {
 }
 
 pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
-    let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_SYMLINK)?;
+    let (dst, dst_file) = open_parent(dst, wasi::RIGHT_PATH_SYMLINK)?;
     dst.symlink(src.as_os_str().as_bytes(), dst_file.as_os_str().as_bytes())
 }
 
 pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
-    let (src, src_file) = open_parent(src, libc::__WASI_RIGHT_PATH_LINK_SOURCE)?;
-    let (dst, dst_file) = open_parent(dst, libc::__WASI_RIGHT_PATH_LINK_TARGET)?;
+    let (src, src_file) = open_parent(src, wasi::RIGHT_PATH_LINK_SOURCE)?;
+    let (dst, dst_file) = open_parent(dst, wasi::RIGHT_PATH_LINK_TARGET)?;
     src.link(
-        libc::__WASI_LOOKUP_SYMLINK_FOLLOW,
+        wasi::LOOKUP_SYMLINK_FOLLOW,
         src_file.as_os_str().as_bytes(),
         &dst,
         dst_file.as_os_str().as_bytes(),
@@ -586,23 +586,22 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
 }
 
 pub fn stat(p: &Path) -> io::Result<FileAttr> {
-    let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?;
-    metadata_at(&dir, libc::__WASI_LOOKUP_SYMLINK_FOLLOW, &file)
+    let (dir, file) = open_parent(p, wasi::RIGHT_PATH_FILESTAT_GET)?;
+    metadata_at(&dir, wasi::LOOKUP_SYMLINK_FOLLOW, &file)
 }
 
 pub fn lstat(p: &Path) -> io::Result<FileAttr> {
-    let (dir, file) = open_parent(p, libc::__WASI_RIGHT_PATH_FILESTAT_GET)?;
+    let (dir, file) = open_parent(p, wasi::RIGHT_PATH_FILESTAT_GET)?;
     metadata_at(&dir, 0, &file)
 }
 
 fn metadata_at(
     fd: &WasiFd,
-    flags: libc::__wasi_lookupflags_t,
+    flags: wasi::LookupFlags,
     path: &Path,
 ) -> io::Result<FileAttr> {
-    let mut ret = FileAttr::zero();
-    fd.path_filestat_get(flags, path.as_os_str().as_bytes(), &mut ret.meta)?;
-    Ok(ret)
+    fd.path_filestat_get(flags, path.as_os_str().as_bytes())
+        .map_ok(|meta| FileAttr { meta })
 }
 
 pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
@@ -652,12 +651,12 @@ fn open_at(fd: &WasiFd, path: &Path, opts: &OpenOptions) -> io::Result<File> {
 /// to any preopened file descriptor.
 fn open_parent(
     p: &Path,
-    rights: libc::__wasi_rights_t,
+    rights: wasi::Rights,
 ) -> io::Result<(ManuallyDrop<WasiFd>, PathBuf)> {
     let p = CString::new(p.as_os_str().as_bytes())?;
     unsafe {
         let mut ret = ptr::null();
-        let fd = __wasilibc_find_relpath(p.as_ptr(), rights, 0, &mut ret);
+        let fd = libc::__wasilibc_find_relpath(p.as_ptr(), rights, 0, &mut ret);
         if fd == -1 {
             let msg = format!(
                 "failed to find a preopened file descriptor \
@@ -677,15 +676,4 @@ fn open_parent(
 
         return Ok((ManuallyDrop::new(WasiFd::from_raw(fd as u32)), path));
     }
-
-    // FIXME(rust-lang/libc#1314) use the `libc` crate for this when the API
-    // there is published
-    extern "C" {
-        pub fn __wasilibc_find_relpath(
-            path: *const libc::c_char,
-            rights_base: libc::__wasi_rights_t,
-            rights_inheriting: libc::__wasi_rights_t,
-            relative_path: *mut *const libc::c_char,
-        ) -> libc::c_int;
-    }
 }
diff --git a/src/libstd/sys/wasi/io.rs b/src/libstd/sys/wasi/io.rs
index ffecca5d1b6ff..ebea3a03e439f 100644
--- a/src/libstd/sys/wasi/io.rs
+++ b/src/libstd/sys/wasi/io.rs
@@ -1,11 +1,12 @@
 use crate::marker::PhantomData;
 use crate::slice;
 
-use libc::{__wasi_ciovec_t, __wasi_iovec_t, c_void};
+use wasi::wasi_unstable as wasi;
+use core::ffi::c_void;
 
 #[repr(transparent)]
 pub struct IoSlice<'a> {
-    vec: __wasi_ciovec_t,
+    vec: wasi::CIoVec,
     _p: PhantomData<&'a [u8]>,
 }
 
@@ -13,7 +14,7 @@ impl<'a> IoSlice<'a> {
     #[inline]
     pub fn new(buf: &'a [u8]) -> IoSlice<'a> {
         IoSlice {
-            vec: __wasi_ciovec_t {
+            vec: wasi::CIoVec {
                 buf: buf.as_ptr() as *const c_void,
                 buf_len: buf.len(),
             },
@@ -43,7 +44,7 @@ impl<'a> IoSlice<'a> {
 
 #[repr(transparent)]
 pub struct IoSliceMut<'a> {
-    vec: __wasi_iovec_t,
+    vec: wasi::IoVec,
     _p: PhantomData<&'a mut [u8]>,
 }
 
@@ -51,7 +52,7 @@ impl<'a> IoSliceMut<'a> {
     #[inline]
     pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> {
         IoSliceMut {
-            vec: __wasi_iovec_t {
+            vec: wasi::IoVec {
                 buf: buf.as_mut_ptr() as *mut c_void,
                 buf_len: buf.len()
             },
diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs
index f842869e08ee6..0a16c29e5af53 100644
--- a/src/libstd/sys/wasi/mod.rs
+++ b/src/libstd/sys/wasi/mod.rs
@@ -14,10 +14,10 @@
 //! compiling for wasm. That way it's a compile time error for something that's
 //! guaranteed to be a runtime error!
 
-use libc;
-use crate::io::{Error, ErrorKind};
+use crate::io;
 use crate::mem;
 use crate::os::raw::c_char;
+use wasi::wasi_unstable as wasi;
 
 pub mod alloc;
 pub mod args;
@@ -60,12 +60,12 @@ pub fn unsupported<T>() -> crate::io::Result<T> {
     Err(unsupported_err())
 }
 
-pub fn unsupported_err() -> Error {
-    Error::new(ErrorKind::Other, "operation not supported on wasm yet")
+pub fn unsupported_err() -> io::Error {
+    io::Error::new(io::ErrorKind::Other, "operation not supported on wasm yet")
 }
 
-pub fn decode_error_kind(_code: i32) -> ErrorKind {
-    ErrorKind::Other
+pub fn decode_error_kind(_code: i32) -> io::ErrorKind {
+    io::ErrorKind::Other
 }
 
 // This enum is used as the storage for a bunch of types which can't actually
@@ -83,15 +83,18 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize {
 }
 
 pub unsafe fn abort_internal() -> ! {
-    libc::abort()
+    wasi::proc_exit(127)
 }
 
 pub fn hashmap_random_keys() -> (u64, u64) {
     let mut ret = (0u64, 0u64);
     unsafe {
-        let base = &mut ret as *mut (u64, u64) as *mut libc::c_void;
+        let base = &mut ret as *mut (u64, u64) as *mut core::ffi::c_void;
         let len = mem::size_of_val(&ret);
-        cvt_wasi(libc::__wasi_random_get(base, len)).unwrap();
+        let ret = wasi::raw::__wasi_random_get(base, len);
+        if ret != 0 {
+            panic!("__wasi_random_get failure")
+        }
     }
     return ret
 }
@@ -113,16 +116,14 @@ impl_is_minus_one! { i8 i16 i32 i64 isize }
 
 pub fn cvt<T: IsMinusOne>(t: T) -> crate::io::Result<T> {
     if t.is_minus_one() {
-        Err(Error::last_os_error())
+        Err(io::Error::last_os_error())
     } else {
         Ok(t)
     }
 }
 
-pub fn cvt_wasi(r: u16) -> crate::io::Result<()> {
-    if r != libc::__WASI_ESUCCESS {
-        Err(Error::from_raw_os_error(r as i32))
-    } else {
-        Ok(())
+impl From<wasi::Error> for io::Error {
+    fn from(err: wasi::Error) -> Self {
+        Self::from_raw_os_error(err as i32)
     }
 }
diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs
index 822ea02a11b89..026ff71de345b 100644
--- a/src/libstd/sys/wasi/os.rs
+++ b/src/libstd/sys/wasi/os.rs
@@ -12,6 +12,8 @@ use crate::sys::memchr;
 use crate::sys::{cvt, unsupported, Void};
 use crate::vec;
 
+use wasi::wasi_unstable as wasi;
+
 #[cfg(not(target_feature = "atomics"))]
 pub unsafe fn env_lock() -> impl Any {
     // No need for a lock if we're single-threaded, but this function will need
@@ -19,29 +21,11 @@ pub unsafe fn env_lock() -> impl Any {
 }
 
 pub fn errno() -> i32 {
-    extern {
-        #[thread_local]
-        static errno: libc::c_int;
-    }
-
-    unsafe { errno as i32 }
+    panic!("unsupported")
 }
 
 pub fn error_string(errno: i32) -> String {
-    extern {
-        fn strerror_r(errnum: libc::c_int, buf: *mut libc::c_char,
-                      buflen: libc::size_t) -> libc::c_int;
-    }
-
-    let mut buf = [0 as libc::c_char; 1024];
-
-    let p = buf.as_mut_ptr();
-    unsafe {
-        if strerror_r(errno as libc::c_int, p, buf.len()) < 0 {
-            panic!("strerror_r failure");
-        }
-        str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
-    }
+    wasi::error_string(errno).to_string()
 }
 
 pub fn getcwd() -> io::Result<PathBuf> {
@@ -105,6 +89,7 @@ impl Iterator for Env {
 pub fn env() -> Env {
     unsafe {
         let _guard = env_lock();
+        // FIXME: replace with wasi::environ_get
         let mut environ = libc::environ;
         let mut result = Vec::new();
         while environ != ptr::null_mut() && *environ != ptr::null_mut() {
@@ -174,9 +159,7 @@ pub fn home_dir() -> Option<PathBuf> {
 }
 
 pub fn exit(code: i32) -> ! {
-    unsafe {
-        libc::exit(code)
-    }
+    unsafe { wasi::proc_exit(code as u32) }
 }
 
 pub fn getpid() -> u32 {
diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs
index 2bf8d803c01bb..dc6a6ef375a1c 100644
--- a/src/libstd/sys/wasi/stdio.rs
+++ b/src/libstd/sys/wasi/stdio.rs
@@ -1,8 +1,9 @@
 use crate::io::{self, IoSlice, IoSliceMut};
-use crate::libc;
 use crate::mem::ManuallyDrop;
 use crate::sys::fd::WasiFd;
 
+use wasi::wasi_unstable as wasi;
+
 pub struct Stdin;
 pub struct Stdout;
 pub struct Stderr;
@@ -17,7 +18,7 @@ impl Stdin {
     }
 
     pub fn read_vectored(&self, data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) })
+        ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDIN_FD) })
             .read(data)
     }
 }
@@ -32,7 +33,7 @@ impl Stdout {
     }
 
     pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
-        ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDOUT_FILENO as u32) })
+        ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDOUT_FD) })
             .write(data)
     }
 
@@ -51,7 +52,7 @@ impl Stderr {
     }
 
     pub fn write_vectored(&self, data: &[IoSlice<'_>]) -> io::Result<usize> {
-        ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDERR_FILENO as u32) })
+        ManuallyDrop::new(unsafe { WasiFd::from_raw(wasi::STDERR_FD) })
             .write(data)
     }
 
@@ -73,7 +74,7 @@ impl io::Write for Stderr {
 pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
 
 pub fn is_ebadf(err: &io::Error) -> bool {
-    err.raw_os_error() == Some(libc::__WASI_EBADF as i32)
+    err.raw_os_error() == Some(wasi::EBADF as i32)
 }
 
 pub fn panic_output() -> Option<impl io::Write> {
diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs
index 5e69e4d948fee..9e0726432d9c4 100644
--- a/src/libstd/sys/wasi/thread.rs
+++ b/src/libstd/sys/wasi/thread.rs
@@ -19,8 +19,8 @@ impl Thread {
     }
 
     pub fn yield_now() {
-        let ret = unsafe { libc::__wasi_sched_yield() };
-        debug_assert_eq!(ret, 0);
+        let ret = wasi::sched_yield();
+        debug_assert_eq!(ret, Ok(()));
     }
 
     pub fn set_name(_name: &CStr) {
diff --git a/src/libstd/sys/wasi/time.rs b/src/libstd/sys/wasi/time.rs
index 3f14c80928c67..4c89a1781b9ef 100644
--- a/src/libstd/sys/wasi/time.rs
+++ b/src/libstd/sys/wasi/time.rs
@@ -1,7 +1,6 @@
 use crate::time::Duration;
 use crate::mem;
-use crate::sys::cvt_wasi;
-use libc;
+use wasi::wasi_unstable as wasi;
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
 pub struct Instant(Duration);
@@ -12,23 +11,19 @@ pub struct SystemTime(Duration);
 pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));
 
 fn current_time(clock: u32) -> Duration {
-    unsafe {
-        let mut ts = mem::zeroed();
-        cvt_wasi(libc::__wasi_clock_time_get(
-            clock,
-            1, // precision... seems ignored though?
-            &mut ts,
-        )).unwrap();
-        Duration::new(
-            (ts / 1_000_000_000) as u64,
-            (ts % 1_000_000_000) as u32,
-        )
-    }
+    let ts = wasi::clock_time_get(
+        clock,
+        1, // precision... seems ignored though?
+    ).unwrap();
+    Duration::new(
+        (ts / 1_000_000_000) as u64,
+        (ts % 1_000_000_000) as u32,
+    )
 }
 
 impl Instant {
     pub fn now() -> Instant {
-        Instant(current_time(libc::__WASI_CLOCK_MONOTONIC))
+        Instant(current_time(wasi::CLOCK_MONOTONIC))
     }
 
     pub const fn zero() -> Instant {
@@ -54,10 +49,10 @@ impl Instant {
 
 impl SystemTime {
     pub fn now() -> SystemTime {
-        SystemTime(current_time(libc::__WASI_CLOCK_REALTIME))
+        SystemTime(current_time(wasi::CLOCK_REALTIME))
     }
 
-    pub fn from_wasi_timestamp(ts: libc::__wasi_timestamp_t) -> SystemTime {
+    pub fn from_wasi_timestamp(ts: wasi::Timestamp) -> SystemTime {
         SystemTime(Duration::from_nanos(ts))
     }
 

From 23cc850ff18652c7b75fa423f9dfff5526a239a7 Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 10:44:08 +0300
Subject: [PATCH 023/943] return 0 from errno function

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

diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs
index 026ff71de345b..8411878eeccd9 100644
--- a/src/libstd/sys/wasi/os.rs
+++ b/src/libstd/sys/wasi/os.rs
@@ -21,7 +21,7 @@ pub unsafe fn env_lock() -> impl Any {
 }
 
 pub fn errno() -> i32 {
-    panic!("unsupported")
+    0
 }
 
 pub fn error_string(errno: i32) -> String {

From b78367d8e8c3273b2cdeefc4ce55897e08e592b2 Mon Sep 17 00:00:00 2001
From: Shotaro Yamada <sinkuu@sinkuu.xyz>
Date: Fri, 21 Jun 2019 12:23:05 +0900
Subject: [PATCH 024/943] Support `impl Trait` in inlined documentation

---
 src/librustdoc/clean/inline.rs                |  9 +-
 src/librustdoc/clean/mod.rs                   | 91 +++++++++++++++----
 src/librustdoc/core.rs                        | 24 ++++-
 .../inline_cross/auxiliary/impl_trait_aux.rs  |  7 ++
 src/test/rustdoc/inline_cross/impl_trait.rs   | 13 +++
 5 files changed, 122 insertions(+), 22 deletions(-)
 create mode 100644 src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
 create mode 100644 src/test/rustdoc/inline_cross/impl_trait.rs

diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 6f93c95edef08..bcabefa51fab1 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -217,8 +217,9 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
     };
 
     let predicates = cx.tcx.predicates_of(did);
-    let generics = (cx.tcx.generics_of(did), &predicates).clean(cx);
-    let decl = (did, sig).clean(cx);
+    let (generics, decl) = clean::enter_impl_trait(cx, || {
+        ((cx.tcx.generics_of(did), &predicates).clean(cx), (did, sig).clean(cx))
+    });
     let (all_types, ret_types) = clean::get_all_types(&generics, &decl, cx);
     clean::Function {
         decl,
@@ -372,7 +373,9 @@ pub fn build_impl(cx: &DocContext<'_>, did: DefId, attrs: Option<Attrs<'_>>,
                     None
                 }
             }).collect::<Vec<_>>(),
-            (tcx.generics_of(did), &predicates).clean(cx),
+            clean::enter_impl_trait(cx, || {
+                (tcx.generics_of(did), &predicates).clean(cx)
+            }),
         )
     };
     let polarity = tcx.impl_polarity(did);
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 9b4803ce41e29..d3065f1679316 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -45,7 +45,7 @@ use std::cell::RefCell;
 use std::sync::Arc;
 use std::u32;
 
-use crate::core::{self, DocContext};
+use crate::core::{self, DocContext, ImplTraitParam};
 use crate::doctree;
 use crate::html::render::{cache, ExternalLocation};
 use crate::html::item_type::ItemType;
@@ -1540,7 +1540,7 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
             ty::GenericParamDefKind::Lifetime => {
                 (self.name.to_string(), GenericParamDefKind::Lifetime)
             }
-            ty::GenericParamDefKind::Type { has_default, .. } => {
+            ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
                 cx.renderinfo.borrow_mut().external_param_names
                              .insert(self.def_id, self.name.clean(cx));
                 let default = if has_default {
@@ -1552,7 +1552,7 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
                     did: self.def_id,
                     bounds: vec![], // These are filled in from the where-clauses.
                     default,
-                    synthetic: None,
+                    synthetic,
                 })
             }
             ty::GenericParamDefKind::Const { .. } => {
@@ -1641,7 +1641,7 @@ impl Clean<Generics> for hir::Generics {
                 match param.kind {
                     GenericParamDefKind::Lifetime => unreachable!(),
                     GenericParamDefKind::Type { did, ref bounds, .. } => {
-                        cx.impl_trait_bounds.borrow_mut().insert(did, bounds.clone());
+                        cx.impl_trait_bounds.borrow_mut().insert(did.into(), bounds.clone());
                     }
                     GenericParamDefKind::Const { .. } => unreachable!(),
                 }
@@ -1696,25 +1696,76 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
 
         let (gens, preds) = *self;
 
+        // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses,
+        // since `Clean for ty::Predicate` would consume them.
+        let mut impl_trait = FxHashMap::<ImplTraitParam, Vec<_>>::default();
+
         // Bounds in the type_params and lifetimes fields are repeated in the
         // predicates field (see rustc_typeck::collect::ty_generics), so remove
         // them.
-        let stripped_typarams = gens.params.iter().filter_map(|param| match param.kind {
-            ty::GenericParamDefKind::Lifetime => None,
-            ty::GenericParamDefKind::Type { .. } => {
-                if param.name.as_symbol() == kw::SelfUpper {
-                    assert_eq!(param.index, 0);
-                    return None;
+        let stripped_typarams = gens.params.iter()
+            .filter_map(|param| match param.kind {
+                ty::GenericParamDefKind::Lifetime => None,
+                ty::GenericParamDefKind::Type { synthetic, .. } => {
+                    if param.name.as_symbol() == kw::SelfUpper {
+                        assert_eq!(param.index, 0);
+                        return None;
+                    }
+                    if synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) {
+                        impl_trait.insert(param.index.into(), vec![]);
+                        return None;
+                    }
+                    Some(param.clean(cx))
                 }
-                Some(param.clean(cx))
-            }
-            ty::GenericParamDefKind::Const { .. } => None,
-        }).collect::<Vec<GenericParamDef>>();
+                ty::GenericParamDefKind::Const { .. } => None,
+            }).collect::<Vec<GenericParamDef>>();
 
         let mut where_predicates = preds.predicates.iter()
-            .flat_map(|(p, _)| p.clean(cx))
+            .flat_map(|(p, _)| {
+                let param_idx = if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
+                    if let ty::Param(param) = trait_ref.self_ty().sty {
+                        Some(param.index)
+                    } else {
+                        None
+                    }
+                } else if let Some(outlives) = p.to_opt_type_outlives() {
+                    if let ty::Param(param) = outlives.skip_binder().0.sty {
+                        Some(param.index)
+                    } else {
+                        None
+                    }
+                } else {
+                    None
+                };
+
+                let p = p.clean(cx)?;
+
+                if let Some(b) = param_idx.and_then(|i| impl_trait.get_mut(&i.into())) {
+                    b.extend(
+                        p.get_bounds()
+                            .into_iter()
+                            .flatten()
+                            .cloned()
+                            .filter(|b| !b.is_sized_bound(cx))
+                    );
+                    return None;
+                }
+
+                Some(p)
+            })
             .collect::<Vec<_>>();
 
+        // Move `TraitPredicate`s to the front.
+        for (_, bounds) in impl_trait.iter_mut() {
+            bounds.sort_by_key(|b| if let GenericBound::TraitBound(..) = b {
+                false
+            } else {
+                true
+            });
+        }
+
+        cx.impl_trait_bounds.borrow_mut().extend(impl_trait);
+
         // Type parameters and have a Sized bound by default unless removed with
         // ?Sized. Scan through the predicates and mark any type parameter with
         // a Sized bound, removing the bounds as we find them.
@@ -2791,7 +2842,7 @@ impl Clean<Type> for hir::Ty {
                     if let Some(new_ty) = cx.ty_substs.borrow().get(&did).cloned() {
                         return new_ty;
                     }
-                    if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&did) {
+                    if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&did.into()) {
                         return ImplTrait(bounds);
                     }
                 }
@@ -3082,7 +3133,13 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
 
             ty::Projection(ref data) => data.clean(cx),
 
-            ty::Param(ref p) => Generic(p.name.to_string()),
+            ty::Param(ref p) => {
+                if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&p.index.into()) {
+                    ImplTrait(bounds)
+                } else {
+                    Generic(p.name.to_string())
+                }
+            }
 
             ty::Opaque(def_id, substs) => {
                 // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 87381f224d0bb..592a24fa4ae1a 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -61,8 +61,8 @@ pub struct DocContext<'tcx> {
     pub lt_substs: RefCell<FxHashMap<DefId, clean::Lifetime>>,
     /// Table `DefId` of const parameter -> substituted const
     pub ct_substs: RefCell<FxHashMap<DefId, clean::Constant>>,
-    /// Table DefId of `impl Trait` in argument position -> bounds
-    pub impl_trait_bounds: RefCell<FxHashMap<DefId, Vec<clean::GenericBound>>>,
+    /// Table synthetic type parameter for `impl Trait` in argument position -> bounds
+    pub impl_trait_bounds: RefCell<FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>>,
     pub fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>,
     pub all_fake_def_ids: RefCell<FxHashSet<DefId>>,
     /// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`.
@@ -459,3 +459,23 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
         })
     })
 }
+
+/// `DefId` or parameter index (`ty::ParamTy.index`) of a synthetic type parameter
+/// for `impl Trait` in argument position.
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub enum ImplTraitParam {
+    DefId(DefId),
+    ParamIndex(u32),
+}
+
+impl From<DefId> for ImplTraitParam {
+    fn from(did: DefId) -> Self {
+        ImplTraitParam::DefId(did)
+    }
+}
+
+impl From<u32> for ImplTraitParam {
+    fn from(idx: u32) -> Self {
+        ImplTraitParam::ParamIndex(idx)
+    }
+}
diff --git a/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
new file mode 100644
index 0000000000000..7807acbc4d61d
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
@@ -0,0 +1,7 @@
+pub fn func<'a>(_x: impl Clone + Into<Vec<u8>> + 'a) {}
+
+pub struct Foo;
+
+impl Foo {
+    pub fn method<'a>(_x: impl Clone + Into<Vec<u8>> + 'a) {}
+}
diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs
new file mode 100644
index 0000000000000..091baa9773ecf
--- /dev/null
+++ b/src/test/rustdoc/inline_cross/impl_trait.rs
@@ -0,0 +1,13 @@
+// aux-build:impl_trait_aux.rs
+
+extern crate impl_trait_aux;
+
+// @has impl_trait/fn.func.html
+// @has - '//pre[@class="rust fn"]' "pub fn func<'a>(_x: impl Clone + Into<Vec<u8>> + 'a)"
+// @!has - '//pre[@class="rust fn"]' 'where'
+pub use impl_trait_aux::func;
+
+// @has impl_trait/struct.Foo.html
+// @has - '//code[@id="method.v"]' "pub fn method<'a>(_x: impl Clone + Into<Vec<u8>> + 'a)"
+// @!has - '//code[@id="method.v"]' 'where'
+pub use impl_trait_aux::Foo;

From 9beff38382a88ceafcb6e83636535c07eacad345 Mon Sep 17 00:00:00 2001
From: Shotaro Yamada <sinkuu@sinkuu.xyz>
Date: Mon, 8 Jul 2019 17:59:26 +0900
Subject: [PATCH 025/943] Associated type bound for inlined impl Trait doc

---
 src/librustdoc/clean/mod.rs                   | 93 +++++++++++++-----
 src/librustdoc/clean/simplify.rs              | 96 ++++++++++---------
 .../inline_cross/auxiliary/impl_trait_aux.rs  |  4 +
 src/test/rustdoc/inline_cross/impl_trait.rs   |  6 ++
 4 files changed, 131 insertions(+), 68 deletions(-)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index d3065f1679316..bde1826c7fd5a 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1698,7 +1698,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
 
         // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses,
         // since `Clean for ty::Predicate` would consume them.
-        let mut impl_trait = FxHashMap::<ImplTraitParam, Vec<_>>::default();
+        let mut impl_trait = FxHashMap::<ImplTraitParam, Vec<GenericBound>>::default();
 
         // Bounds in the type_params and lifetimes fields are repeated in the
         // predicates field (see rustc_typeck::collect::ty_generics), so remove
@@ -1720,41 +1720,73 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
                 ty::GenericParamDefKind::Const { .. } => None,
             }).collect::<Vec<GenericParamDef>>();
 
+        // (param index, def id of trait) -> (name, type)
+        let mut impl_trait_proj = FxHashMap::<(u32, DefId), Vec<(String, Type)>>::default();
+
         let mut where_predicates = preds.predicates.iter()
             .flat_map(|(p, _)| {
-                let param_idx = if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
-                    if let ty::Param(param) = trait_ref.self_ty().sty {
-                        Some(param.index)
-                    } else {
-                        None
-                    }
-                } else if let Some(outlives) = p.to_opt_type_outlives() {
-                    if let ty::Param(param) = outlives.skip_binder().0.sty {
-                        Some(param.index)
-                    } else {
-                        None
+                let param_idx = (|| {
+                    if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
+                        if let ty::Param(param) = trait_ref.self_ty().sty {
+                            return Some(param.index);
+                        }
+                    } else if let Some(outlives) = p.to_opt_type_outlives() {
+                        if let ty::Param(param) = outlives.skip_binder().0.sty {
+                            return Some(param.index);
+                        }
+                    } else if let ty::Predicate::Projection(proj) = p {
+                        if let ty::Param(param) = proj.skip_binder().projection_ty.self_ty().sty {
+                            return Some(param.index);
+                        }
                     }
-                } else {
+
                     None
-                };
+                })();
 
                 let p = p.clean(cx)?;
 
-                if let Some(b) = param_idx.and_then(|i| impl_trait.get_mut(&i.into())) {
-                    b.extend(
-                        p.get_bounds()
-                            .into_iter()
-                            .flatten()
-                            .cloned()
-                            .filter(|b| !b.is_sized_bound(cx))
-                    );
-                    return None;
+                if let Some(param_idx) = param_idx {
+                    if let Some(b) = impl_trait.get_mut(&param_idx.into()) {
+                        b.extend(
+                            p.get_bounds()
+                                .into_iter()
+                                .flatten()
+                                .cloned()
+                                .filter(|b| !b.is_sized_bound(cx))
+                        );
+
+                        let proj = match &p {
+                            WherePredicate::EqPredicate { lhs, rhs } => Some((lhs, rhs))
+                                .and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs))),
+                            _ => None,
+                        };
+                        if let Some(((_, trait_did, name), rhs)) = proj {
+                            impl_trait_proj
+                                .entry((param_idx, trait_did))
+                                .or_default()
+                                .push((name.to_string(), rhs.clone()));
+                        }
+
+                        return None;
+                    }
                 }
 
                 Some(p)
             })
             .collect::<Vec<_>>();
 
+        for ((param_idx, trait_did), bounds) in impl_trait_proj {
+            for (name, rhs) in bounds {
+                simplify::merge_bounds(
+                    cx,
+                    impl_trait.get_mut(&param_idx.into()).unwrap(),
+                    trait_did,
+                    &name,
+                    &rhs,
+                );
+            }
+        }
+
         // Move `TraitPredicate`s to the front.
         for (_, bounds) in impl_trait.iter_mut() {
             bounds.sort_by_key(|b| if let GenericBound::TraitBound(..) = b {
@@ -2664,6 +2696,21 @@ impl Type {
             _ => false,
         }
     }
+
+    pub fn projection(&self) -> Option<(&Type, DefId, &str)> {
+        let (self_, trait_, name) = match self {
+            QPath { ref self_type, ref trait_, ref name } => {
+                (self_type, trait_, name)
+            }
+            _ => return None,
+        };
+        let trait_did = match **trait_ {
+            ResolvedPath { did, .. } => did,
+            _ => return None,
+        };
+        Some((&self_, trait_did, name))
+    }
+
 }
 
 impl GetDefId for Type {
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 3801c42307fc6..8758ab1969116 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -53,58 +53,21 @@ pub fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     // Look for equality predicates on associated types that can be merged into
     // general bound predicates
     equalities.retain(|&(ref lhs, ref rhs)| {
-        let (self_, trait_, name) = match *lhs {
-            clean::QPath { ref self_type, ref trait_, ref name } => {
-                (self_type, trait_, name)
-            }
-            _ => return true,
-        };
-        let generic = match **self_ {
-            clean::Generic(ref s) => s,
-            _ => return true,
+        let (self_, trait_did, name) = if let Some(p) = lhs.projection() {
+            p
+        } else {
+            return true;
         };
-        let trait_did = match **trait_ {
-            clean::ResolvedPath { did, .. } => did,
+        let generic = match self_ {
+            clean::Generic(s) => s,
             _ => return true,
         };
         let bounds = match params.get_mut(generic) {
             Some(bound) => bound,
             None => return true,
         };
-        !bounds.iter_mut().any(|b| {
-            let trait_ref = match *b {
-                clean::GenericBound::TraitBound(ref mut tr, _) => tr,
-                clean::GenericBound::Outlives(..) => return false,
-            };
-            let (did, path) = match trait_ref.trait_ {
-                clean::ResolvedPath { did, ref mut path, ..} => (did, path),
-                _ => return false,
-            };
-            // If this QPath's trait `trait_did` is the same as, or a supertrait
-            // of, the bound's trait `did` then we can keep going, otherwise
-            // this is just a plain old equality bound.
-            if !trait_is_same_or_supertrait(cx, did, trait_did) {
-                return false
-            }
-            let last = path.segments.last_mut().expect("segments were empty");
-            match last.args {
-                PP::AngleBracketed { ref mut bindings, .. } => {
-                    bindings.push(clean::TypeBinding {
-                        name: name.clone(),
-                        kind: clean::TypeBindingKind::Equality {
-                            ty: rhs.clone(),
-                        },
-                    });
-                }
-                PP::Parenthesized { ref mut output, .. } => {
-                    assert!(output.is_none());
-                    if *rhs != clean::Type::Tuple(Vec::new()) {
-                        *output = Some(rhs.clone());
-                    }
-                }
-            };
-            true
-        })
+
+        merge_bounds(cx, bounds, trait_did, name, rhs)
     });
 
     // And finally, let's reassemble everything
@@ -127,6 +90,49 @@ pub fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> {
     clauses
 }
 
+pub fn merge_bounds(
+    cx: &clean::DocContext<'_>,
+    bounds: &mut Vec<clean::GenericBound>,
+    trait_did: DefId,
+    name: &str,
+    rhs: &clean::Type,
+) -> bool {
+    !bounds.iter_mut().any(|b| {
+        let trait_ref = match *b {
+            clean::GenericBound::TraitBound(ref mut tr, _) => tr,
+            clean::GenericBound::Outlives(..) => return false,
+        };
+        let (did, path) = match trait_ref.trait_ {
+            clean::ResolvedPath { did, ref mut path, ..} => (did, path),
+            _ => return false,
+        };
+        // If this QPath's trait `trait_did` is the same as, or a supertrait
+        // of, the bound's trait `did` then we can keep going, otherwise
+        // this is just a plain old equality bound.
+        if !trait_is_same_or_supertrait(cx, did, trait_did) {
+            return false
+        }
+        let last = path.segments.last_mut().expect("segments were empty");
+        match last.args {
+            PP::AngleBracketed { ref mut bindings, .. } => {
+                bindings.push(clean::TypeBinding {
+                    name: name.to_string(),
+                    kind: clean::TypeBindingKind::Equality {
+                        ty: rhs.clone(),
+                    },
+                });
+            }
+            PP::Parenthesized { ref mut output, .. } => {
+                assert!(output.is_none());
+                if *rhs != clean::Type::Tuple(Vec::new()) {
+                    *output = Some(rhs.clone());
+                }
+            }
+        };
+        true
+    })
+}
+
 pub fn ty_params(mut params: Vec<clean::GenericParamDef>) -> Vec<clean::GenericParamDef> {
     for param in &mut params {
         match param.kind {
diff --git a/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
index 7807acbc4d61d..7b6e665b85f19 100644
--- a/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
+++ b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
@@ -1,5 +1,9 @@
+use std::ops::Deref;
+
 pub fn func<'a>(_x: impl Clone + Into<Vec<u8>> + 'a) {}
 
+pub fn func2<T>(_x: impl Deref<Target = Option<T>> + Iterator<Item = T>, _y: impl Iterator<Item = u8>) {}
+
 pub struct Foo;
 
 impl Foo {
diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs
index 091baa9773ecf..20d193aad16dc 100644
--- a/src/test/rustdoc/inline_cross/impl_trait.rs
+++ b/src/test/rustdoc/inline_cross/impl_trait.rs
@@ -7,6 +7,12 @@ extern crate impl_trait_aux;
 // @!has - '//pre[@class="rust fn"]' 'where'
 pub use impl_trait_aux::func;
 
+// @has impl_trait/fn.func2.html
+// @has - '//pre[@class="rust fn"]' "_x: impl Deref<Target = Option<T>> + Iterator<Item = T>,"
+// @has - '//pre[@class="rust fn"]' "_y: impl Iterator<Item = u8>)"
+// @!has - '//pre[@class="rust fn"]' 'where'
+pub use impl_trait_aux::func2;
+
 // @has impl_trait/struct.Foo.html
 // @has - '//code[@id="method.v"]' "pub fn method<'a>(_x: impl Clone + Into<Vec<u8>> + 'a)"
 // @!has - '//code[@id="method.v"]' 'where'

From 5f9e26382f3d8a1a90f866d1089e74ab9cf5b152 Mon Sep 17 00:00:00 2001
From: Shotaro Yamada <sinkuu@sinkuu.xyz>
Date: Mon, 8 Jul 2019 20:42:45 +0900
Subject: [PATCH 026/943] Support nested `impl Trait`

---
 src/librustdoc/clean/mod.rs                   | 58 +++++++++++--------
 .../inline_cross/auxiliary/impl_trait_aux.rs  |  2 +
 src/test/rustdoc/inline_cross/impl_trait.rs   |  6 ++
 3 files changed, 41 insertions(+), 25 deletions(-)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index bde1826c7fd5a..93e650d6d61ae 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1720,11 +1720,13 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
                 ty::GenericParamDefKind::Const { .. } => None,
             }).collect::<Vec<GenericParamDef>>();
 
-        // (param index, def id of trait) -> (name, type)
-        let mut impl_trait_proj = FxHashMap::<(u32, DefId), Vec<(String, Type)>>::default();
+        // param index -> [(DefId of trait, associated type name, type)]
+        let mut impl_trait_proj =
+            FxHashMap::<u32, Vec<(DefId, String, Ty<'tcx>)>>::default();
 
         let mut where_predicates = preds.predicates.iter()
             .flat_map(|(p, _)| {
+                let mut projection = None;
                 let param_idx = (|| {
                     if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
                         if let ty::Param(param) = trait_ref.self_ty().sty {
@@ -1734,8 +1736,9 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
                         if let ty::Param(param) = outlives.skip_binder().0.sty {
                             return Some(param.index);
                         }
-                    } else if let ty::Predicate::Projection(proj) = p {
-                        if let ty::Param(param) = proj.skip_binder().projection_ty.self_ty().sty {
+                    } else if let ty::Predicate::Projection(p) = p {
+                        if let ty::Param(param) = p.skip_binder().projection_ty.self_ty().sty {
+                            projection = Some(p);
                             return Some(param.index);
                         }
                     }
@@ -1755,16 +1758,15 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
                                 .filter(|b| !b.is_sized_bound(cx))
                         );
 
-                        let proj = match &p {
-                            WherePredicate::EqPredicate { lhs, rhs } => Some((lhs, rhs))
-                                .and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs))),
-                            _ => None,
-                        };
-                        if let Some(((_, trait_did, name), rhs)) = proj {
+                        let proj = projection
+                            .map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty));
+                        if let Some(((_, trait_did, name), rhs)) =
+                            proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs)))
+                        {
                             impl_trait_proj
-                                .entry((param_idx, trait_did))
+                                .entry(param_idx)
                                 .or_default()
-                                .push((name.to_string(), rhs.clone()));
+                                .push((trait_did, name.to_string(), rhs));
                         }
 
                         return None;
@@ -1775,18 +1777,6 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
             })
             .collect::<Vec<_>>();
 
-        for ((param_idx, trait_did), bounds) in impl_trait_proj {
-            for (name, rhs) in bounds {
-                simplify::merge_bounds(
-                    cx,
-                    impl_trait.get_mut(&param_idx.into()).unwrap(),
-                    trait_did,
-                    &name,
-                    &rhs,
-                );
-            }
-        }
-
         // Move `TraitPredicate`s to the front.
         for (_, bounds) in impl_trait.iter_mut() {
             bounds.sort_by_key(|b| if let GenericBound::TraitBound(..) = b {
@@ -1796,7 +1786,25 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
             });
         }
 
-        cx.impl_trait_bounds.borrow_mut().extend(impl_trait);
+        for (param, mut bounds) in impl_trait {
+            if let crate::core::ImplTraitParam::ParamIndex(idx) = param {
+                if let Some(proj) = impl_trait_proj.remove(&idx) {
+                    for (trait_did, name, rhs) in proj {
+                        simplify::merge_bounds(
+                            cx,
+                            &mut bounds,
+                            trait_did,
+                            &name,
+                            &rhs.clean(cx),
+                        );
+                    }
+                }
+            } else {
+                unreachable!();
+            }
+
+            cx.impl_trait_bounds.borrow_mut().insert(param, bounds);
+        }
 
         // Type parameters and have a Sized bound by default unless removed with
         // ?Sized. Scan through the predicates and mark any type parameter with
diff --git a/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
index 7b6e665b85f19..e0f7c6d08ce2f 100644
--- a/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
+++ b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
@@ -4,6 +4,8 @@ pub fn func<'a>(_x: impl Clone + Into<Vec<u8>> + 'a) {}
 
 pub fn func2<T>(_x: impl Deref<Target = Option<T>> + Iterator<Item = T>, _y: impl Iterator<Item = u8>) {}
 
+pub fn func3(_x: impl Iterator<Item = impl Iterator<Item = u8>> + Clone) {}
+
 pub struct Foo;
 
 impl Foo {
diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs
index 20d193aad16dc..b08a070dcb74d 100644
--- a/src/test/rustdoc/inline_cross/impl_trait.rs
+++ b/src/test/rustdoc/inline_cross/impl_trait.rs
@@ -8,11 +8,17 @@ extern crate impl_trait_aux;
 pub use impl_trait_aux::func;
 
 // @has impl_trait/fn.func2.html
+// @has - '//pre[@class="rust fn"]' "func2<T>("
 // @has - '//pre[@class="rust fn"]' "_x: impl Deref<Target = Option<T>> + Iterator<Item = T>,"
 // @has - '//pre[@class="rust fn"]' "_y: impl Iterator<Item = u8>)"
 // @!has - '//pre[@class="rust fn"]' 'where'
 pub use impl_trait_aux::func2;
 
+// @has impl_trait/fn.func3.html
+// @has - '//pre[@class="rust fn"]' "func3(_x: impl Clone + Iterator<Item = impl Iterator<Item = u8>>)"
+// @!has - '//pre[@class="rust fn"]' 'where'
+pub use impl_trait_aux::func3;
+
 // @has impl_trait/struct.Foo.html
 // @has - '//code[@id="method.v"]' "pub fn method<'a>(_x: impl Clone + Into<Vec<u8>> + 'a)"
 // @!has - '//code[@id="method.v"]' 'where'

From cc6dbb4f237ae0d84db5994cd075065efe05306b Mon Sep 17 00:00:00 2001
From: Shotaro Yamada <sinkuu@sinkuu.xyz>
Date: Mon, 8 Jul 2019 20:45:59 +0900
Subject: [PATCH 027/943] Fix tidy

---
 src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs | 5 ++++-
 src/test/rustdoc/inline_cross/impl_trait.rs               | 3 ++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
index e0f7c6d08ce2f..24efe4297103f 100644
--- a/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
+++ b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
@@ -2,7 +2,10 @@ use std::ops::Deref;
 
 pub fn func<'a>(_x: impl Clone + Into<Vec<u8>> + 'a) {}
 
-pub fn func2<T>(_x: impl Deref<Target = Option<T>> + Iterator<Item = T>, _y: impl Iterator<Item = u8>) {}
+pub fn func2<T>(
+    _x: impl Deref<Target = Option<T>> + Iterator<Item = T>,
+    _y: impl Iterator<Item = u8>,
+) {}
 
 pub fn func3(_x: impl Iterator<Item = impl Iterator<Item = u8>> + Clone) {}
 
diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs
index b08a070dcb74d..3a9f2f880798d 100644
--- a/src/test/rustdoc/inline_cross/impl_trait.rs
+++ b/src/test/rustdoc/inline_cross/impl_trait.rs
@@ -15,7 +15,8 @@ pub use impl_trait_aux::func;
 pub use impl_trait_aux::func2;
 
 // @has impl_trait/fn.func3.html
-// @has - '//pre[@class="rust fn"]' "func3(_x: impl Clone + Iterator<Item = impl Iterator<Item = u8>>)"
+// @has - '//pre[@class="rust fn"]' "func3("
+// @has - '//pre[@class="rust fn"]' "_x: impl Clone + Iterator<Item = impl Iterator<Item = u8>>)"
 // @!has - '//pre[@class="rust fn"]' 'where'
 pub use impl_trait_aux::func3;
 

From 3620456fafa04505c23511aa07d34f704ee7c84b Mon Sep 17 00:00:00 2001
From: Shotaro Yamada <sinkuu@sinkuu.xyz>
Date: Tue, 9 Jul 2019 16:37:55 +0900
Subject: [PATCH 028/943] Use BTreeMap for deterministic iter order

---
 src/librustdoc/clean/mod.rs | 9 ++++-----
 src/librustdoc/core.rs      | 2 +-
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 93e650d6d61ae..37ee79aa9e4f1 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1693,12 +1693,13 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
                                     &'a &'tcx ty::GenericPredicates<'tcx>) {
     fn clean(&self, cx: &DocContext<'_>) -> Generics {
         use self::WherePredicate as WP;
+        use std::collections::BTreeMap;
 
         let (gens, preds) = *self;
 
         // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses,
         // since `Clean for ty::Predicate` would consume them.
-        let mut impl_trait = FxHashMap::<ImplTraitParam, Vec<GenericBound>>::default();
+        let mut impl_trait = BTreeMap::<ImplTraitParam, Vec<GenericBound>>::default();
 
         // Bounds in the type_params and lifetimes fields are repeated in the
         // predicates field (see rustc_typeck::collect::ty_generics), so remove
@@ -1777,16 +1778,14 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
             })
             .collect::<Vec<_>>();
 
-        // Move `TraitPredicate`s to the front.
-        for (_, bounds) in impl_trait.iter_mut() {
+        for (param, mut bounds) in impl_trait {
+            // Move trait bounds to the front.
             bounds.sort_by_key(|b| if let GenericBound::TraitBound(..) = b {
                 false
             } else {
                 true
             });
-        }
 
-        for (param, mut bounds) in impl_trait {
             if let crate::core::ImplTraitParam::ParamIndex(idx) = param {
                 if let Some(proj) = impl_trait_proj.remove(&idx) {
                     for (trait_did, name, rhs) in proj {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 592a24fa4ae1a..04e69613d4b0f 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -462,7 +462,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
 
 /// `DefId` or parameter index (`ty::ParamTy.index`) of a synthetic type parameter
 /// for `impl Trait` in argument position.
-#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub enum ImplTraitParam {
     DefId(DefId),
     ParamIndex(u32),

From 1fe6160c7e4b584795c66f21683064f62803acf0 Mon Sep 17 00:00:00 2001
From: Shotaro Yamada <sinkuu@sinkuu.xyz>
Date: Tue, 9 Jul 2019 16:59:34 +0900
Subject: [PATCH 029/943] Fix ICE with `impl Trait` in type bounds

---
 src/librustdoc/clean/mod.rs                         | 13 ++++++++++---
 .../inline_cross/auxiliary/impl_trait_aux.rs        |  2 ++
 src/test/rustdoc/inline_cross/impl_trait.rs         |  6 ++++++
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 37ee79aa9e4f1..ba792a413b3c4 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1725,7 +1725,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
         let mut impl_trait_proj =
             FxHashMap::<u32, Vec<(DefId, String, Ty<'tcx>)>>::default();
 
-        let mut where_predicates = preds.predicates.iter()
+        let where_predicates = preds.predicates.iter()
             .flat_map(|(p, _)| {
                 let mut projection = None;
                 let param_idx = (|| {
@@ -1747,10 +1747,10 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
                     None
                 })();
 
-                let p = p.clean(cx)?;
-
                 if let Some(param_idx) = param_idx {
                     if let Some(b) = impl_trait.get_mut(&param_idx.into()) {
+                        let p = p.clean(cx)?;
+
                         b.extend(
                             p.get_bounds()
                                 .into_iter()
@@ -1805,6 +1805,13 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
             cx.impl_trait_bounds.borrow_mut().insert(param, bounds);
         }
 
+        // Now that `cx.impl_trait_bounds` is populated, we can process
+        // remaining predicates which could contain `impl Trait`.
+        let mut where_predicates = where_predicates
+            .into_iter()
+            .flat_map(|p| p.clean(cx))
+            .collect::<Vec<_>>();
+
         // Type parameters and have a Sized bound by default unless removed with
         // ?Sized. Scan through the predicates and mark any type parameter with
         // a Sized bound, removing the bounds as we find them.
diff --git a/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
index 24efe4297103f..21c733a9bc98e 100644
--- a/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
+++ b/src/test/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
@@ -9,6 +9,8 @@ pub fn func2<T>(
 
 pub fn func3(_x: impl Iterator<Item = impl Iterator<Item = u8>> + Clone) {}
 
+pub fn func4<T: Iterator<Item = impl Clone>>(_x: T) {}
+
 pub struct Foo;
 
 impl Foo {
diff --git a/src/test/rustdoc/inline_cross/impl_trait.rs b/src/test/rustdoc/inline_cross/impl_trait.rs
index 3a9f2f880798d..b1e3f8d145b5f 100644
--- a/src/test/rustdoc/inline_cross/impl_trait.rs
+++ b/src/test/rustdoc/inline_cross/impl_trait.rs
@@ -20,6 +20,12 @@ pub use impl_trait_aux::func2;
 // @!has - '//pre[@class="rust fn"]' 'where'
 pub use impl_trait_aux::func3;
 
+
+// @has impl_trait/fn.func4.html
+// @has - '//pre[@class="rust fn"]' "func4<T>("
+// @has - '//pre[@class="rust fn"]' "T: Iterator<Item = impl Clone>,"
+pub use impl_trait_aux::func4;
+
 // @has impl_trait/struct.Foo.html
 // @has - '//code[@id="method.v"]' "pub fn method<'a>(_x: impl Clone + Into<Vec<u8>> + 'a)"
 // @!has - '//code[@id="method.v"]' 'where'

From c4569347b260fa1ae00ede021e39f2a3227da4ad Mon Sep 17 00:00:00 2001
From: Phosphorus15 <steepout@qq.com>
Date: Mon, 19 Aug 2019 17:22:08 +0800
Subject: [PATCH 030/943] Added negative cases for `asinh` according to
 IEEE-754.

---
 src/libstd/f32.rs | 15 +++++++++++----
 src/libstd/f64.rs | 15 +++++++++++----
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index f649170c40372..653108cbeceae 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -908,10 +908,17 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn asinh(self) -> f32 {
-        if self == NEG_INFINITY {
-            NEG_INFINITY
-        } else {
-            (self + ((self * self) + 1.0).sqrt()).ln()
+        match self {
+            x if x == NEG_INFINITY => NEG_INFINITY,
+            x if x.is_sign_negative() => {
+                let v = (x + ((x * x) + 1.0).sqrt()).ln();
+                if v.is_sign_negative() {
+                    v
+                } else {
+                    -v
+                }
+            }
+            x => (x + ((x * x) + 1.0).sqrt()).ln()
         }
     }
 
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index f61630997dcdb..e5f963d873672 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -831,10 +831,17 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn asinh(self) -> f64 {
-        if self == NEG_INFINITY {
-            NEG_INFINITY
-        } else {
-            (self + ((self * self) + 1.0).sqrt()).ln()
+        match self {
+            x if x == NEG_INFINITY => NEG_INFINITY,
+            x if x.is_sign_negative() => {
+                let v = (x + ((x * x) + 1.0).sqrt()).ln();
+                if v.is_sign_negative() {
+                    v
+                } else {
+                    -v
+                }
+            }
+            x => (x + ((x * x) + 1.0).sqrt()).ln()
         }
     }
 

From 64e3a10a82e6abad20f4a56750dac4cdd5df19ab Mon Sep 17 00:00:00 2001
From: Phosphorus15 <steepout@qq.com>
Date: Mon, 19 Aug 2019 17:29:37 +0800
Subject: [PATCH 031/943] test cases for both `f32` and `f64` on asinh(-0.0)

---
 src/libstd/f32.rs | 1 +
 src/libstd/f64.rs | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 653108cbeceae..ba75650fc4cb0 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -1495,6 +1495,7 @@ mod tests {
         assert_eq!(inf.asinh(), inf);
         assert_eq!(neg_inf.asinh(), neg_inf);
         assert!(nan.asinh().is_nan());
+        assert!((-0.0f32).asinh().is_sign_negative()); // issue 63271
         assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
         assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
     }
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index e5f963d873672..62c659739de79 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -1441,6 +1441,7 @@ mod tests {
         assert_eq!(inf.asinh(), inf);
         assert_eq!(neg_inf.asinh(), neg_inf);
         assert!(nan.asinh().is_nan());
+        assert!((-0.0f64).asinh().is_sign_negative()); // issue 63271
         assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
         assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
     }

From cb52065d55e5ba1383aa155880a5e6661e6415a7 Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 13:31:41 +0300
Subject: [PATCH 032/943] replace libc::nanosleep with wasi::poll_oneoff

---
 src/libstd/sys/wasi/thread.rs | 37 ++++++++++++++++++++++-------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs
index 9e0726432d9c4..eedc584dde500 100644
--- a/src/libstd/sys/wasi/thread.rs
+++ b/src/libstd/sys/wasi/thread.rs
@@ -1,7 +1,7 @@
 use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
-use crate::sys::cvt;
+use crate::mem;
 use crate::sys::{unsupported, Void};
 use crate::time::Duration;
 use libc;
@@ -28,19 +28,28 @@ impl Thread {
     }
 
     pub fn sleep(dur: Duration) {
-        let mut secs = dur.as_secs();
-        let mut nsecs = dur.subsec_nanos() as i32;
-
-        unsafe {
-            while secs > 0 || nsecs > 0 {
-                let mut ts = libc::timespec {
-                    tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t,
-                    tv_nsec: nsecs,
-                };
-                secs -= ts.tv_sec as u64;
-                cvt(libc::nanosleep(&ts, &mut ts)).unwrap();
-                nsecs = 0;
-            }
+        let nanos = dur.as_nanos();
+        assert!(nanos <= u64::max_value() as u128);
+
+        let clock = wasi::raw::__wasi_subscription_u_clock_t {
+            identifier: 0,
+            clock_id: wasi::CLOCK_MONOTONIC,
+            timeout: nanos as u64,
+            precision: 0,
+            flags: 0,
+        };
+
+        let in_ = [wasi::Subscription {
+            userdata: 0,
+            type_: wasi::EVENTTYPE_CLOCK,
+            u: wasi::raw::__wasi_subscription_u { clock: clock },
+        }];
+        let mut out: [wasi::Event; 1] = [unsafe { mem::zeroed() }];
+        let n = wasi::poll_oneoff(&in_, &mut out).unwrap();
+        let wasi::Event { userdata, error, type_, .. } = out[0];
+        match (n, userdata, error) {
+            (1, 0, 0) if type_ == wasi::EVENTTYPE_CLOCK => {}
+            _ => panic!("thread::sleep(): unexpected result of poll_oneof"),
         }
     }
 

From 75a553fa27ffa293a21be5c5138b2b9fd69adfd2 Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 13:50:22 +0300
Subject: [PATCH 033/943] remove to_string

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

diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs
index 8411878eeccd9..091ff3480bf85 100644
--- a/src/libstd/sys/wasi/os.rs
+++ b/src/libstd/sys/wasi/os.rs
@@ -25,7 +25,7 @@ pub fn errno() -> i32 {
 }
 
 pub fn error_string(errno: i32) -> String {
-    wasi::error_string(errno).to_string()
+    wasi::error_string(errno)
 }
 
 pub fn getcwd() -> io::Result<PathBuf> {

From 7a4f0aece871f9850f83db4760a6fea4f595dc8d Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 14:54:37 +0300
Subject: [PATCH 034/943] use wasi::get_args

---
 src/libstd/sys/wasi/args.rs | 42 +++++--------------------------------
 1 file changed, 5 insertions(+), 37 deletions(-)

diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs
index 679bb1b2cbe30..e2fe0548f1266 100644
--- a/src/libstd/sys/wasi/args.rs
+++ b/src/libstd/sys/wasi/args.rs
@@ -13,47 +13,15 @@ pub unsafe fn cleanup() {
 }
 
 pub struct Args {
-    iter: vec::IntoIter<OsString>,
+    iter: vec::IntoIter<Vec<u8>>,
     _dont_send_or_sync_me: PhantomData<*mut ()>,
 }
 
 /// Returns the command line arguments
 pub fn args() -> Args {
-    maybe_args().unwrap_or_else(|_| {
-        Args {
-            iter: Vec::new().into_iter(),
-            _dont_send_or_sync_me: PhantomData
-        }
-    })
-}
-
-fn cvt_wasi(r: u16) -> crate::io::Result<()> {
-    if r != 0 {
-        Err(Error::from_raw_os_error(r as i32))
-    } else {
-        Ok(())
-    }
-}
-
-fn maybe_args() -> io::Result<Args> {
-    // FIXME: replace with safe functions
-    use wasi::wasi_unstable::raw::{__wasi_args_sizes_get, __wasi_args_get};
-    unsafe {
-        let (mut argc, mut argv_buf_size) = (0, 0);
-        cvt_wasi(__wasi_args_sizes_get(&mut argc, &mut argv_buf_size))?;
-
-        let mut argc = vec![core::ptr::null_mut::<u8>(); argc];
-        let mut argv_buf = vec![0; argv_buf_size];
-        cvt_wasi(__wasi_args_get(argc.as_mut_ptr(), argv_buf.as_mut_ptr()))?;
-
-        let args = argc.into_iter()
-            .map(|ptr| CStr::from_ptr(ptr).to_bytes().to_vec())
-            .map(|bytes| OsString::from_vec(bytes))
-            .collect::<Vec<_>>();
-        Ok(Args {
-            iter: args.into_iter(),
-            _dont_send_or_sync_me: PhantomData,
-        })
+    Args {
+        iter: wasi::get_args().unwrap_or(Vec::new()),
+        _dont_send_or_sync_me: PhantomData
     }
 }
 
@@ -66,7 +34,7 @@ impl Args {
 impl Iterator for Args {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> {
-        self.iter.next()
+        self.iter.next().map(OsString::from_vec)
     }
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()

From 52d2871e10202279b7039f4ad6d4485093fb99cc Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 15:18:02 +0300
Subject: [PATCH 035/943] use wasi::get_environ

---
 src/libstd/sys/wasi/args.rs |  1 -
 src/libstd/sys/wasi/os.rs   | 46 ++++++++++++++-----------------------
 2 files changed, 17 insertions(+), 30 deletions(-)

diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs
index e2fe0548f1266..23ab2051bf6f6 100644
--- a/src/libstd/sys/wasi/args.rs
+++ b/src/libstd/sys/wasi/args.rs
@@ -1,6 +1,5 @@
 use crate::ffi::CStr;
 use crate::io;
-use crate::sys::cvt_wasi;
 use crate::ffi::OsString;
 use crate::marker::PhantomData;
 use crate::os::wasi::ffi::OsStringExt;
diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs
index 091ff3480bf85..65c80c838dc82 100644
--- a/src/libstd/sys/wasi/os.rs
+++ b/src/libstd/sys/wasi/os.rs
@@ -75,45 +75,33 @@ pub fn current_exe() -> io::Result<PathBuf> {
 }
 
 pub struct Env {
-    iter: vec::IntoIter<(OsString, OsString)>,
+    iter: Vec<Vec<u8>>,
     _dont_send_or_sync_me: PhantomData<*mut ()>,
 }
 
 impl Iterator for Env {
     type Item = (OsString, OsString);
-    fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() }
+    fn next(&mut self) -> Option<(OsString, OsString)> {
+        self.iter.next().and_then(|input| {
+            // See src/libstd/sys/unix/os.rs, same as that
+            if input.is_empty() {
+                return None;
+            }
+            let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
+            pos.map(|p| (
+                OsStringExt::from_vec(input[..p].to_vec()),
+                OsStringExt::from_vec(input[p+1..].to_vec()),
+            ))
+        })
+    }
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
 }
 
 
 pub fn env() -> Env {
-    unsafe {
-        let _guard = env_lock();
-        // FIXME: replace with wasi::environ_get
-        let mut environ = libc::environ;
-        let mut result = Vec::new();
-        while environ != ptr::null_mut() && *environ != ptr::null_mut() {
-            if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
-                result.push(key_value);
-            }
-            environ = environ.offset(1);
-        }
-        return Env {
-            iter: result.into_iter(),
-            _dont_send_or_sync_me: PhantomData,
-        }
-    }
-
-    // See src/libstd/sys/unix/os.rs, same as that
-    fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
-        if input.is_empty() {
-            return None;
-        }
-        let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
-        pos.map(|p| (
-            OsStringExt::from_vec(input[..p].to_vec()),
-            OsStringExt::from_vec(input[p+1..].to_vec()),
-        ))
+    Env {
+        iter: wasi::get_environ().unwrap_or(Vec::new()),
+        _dont_send_or_sync_me: PhantomData,
     }
 }
 

From 8394dbba7a46cd480b0934331b2654663d487e7b Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 15:18:39 +0300
Subject: [PATCH 036/943] remove libc import

---
 src/libstd/sys/wasi/thread.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs
index eedc584dde500..a399d1f844cb0 100644
--- a/src/libstd/sys/wasi/thread.rs
+++ b/src/libstd/sys/wasi/thread.rs
@@ -4,7 +4,6 @@ use crate::io;
 use crate::mem;
 use crate::sys::{unsupported, Void};
 use crate::time::Duration;
-use libc;
 
 pub struct Thread(Void);
 

From 338fc7d042ac868e2c92bfedf2b6850bac1970c9 Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 15:32:37 +0300
Subject: [PATCH 037/943] use non-zero clock id

---
 src/libstd/sys/wasi/thread.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs
index a399d1f844cb0..7a2246de86c4f 100644
--- a/src/libstd/sys/wasi/thread.rs
+++ b/src/libstd/sys/wasi/thread.rs
@@ -31,7 +31,7 @@ impl Thread {
         assert!(nanos <= u64::max_value() as u128);
 
         let clock = wasi::raw::__wasi_subscription_u_clock_t {
-            identifier: 0,
+            identifier: 0x0123_45678,
             clock_id: wasi::CLOCK_MONOTONIC,
             timeout: nanos as u64,
             precision: 0,
@@ -47,7 +47,7 @@ impl Thread {
         let n = wasi::poll_oneoff(&in_, &mut out).unwrap();
         let wasi::Event { userdata, error, type_, .. } = out[0];
         match (n, userdata, error) {
-            (1, 0, 0) if type_ == wasi::EVENTTYPE_CLOCK => {}
+            (1, 0x0123_45678, 0) if type_ == wasi::EVENTTYPE_CLOCK => {}
             _ => panic!("thread::sleep(): unexpected result of poll_oneof"),
         }
     }

From 7658a13c650e3dd931250f6039c4f12bcc77534f Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 15:33:05 +0300
Subject: [PATCH 038/943] typo fix

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

diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs
index 7a2246de86c4f..f9e2433dca064 100644
--- a/src/libstd/sys/wasi/thread.rs
+++ b/src/libstd/sys/wasi/thread.rs
@@ -48,7 +48,7 @@ impl Thread {
         let wasi::Event { userdata, error, type_, .. } = out[0];
         match (n, userdata, error) {
             (1, 0x0123_45678, 0) if type_ == wasi::EVENTTYPE_CLOCK => {}
-            _ => panic!("thread::sleep(): unexpected result of poll_oneof"),
+            _ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
         }
     }
 

From e5ba80a87c54ab7770d9c300dacd0976f74e563e Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 15:36:30 +0300
Subject: [PATCH 039/943] use const

---
 src/libstd/sys/wasi/thread.rs | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs
index f9e2433dca064..a6c8f2487013b 100644
--- a/src/libstd/sys/wasi/thread.rs
+++ b/src/libstd/sys/wasi/thread.rs
@@ -30,8 +30,10 @@ impl Thread {
         let nanos = dur.as_nanos();
         assert!(nanos <= u64::max_value() as u128);
 
+        const CLOCK_ID: wasi::Userdata = 0x0123_45678;
+
         let clock = wasi::raw::__wasi_subscription_u_clock_t {
-            identifier: 0x0123_45678,
+            identifier: CLOCK_ID,
             clock_id: wasi::CLOCK_MONOTONIC,
             timeout: nanos as u64,
             precision: 0,
@@ -47,7 +49,7 @@ impl Thread {
         let n = wasi::poll_oneoff(&in_, &mut out).unwrap();
         let wasi::Event { userdata, error, type_, .. } = out[0];
         match (n, userdata, error) {
-            (1, 0x0123_45678, 0) if type_ == wasi::EVENTTYPE_CLOCK => {}
+            (1, CLOCK_ID, 0) if type_ == wasi::EVENTTYPE_CLOCK => {}
             _ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
         }
     }

From c05237686f994144f2f0bae68dc5b337b06e9a97 Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 16:01:21 +0300
Subject: [PATCH 040/943] fix

---
 src/libstd/sys/wasi/args.rs | 2 +-
 src/libstd/sys/wasi/os.rs   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs
index 23ab2051bf6f6..14aa391912ed2 100644
--- a/src/libstd/sys/wasi/args.rs
+++ b/src/libstd/sys/wasi/args.rs
@@ -19,7 +19,7 @@ pub struct Args {
 /// Returns the command line arguments
 pub fn args() -> Args {
     Args {
-        iter: wasi::get_args().unwrap_or(Vec::new()),
+        iter: wasi::get_args().unwrap_or(Vec::new()).into_iter(),
         _dont_send_or_sync_me: PhantomData
     }
 }
diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs
index 65c80c838dc82..04eee3ef28ff1 100644
--- a/src/libstd/sys/wasi/os.rs
+++ b/src/libstd/sys/wasi/os.rs
@@ -75,7 +75,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
 }
 
 pub struct Env {
-    iter: Vec<Vec<u8>>,
+    iter: vec::IntoIter<Vec<u8>>,
     _dont_send_or_sync_me: PhantomData<*mut ()>,
 }
 
@@ -100,7 +100,7 @@ impl Iterator for Env {
 
 pub fn env() -> Env {
     Env {
-        iter: wasi::get_environ().unwrap_or(Vec::new()),
+        iter: wasi::get_environ().unwrap_or(Vec::new()).into_iter(),
         _dont_send_or_sync_me: PhantomData,
     }
 }

From 0ec2e9fcebd18d98a32884786e1c4bbaf3db1ce0 Mon Sep 17 00:00:00 2001
From: Tom Milligan <tom@reinfer.io>
Date: Mon, 19 Aug 2019 15:19:26 +0100
Subject: [PATCH 041/943] librustdoc: warn on empty doc test

---
 .../passes/check_code_block_syntax.rs         | 37 ++++++++++++++-----
 src/test/rustdoc-ui/invalid-syntax.rs         | 10 +++++
 src/test/rustdoc-ui/invalid-syntax.stderr     | 22 +++++++++++
 3 files changed, 59 insertions(+), 10 deletions(-)

diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 357e17d2d1bc4..5c4159433c7b2 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -32,27 +32,39 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
             dox[code_block.code].to_owned(),
         );
 
-        let has_errors = {
-            let mut has_errors = false;
+        let validation_status = {
+            let mut has_syntax_errors = false;
+            let mut only_whitespace = true;
+            // even if there is a syntax error, we need to run the lexer over the whole file
             let mut lexer = Lexer::new(&sess, source_file, None);
             loop  {
                 match lexer.next_token().kind {
                     token::Eof => break,
-                    token::Unknown(..) => has_errors = true,
-                    _ => (),
+                    token::Whitespace => (),
+                    token::Unknown(..) => has_syntax_errors = true,
+                    _ => only_whitespace = false,
                 }
             }
-            has_errors
+
+            if has_syntax_errors {
+                Some(CodeBlockInvalid::SyntaxError)
+            } else if only_whitespace {
+                Some(CodeBlockInvalid::Empty)
+            } else {
+                None
+            }
         };
 
-        if has_errors {
+        if let Some(code_block_invalid) = validation_status {
             let mut diag = if let Some(sp) =
                 super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs)
             {
-                let mut diag = self
-                    .cx
-                    .sess()
-                    .struct_span_warn(sp, "could not parse code block as Rust code");
+                let warning_message = match code_block_invalid {
+                    CodeBlockInvalid::SyntaxError => "could not parse code block as Rust code",
+                    CodeBlockInvalid::Empty => "Rust code block is empty",
+                };
+
+                let mut diag = self.cx.sess().struct_span_warn(sp, warning_message);
 
                 if code_block.syntax.is_none() && code_block.is_fenced {
                     let sp = sp.from_inner(InnerSpan::new(0, 3));
@@ -96,3 +108,8 @@ impl<'a, 'tcx> DocFolder for SyntaxChecker<'a, 'tcx> {
         self.fold_item_recur(item)
     }
 }
+
+enum CodeBlockInvalid {
+    SyntaxError,
+    Empty,
+}
diff --git a/src/test/rustdoc-ui/invalid-syntax.rs b/src/test/rustdoc-ui/invalid-syntax.rs
index 2b02d47d4b851..3ef66e273d0d0 100644
--- a/src/test/rustdoc-ui/invalid-syntax.rs
+++ b/src/test/rustdoc-ui/invalid-syntax.rs
@@ -64,3 +64,13 @@ pub fn blargh() {}
 /// \_
 #[doc = "```"]
 pub fn crazy_attrs() {}
+
+/// ```rust
+/// ```
+pub fn empty_rust() {}
+
+/// ```
+///
+///
+/// ```
+pub fn empty_rust_with_whitespace() {}
diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr
index 3bebbecb9dfcf..36209e2927771 100644
--- a/src/test/rustdoc-ui/invalid-syntax.stderr
+++ b/src/test/rustdoc-ui/invalid-syntax.stderr
@@ -179,6 +179,28 @@ LL | | #[doc = "```"]
    |
    = help: mark blocks that do not contain Rust code as text: ```text
 
+warning: Rust code block is empty
+  --> $DIR/invalid-syntax.rs:68:5
+   |
+LL |   /// ```rust
+   |  _____^
+LL | | /// ```
+   | |_______^
+
+warning: Rust code block is empty
+  --> $DIR/invalid-syntax.rs:72:5
+   |
+LL |   /// ```
+   |  _____^
+LL | | ///
+LL | | ///
+LL | | /// ```
+   | |_______^
+help: mark blocks that do not contain Rust code as text
+   |
+LL | /// ```text
+   |     ^^^^^^^
+
 error: unknown start of token: \
  --> <rustdoc-highlighting>:1:1
   |

From 1417f53863c6afb1b90aef2d1c518cc8449a77f2 Mon Sep 17 00:00:00 2001
From: Artyom Pavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 19:58:35 +0000
Subject: [PATCH 042/943] fix cfg

---
 src/libstd/sys/unix/process/process_unix.rs | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index 327d82e60cff3..ea0e8b38e2b53 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -183,18 +183,16 @@ impl Command {
                 cvt(libc::setgid(u as gid_t))?;
             }
             if let Some(u) = self.get_uid() {
+                // When dropping privileges from root, the `setgroups` call
+                // will remove any extraneous groups. If we don't call this,
+                // then even though our uid has dropped, we may still have
+                // groups that enable us to do super-user things. This will
+                // fail if we aren't root, so don't bother checking the
+                // return value, this is just done as an optimistic
+                // privilege dropping function.
                 //FIXME: Redox kernel does not support setgroups yet
-                if cfg!(not(target_os = "redox")) {
-                    // When dropping privileges from root, the `setgroups` call
-                    // will remove any extraneous groups. If we don't call this,
-                    // then even though our uid has dropped, we may still have
-                    // groups that enable us to do super-user things. This will
-                    // fail if we aren't root, so don't bother checking the
-                    // return value, this is just done as an optimistic
-                    // privilege dropping function.
-                    let _ = libc::setgroups(0, ptr::null());
-                }
-
+                #[cfg(not(target_os = "redox"))]
+                let _ = libc::setgroups(0, ptr::null());
                 cvt(libc::setuid(u as uid_t))?;
             }
         }

From 1dd2d3076df1ff8eb3b722769d9025c3a7f59458 Mon Sep 17 00:00:00 2001
From: Artyom Pavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 20:01:02 +0000
Subject: [PATCH 043/943] cfg fix 2

---
 src/libstd/sys/unix/process/process_unix.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index ea0e8b38e2b53..c05484df330ae 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -178,7 +178,8 @@ impl Command {
             cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?;
         }
 
-        if cfg!(not(any(target_os = "l4re"))) {
+        #[cfg(not(any(target_os = "l4re")))]
+        {
             if let Some(u) = self.get_gid() {
                 cvt(libc::setgid(u as gid_t))?;
             }

From 34c9f8c6490bb1179c504bccd51b2827c05f10db Mon Sep 17 00:00:00 2001
From: Artyom Pavlov <newpavlov@gmail.com>
Date: Mon, 19 Aug 2019 20:02:50 +0000
Subject: [PATCH 044/943] remove any from cfgs

---
 src/libstd/sys/unix/process/process_unix.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index c05484df330ae..7e0986d8eeb6a 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -178,7 +178,7 @@ impl Command {
             cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?;
         }
 
-        #[cfg(not(any(target_os = "l4re")))]
+        #[cfg(not(target_os = "l4re"))]
         {
             if let Some(u) = self.get_gid() {
                 cvt(libc::setgid(u as gid_t))?;
@@ -202,7 +202,7 @@ impl Command {
         }
 
         // emscripten has no signal support.
-        #[cfg(not(any(target_os = "emscripten")))]
+        #[cfg(not(target_os = "emscripten"))]
         {
             use crate::mem::MaybeUninit;
             // Reset signal handling so the child process starts in a

From 859657f2c5dbe2cf55cf7a7665383a81e676bdf3 Mon Sep 17 00:00:00 2001
From: Jeremy Fitzhardinge <jsgf@fb.com>
Date: Thu, 1 Aug 2019 11:06:52 -0700
Subject: [PATCH 045/943] Use named arguments for formatting usage message.

It was getting a bit awkward.
---
 src/librustc_driver/lib.rs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index fdd0773b73ae2..cd030f3c9184e 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -777,13 +777,13 @@ fn usage(verbose: bool, include_unstable_options: bool) {
     } else {
         "\n    --help -v           Print the full set of options rustc accepts"
     };
-    println!("{}\nAdditional help:
+    println!("{options}\nAdditional help:
     -C help             Print codegen options
     -W help             \
-              Print 'lint' options and default settings{}{}\n",
-             options.usage(message),
-             nightly_help,
-             verbose_help);
+              Print 'lint' options and default settings{nightly}{verbose}\n",
+             options = options.usage(message),
+             nightly = nightly_help,
+             verbose = verbose_help);
 }
 
 fn print_wall_help() {

From d2219c2e2e287d50c0f9761203d26d5fe3b0e639 Mon Sep 17 00:00:00 2001
From: Jeremy Fitzhardinge <jsgf@fb.com>
Date: Tue, 30 Jul 2019 15:57:10 -0700
Subject: [PATCH 046/943] rustc: implement argsfiles for command line

This makes `rustc` support `@path` arguments on the command line. The `path` is opened and the file is interpreted
as new command line options which are logically inserted at that point in the command-line. The options in the file
are one per line. The file is UTF-8 encoded, and may have either Unix or Windows line endings.
It does not support recursive use of `@path`.

This is useful for very large command lines, or when command-lines are being generated into files by other tooling.
---
 src/doc/rustc/src/command-line-arguments.md   |   7 +
 src/librustc_driver/args/mod.rs               |  84 ++++++++++
 src/librustc_driver/args/tests.rs             | 145 ++++++++++++++++++
 src/librustc_driver/lib.rs                    |  21 ++-
 src/test/ui/commandline-argfile-badutf8.args  |   2 +
 src/test/ui/commandline-argfile-badutf8.rs    |  14 ++
 .../ui/commandline-argfile-badutf8.stderr     |   2 +
 src/test/ui/commandline-argfile-missing.rs    |  16 ++
 .../ui/commandline-argfile-missing.stderr     |   2 +
 src/test/ui/commandline-argfile.args          |   2 +
 src/test/ui/commandline-argfile.rs            |  13 ++
 11 files changed, 304 insertions(+), 4 deletions(-)
 create mode 100644 src/librustc_driver/args/mod.rs
 create mode 100644 src/librustc_driver/args/tests.rs
 create mode 100644 src/test/ui/commandline-argfile-badutf8.args
 create mode 100644 src/test/ui/commandline-argfile-badutf8.rs
 create mode 100644 src/test/ui/commandline-argfile-badutf8.stderr
 create mode 100644 src/test/ui/commandline-argfile-missing.rs
 create mode 100644 src/test/ui/commandline-argfile-missing.stderr
 create mode 100644 src/test/ui/commandline-argfile.args
 create mode 100644 src/test/ui/commandline-argfile.rs

diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index d774e465118b3..5eea9c8687900 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -304,3 +304,10 @@ to customize the output:
 
 Note that it is invalid to combine the `--json` argument with the `--color`
 argument, and it is required to combine `--json` with `--error-format=json`.
+
+## `@path`: load command-line flags from a path
+
+If you specify `@path` on the command-line, then it will open `path` and read
+command line options from it. These options are one per line; a blank line indicates
+an empty option. The file can use Unix or Windows style line endings, and must be
+encoded as UTF-8.
diff --git a/src/librustc_driver/args/mod.rs b/src/librustc_driver/args/mod.rs
new file mode 100644
index 0000000000000..a59f9afd8beb5
--- /dev/null
+++ b/src/librustc_driver/args/mod.rs
@@ -0,0 +1,84 @@
+use std::env;
+use std::error;
+use std::fmt;
+use std::fs;
+use std::io;
+use std::str;
+use std::sync::atomic::{AtomicBool, Ordering};
+
+#[cfg(test)]
+mod tests;
+
+static USED_ARGSFILE_FEATURE: AtomicBool = AtomicBool::new(false);
+
+pub fn used_unstable_argsfile() -> bool {
+    USED_ARGSFILE_FEATURE.load(Ordering::Relaxed)
+}
+
+pub struct ArgsIter {
+    base: env::ArgsOs,
+    file: std::vec::IntoIter<String>,
+}
+
+impl ArgsIter {
+    pub fn new() -> Self {
+        ArgsIter { base: env::args_os(), file: vec![].into_iter() }
+    }
+}
+
+impl Iterator for ArgsIter {
+    type Item = Result<String, Error>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        loop {
+            if let Some(line) = self.file.next() {
+                return Some(Ok(line));
+            }
+
+            let arg =
+                self.base.next().map(|arg| arg.into_string().map_err(|_| Error::Utf8Error(None)));
+            match arg {
+                Some(Err(err)) => return Some(Err(err)),
+                Some(Ok(ref arg)) if arg.starts_with("@") => {
+                    let path = &arg[1..];
+                    let file = match fs::read_to_string(path) {
+                        Ok(file) => {
+                            USED_ARGSFILE_FEATURE.store(true, Ordering::Relaxed);
+                            file
+                        }
+                        Err(ref err) if err.kind() == io::ErrorKind::InvalidData => {
+                            return Some(Err(Error::Utf8Error(Some(path.to_string()))));
+                        }
+                        Err(err) => return Some(Err(Error::IOError(path.to_string(), err))),
+                    };
+                    self.file =
+                        file.lines().map(ToString::to_string).collect::<Vec<_>>().into_iter();
+                }
+                Some(Ok(arg)) => return Some(Ok(arg)),
+                None => return None,
+            }
+        }
+    }
+}
+
+#[derive(Debug)]
+pub enum Error {
+    Utf8Error(Option<String>),
+    IOError(String, io::Error),
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Error::Utf8Error(None) => write!(fmt, "Utf8 error"),
+            Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {}", path),
+            Error::IOError(path, err) => write!(fmt, "IO Error: {}: {}", path, err),
+        }
+    }
+}
+
+impl error::Error for Error {
+    fn description(&self) -> &'static str {
+        "argument error"
+    }
+}
diff --git a/src/librustc_driver/args/tests.rs b/src/librustc_driver/args/tests.rs
new file mode 100644
index 0000000000000..080dd5cb746c3
--- /dev/null
+++ b/src/librustc_driver/args/tests.rs
@@ -0,0 +1,145 @@
+use super::*;
+
+use std::str;
+
+fn want_args(v: impl IntoIterator<Item = &'static str>) -> Vec<String> {
+    v.into_iter().map(String::from).collect()
+}
+
+fn got_args(file: &[u8]) -> Result<Vec<String>, Error> {
+    let ret = str::from_utf8(file)
+        .map_err(|_| Error::Utf8Error(None))?
+        .lines()
+        .map(ToString::to_string)
+        .collect::<Vec<_>>();
+    Ok(ret)
+}
+
+#[test]
+fn nothing() {
+    let file = b"";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec![]));
+}
+
+#[test]
+fn empty() {
+    let file = b"\n";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec![""]));
+}
+
+#[test]
+fn simple() {
+    let file = b"foo";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo"]));
+}
+
+#[test]
+fn simple_eol() {
+    let file = b"foo\n";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo"]));
+}
+
+#[test]
+fn multi() {
+    let file = b"foo\nbar";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar"]));
+}
+
+#[test]
+fn multi_eol() {
+    let file = b"foo\nbar\n";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar"]));
+}
+
+#[test]
+fn multi_empty() {
+    let file = b"foo\n\nbar";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "", "bar"]));
+}
+
+#[test]
+fn multi_empty_eol() {
+    let file = b"foo\n\nbar\n";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "", "bar"]));
+}
+
+#[test]
+fn multi_empty_start() {
+    let file = b"\nfoo\nbar";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["", "foo", "bar"]));
+}
+
+#[test]
+fn multi_empty_end() {
+    let file = b"foo\nbar\n\n";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar", ""]));
+}
+
+#[test]
+fn simple_eol_crlf() {
+    let file = b"foo\r\n";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo"]));
+}
+
+#[test]
+fn multi_crlf() {
+    let file = b"foo\r\nbar";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar"]));
+}
+
+#[test]
+fn multi_eol_crlf() {
+    let file = b"foo\r\nbar\r\n";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar"]));
+}
+
+#[test]
+fn multi_empty_crlf() {
+    let file = b"foo\r\n\r\nbar";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "", "bar"]));
+}
+
+#[test]
+fn multi_empty_eol_crlf() {
+    let file = b"foo\r\n\r\nbar\r\n";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "", "bar"]));
+}
+
+#[test]
+fn multi_empty_start_crlf() {
+    let file = b"\r\nfoo\r\nbar";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["", "foo", "bar"]));
+}
+
+#[test]
+fn multi_empty_end_crlf() {
+    let file = b"foo\r\nbar\r\n\r\n";
+
+    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar", ""]));
+}
+
+#[test]
+fn bad_utf8() {
+    let file = b"foo\x80foo";
+
+    match got_args(file).unwrap_err() {
+        Error::Utf8Error(_) => (),
+        bad => panic!("bad err: {:?}", bad),
+    }
+}
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index cd030f3c9184e..4843c1a951b31 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -66,6 +66,7 @@ use syntax::symbol::sym;
 use syntax_pos::{DUMMY_SP, MultiSpan, FileName};
 
 pub mod pretty;
+mod args;
 
 /// Exit status code used for successful compilation and help output.
 pub const EXIT_SUCCESS: i32 = 0;
@@ -777,11 +778,17 @@ fn usage(verbose: bool, include_unstable_options: bool) {
     } else {
         "\n    --help -v           Print the full set of options rustc accepts"
     };
-    println!("{options}\nAdditional help:
+    let at_path = if verbose && nightly_options::is_nightly_build() {
+        "    @path               Read newline separated options from `path`\n"
+    } else {
+        ""
+    };
+    println!("{options}{at_path}\nAdditional help:
     -C help             Print codegen options
     -W help             \
               Print 'lint' options and default settings{nightly}{verbose}\n",
              options = options.usage(message),
+             at_path = at_path,
              nightly = nightly_help,
              verbose = verbose_help);
 }
@@ -1008,6 +1015,12 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
     //   (unstable option being used on stable)
     nightly_options::check_nightly_options(&matches, &config::rustc_optgroups());
 
+    // Late check to see if @file was used without unstable options enabled
+    if crate::args::used_unstable_argsfile() && !nightly_options::is_unstable_enabled(&matches) {
+        early_error(ErrorOutputType::default(),
+            "@path is unstable - use -Z unstable-options to enable its use");
+    }
+
     if matches.opt_present("h") || matches.opt_present("help") {
         // Only show unstable options in --help if we accept unstable options.
         usage(matches.opt_present("verbose"), nightly_options::is_unstable_enabled(&matches));
@@ -1186,10 +1199,10 @@ pub fn main() {
     init_rustc_env_logger();
     let mut callbacks = TimePassesCallbacks::default();
     let result = report_ices_to_stderr_if_any(|| {
-        let args = env::args_os().enumerate()
-            .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| {
+        let args = args::ArgsIter::new().enumerate()
+            .map(|(i, arg)| arg.unwrap_or_else(|err| {
                 early_error(ErrorOutputType::default(),
-                            &format!("Argument {} is not valid Unicode: {:?}", i, arg))
+                            &format!("Argument {} is not valid: {}", i, err))
             }))
             .collect::<Vec<_>>();
         run_compiler(&args, &mut callbacks, None, None)
diff --git a/src/test/ui/commandline-argfile-badutf8.args b/src/test/ui/commandline-argfile-badutf8.args
new file mode 100644
index 0000000000000..c070b0c2400d8
--- /dev/null
+++ b/src/test/ui/commandline-argfile-badutf8.args
@@ -0,0 +1,2 @@
+--cfg
+unbroken�
\ No newline at end of file
diff --git a/src/test/ui/commandline-argfile-badutf8.rs b/src/test/ui/commandline-argfile-badutf8.rs
new file mode 100644
index 0000000000000..c017e7b5ea60b
--- /dev/null
+++ b/src/test/ui/commandline-argfile-badutf8.rs
@@ -0,0 +1,14 @@
+// Check to see if we can get parameters from an @argsfile file
+//
+// build-fail
+// normalize-stderr-test: "Argument \d+" -> "Argument $$N"
+// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args
+
+#[cfg(not(cmdline_set))]
+compile_error!("cmdline_set not set");
+
+#[cfg(not(unbroken))]
+compile_error!("unbroken not set");
+
+fn main() {
+}
diff --git a/src/test/ui/commandline-argfile-badutf8.stderr b/src/test/ui/commandline-argfile-badutf8.stderr
new file mode 100644
index 0000000000000..cd8a03e34eac9
--- /dev/null
+++ b/src/test/ui/commandline-argfile-badutf8.stderr
@@ -0,0 +1,2 @@
+error: Argument $N is not valid: Utf8 error in $DIR/commandline-argfile-badutf8.args
+
diff --git a/src/test/ui/commandline-argfile-missing.rs b/src/test/ui/commandline-argfile-missing.rs
new file mode 100644
index 0000000000000..34faf07633599
--- /dev/null
+++ b/src/test/ui/commandline-argfile-missing.rs
@@ -0,0 +1,16 @@
+// Check to see if we can get parameters from an @argsfile file
+//
+// build-fail
+// normalize-stderr-test: "Argument \d+" -> "Argument $$N"
+// normalize-stderr-test: "os error \d+" -> "os error $$ERR"
+// normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING "
+// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args
+
+#[cfg(not(cmdline_set))]
+compile_error!("cmdline_set not set");
+
+#[cfg(not(unbroken))]
+compile_error!("unbroken not set");
+
+fn main() {
+}
diff --git a/src/test/ui/commandline-argfile-missing.stderr b/src/test/ui/commandline-argfile-missing.stderr
new file mode 100644
index 0000000000000..c0017782f2eb3
--- /dev/null
+++ b/src/test/ui/commandline-argfile-missing.stderr
@@ -0,0 +1,2 @@
+error: Argument $N is not valid: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
+
diff --git a/src/test/ui/commandline-argfile.args b/src/test/ui/commandline-argfile.args
new file mode 100644
index 0000000000000..972938bf6c8dd
--- /dev/null
+++ b/src/test/ui/commandline-argfile.args
@@ -0,0 +1,2 @@
+--cfg
+unbroken
\ No newline at end of file
diff --git a/src/test/ui/commandline-argfile.rs b/src/test/ui/commandline-argfile.rs
new file mode 100644
index 0000000000000..fc1ba0c8d677d
--- /dev/null
+++ b/src/test/ui/commandline-argfile.rs
@@ -0,0 +1,13 @@
+// Check to see if we can get parameters from an @argsfile file
+//
+// build-pass
+// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args
+
+#[cfg(not(cmdline_set))]
+compile_error!("cmdline_set not set");
+
+#[cfg(not(unbroken))]
+compile_error!("unbroken not set");
+
+fn main() {
+}

From 535efa4afd3bb5a141eae8579f54aa641ccedaa2 Mon Sep 17 00:00:00 2001
From: Phosphorus15 <steepout@qq.com>
Date: Tue, 20 Aug 2019 12:39:12 +0800
Subject: [PATCH 047/943] Used `copysign` to avoid unnecessary branches.

---
 src/libstd/f32.rs | 10 +---------
 src/libstd/f64.rs | 10 +---------
 2 files changed, 2 insertions(+), 18 deletions(-)

diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index ba75650fc4cb0..dcb035993ae39 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -910,15 +910,7 @@ impl f32 {
     pub fn asinh(self) -> f32 {
         match self {
             x if x == NEG_INFINITY => NEG_INFINITY,
-            x if x.is_sign_negative() => {
-                let v = (x + ((x * x) + 1.0).sqrt()).ln();
-                if v.is_sign_negative() {
-                    v
-                } else {
-                    -v
-                }
-            }
-            x => (x + ((x * x) + 1.0).sqrt()).ln()
+            x => (x + ((x * x) + 1.0).sqrt()).ln().copysign(self)
         }
     }
 
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index 62c659739de79..076b6340d89bc 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -833,15 +833,7 @@ impl f64 {
     pub fn asinh(self) -> f64 {
         match self {
             x if x == NEG_INFINITY => NEG_INFINITY,
-            x if x.is_sign_negative() => {
-                let v = (x + ((x * x) + 1.0).sqrt()).ln();
-                if v.is_sign_negative() {
-                    v
-                } else {
-                    -v
-                }
-            }
-            x => (x + ((x * x) + 1.0).sqrt()).ln()
+            x => (x + ((x * x) + 1.0).sqrt()).ln().copysign(self)
         }
     }
 

From e33d8707c8ed516fd798c835acf7e1567293cf9a Mon Sep 17 00:00:00 2001
From: Phosphorus15 <steepout@qq.com>
Date: Tue, 20 Aug 2019 15:12:41 +0800
Subject: [PATCH 048/943] Refined implementations of `asinh` and `acosh`

---
 src/libstd/f32.rs | 14 ++++++++------
 src/libstd/f64.rs | 39 +++++++++++++++++++++------------------
 2 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index dcb035993ae39..f8f38cb75ab77 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -908,9 +908,10 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn asinh(self) -> f32 {
-        match self {
-            x if x == NEG_INFINITY => NEG_INFINITY,
-            x => (x + ((x * x) + 1.0).sqrt()).ln().copysign(self)
+        if self == NEG_INFINITY {
+            NEG_INFINITY
+        } else {
+            (self + ((self * self) + 1.0).sqrt()).ln().copysign(self)
         }
     }
 
@@ -931,9 +932,10 @@ impl f32 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn acosh(self) -> f32 {
-        match self {
-            x if x < 1.0 => crate::f32::NAN,
-            x => (x + ((x * x) - 1.0).sqrt()).ln(),
+        if self < 1.0 {
+            crate::f32::NAN
+        } else {
+            (self + ((self * self) - 1.0).sqrt()).ln()
         }
     }
 
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index 076b6340d89bc..06f68bc72e764 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -244,7 +244,7 @@ impl f64 {
     pub fn div_euclid(self, rhs: f64) -> f64 {
         let q = (self / rhs).trunc();
         if self % rhs < 0.0 {
-            return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }
+            return if rhs > 0.0 { q - 1.0 } else { q + 1.0 };
         }
         q
     }
@@ -437,9 +437,9 @@ impl f64 {
     pub fn log2(self) -> f64 {
         self.log_wrapper(|n| {
             #[cfg(target_os = "android")]
-            return crate::sys::android::log2f64(n);
+                return crate::sys::android::log2f64(n);
             #[cfg(not(target_os = "android"))]
-            return unsafe { intrinsics::log2f64(n) };
+                return unsafe { intrinsics::log2f64(n) };
         })
     }
 
@@ -481,16 +481,16 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     #[rustc_deprecated(since = "1.10.0",
-                       reason = "you probably meant `(self - other).abs()`: \
+    reason = "you probably meant `(self - other).abs()`: \
                                  this operation is `(self - other).max(0.0)` \
                                  except that `abs_sub` also propagates NaNs (also \
                                  known as `fdim` in C). If you truly need the positive \
                                  difference, consider using that expression or the C function \
                                  `fdim`, depending on how you wish to handle NaN (please consider \
                                  filing an issue describing your use-case too).")]
-     pub fn abs_sub(self, other: f64) -> f64 {
-         unsafe { cmath::fdim(self, other) }
-     }
+    pub fn abs_sub(self, other: f64) -> f64 {
+        unsafe { cmath::fdim(self, other) }
+    }
 
     /// Takes the cubic root of a number.
     ///
@@ -831,9 +831,10 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn asinh(self) -> f64 {
-        match self {
-            x if x == NEG_INFINITY => NEG_INFINITY,
-            x => (x + ((x * x) + 1.0).sqrt()).ln().copysign(self)
+        if self == NEG_INFINITY {
+            NEG_INFINITY
+        } else {
+            (self + ((self * self) + 1.0).sqrt()).ln().copysign(self)
         }
     }
 
@@ -852,9 +853,10 @@ impl f64 {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn acosh(self) -> f64 {
-        match self {
-            x if x < 1.0 => NAN,
-            x => (x + ((x * x) - 1.0).sqrt()).ln(),
+        if self < 1.0 {
+            NAN
+        } else {
+            (self + ((self * self) - 1.0).sqrt()).ln()
         }
     }
 
@@ -1187,7 +1189,7 @@ mod tests {
         assert_eq!((-0f64).abs(), 0f64);
         assert_eq!((-1f64).abs(), 1f64);
         assert_eq!(NEG_INFINITY.abs(), INFINITY);
-        assert_eq!((1f64/NEG_INFINITY).abs(), 0f64);
+        assert_eq!((1f64 / NEG_INFINITY).abs(), 0f64);
         assert!(NAN.abs().is_nan());
     }
 
@@ -1199,7 +1201,7 @@ mod tests {
         assert_eq!((-0f64).signum(), -1f64);
         assert_eq!((-1f64).signum(), -1f64);
         assert_eq!(NEG_INFINITY.signum(), -1f64);
-        assert_eq!((1f64/NEG_INFINITY).signum(), -1f64);
+        assert_eq!((1f64 / NEG_INFINITY).signum(), -1f64);
         assert!(NAN.signum().is_nan());
     }
 
@@ -1211,7 +1213,7 @@ mod tests {
         assert!(!(-0f64).is_sign_positive());
         assert!(!(-1f64).is_sign_positive());
         assert!(!NEG_INFINITY.is_sign_positive());
-        assert!(!(1f64/NEG_INFINITY).is_sign_positive());
+        assert!(!(1f64 / NEG_INFINITY).is_sign_positive());
         assert!(NAN.is_sign_positive());
         assert!(!(-NAN).is_sign_positive());
     }
@@ -1224,7 +1226,7 @@ mod tests {
         assert!((-0f64).is_sign_negative());
         assert!((-1f64).is_sign_negative());
         assert!(NEG_INFINITY.is_sign_negative());
-        assert!((1f64/NEG_INFINITY).is_sign_negative());
+        assert!((1f64 / NEG_INFINITY).is_sign_negative());
         assert!(!NAN.is_sign_negative());
         assert!((-NAN).is_sign_negative());
     }
@@ -1433,7 +1435,8 @@ mod tests {
         assert_eq!(inf.asinh(), inf);
         assert_eq!(neg_inf.asinh(), neg_inf);
         assert!(nan.asinh().is_nan());
-        assert!((-0.0f64).asinh().is_sign_negative()); // issue 63271
+        assert!((-0.0f64).asinh().is_sign_negative());
+        // issue 63271
         assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
         assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
     }

From 0be01fa655439787283aa85779befb4e23f1b337 Mon Sep 17 00:00:00 2001
From: Seiichi Uchida <seiichi.uchida@dena.com>
Date: Tue, 20 Aug 2019 16:21:47 +0900
Subject: [PATCH 049/943] Update rustfmt to 1.4.5

---
 Cargo.lock        | 2 +-
 src/tools/rustfmt | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 9e7dd54e13532..06d13dac9daca 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3546,7 +3546,7 @@ dependencies = [
 
 [[package]]
 name = "rustfmt-nightly"
-version = "1.4.4"
+version = "1.4.5"
 dependencies = [
  "annotate-snippets",
  "atty",
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
index 0462008de87d2..9792ff05297c0 160000
--- a/src/tools/rustfmt
+++ b/src/tools/rustfmt
@@ -1 +1 @@
-Subproject commit 0462008de87d2757e8ef1dc26f2c54dd789a59a8
+Subproject commit 9792ff05297c0a5c40942b346c9b0341b9e7c0ee

From bd1dc7cf92f22913ea34ada119393a9a6c880fa4 Mon Sep 17 00:00:00 2001
From: Artyom Pavlov <newpavlov@gmail.com>
Date: Tue, 20 Aug 2019 10:26:10 +0000
Subject: [PATCH 050/943] fix libc checksum

---
 Cargo.lock | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Cargo.lock b/Cargo.lock
index 2412d5e9627ff..fbe9e462025bf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1571,7 +1571,7 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 name = "libc"
 version = "0.2.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb"
+checksum = "c665266eb592905e8503ba3403020f4b8794d26263f412ca33171600eca9a6fa"
 dependencies = [
  "rustc-std-workspace-core",
 ]

From 744442d19a76c4dd39f5fa2a2bbd74638e8569ec Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Tue, 20 Aug 2019 15:43:34 +0300
Subject: [PATCH 051/943] fix C incompatibilities

---
 src/libstd/sys/wasi/mod.rs |  2 +-
 src/libstd/sys/wasi/os.rs  | 67 ++++++++++++++++++++++++++------------
 2 files changed, 47 insertions(+), 22 deletions(-)

diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs
index 0a16c29e5af53..28b49996d1433 100644
--- a/src/libstd/sys/wasi/mod.rs
+++ b/src/libstd/sys/wasi/mod.rs
@@ -83,7 +83,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize {
 }
 
 pub unsafe fn abort_internal() -> ! {
-    wasi::proc_exit(127)
+    libc::abort()
 }
 
 pub fn hashmap_random_keys() -> (u64, u64) {
diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs
index 04eee3ef28ff1..dca58179e0c8d 100644
--- a/src/libstd/sys/wasi/os.rs
+++ b/src/libstd/sys/wasi/os.rs
@@ -21,11 +21,24 @@ pub unsafe fn env_lock() -> impl Any {
 }
 
 pub fn errno() -> i32 {
-    0
+    extern {
+        #[thread_local]
+        static errno: libc::c_int;
+    }
+
+    unsafe { errno as i32 }
 }
 
 pub fn error_string(errno: i32) -> String {
-    wasi::error_string(errno)
+    let mut buf = [0 as libc::c_char; 1024];
+
+    let p = buf.as_mut_ptr();
+    unsafe {
+        if libc::strerror_r(errno as libc::c_int, p, buf.len()) < 0 {
+            panic!("strerror_r failure");
+        }
+        str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned()
+    }
 }
 
 pub fn getcwd() -> io::Result<PathBuf> {
@@ -73,35 +86,45 @@ impl StdError for JoinPathsError {
 pub fn current_exe() -> io::Result<PathBuf> {
     unsupported()
 }
-
 pub struct Env {
-    iter: vec::IntoIter<Vec<u8>>,
+    iter: vec::IntoIter<(OsString, OsString)>,
     _dont_send_or_sync_me: PhantomData<*mut ()>,
 }
 
 impl Iterator for Env {
     type Item = (OsString, OsString);
-    fn next(&mut self) -> Option<(OsString, OsString)> {
-        self.iter.next().and_then(|input| {
-            // See src/libstd/sys/unix/os.rs, same as that
-            if input.is_empty() {
-                return None;
-            }
-            let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
-            pos.map(|p| (
-                OsStringExt::from_vec(input[..p].to_vec()),
-                OsStringExt::from_vec(input[p+1..].to_vec()),
-            ))
-        })
-    }
+    fn next(&mut self) -> Option<(OsString, OsString)> { self.iter.next() }
     fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
 }
 
 
 pub fn env() -> Env {
-    Env {
-        iter: wasi::get_environ().unwrap_or(Vec::new()).into_iter(),
-        _dont_send_or_sync_me: PhantomData,
+    unsafe {
+        let _guard = env_lock();
+        let mut environ = libc::environ;
+        let mut result = Vec::new();
+        while environ != ptr::null_mut() && *environ != ptr::null_mut() {
+            if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
+                result.push(key_value);
+            }
+            environ = environ.offset(1);
+        }
+        return Env {
+            iter: result.into_iter(),
+            _dont_send_or_sync_me: PhantomData,
+        }
+    }
+
+    // See src/libstd/sys/unix/os.rs, same as that
+    fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
+        if input.is_empty() {
+            return None;
+        }
+        let pos = memchr::memchr(b'=', &input[1..]).map(|p| p + 1);
+        pos.map(|p| (
+            OsStringExt::from_vec(input[..p].to_vec()),
+            OsStringExt::from_vec(input[p+1..].to_vec()),
+        ))
     }
 }
 
@@ -147,7 +170,9 @@ pub fn home_dir() -> Option<PathBuf> {
 }
 
 pub fn exit(code: i32) -> ! {
-    unsafe { wasi::proc_exit(code as u32) }
+    unsafe {
+        libc::exit(code)
+    }
 }
 
 pub fn getpid() -> u32 {

From 99ce39b30a296354409c5161c4a5bc833f5f72d0 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 19 Aug 2019 18:04:25 -0400
Subject: [PATCH 052/943] Load error codes via build script instead of JSON
 parsing

This scans the tree for `error_codes.rs` and loads all of them.
---
 Cargo.lock                                 |  1 +
 src/tools/error_index_generator/Cargo.toml |  4 ++
 src/tools/error_index_generator/build.rs   | 64 ++++++++++++++++++++++
 src/tools/error_index_generator/main.rs    | 46 +++++-----------
 4 files changed, 84 insertions(+), 31 deletions(-)
 create mode 100644 src/tools/error_index_generator/build.rs

diff --git a/Cargo.lock b/Cargo.lock
index 910d6ba22c16f..82bfc671355aa 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -946,6 +946,7 @@ name = "error_index_generator"
 version = "0.0.0"
 dependencies = [
  "rustdoc",
+ "walkdir",
 ]
 
 [[package]]
diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml
index 116be234f3ceb..992af261b8352 100644
--- a/src/tools/error_index_generator/Cargo.toml
+++ b/src/tools/error_index_generator/Cargo.toml
@@ -3,10 +3,14 @@ authors = ["The Rust Project Developers"]
 name = "error_index_generator"
 version = "0.0.0"
 edition = "2018"
+build = "build.rs"
 
 [dependencies]
 rustdoc = { path = "../../librustdoc" }
 
+[build-dependencies]
+walkdir = "2"
+
 [[bin]]
 name = "error_index_generator"
 path = "main.rs"
diff --git a/src/tools/error_index_generator/build.rs b/src/tools/error_index_generator/build.rs
new file mode 100644
index 0000000000000..2ac7351fce469
--- /dev/null
+++ b/src/tools/error_index_generator/build.rs
@@ -0,0 +1,64 @@
+use walkdir::WalkDir;
+use std::path::PathBuf;
+use std::{env, fs};
+
+fn main() {
+    // The src directory (we are in src/tools/error_index_generator)
+    // Note that we could skip one of the .. but this ensures we at least loosely find the right
+    // directory.
+    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
+    let dest = out_dir.join("error_codes.rs");
+    let mut idx = 0;
+    for entry in WalkDir::new("../../../src") {
+        let entry = entry.unwrap();
+        if entry.file_name() == "error_codes.rs" {
+            println!("cargo:rerun-if-changed={}", entry.path().to_str().unwrap());
+            let file = fs::read_to_string(entry.path()).unwrap()
+                .replace("use syntax::{register_diagnostics, register_long_diagnostics};", "")
+                .replace("use syntax::register_diagnostics;", "")
+                .replace("use syntax::register_long_diagnostics;", "");
+            let contents = format!("(|| {{\n{}\n}})();", file);
+
+            fs::write(&out_dir.join(&format!("error_{}.rs", idx)), &contents).unwrap();
+
+            idx += 1;
+        }
+    }
+
+    let mut all = String::new();
+    all.push_str("fn register_all() -> Vec<(&'static str, Option<&'static str>)> {\n");
+    all.push_str("let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();\n");
+    all.push_str(r#"
+macro_rules! register_diagnostics {
+    ($($code:tt),*) => {{
+        long_codes.extend([$(
+            stringify!($code),
+        )*].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());
+    }};
+    ($($code:tt),*,) => {{
+        long_codes.extend([$(
+            stringify!($code),
+        )*].iter().cloned().map(|s| (s, None)));
+    }}
+}
+
+macro_rules! register_long_diagnostics {
+    ($($code:tt: $description:tt),*) => {
+        {long_codes.extend([$(
+            (stringify!($code), Some(stringify!($description))),
+        )*].iter());}
+    };
+    ($($code:tt: $description:tt),*,) => {
+        {long_codes.extend([$(
+            (stringify!($code), Some(stringify!($description))),
+        )*].iter());}
+    }
+}"#);
+    for idx in 0..idx {
+        all.push_str(&format!(r#"include!(concat!(env!("OUT_DIR"), "/error_{}.rs"));"#, idx));
+    }
+    all.push_str("\nlong_codes\n");
+    all.push_str("}\n");
+
+    fs::write(&dest, all).unwrap();
+}
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index a9d1d9997f6ef..b35d304e760fe 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -2,22 +2,20 @@
 
 extern crate env_logger;
 extern crate syntax;
-extern crate serialize as rustc_serialize;
 
 use std::collections::BTreeMap;
 use std::env;
 use std::error::Error;
-use std::fs::{self, read_dir, File};
+use std::fs::File;
 use std::io::Write;
 use std::path::Path;
 use std::path::PathBuf;
 use std::cell::RefCell;
 
 use syntax::edition::DEFAULT_EDITION;
-use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
+use syntax::diagnostics::metadata::{ErrorMetadataMap, ErrorMetadata};
 
 use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, Playground};
-use rustc_serialize::json;
 
 enum OutputFormat {
     HTML(HTMLFormatter),
@@ -80,11 +78,7 @@ impl Formatter for HTMLFormatter {
             Some(_) => "error-described",
             None => "error-undescribed",
         };
-        let use_desc = match info.use_site {
-            Some(_) => "error-used",
-            None => "error-unused",
-        };
-        write!(output, "<div class=\"{} {}\">", desc_desc, use_desc)?;
+        write!(output, "<div class=\"{}\">", desc_desc)?;
 
         // Error title (with self-link).
         write!(output,
@@ -199,25 +193,6 @@ impl Formatter for MarkdownFormatter {
     }
 }
 
-/// Loads all the metadata files from `metadata_dir` into an in-memory map.
-fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<dyn Error>> {
-    let mut all_errors = BTreeMap::new();
-
-    for entry in read_dir(metadata_dir)? {
-        let path = entry?.path();
-
-        let metadata_str = fs::read_to_string(&path)?;
-
-        let some_errors: ErrorMetadataMap = json::decode(&metadata_str)?;
-
-        for (err_code, info) in some_errors {
-            all_errors.insert(err_code, info);
-        }
-    }
-
-    Ok(all_errors)
-}
-
 /// Output an HTML page for the errors in `err_map` to `output_path`.
 fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path,
                                    formatter: T) -> Result<(), Box<dyn Error>> {
@@ -234,9 +209,16 @@ fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Pat
 }
 
 fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Error>> {
-    let build_arch = env::var("CFG_BUILD")?;
-    let metadata_dir = get_metadata_dir(&build_arch);
-    let err_map = load_all_errors(&metadata_dir)?;
+    let long_codes = register_all();
+    let mut err_map = BTreeMap::new();
+    for (code, desc) in long_codes {
+        err_map.insert(code.to_string(), ErrorMetadata {
+            description: desc.map(String::from),
+            // FIXME: this indicates that the error code is not used, which may not be true.
+            // We currently do not use this information.
+            use_site: None,
+        });
+    }
     match format {
         OutputFormat::Unknown(s)  => panic!("Unknown output format: {}", s),
         OutputFormat::HTML(h)     => render_error_page(&err_map, dst, h)?,
@@ -272,3 +254,5 @@ fn main() {
         panic!("{}", e.description());
     }
 }
+
+include!(concat!(env!("OUT_DIR"), "/error_codes.rs"));

From 72e2cfd93438ef0109cbaca9f961efa5ac6d4f84 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 19 Aug 2019 18:26:08 -0400
Subject: [PATCH 053/943] Remove serialization of diagnostics to files

This is no longer used by the index generator and was always an unstable
compiler detail, so strip it out.

This also leaves in RUSTC_ERROR_METADATA_DST since the stage0 compiler
still needs it to be set.
---
 src/bootstrap/doc.rs                    |  3 +-
 src/bootstrap/test.rs                   |  3 +-
 src/libsyntax/diagnostics/metadata.rs   | 93 -------------------------
 src/libsyntax/diagnostics/plugin.rs     | 34 ++-------
 src/libsyntax/lib.rs                    |  1 -
 src/tools/error_index_generator/main.rs | 11 +--
 6 files changed, 13 insertions(+), 132 deletions(-)
 delete mode 100644 src/libsyntax/diagnostics/metadata.rs

diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 36229720e42cd..4f96c12fc1ddd 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -825,8 +825,7 @@ impl Step for ErrorIndex {
         index.arg(crate::channel::CFG_RELEASE_NUM);
 
         // FIXME: shouldn't have to pass this env var
-        index.env("CFG_BUILD", &builder.config.build)
-             .env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir());
+        index.env("CFG_BUILD", &builder.config.build);
 
         builder.run(&mut index);
     }
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index c2c134bfd1d7d..87bd5cbacfffa 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1535,8 +1535,7 @@ impl Step for ErrorIndex {
         );
         tool.arg("markdown")
             .arg(&output)
-            .env("CFG_BUILD", &builder.config.build)
-            .env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir());
+            .env("CFG_BUILD", &builder.config.build);
 
         builder.info(&format!("Testing error-index stage{}", compiler.stage));
         let _time = util::timeit(&builder);
diff --git a/src/libsyntax/diagnostics/metadata.rs b/src/libsyntax/diagnostics/metadata.rs
deleted file mode 100644
index 53f37bb10bdc0..0000000000000
--- a/src/libsyntax/diagnostics/metadata.rs
+++ /dev/null
@@ -1,93 +0,0 @@
-//! This module contains utilities for outputting metadata for diagnostic errors.
-//!
-//! Each set of errors is mapped to a metadata file by a name, which is
-//! currently always a crate name.
-
-use std::collections::BTreeMap;
-use std::env;
-use std::fs::{remove_file, create_dir_all, File};
-use std::io::Write;
-use std::path::PathBuf;
-use std::error::Error;
-use rustc_serialize::json::as_json;
-
-use syntax_pos::{Span, FileName};
-
-use crate::ext::base::ExtCtxt;
-use crate::diagnostics::plugin::{ErrorMap, ErrorInfo};
-
-/// JSON encodable/decodable version of `ErrorInfo`.
-#[derive(PartialEq, RustcDecodable, RustcEncodable)]
-pub struct ErrorMetadata {
-    pub description: Option<String>,
-    pub use_site: Option<ErrorLocation>
-}
-
-/// Mapping from error codes to metadata that can be (de)serialized.
-pub type ErrorMetadataMap = BTreeMap<String, ErrorMetadata>;
-
-/// JSON encodable error location type with filename and line number.
-#[derive(PartialEq, RustcDecodable, RustcEncodable)]
-pub struct ErrorLocation {
-    pub filename: FileName,
-    pub line: usize
-}
-
-impl ErrorLocation {
-    /// Creates an error location from a span.
-    pub fn from_span(ecx: &ExtCtxt<'_>, sp: Span) -> ErrorLocation {
-        let loc = ecx.source_map().lookup_char_pos(sp.lo());
-        ErrorLocation {
-            filename: loc.file.name.clone(),
-            line: loc.line
-        }
-    }
-}
-
-/// Gets the directory where metadata for a given `prefix` should be stored.
-///
-/// See `output_metadata`.
-pub fn get_metadata_dir(prefix: &str) -> PathBuf {
-    env::var_os("RUSTC_ERROR_METADATA_DST")
-        .map(PathBuf::from)
-        .expect("env var `RUSTC_ERROR_METADATA_DST` isn't set")
-        .join(prefix)
-}
-
-/// Map `name` to a path in the given directory: <directory>/<name>.json
-fn get_metadata_path(directory: PathBuf, name: &str) -> PathBuf {
-    directory.join(format!("{}.json", name))
-}
-
-/// Write metadata for the errors in `err_map` to disk, to a file corresponding to `prefix/name`.
-///
-/// For our current purposes the prefix is the target architecture and the name is a crate name.
-/// If an error occurs steps will be taken to ensure that no file is created.
-pub fn output_metadata(ecx: &ExtCtxt<'_>, prefix: &str, name: &str, err_map: &ErrorMap)
-    -> Result<(), Box<dyn Error>>
-{
-    // Create the directory to place the file in.
-    let metadata_dir = get_metadata_dir(prefix);
-    create_dir_all(&metadata_dir)?;
-
-    // Open the metadata file.
-    let metadata_path = get_metadata_path(metadata_dir, name);
-    let mut metadata_file = File::create(&metadata_path)?;
-
-    // Construct a serializable map.
-    let json_map = err_map.iter().map(|(k, &ErrorInfo { description, use_site })| {
-        let key = k.as_str().to_string();
-        let value = ErrorMetadata {
-            description: description.map(|n| n.as_str().to_string()),
-            use_site: use_site.map(|sp| ErrorLocation::from_span(ecx, sp))
-        };
-        (key, value)
-    }).collect::<ErrorMetadataMap>();
-
-    // Write the data to the file, deleting it if the write fails.
-    let result = write!(&mut metadata_file, "{}", as_json(&json_map));
-    if result.is_err() {
-        remove_file(&metadata_path)?;
-    }
-    Ok(result?)
-}
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index 9618b5acfb0f1..e9a55af52e878 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -1,5 +1,4 @@
 use std::collections::BTreeMap;
-use std::env;
 
 use crate::ast::{self, Ident, Name};
 use crate::source_map;
@@ -12,8 +11,6 @@ use crate::tokenstream::{TokenTree};
 use smallvec::smallvec;
 use syntax_pos::Span;
 
-use crate::diagnostics::metadata::output_metadata;
-
 pub use errors::*;
 
 // Maximum width of any line in an extended error description (inclusive).
@@ -127,36 +124,13 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                           token_tree: &[TokenTree])
                                           -> Box<dyn MacResult+'cx> {
     assert_eq!(token_tree.len(), 3);
-    let (crate_name, ident) = match (&token_tree[0], &token_tree[2]) {
-        (
-            // Crate name.
-            &TokenTree::Token(Token { kind: token::Ident(crate_name, _), .. }),
-            // DIAGNOSTICS ident.
-            &TokenTree::Token(Token { kind: token::Ident(name, _), span })
-        ) => (crate_name, Ident::new(name, span)),
+    let ident = match &token_tree[2] {
+        // DIAGNOSTICS ident.
+        &TokenTree::Token(Token { kind: token::Ident(name, _), span })
+        => Ident::new(name, span),
         _ => unreachable!()
     };
 
-    // Output error metadata to `tmp/extended-errors/<target arch>/<crate name>.json`
-    if let Ok(target_triple) = env::var("CFG_COMPILER_HOST_TRIPLE") {
-        ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
-            if let Err(e) = output_metadata(ecx,
-                                            &target_triple,
-                                            &crate_name.as_str(),
-                                            diagnostics) {
-                ecx.span_bug(span, &format!(
-                    "error writing metadata for triple `{}` and crate `{}`, error: {}, \
-                     cause: {:?}",
-                    target_triple, crate_name, e.description(), e.source()
-                ));
-            }
-        });
-    } else {
-        ecx.span_err(span, &format!(
-            "failed to write metadata for crate `{}` because $CFG_COMPILER_HOST_TRIPLE is not set",
-            crate_name));
-    }
-
     // Construct the output expression.
     let (count, expr) =
         ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 8ac48d8d74a42..1741932c1b80e 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -124,7 +124,6 @@ pub mod diagnostics {
     #[macro_use]
     pub mod macros;
     pub mod plugin;
-    pub mod metadata;
 }
 
 // N.B., this module needs to be declared first so diagnostics are
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index b35d304e760fe..c4826a0c31d6c 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -13,10 +13,16 @@ use std::path::PathBuf;
 use std::cell::RefCell;
 
 use syntax::edition::DEFAULT_EDITION;
-use syntax::diagnostics::metadata::{ErrorMetadataMap, ErrorMetadata};
 
 use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, Playground};
 
+pub struct ErrorMetadata {
+    pub description: Option<String>,
+}
+
+/// Mapping from error codes to metadata that can be (de)serialized.
+pub type ErrorMetadataMap = BTreeMap<String, ErrorMetadata>;
+
 enum OutputFormat {
     HTML(HTMLFormatter),
     Markdown(MarkdownFormatter),
@@ -214,9 +220,6 @@ fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Erro
     for (code, desc) in long_codes {
         err_map.insert(code.to_string(), ErrorMetadata {
             description: desc.map(String::from),
-            // FIXME: this indicates that the error code is not used, which may not be true.
-            // We currently do not use this information.
-            use_site: None,
         });
     }
     match format {

From 4dee102a67466ca0c95f540aa458f8779f3a1cb5 Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Tue, 20 Aug 2019 19:16:01 +0300
Subject: [PATCH 054/943] use new get_args

---
 src/libstd/sys/wasi/args.rs | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs
index 14aa391912ed2..2d0ddea385afd 100644
--- a/src/libstd/sys/wasi/args.rs
+++ b/src/libstd/sys/wasi/args.rs
@@ -12,14 +12,16 @@ pub unsafe fn cleanup() {
 }
 
 pub struct Args {
-    iter: vec::IntoIter<Vec<u8>>,
+    iter: vec::IntoIter<OsString>,
     _dont_send_or_sync_me: PhantomData<*mut ()>,
 }
 
 /// Returns the command line arguments
 pub fn args() -> Args {
+    let mut buf = Vec::new();
+    let _ = wasi::get_args(|arg| buf.push(OsString::from_vec(arg.to_vec())));
     Args {
-        iter: wasi::get_args().unwrap_or(Vec::new()).into_iter(),
+        iter: buf.into_iter(),
         _dont_send_or_sync_me: PhantomData
     }
 }
@@ -33,7 +35,7 @@ impl Args {
 impl Iterator for Args {
     type Item = OsString;
     fn next(&mut self) -> Option<OsString> {
-        self.iter.next().map(OsString::from_vec)
+        self.iter.next()
     }
     fn size_hint(&self) -> (usize, Option<usize>) {
         self.iter.size_hint()

From 7d92cf4826706669c7e1938fb879d91f572b717a Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Tue, 20 Aug 2019 10:46:35 -0700
Subject: [PATCH 055/943] Bump toml dependency.

Just removing an old/duplicated dependency from the workspace.
---
 Cargo.lock                          | 25 ++++++++-----------------
 src/bootstrap/Cargo.toml            |  2 +-
 src/tools/build-manifest/Cargo.toml |  2 +-
 3 files changed, 10 insertions(+), 19 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 2a07a2f0c3da6..7f2ed3823f108 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -185,7 +185,7 @@ dependencies = [
  "serde",
  "serde_json",
  "time",
- "toml 0.4.10",
+ "toml",
 ]
 
 [[package]]
@@ -202,7 +202,7 @@ name = "build-manifest"
 version = "0.1.0"
 dependencies = [
  "serde",
- "toml 0.4.10",
+ "toml",
 ]
 
 [[package]]
@@ -316,7 +316,7 @@ dependencies = [
  "tar",
  "tempfile",
  "termcolor",
- "toml 0.5.3",
+ "toml",
  "unicode-width",
  "url 2.1.0",
  "walkdir",
@@ -442,7 +442,7 @@ dependencies = [
  "semver",
  "serde",
  "smallvec",
- "toml 0.5.3",
+ "toml",
  "unicode-normalization",
  "url 2.1.0",
 ]
@@ -1785,7 +1785,7 @@ dependencies = [
  "serde_json",
  "shlex",
  "tempfile",
- "toml 0.5.3",
+ "toml",
  "toml-query",
 ]
 
@@ -2760,7 +2760,7 @@ dependencies = [
  "tokio",
  "tokio-process",
  "tokio-timer",
- "toml 0.5.3",
+ "toml",
  "url 1.7.2",
  "walkdir",
 ]
@@ -3582,7 +3582,7 @@ dependencies = [
  "serde_json",
  "structopt",
  "term 0.6.0",
- "toml 0.5.3",
+ "toml",
  "unicode-segmentation",
  "unicode-width",
  "unicode_categories",
@@ -4374,15 +4374,6 @@ dependencies = [
  "tokio-reactor",
 ]
 
-[[package]]
-name = "toml"
-version = "0.4.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
-dependencies = [
- "serde",
-]
-
 [[package]]
 name = "toml"
 version = "0.5.3"
@@ -4403,7 +4394,7 @@ dependencies = [
  "is-match",
  "lazy_static 1.3.0",
  "regex",
- "toml 0.5.3",
+ "toml",
  "toml-query_derive",
 ]
 
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 589ee9276a5a3..c27c318f5ad07 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -44,7 +44,7 @@ cc = "1.0.35"
 libc = "0.2"
 serde = { version = "1.0.8", features = ["derive"] }
 serde_json = "1.0.2"
-toml = "0.4"
+toml = "0.5"
 lazy_static = "1.3.0"
 time = "0.1"
 petgraph = "0.4.13"
diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml
index 63b6399bb9034..c364479d8db13 100644
--- a/src/tools/build-manifest/Cargo.toml
+++ b/src/tools/build-manifest/Cargo.toml
@@ -5,5 +5,5 @@ authors = ["Alex Crichton <alex@alexcrichton.com>"]
 edition = "2018"
 
 [dependencies]
-toml = "0.4"
+toml = "0.5"
 serde = { version = "1.0", features = ["derive"] }

From 777a12c3a4533e70baa46391e8c557950191a7c7 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 20 Aug 2019 17:07:42 +0200
Subject: [PATCH 056/943] Use dedicated type for spans in pre-expansion gating.

---
 src/libsyntax/feature_gate.rs      | 15 ++++++++------
 src/libsyntax/parse/attr.rs        |  5 ++---
 src/libsyntax/parse/mod.rs         | 32 +++++++++++++++++-------------
 src/libsyntax/parse/parser/expr.rs |  8 ++++----
 src/libsyntax/parse/parser/pat.rs  |  2 +-
 5 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index bbc3ae2822558..df86ba790d6a6 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -2438,16 +2438,19 @@ pub fn check_crate(krate: &ast::Crate,
     };
 
     macro_rules! gate_all {
+        ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); };
         ($spans:ident, $gate:ident, $msg:literal) => {
-            for span in &*sess.$spans.borrow() { gate_feature!(&ctx, $gate, *span, $msg); }
+            for span in &*sess.gated_spans.$spans.borrow() {
+                gate_feature!(&ctx, $gate, *span, $msg);
+            }
         }
     }
 
-    gate_all!(param_attr_spans, param_attrs, "attributes on function parameters are unstable");
-    gate_all!(let_chains_spans, let_chains, "`let` expressions in this position are experimental");
-    gate_all!(async_closure_spans, async_closure, "async closures are unstable");
-    gate_all!(yield_spans, generators, "yield syntax is experimental");
-    gate_all!(or_pattern_spans, or_patterns, "or-patterns syntax is experimental");
+    gate_all!(param_attrs, "attributes on function parameters are unstable");
+    gate_all!(let_chains, "`let` expressions in this position are experimental");
+    gate_all!(async_closure, "async closures are unstable");
+    gate_all!(yields, generators, "yield syntax is experimental");
+    gate_all!(or_patterns, "or-patterns syntax is experimental");
 
     let visitor = &mut PostExpansionVisitor {
         context: &ctx,
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index a42da1123600a..c703058e7952d 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -21,9 +21,8 @@ const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
 impl<'a> Parser<'a> {
     crate fn parse_arg_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let attrs = self.parse_outer_attributes()?;
-        attrs.iter().for_each(|a|
-            self.sess.param_attr_spans.borrow_mut().push(a.span)
-        );
+        self.sess.gated_spans.param_attrs.borrow_mut()
+            .extend(attrs.iter().map(|a| a.span));
         Ok(attrs)
     }
 
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index b1f3612a839a2..b1af4806e2d78 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -39,6 +39,22 @@ crate mod unescape_error_reporting;
 
 pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
 
+/// Collected spans during parsing for places where a certain feature was
+/// used and should be feature gated accordingly in `check_crate`.
+#[derive(Default)]
+pub struct GatedSpans {
+    /// Spans collected for gating `param_attrs`, e.g. `fn foo(#[attr] x: u8) {}`.
+    pub param_attrs: Lock<Vec<Span>>,
+    /// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`.
+    pub let_chains: Lock<Vec<Span>>,
+    /// Spans collected for gating `async_closure`, e.g. `async || ..`.
+    pub async_closure: Lock<Vec<Span>>,
+    /// Spans collected for gating `yield e?` expressions (`generators` gate).
+    pub yields: Lock<Vec<Span>>,
+    /// Spans collected for gating `or_patterns`, e.g. `Some(Foo | Bar)`.
+    pub or_patterns: Lock<Vec<Span>>,
+}
+
 /// Info about a parsing session.
 pub struct ParseSess {
     pub span_diagnostic: Handler,
@@ -58,16 +74,8 @@ pub struct ParseSess {
     /// operation token that followed it, but that the parser cannot identify without further
     /// analysis.
     pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
-    pub param_attr_spans: Lock<Vec<Span>>,
-    // Places where `let` exprs were used and should be feature gated according to `let_chains`.
-    pub let_chains_spans: Lock<Vec<Span>>,
-    // Places where `async || ..` exprs were used and should be feature gated.
-    pub async_closure_spans: Lock<Vec<Span>>,
-    // Places where `yield e?` exprs were used and should be feature gated.
-    pub yield_spans: Lock<Vec<Span>>,
     pub injected_crate_name: Once<Symbol>,
-    // Places where or-patterns e.g. `Some(Foo | Bar)` were used and should be feature gated.
-    pub or_pattern_spans: Lock<Vec<Span>>,
+    pub gated_spans: GatedSpans,
 }
 
 impl ParseSess {
@@ -93,12 +101,8 @@ impl ParseSess {
             buffered_lints: Lock::new(vec![]),
             edition: ExpnId::root().expn_data().edition,
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
-            param_attr_spans: Lock::new(Vec::new()),
-            let_chains_spans: Lock::new(Vec::new()),
-            async_closure_spans: Lock::new(Vec::new()),
-            yield_spans: Lock::new(Vec::new()),
             injected_crate_name: Once::new(),
-            or_pattern_spans: Lock::new(Vec::new()),
+            gated_spans: GatedSpans::default(),
         }
     }
 
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index ccc6bd1506709..5da9b75d53b04 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -999,7 +999,7 @@ impl<'a> Parser<'a> {
                     }
 
                     let span = lo.to(hi);
-                    self.sess.yield_spans.borrow_mut().push(span);
+                    self.sess.gated_spans.yields.borrow_mut().push(span);
                 } else if self.eat_keyword(kw::Let) {
                     return self.parse_let_expr(attrs);
                 } else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
@@ -1111,7 +1111,7 @@ impl<'a> Parser<'a> {
         };
         if asyncness.is_async() {
             // Feature gate `async ||` closures.
-            self.sess.async_closure_spans.borrow_mut().push(self.prev_span);
+            self.sess.gated_spans.async_closure.borrow_mut().push(self.prev_span);
         }
 
         let capture_clause = self.parse_capture_clause();
@@ -1234,7 +1234,7 @@ impl<'a> Parser<'a> {
 
         if let ExprKind::Let(..) = cond.node {
             // Remove the last feature gating of a `let` expression since it's stable.
-            let last = self.sess.let_chains_spans.borrow_mut().pop();
+            let last = self.sess.gated_spans.let_chains.borrow_mut().pop();
             debug_assert_eq!(cond.span, last.unwrap());
         }
 
@@ -1252,7 +1252,7 @@ impl<'a> Parser<'a> {
             |this| this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into())
         )?;
         let span = lo.to(expr.span);
-        self.sess.let_chains_spans.borrow_mut().push(span);
+        self.sess.gated_spans.let_chains.borrow_mut().push(span);
         Ok(self.mk_expr(span, ExprKind::Let(pats, expr), attrs))
     }
 
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index fd458aec74331..8cfa6abbe6270 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -123,7 +123,7 @@ impl<'a> Parser<'a> {
 
         let or_pattern_span = lo.to(self.prev_span);
 
-        self.sess.or_pattern_spans.borrow_mut().push(or_pattern_span);
+        self.sess.gated_spans.or_patterns.borrow_mut().push(or_pattern_span);
 
         Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats)))
     }

From d9497749a87440d836495da6d40a5ce667a67ccb Mon Sep 17 00:00:00 2001
From: Jeremy Fitzhardinge <jsgf@fb.com>
Date: Mon, 19 Aug 2019 19:02:12 -0700
Subject: [PATCH 057/943] Move argfile expansion into run_compiler

This will make @path work with miri and other non-standard entrypoints.

Also since this simplifies librustc_driver::args, move it into a simple source file. Also
remove the tests since they're doing nothing more than checking `str::lines` has the right
behaviour.
---
 src/librustc_driver/args.rs                   |  53 +++++++
 src/librustc_driver/args/mod.rs               |  84 ----------
 src/librustc_driver/args/tests.rs             | 145 ------------------
 src/librustc_driver/lib.rs                    |  20 ++-
 src/test/ui/commandline-argfile-badutf8.rs    |   1 -
 .../ui/commandline-argfile-badutf8.stderr     |   2 +-
 src/test/ui/commandline-argfile-missing.rs    |   2 +-
 .../ui/commandline-argfile-missing.stderr     |   2 +-
 8 files changed, 70 insertions(+), 239 deletions(-)
 create mode 100644 src/librustc_driver/args.rs
 delete mode 100644 src/librustc_driver/args/mod.rs
 delete mode 100644 src/librustc_driver/args/tests.rs

diff --git a/src/librustc_driver/args.rs b/src/librustc_driver/args.rs
new file mode 100644
index 0000000000000..0906d358badd4
--- /dev/null
+++ b/src/librustc_driver/args.rs
@@ -0,0 +1,53 @@
+use std::error;
+use std::fmt;
+use std::fs;
+use std::io;
+use std::str;
+use std::sync::atomic::{AtomicBool, Ordering};
+
+static USED_ARGSFILE_FEATURE: AtomicBool = AtomicBool::new(false);
+
+pub fn used_unstable_argsfile() -> bool {
+    USED_ARGSFILE_FEATURE.load(Ordering::Relaxed)
+}
+
+pub fn arg_expand(arg: String) -> Result<Vec<String>, Error> {
+    if arg.starts_with("@") {
+        let path = &arg[1..];
+        let file = match fs::read_to_string(path) {
+            Ok(file) => {
+                USED_ARGSFILE_FEATURE.store(true, Ordering::Relaxed);
+                file
+            }
+            Err(ref err) if err.kind() == io::ErrorKind::InvalidData => {
+                return Err(Error::Utf8Error(Some(path.to_string())));
+            }
+            Err(err) => return Err(Error::IOError(path.to_string(), err)),
+        };
+        Ok(file.lines().map(ToString::to_string).collect())
+    } else {
+        Ok(vec![arg])
+    }
+}
+
+#[derive(Debug)]
+pub enum Error {
+    Utf8Error(Option<String>),
+    IOError(String, io::Error),
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Error::Utf8Error(None) => write!(fmt, "Utf8 error"),
+            Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {}", path),
+            Error::IOError(path, err) => write!(fmt, "IO Error: {}: {}", path, err),
+        }
+    }
+}
+
+impl error::Error for Error {
+    fn description(&self) -> &'static str {
+        "argument error"
+    }
+}
diff --git a/src/librustc_driver/args/mod.rs b/src/librustc_driver/args/mod.rs
deleted file mode 100644
index a59f9afd8beb5..0000000000000
--- a/src/librustc_driver/args/mod.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-use std::env;
-use std::error;
-use std::fmt;
-use std::fs;
-use std::io;
-use std::str;
-use std::sync::atomic::{AtomicBool, Ordering};
-
-#[cfg(test)]
-mod tests;
-
-static USED_ARGSFILE_FEATURE: AtomicBool = AtomicBool::new(false);
-
-pub fn used_unstable_argsfile() -> bool {
-    USED_ARGSFILE_FEATURE.load(Ordering::Relaxed)
-}
-
-pub struct ArgsIter {
-    base: env::ArgsOs,
-    file: std::vec::IntoIter<String>,
-}
-
-impl ArgsIter {
-    pub fn new() -> Self {
-        ArgsIter { base: env::args_os(), file: vec![].into_iter() }
-    }
-}
-
-impl Iterator for ArgsIter {
-    type Item = Result<String, Error>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        loop {
-            if let Some(line) = self.file.next() {
-                return Some(Ok(line));
-            }
-
-            let arg =
-                self.base.next().map(|arg| arg.into_string().map_err(|_| Error::Utf8Error(None)));
-            match arg {
-                Some(Err(err)) => return Some(Err(err)),
-                Some(Ok(ref arg)) if arg.starts_with("@") => {
-                    let path = &arg[1..];
-                    let file = match fs::read_to_string(path) {
-                        Ok(file) => {
-                            USED_ARGSFILE_FEATURE.store(true, Ordering::Relaxed);
-                            file
-                        }
-                        Err(ref err) if err.kind() == io::ErrorKind::InvalidData => {
-                            return Some(Err(Error::Utf8Error(Some(path.to_string()))));
-                        }
-                        Err(err) => return Some(Err(Error::IOError(path.to_string(), err))),
-                    };
-                    self.file =
-                        file.lines().map(ToString::to_string).collect::<Vec<_>>().into_iter();
-                }
-                Some(Ok(arg)) => return Some(Ok(arg)),
-                None => return None,
-            }
-        }
-    }
-}
-
-#[derive(Debug)]
-pub enum Error {
-    Utf8Error(Option<String>),
-    IOError(String, io::Error),
-}
-
-impl fmt::Display for Error {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match self {
-            Error::Utf8Error(None) => write!(fmt, "Utf8 error"),
-            Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {}", path),
-            Error::IOError(path, err) => write!(fmt, "IO Error: {}: {}", path, err),
-        }
-    }
-}
-
-impl error::Error for Error {
-    fn description(&self) -> &'static str {
-        "argument error"
-    }
-}
diff --git a/src/librustc_driver/args/tests.rs b/src/librustc_driver/args/tests.rs
deleted file mode 100644
index 080dd5cb746c3..0000000000000
--- a/src/librustc_driver/args/tests.rs
+++ /dev/null
@@ -1,145 +0,0 @@
-use super::*;
-
-use std::str;
-
-fn want_args(v: impl IntoIterator<Item = &'static str>) -> Vec<String> {
-    v.into_iter().map(String::from).collect()
-}
-
-fn got_args(file: &[u8]) -> Result<Vec<String>, Error> {
-    let ret = str::from_utf8(file)
-        .map_err(|_| Error::Utf8Error(None))?
-        .lines()
-        .map(ToString::to_string)
-        .collect::<Vec<_>>();
-    Ok(ret)
-}
-
-#[test]
-fn nothing() {
-    let file = b"";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec![]));
-}
-
-#[test]
-fn empty() {
-    let file = b"\n";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec![""]));
-}
-
-#[test]
-fn simple() {
-    let file = b"foo";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo"]));
-}
-
-#[test]
-fn simple_eol() {
-    let file = b"foo\n";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo"]));
-}
-
-#[test]
-fn multi() {
-    let file = b"foo\nbar";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar"]));
-}
-
-#[test]
-fn multi_eol() {
-    let file = b"foo\nbar\n";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar"]));
-}
-
-#[test]
-fn multi_empty() {
-    let file = b"foo\n\nbar";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "", "bar"]));
-}
-
-#[test]
-fn multi_empty_eol() {
-    let file = b"foo\n\nbar\n";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "", "bar"]));
-}
-
-#[test]
-fn multi_empty_start() {
-    let file = b"\nfoo\nbar";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["", "foo", "bar"]));
-}
-
-#[test]
-fn multi_empty_end() {
-    let file = b"foo\nbar\n\n";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar", ""]));
-}
-
-#[test]
-fn simple_eol_crlf() {
-    let file = b"foo\r\n";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo"]));
-}
-
-#[test]
-fn multi_crlf() {
-    let file = b"foo\r\nbar";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar"]));
-}
-
-#[test]
-fn multi_eol_crlf() {
-    let file = b"foo\r\nbar\r\n";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar"]));
-}
-
-#[test]
-fn multi_empty_crlf() {
-    let file = b"foo\r\n\r\nbar";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "", "bar"]));
-}
-
-#[test]
-fn multi_empty_eol_crlf() {
-    let file = b"foo\r\n\r\nbar\r\n";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "", "bar"]));
-}
-
-#[test]
-fn multi_empty_start_crlf() {
-    let file = b"\r\nfoo\r\nbar";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["", "foo", "bar"]));
-}
-
-#[test]
-fn multi_empty_end_crlf() {
-    let file = b"foo\r\nbar\r\n\r\n";
-
-    assert_eq!(got_args(file).unwrap(), want_args(vec!["foo", "bar", ""]));
-}
-
-#[test]
-fn bad_utf8() {
-    let file = b"foo\x80foo";
-
-    match got_args(file).unwrap_err() {
-        Error::Utf8Error(_) => (),
-        bad => panic!("bad err: {:?}", bad),
-    }
-}
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 4843c1a951b31..2cec404c3d7f6 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -140,14 +140,22 @@ impl Callbacks for TimePassesCallbacks {
 // See comments on CompilerCalls below for details about the callbacks argument.
 // The FileLoader provides a way to load files from sources other than the file system.
 pub fn run_compiler(
-    args: &[String],
+    at_args: &[String],
     callbacks: &mut (dyn Callbacks + Send),
     file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
     emitter: Option<Box<dyn Write + Send>>
 ) -> interface::Result<()> {
+    let mut args = Vec::new();
+    for arg in at_args {
+        match args::arg_expand(arg.clone()) {
+            Ok(arg) => args.extend(arg),
+            Err(err) => early_error(ErrorOutputType::default(),
+                &format!("Failed to load argument file: {}", err)),
+        }
+    }
     let diagnostic_output = emitter.map(|emitter| DiagnosticOutput::Raw(emitter))
                                    .unwrap_or(DiagnosticOutput::Default);
-    let matches = match handle_options(args) {
+    let matches = match handle_options(&args) {
         Some(matches) => matches,
         None => return Ok(()),
     };
@@ -1199,10 +1207,10 @@ pub fn main() {
     init_rustc_env_logger();
     let mut callbacks = TimePassesCallbacks::default();
     let result = report_ices_to_stderr_if_any(|| {
-        let args = args::ArgsIter::new().enumerate()
-            .map(|(i, arg)| arg.unwrap_or_else(|err| {
-                early_error(ErrorOutputType::default(),
-                            &format!("Argument {} is not valid: {}", i, err))
+        let args = env::args_os().enumerate()
+            .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| {
+                    early_error(ErrorOutputType::default(),
+                            &format!("Argument {} is not valid Unicode: {:?}", i, arg))
             }))
             .collect::<Vec<_>>();
         run_compiler(&args, &mut callbacks, None, None)
diff --git a/src/test/ui/commandline-argfile-badutf8.rs b/src/test/ui/commandline-argfile-badutf8.rs
index c017e7b5ea60b..161715685b57f 100644
--- a/src/test/ui/commandline-argfile-badutf8.rs
+++ b/src/test/ui/commandline-argfile-badutf8.rs
@@ -1,7 +1,6 @@
 // Check to see if we can get parameters from an @argsfile file
 //
 // build-fail
-// normalize-stderr-test: "Argument \d+" -> "Argument $$N"
 // compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args
 
 #[cfg(not(cmdline_set))]
diff --git a/src/test/ui/commandline-argfile-badutf8.stderr b/src/test/ui/commandline-argfile-badutf8.stderr
index cd8a03e34eac9..9af6fc0a518df 100644
--- a/src/test/ui/commandline-argfile-badutf8.stderr
+++ b/src/test/ui/commandline-argfile-badutf8.stderr
@@ -1,2 +1,2 @@
-error: Argument $N is not valid: Utf8 error in $DIR/commandline-argfile-badutf8.args
+error: Failed to load argument file: Utf8 error in $DIR/commandline-argfile-badutf8.args
 
diff --git a/src/test/ui/commandline-argfile-missing.rs b/src/test/ui/commandline-argfile-missing.rs
index 34faf07633599..a29b4ab062de3 100644
--- a/src/test/ui/commandline-argfile-missing.rs
+++ b/src/test/ui/commandline-argfile-missing.rs
@@ -1,7 +1,7 @@
 // Check to see if we can get parameters from an @argsfile file
 //
+// ignore-tidy-linelength
 // build-fail
-// normalize-stderr-test: "Argument \d+" -> "Argument $$N"
 // normalize-stderr-test: "os error \d+" -> "os error $$ERR"
 // normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING "
 // compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args
diff --git a/src/test/ui/commandline-argfile-missing.stderr b/src/test/ui/commandline-argfile-missing.stderr
index c0017782f2eb3..179ad83100419 100644
--- a/src/test/ui/commandline-argfile-missing.stderr
+++ b/src/test/ui/commandline-argfile-missing.stderr
@@ -1,2 +1,2 @@
-error: Argument $N is not valid: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
+error: Failed to load argument file: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR)
 

From 7ee4f1da8c75b44501c01fb3e754c1732dad76c3 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 20 Aug 2019 18:10:43 +0200
Subject: [PATCH 058/943] Allow 'default async fn' to parse.

---
 src/libsyntax/parse/parser/item.rs                 |  1 +
 .../ui/specialization/issue-63716-parse-async.rs   | 14 ++++++++++++++
 2 files changed, 15 insertions(+)
 create mode 100644 src/test/ui/specialization/issue-63716-parse-async.rs

diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index 72819c9966035..03d7e92212382 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -825,6 +825,7 @@ impl<'a> Parser<'a> {
             self.is_keyword_ahead(1, &[
                 kw::Impl,
                 kw::Const,
+                kw::Async,
                 kw::Fn,
                 kw::Unsafe,
                 kw::Extern,
diff --git a/src/test/ui/specialization/issue-63716-parse-async.rs b/src/test/ui/specialization/issue-63716-parse-async.rs
new file mode 100644
index 0000000000000..c3764ffaab83f
--- /dev/null
+++ b/src/test/ui/specialization/issue-63716-parse-async.rs
@@ -0,0 +1,14 @@
+// Ensure that `default async fn` will parse.
+// See issue #63716 for details.
+
+// check-pass
+// edition:2018
+
+#![feature(specialization)]
+
+fn main() {}
+
+#[cfg(FALSE)]
+impl Foo for Bar {
+    default async fn baz() {}
+}

From 13c1db981905ea61d2d4ef7bf067b7d495a7f219 Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Tue, 20 Aug 2019 14:03:13 -0700
Subject: [PATCH 059/943] Update books

---
 src/doc/embedded-book   | 2 +-
 src/doc/nomicon         | 2 +-
 src/doc/reference       | 2 +-
 src/doc/rust-by-example | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/doc/embedded-book b/src/doc/embedded-book
index c5da1e11915d3..432ca26686c11 160000
--- a/src/doc/embedded-book
+++ b/src/doc/embedded-book
@@ -1 +1 @@
-Subproject commit c5da1e11915d3f28266168baaf55822f7e3fe999
+Subproject commit 432ca26686c11d396eed6a59499f93ce1bf2433c
diff --git a/src/doc/nomicon b/src/doc/nomicon
index 8a7d05615e5bc..38b9a76bc8b59 160000
--- a/src/doc/nomicon
+++ b/src/doc/nomicon
@@ -1 +1 @@
-Subproject commit 8a7d05615e5bc0a7fb961b4919c44f5221ee54da
+Subproject commit 38b9a76bc8b59ac862663807fc51c9b757337fd6
diff --git a/src/doc/reference b/src/doc/reference
index b4b3536839042..d191a0cdd3b92 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit b4b3536839042a6743fc76f0d9ad2a812020aeaa
+Subproject commit d191a0cdd3b92648e0f1e53b13140a14677cc65b
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index f2c15ba5ee89a..580839d90aacd 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit f2c15ba5ee89ae9469a2cf60494977749901d764
+Subproject commit 580839d90aacd537f0293697096fa8355bc4e673

From 0c5220dc364a389935b5bd99f5f8e4ebbf47f6f8 Mon Sep 17 00:00:00 2001
From: Ilija Tovilo <ilija.tovilo@me.com>
Date: Sun, 18 Aug 2019 23:59:46 +0200
Subject: [PATCH 060/943] Test that Wrapping arithmetic ops are implemented for
 all int types

---
 src/libcore/num/wrapping.rs              |  8 +++
 src/test/ui/wrapping-int-combinations.rs | 73 ++++++++++++++++++++++++
 2 files changed, 81 insertions(+)
 create mode 100644 src/test/ui/wrapping-int-combinations.rs

diff --git a/src/libcore/num/wrapping.rs b/src/libcore/num/wrapping.rs
index fd129a306d1c5..59a10ae99bb6a 100644
--- a/src/libcore/num/wrapping.rs
+++ b/src/libcore/num/wrapping.rs
@@ -18,6 +18,8 @@ macro_rules! sh_impl_signed {
                 }
             }
         }
+        forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f,
+                #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl ShlAssign<$f> for Wrapping<$t> {
@@ -41,6 +43,8 @@ macro_rules! sh_impl_signed {
                 }
             }
         }
+        forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f,
+                #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl ShrAssign<$f> for Wrapping<$t> {
@@ -64,6 +68,8 @@ macro_rules! sh_impl_unsigned {
                 Wrapping(self.0.wrapping_shl((other & self::shift_max::$t as $f) as u32))
             }
         }
+        forward_ref_binop! { impl Shl, shl for Wrapping<$t>, $f,
+                #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl ShlAssign<$f> for Wrapping<$t> {
@@ -83,6 +89,8 @@ macro_rules! sh_impl_unsigned {
                 Wrapping(self.0.wrapping_shr((other & self::shift_max::$t as $f) as u32))
             }
         }
+        forward_ref_binop! { impl Shr, shr for Wrapping<$t>, $f,
+                #[stable(feature = "wrapping_ref_ops", since = "1.39.0")] }
 
         #[stable(feature = "op_assign_traits", since = "1.8.0")]
         impl ShrAssign<$f> for Wrapping<$t> {
diff --git a/src/test/ui/wrapping-int-combinations.rs b/src/test/ui/wrapping-int-combinations.rs
new file mode 100644
index 0000000000000..e09f7232bd2fb
--- /dev/null
+++ b/src/test/ui/wrapping-int-combinations.rs
@@ -0,0 +1,73 @@
+// run-pass
+
+use std::num::Wrapping;
+
+macro_rules! wrapping_operation {
+    ($result:expr, $lhs:ident $op:tt $rhs:expr) => {
+        assert_eq!($result, $lhs $op $rhs);
+        assert_eq!($result, &$lhs $op $rhs);
+        assert_eq!($result, $lhs $op &$rhs);
+        assert_eq!($result, &$lhs $op &$rhs);
+    };
+    ($result:expr, $op:tt $expr:expr) => {
+        assert_eq!($result, $op $expr);
+        assert_eq!($result, $op &$expr);
+    };
+}
+
+macro_rules! wrapping_assignment {
+    ($result:expr, $lhs:ident $op:tt $rhs:expr) => {
+        let mut lhs1 = $lhs;
+        lhs1 $op $rhs;
+        assert_eq!($result, lhs1);
+
+        let mut lhs2 = $lhs;
+        lhs2 $op &$rhs;
+        assert_eq!($result, lhs2);
+    };
+}
+
+macro_rules! wrapping_test {
+    ($type:ty, $min:expr, $max:expr) => {
+        let zero: Wrapping<$type> = Wrapping(0);
+        let one: Wrapping<$type> = Wrapping(1);
+        let min: Wrapping<$type> = Wrapping($min);
+        let max: Wrapping<$type> = Wrapping($max);
+
+        wrapping_operation!(min, max + one);
+        wrapping_assignment!(min, max += one);
+        wrapping_operation!(max, min - one);
+        wrapping_assignment!(max, min -= one);
+        wrapping_operation!(max, max * one);
+        wrapping_assignment!(max, max *= one);
+        wrapping_operation!(max, max / one);
+        wrapping_assignment!(max, max /= one);
+        wrapping_operation!(zero, max % one);
+        wrapping_assignment!(zero, max %= one);
+        wrapping_operation!(zero, zero & max);
+        wrapping_assignment!(zero, zero &= max);
+        wrapping_operation!(max, zero | max);
+        wrapping_assignment!(max, zero |= max);
+        wrapping_operation!(zero, max ^ max);
+        wrapping_assignment!(zero, max ^= max);
+        wrapping_operation!(zero, zero << 1usize);
+        wrapping_assignment!(zero, zero <<= 1usize);
+        wrapping_operation!(zero, zero >> 1usize);
+        wrapping_assignment!(zero, zero >>= 1usize);
+        wrapping_operation!(zero, -zero);
+        wrapping_operation!(max, !min);
+    };
+}
+
+fn main() {
+    wrapping_test!(i8, std::i8::MIN, std::i8::MAX);
+    wrapping_test!(i16, std::i16::MIN, std::i16::MAX);
+    wrapping_test!(i32, std::i32::MIN, std::i32::MAX);
+    wrapping_test!(i64, std::i64::MIN, std::i64::MAX);
+    wrapping_test!(i128, std::i128::MIN, std::i128::MAX);
+    wrapping_test!(u8, std::u8::MIN, std::u8::MAX);
+    wrapping_test!(u16, std::u16::MIN, std::u16::MAX);
+    wrapping_test!(u32, std::u32::MIN, std::u32::MAX);
+    wrapping_test!(u64, std::u64::MIN, std::u64::MAX);
+    wrapping_test!(u128, std::u128::MIN, std::u128::MAX);
+}

From 418eb181ca5777fb06e29a2acf37a5c641340538 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 21 Aug 2019 00:23:08 +0200
Subject: [PATCH 061/943] async_await was stabilized in 1.39.0, not 1.38.0.

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

diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index bce0b07db1c23..f7aaf5cd22a3d 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -855,7 +855,7 @@ declare_features! (
     // Allows `const _: TYPE = VALUE`.
     (accepted, underscore_const_names, "1.37.0", Some(54912), None),
     // Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
-    (accepted, async_await, "1.38.0", Some(50547), None),
+    (accepted, async_await, "1.39.0", Some(50547), None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features

From 40cb69da59f2c759dadf40c1d86d1d11a995d3dd Mon Sep 17 00:00:00 2001
From: Artyom Pavlov <newpavlov@gmail.com>
Date: Wed, 21 Aug 2019 00:15:11 +0000
Subject: [PATCH 062/943] fix libtest

---
 src/libtest/lib.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index ef66c4df99da7..709c12f60fc41 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -965,12 +965,11 @@ fn use_color(opts: &TestOpts) -> bool {
 
 #[cfg(any(
     target_os = "cloudabi",
-    target_os = "redox",
     all(target_arch = "wasm32", not(target_os = "emscripten")),
     all(target_vendor = "fortanix", target_env = "sgx")
 ))]
 fn stdout_isatty() -> bool {
-    // FIXME: Implement isatty on Redox and SGX
+    // FIXME: Implement isatty on SGX
     false
 }
 #[cfg(unix)]

From 82cb2076072546c958fbe0e3c28f87849e42817a Mon Sep 17 00:00:00 2001
From: Artyom Pavlov <newpavlov@gmail.com>
Date: Wed, 21 Aug 2019 00:18:05 +0000
Subject: [PATCH 063/943] fix num_cpus

---
 src/libtest/lib.rs | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 709c12f60fc41..216112cb6e0be 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -1192,12 +1192,6 @@ fn get_concurrency() -> usize {
         }
     }
 
-    #[cfg(target_os = "redox")]
-    fn num_cpus() -> usize {
-        // FIXME: Implement num_cpus on Redox
-        1
-    }
-
     #[cfg(target_os = "vxworks")]
     fn num_cpus() -> usize {
         // FIXME: Implement num_cpus on vxWorks
@@ -1220,7 +1214,8 @@ fn get_concurrency() -> usize {
         target_os = "ios",
         target_os = "linux",
         target_os = "macos",
-        target_os = "solaris"
+        target_os = "solaris",
+        target_os = "redox",
     ))]
     fn num_cpus() -> usize {
         unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize }

From 7dbc4b95fc274ac23453e1f4c3b01e22cc4e7836 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Wed, 21 Aug 2019 02:29:08 +0200
Subject: [PATCH 064/943] Remove some duplication when resolving constants

---
 src/librustc/ty/relate.rs | 24 +++---------------------
 src/librustc/ty/sty.rs    | 24 +++++++++++++++++-------
 2 files changed, 20 insertions(+), 28 deletions(-)

diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 945e3e158eafb..565447dd7e1af 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -8,7 +8,7 @@ use crate::hir::def_id::DefId;
 use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
 use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
 use crate::ty::error::{ExpectedFound, TypeError};
-use crate::mir::interpret::{ConstValue, Scalar, GlobalId};
+use crate::mir::interpret::{ConstValue, Scalar};
 use std::rc::Rc;
 use std::iter;
 use rustc_target::spec::abi;
@@ -551,26 +551,8 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
     let tcx = relation.tcx();
 
     let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
-        if let ConstValue::Unevaluated(def_id, substs) = x.val {
-            // FIXME(eddyb) get the right param_env.
-            let param_env = ty::ParamEnv::empty();
-            if !substs.has_local_value() {
-                let instance = ty::Instance::resolve(
-                    tcx.global_tcx(),
-                    param_env,
-                    def_id,
-                    substs,
-                );
-                if let Some(instance) = instance {
-                    let cid = GlobalId {
-                        instance,
-                        promoted: None,
-                    };
-                    if let Ok(ct) = tcx.const_eval(param_env.and(cid)) {
-                        return ct.val;
-                    }
-                }
-            }
+        if !x.val.has_local_value() {
+            return x.eval(tcx, relation.param_env()).val;
         }
         x.val
     };
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 2b173068b38e4..da66fdf5b1b1b 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -2299,23 +2299,33 @@ impl<'tcx> Const<'tcx> {
         assert_eq!(self.ty, ty);
         // if `ty` does not depend on generic parameters, use an empty param_env
         let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
+        self.eval(tcx, param_env).val.try_to_bits(size)
+    }
+
+    #[inline]
+    pub fn eval(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        param_env: ParamEnv<'tcx>,
+    ) -> &Const<'tcx> {
+        // FIXME(const_generics): this doesn't work right now,
+        // because it tries to relate an `Infer` to a `Param`.
         match self.val {
-            // FIXME(const_generics): this doesn't work right now,
-            // because it tries to relate an `Infer` to a `Param`.
             ConstValue::Unevaluated(did, substs) => {
                 // if `substs` has no unresolved components, use and empty param_env
                 let (param_env, substs) = param_env.with_reveal_all().and(substs).into_parts();
                 // try to resolve e.g. associated constants to their definition on an impl
-                let instance = ty::Instance::resolve(tcx, param_env, did, substs)?;
+                let instance = match ty::Instance::resolve(tcx, param_env, did, substs) {
+                    Some(instance) => instance,
+                    None => return self,
+                };
                 let gid = GlobalId {
                     instance,
                     promoted: None,
                 };
-                let evaluated = tcx.const_eval(param_env.and(gid)).ok()?;
-                evaluated.val.try_to_bits(size)
+                tcx.const_eval(param_env.and(gid)).unwrap_or(self)
             },
-            // otherwise just extract a `ConstValue`'s bits if possible
-            _ => self.val.try_to_bits(size),
+            _ => self,
         }
     }
 

From 0337cc117d3c972b7b98e5c09212d58d3d16a009 Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Wed, 21 Aug 2019 00:37:17 +0000
Subject: [PATCH 065/943] Use more optimal Ord implementation for integers

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

diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index cb9feb074dd70..74e9ceb510a99 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -1012,9 +1012,9 @@ mod impls {
             impl Ord for $t {
                 #[inline]
                 fn cmp(&self, other: &$t) -> Ordering {
-                    if *self == *other { Equal }
-                    else if *self < *other { Less }
-                    else { Greater }
+                    if *self < *other { Less }
+                    else if *self > *other { Greater }
+                    else { Equal }
                 }
             }
         )*)

From 88fd9450aa2111fcbe981006a9c391d57775ec14 Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Wed, 21 Aug 2019 04:16:05 +0300
Subject: [PATCH 066/943] update args

---
 src/libstd/sys/wasi/args.rs | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs
index 2d0ddea385afd..de9ca62469d5d 100644
--- a/src/libstd/sys/wasi/args.rs
+++ b/src/libstd/sys/wasi/args.rs
@@ -18,8 +18,14 @@ pub struct Args {
 
 /// Returns the command line arguments
 pub fn args() -> Args {
-    let mut buf = Vec::new();
-    let _ = wasi::get_args(|arg| buf.push(OsString::from_vec(arg.to_vec())));
+    let buf = wasi::args_sizes_get().and_then(|args_sizes| {
+        let mut buf = Vec::with_capacity(args_sizes.get_count());
+        wasi::get_args(args_sizes, |arg| {
+            let arg = OsString::from_vec(arg.to_vec());
+            buf.push(arg);
+        })?;
+        Ok(buf)
+    }).unwrap_or(vec![]);
     Args {
         iter: buf.into_iter(),
         _dont_send_or_sync_me: PhantomData

From 96983fc53009a2a2d2f93e7cec012634800be1fa Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Wed, 21 Aug 2019 06:25:37 +0000
Subject: [PATCH 067/943] Add comment to avoid accidentally remove the changes.

---
 src/libcore/cmp.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 74e9ceb510a99..167a9dd1c3620 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -1012,6 +1012,8 @@ mod impls {
             impl Ord for $t {
                 #[inline]
                 fn cmp(&self, other: &$t) -> Ordering {
+                    // The order here is important to generate more optimal assembly.
+                    // See <https://github.com/rust-lang/rust/issues/63758> for more info.
                     if *self < *other { Less }
                     else if *self > *other { Greater }
                     else { Equal }

From 9b8514bb873c4bf8cfa1b5342c7b79f0fab5614a Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro@pietroalbini.org>
Date: Wed, 21 Aug 2019 09:06:55 +0200
Subject: [PATCH 068/943] ci: move libc mirrors to the rust-lang-ci-mirrors
 bucket

---
 src/ci/docker/dist-various-1/install-mipsel-musl.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ci/docker/dist-various-1/install-mipsel-musl.sh b/src/ci/docker/dist-various-1/install-mipsel-musl.sh
index 9ae41218ee4fb..de8c359d16757 100755
--- a/src/ci/docker/dist-various-1/install-mipsel-musl.sh
+++ b/src/ci/docker/dist-various-1/install-mipsel-musl.sh
@@ -5,7 +5,7 @@ mkdir /usr/local/mipsel-linux-musl
 # Note that this originally came from:
 # https://downloads.openwrt.org/snapshots/trunk/malta/generic/
 # OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2
-URL="https://rust-lang-ci2.s3.amazonaws.com/libc"
+URL="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc"
 FILE="OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2"
 curl -L "$URL/$FILE" | tar xjf - -C /usr/local/mipsel-linux-musl --strip-components=2
 

From 4d50b249d76c6335a04d0210f3118fb3bc8d1cbc Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Wed, 21 Aug 2019 09:37:23 +0200
Subject: [PATCH 069/943] update Miri

---
 src/tools/miri | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/miri b/src/tools/miri
index 4f6f264c305ea..d77fe6c63ca4c 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 4f6f264c305ea30f1de90ad0c2f341e84d972b2e
+Subproject commit d77fe6c63ca4c50b207a1161def90c9e57368d5b

From c076d30ce45cc0ad573bc15d8f1c11db261924f3 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Mon, 27 May 2019 15:57:44 +0200
Subject: [PATCH 070/943] take into account the system theme

---
 src/librustdoc/html/static/rustdoc.css | 15 +++++++++++++++
 src/librustdoc/html/static/storage.js  | 16 +++++++++++++---
 2 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index 59d10668f11ab..244b24af43f35 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -54,6 +54,21 @@
 		  box-sizing: border-box;
 }
 
+/* This part handles the "default" theme being used depending on the system one. */
+html {
+	content: "";
+}
+@media (prefers-color-scheme: light) {
+	html {
+		content: "light";
+	}
+}
+@media (prefers-color-scheme: dark) {
+	html {
+		content: "dark";
+	}
+}
+
 /* General structure and fonts */
 
 body {
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index e3927350d1104..86efc7815602f 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -86,7 +86,7 @@ function getCurrentValue(name) {
     return null;
 }
 
-function switchTheme(styleElem, mainStyleElem, newTheme) {
+function switchTheme(styleElem, mainStyleElem, newTheme, skipStorage) {
     var fullBasicCss = "rustdoc" + resourcesSuffix + ".css";
     var fullNewTheme = newTheme + resourcesSuffix + ".css";
     var newHref = mainStyleElem.href.replace(fullBasicCss, fullNewTheme);
@@ -109,8 +109,18 @@ function switchTheme(styleElem, mainStyleElem, newTheme) {
     });
     if (found === true) {
         styleElem.href = newHref;
-        updateLocalStorage("rustdoc-theme", newTheme);
+        // If this new value comes from a system setting or from the previously saved theme, no
+        // need to save it.
+        if (skipStorage !== true) {
+            updateLocalStorage("rustdoc-theme", newTheme);
+        }
     }
 }
 
-switchTheme(currentTheme, mainTheme, getCurrentValue("rustdoc-theme") || "light");
+function getSystemValue() {
+    return getComputedStyle(document.documentElement).getPropertyValue('content');
+}
+
+switchTheme(currentTheme, mainTheme,
+            getCurrentValue("rustdoc-theme") || getSystemValue() || "light",
+            true);

From 5a446c1ea9b829f291fe2d29b3ec7f1eabe8f26e Mon Sep 17 00:00:00 2001
From: Ferdia McKeogh <ferdia@mckeogh.tech>
Date: Wed, 21 Aug 2019 09:13:51 +0100
Subject: [PATCH 071/943] Fix `window.hashchange is not a function`

---
 src/librustdoc/html/static/main.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 82d2c11b2497b..1f5a9447f46b3 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -344,7 +344,7 @@ if (!DOMTokenList.prototype.remove) {
             var set_fragment = function(name) {
                 if (browserSupportsHistoryApi()) {
                     history.replaceState(null, null, "#" + name);
-                    window.hashchange();
+                    highlightSourceLines(null);
                 } else {
                     location.replace("#" + name);
                 }

From 1dd56aa3047851891e6a1923e8fec3569d0fc89f Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Mon, 19 Aug 2019 23:10:07 +0300
Subject: [PATCH 072/943] Add a test for an opaque macro eagerly expanding its
 arguments

---
 src/test/ui/hygiene/eager-from-opaque.rs     | 18 ++++++++++++++++++
 src/test/ui/hygiene/eager-from-opaque.stderr |  8 ++++++++
 2 files changed, 26 insertions(+)
 create mode 100644 src/test/ui/hygiene/eager-from-opaque.rs
 create mode 100644 src/test/ui/hygiene/eager-from-opaque.stderr

diff --git a/src/test/ui/hygiene/eager-from-opaque.rs b/src/test/ui/hygiene/eager-from-opaque.rs
new file mode 100644
index 0000000000000..57925d626b9d1
--- /dev/null
+++ b/src/test/ui/hygiene/eager-from-opaque.rs
@@ -0,0 +1,18 @@
+// Opaque macro can eagerly expand its input without breaking its resolution.
+// Regression test for issue #63685.
+
+macro_rules! foo {
+    () => {
+        "foo"
+    };
+}
+
+macro_rules! bar {
+    () => {
+        foo!() //~ ERROR cannot find macro `foo!` in this scope
+    };
+}
+
+fn main() {
+    format_args!(bar!());
+}
diff --git a/src/test/ui/hygiene/eager-from-opaque.stderr b/src/test/ui/hygiene/eager-from-opaque.stderr
new file mode 100644
index 0000000000000..8db96e6ac95e5
--- /dev/null
+++ b/src/test/ui/hygiene/eager-from-opaque.stderr
@@ -0,0 +1,8 @@
+error: cannot find macro `foo!` in this scope
+  --> $DIR/eager-from-opaque.rs:12:9
+   |
+LL |         foo!()
+   |         ^^^
+
+error: aborting due to previous error
+

From 96032aa5efd82c3cddc485332162614b9b8dd3dd Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Mon, 19 Aug 2019 23:35:25 +0300
Subject: [PATCH 073/943] expand: Keep the correct current expansion ID for
 eager expansions

Solve the problem of `ParentScope` entries for eager expansions not exising in the resolver map by creating them on demand.
---
 src/librustc_resolve/macros.rs                           | 4 +++-
 src/libsyntax/ext/expand.rs                              | 1 -
 src/test/ui/hygiene/eager-from-opaque.stderr             | 3 +++
 src/test/ui/macros/derive-in-eager-expansion-hang.stderr | 3 +++
 4 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 01ad67252a387..8a7a30813c1e0 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -142,7 +142,9 @@ impl<'a> base::Resolver for Resolver<'a> {
 
     fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool)
                                 -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> {
-        let parent_scope = self.invocation_parent_scopes[&invoc_id];
+        let inherited_parent_scope = self.invocation_parent_scopes[&invoc_id];
+        let parent_scope = *self.invocation_parent_scopes.entry(invoc.expansion_data.id)
+                                                         .or_insert(inherited_parent_scope);
         let (path, kind, derives, after_derive) = match invoc.kind {
             InvocationKind::Attr { ref attr, ref derives, after_derive, .. } =>
                 (&attr.path, MacroKind::Attr, self.arenas.alloc_ast_paths(derives), after_derive),
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index c1d52c9745529..5ac234b78d0fe 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -318,7 +318,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             progress = true;
             let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data;
             self.cx.current_expansion = invoc.expansion_data.clone();
-            self.cx.current_expansion.id = scope;
 
             // FIXME(jseyfried): Refactor out the following logic
             let (expanded_fragment, new_invocations) = if let Some(ext) = ext {
diff --git a/src/test/ui/hygiene/eager-from-opaque.stderr b/src/test/ui/hygiene/eager-from-opaque.stderr
index 8db96e6ac95e5..f696e6caff7ca 100644
--- a/src/test/ui/hygiene/eager-from-opaque.stderr
+++ b/src/test/ui/hygiene/eager-from-opaque.stderr
@@ -3,6 +3,9 @@ error: cannot find macro `foo!` in this scope
    |
 LL |         foo!()
    |         ^^^
+...
+LL |     format_args!(bar!());
+   |                  ------ in this macro invocation
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/derive-in-eager-expansion-hang.stderr b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr
index 1ef9427666bc5..5ca4088e585db 100644
--- a/src/test/ui/macros/derive-in-eager-expansion-hang.stderr
+++ b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr
@@ -8,6 +8,9 @@ LL | |
 LL | |         ""
 LL | |     }
    | |_____^
+...
+LL |       format_args!(hang!());
+   |                    ------- in this macro invocation
 help: you might be missing a string literal to format with
    |
 LL |     format_args!("{}", hang!());

From a83c35692fa5fc65ec9860599501f1a5a5e98214 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Mon, 19 Aug 2019 23:44:57 +0300
Subject: [PATCH 074/943] expand: Do not do questionable span adjustment before
 eagerly expanding an expression

Maybe it made sense when it was introduced, but now it's doing something incorrect.
---
 src/libsyntax/ext/base.rs                    |  5 +----
 src/test/ui/hygiene/eager-from-opaque.rs     |  4 +++-
 src/test/ui/hygiene/eager-from-opaque.stderr | 11 -----------
 3 files changed, 4 insertions(+), 16 deletions(-)
 delete mode 100644 src/test/ui/hygiene/eager-from-opaque.stderr

diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index b0a4a6af9839c..376df4062b116 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -908,12 +908,9 @@ impl<'a> ExtCtxt<'a> {
 /// compilation on error, merely emits a non-fatal error and returns `None`.
 pub fn expr_to_spanned_string<'a>(
     cx: &'a mut ExtCtxt<'_>,
-    mut expr: P<ast::Expr>,
+    expr: P<ast::Expr>,
     err_msg: &str,
 ) -> Result<(Symbol, ast::StrStyle, Span), Option<DiagnosticBuilder<'a>>> {
-    // Update `expr.span`'s ctxt now in case expr is an `include!` macro invocation.
-    expr.span = expr.span.apply_mark(cx.current_expansion.id);
-
     // Perform eager expansion on the expression.
     // We want to be able to handle e.g., `concat!("foo", "bar")`.
     let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
diff --git a/src/test/ui/hygiene/eager-from-opaque.rs b/src/test/ui/hygiene/eager-from-opaque.rs
index 57925d626b9d1..6f3215dd697f3 100644
--- a/src/test/ui/hygiene/eager-from-opaque.rs
+++ b/src/test/ui/hygiene/eager-from-opaque.rs
@@ -1,6 +1,8 @@
 // Opaque macro can eagerly expand its input without breaking its resolution.
 // Regression test for issue #63685.
 
+// check-pass
+
 macro_rules! foo {
     () => {
         "foo"
@@ -9,7 +11,7 @@ macro_rules! foo {
 
 macro_rules! bar {
     () => {
-        foo!() //~ ERROR cannot find macro `foo!` in this scope
+        foo!()
     };
 }
 
diff --git a/src/test/ui/hygiene/eager-from-opaque.stderr b/src/test/ui/hygiene/eager-from-opaque.stderr
deleted file mode 100644
index f696e6caff7ca..0000000000000
--- a/src/test/ui/hygiene/eager-from-opaque.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: cannot find macro `foo!` in this scope
-  --> $DIR/eager-from-opaque.rs:12:9
-   |
-LL |         foo!()
-   |         ^^^
-...
-LL |     format_args!(bar!());
-   |                  ------ in this macro invocation
-
-error: aborting due to previous error
-

From 93d369bc2b65e822d001a8d08f99c6bbaf105ee5 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 20 Aug 2019 00:24:28 +0300
Subject: [PATCH 075/943] resolve/expand: Rename some things for clarity and
 add comments

---
 src/librustc_resolve/macros.rs | 36 +++++++++++++++++++++-------------
 src/libsyntax/ext/base.rs      |  5 +++--
 src/libsyntax/ext/expand.rs    |  6 ++++--
 3 files changed, 29 insertions(+), 18 deletions(-)

diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 8a7a30813c1e0..719167eb057b2 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -140,11 +140,23 @@ impl<'a> base::Resolver for Resolver<'a> {
         ImportResolver { r: self }.resolve_imports()
     }
 
-    fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool)
-                                -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> {
-        let inherited_parent_scope = self.invocation_parent_scopes[&invoc_id];
-        let parent_scope = *self.invocation_parent_scopes.entry(invoc.expansion_data.id)
-                                                         .or_insert(inherited_parent_scope);
+    fn resolve_macro_invocation(
+        &mut self, invoc: &Invocation, eager_expansion_root: ExpnId, force: bool
+    ) -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> {
+        let invoc_id = invoc.expansion_data.id;
+        let parent_scope = match self.invocation_parent_scopes.get(&invoc_id) {
+            Some(parent_scope) => *parent_scope,
+            None => {
+                // If there's no entry in the table, then we are resolving an eagerly expanded
+                // macro, which should inherit its parent scope from its eager expansion root -
+                // the macro that requested this eager expansion.
+                let parent_scope = *self.invocation_parent_scopes.get(&eager_expansion_root)
+                    .expect("non-eager expansion without a parent scope");
+                self.invocation_parent_scopes.insert(invoc_id, parent_scope);
+                parent_scope
+            }
+        };
+
         let (path, kind, derives, after_derive) = match invoc.kind {
             InvocationKind::Attr { ref attr, ref derives, after_derive, .. } =>
                 (&attr.path, MacroKind::Attr, self.arenas.alloc_ast_paths(derives), after_derive),
@@ -163,7 +175,7 @@ impl<'a> base::Resolver for Resolver<'a> {
                         match self.resolve_macro_path(path, Some(MacroKind::Derive),
                                                       &parent_scope, true, force) {
                             Ok((Some(ref ext), _)) if ext.is_derive_copy => {
-                                self.add_derives(invoc.expansion_data.id, SpecialDerives::COPY);
+                                self.add_derives(invoc_id, SpecialDerives::COPY);
                                 return Ok(None);
                             }
                             Err(Determinacy::Undetermined) => result = Err(Indeterminate),
@@ -180,19 +192,15 @@ impl<'a> base::Resolver for Resolver<'a> {
         let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?;
 
         let span = invoc.span();
-        invoc.expansion_data.id.set_expn_data(
-            ext.expn_data(parent_scope.expansion, span, fast_print_path(path))
-        );
+        invoc_id.set_expn_data(ext.expn_data(parent_scope.expansion, span, fast_print_path(path)));
 
         if let Res::Def(_, def_id) = res {
             if after_derive {
                 self.session.span_err(span, "macro attributes must be placed before `#[derive]`");
             }
-            self.macro_defs.insert(invoc.expansion_data.id, def_id);
-            let normal_module_def_id =
-                self.macro_def_scope(invoc.expansion_data.id).normal_ancestor_id;
-            self.definitions.add_parent_module_of_macro_def(invoc.expansion_data.id,
-                                                            normal_module_def_id);
+            self.macro_defs.insert(invoc_id, def_id);
+            let normal_module_def_id = self.macro_def_scope(invoc_id).normal_ancestor_id;
+            self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id);
         }
 
         Ok(Some(ext))
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 376df4062b116..075e6a8001336 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -682,8 +682,9 @@ pub trait Resolver {
 
     fn resolve_imports(&mut self);
 
-    fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool)
-                                -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate>;
+    fn resolve_macro_invocation(
+        &mut self, invoc: &Invocation, eager_expansion_root: ExpnId, force: bool
+    ) -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate>;
 
     fn check_unused_macros(&self);
 
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 5ac234b78d0fe..72f2c1375e7a2 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -305,9 +305,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 continue
             };
 
-            let scope =
+            let eager_expansion_root =
                 if self.monotonic { invoc.expansion_data.id } else { orig_expansion_data.id };
-            let ext = match self.cx.resolver.resolve_macro_invocation(&invoc, scope, force) {
+            let ext = match self.cx.resolver.resolve_macro_invocation(
+                &invoc, eager_expansion_root, force
+            ) {
                 Ok(ext) => ext,
                 Err(Indeterminate) => {
                     undetermined_invocations.push(invoc);

From d8c5bc7ec6ea2501bdbd2853551aa83175d6e8d0 Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Tue, 30 Jul 2019 23:10:51 +0200
Subject: [PATCH 076/943] Replace usage of alloc.bytes in interpret

There is now a dedicate `len` method which avoids the need to access the
bytes. Access the length as `Size` can also be done by a direct member.
The constructors guarantee that these representations are convertable.

Access which relies on the bytes, such as snapshot, can use direct raw
access by reference as it does not care about undef and relocations or
properly checks them seperately.
---
 src/librustc/mir/interpret/allocation.rs      |  2 ++
 src/librustc_mir/interpret/intrinsics.rs      |  2 +-
 .../interpret/intrinsics/type_name.rs         |  2 +-
 src/librustc_mir/interpret/memory.rs          | 25 +++++++++++--------
 src/librustc_mir/interpret/snapshot.rs        | 20 +++++++++++++--
 5 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index e0ada7e2f11a3..bfbfffeb3b8c6 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -13,6 +13,8 @@ use rustc_data_structures::sorted_map::SortedMap;
 use rustc_target::abi::HasDataLayout;
 use std::borrow::Cow;
 
+// NOTE: When adding new fields, make sure to adjust the Snapshot impl in
+// `src/librustc_mir/interpret/snapshot.rs`.
 #[derive(
     Clone,
     Debug,
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 89c5be137a4e5..a48a4abf796b2 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -81,7 +81,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let alloc = alloc_type_name(self.tcx.tcx, substs.type_at(0));
                 let name_id = self.tcx.alloc_map.lock().create_memory_alloc(alloc);
                 let id_ptr = self.memory.tag_static_base_pointer(name_id.into());
-                let alloc_len = alloc.bytes.len() as u64;
+                let alloc_len = alloc.size.bytes();
                 let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc_len, self);
                 self.write_immediate(name_val, dest)?;
             }
diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs
index f207cfc6b39cd..032d16a49db4b 100644
--- a/src/librustc_mir/interpret/intrinsics/type_name.rs
+++ b/src/librustc_mir/interpret/intrinsics/type_name.rs
@@ -221,7 +221,7 @@ pub fn type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx>
         val: ConstValue::Slice {
             data: alloc,
             start: 0,
-            end: alloc.bytes.len(),
+            end: alloc.len(),
         },
         ty: tcx.mk_static_str(),
     })
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index f572651f02b56..15180265ad29f 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -210,7 +210,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         let new_ptr = self.allocate(new_size, new_align, kind);
         let old_size = match old_size_and_align {
             Some((size, _align)) => size,
-            None => Size::from_bytes(self.get(ptr.alloc_id)?.bytes.len() as u64),
+            None => self.get(ptr.alloc_id)?.size,
         };
         self.copy(
             ptr,
@@ -271,20 +271,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
             ))
         }
         if let Some((size, align)) = old_size_and_align {
-            if size.bytes() != alloc.bytes.len() as u64 || align != alloc.align {
-                let bytes = Size::from_bytes(alloc.bytes.len() as u64);
+            if size != alloc.size || align != alloc.align {
+                let bytes = alloc.size;
                 throw_unsup!(IncorrectAllocationInformation(size, bytes, align, alloc.align))
             }
         }
 
         // Let the machine take some extra action
-        let size = Size::from_bytes(alloc.bytes.len() as u64);
+        let size = alloc.size;
         AllocationExtra::memory_deallocated(&mut alloc, ptr, size)?;
 
         // Don't forget to remember size and align of this now-dead allocation
         let old = self.dead_alloc_map.insert(
             ptr.alloc_id,
-            (Size::from_bytes(alloc.bytes.len() as u64), alloc.align)
+            (alloc.size, alloc.align)
         );
         if old.is_some() {
             bug!("Nothing can be deallocated twice");
@@ -555,7 +555,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // a) cause cycles in case `id` refers to a static
         // b) duplicate a static's allocation in miri
         if let Some((_, alloc)) = self.alloc_map.get(id) {
-            return Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align));
+            return Ok((alloc.size, alloc.align));
         }
 
         // # Function pointers
@@ -583,7 +583,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
             Some(GlobalAlloc::Memory(alloc)) =>
                 // Need to duplicate the logic here, because the global allocations have
                 // different associated types than the interpreter-local ones.
-                Ok((Size::from_bytes(alloc.bytes.len() as u64), alloc.align)),
+                Ok((alloc.size, alloc.align)),
             Some(GlobalAlloc::Function(_)) =>
                 bug!("We already checked function pointers above"),
             // The rest must be dead.
@@ -645,7 +645,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         let prefix_len = msg.len();
         let mut relocations = vec![];
 
-        for i in 0..(alloc.bytes.len() as u64) {
+        for i in 0..alloc.size.bytes() {
             let i = Size::from_bytes(i);
             if let Some(&(_, target_id)) = alloc.relocations.get(&i) {
                 if allocs_seen.insert(target_id) {
@@ -655,7 +655,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
             }
             if alloc.undef_mask.is_range_defined(i, i + Size::from_bytes(1)).is_ok() {
                 // this `as usize` is fine, since `i` came from a `usize`
-                write!(msg, "{:02x} ", alloc.bytes[i.bytes() as usize]).unwrap();
+                let i = i.bytes() as usize;
+
+                // Checked definedness (and thus range) and relocations. This access also doesn't
+                // influence interpreter execution but is only for debugging.
+                let bytes = alloc.inspect_with_undef_and_ptr_outside_interpreter(i..i+1);
+                write!(msg, "{:02x} ", bytes[0]).unwrap();
             } else {
                 msg.push_str("__ ");
             }
@@ -664,7 +669,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         trace!(
             "{}({} bytes, alignment {}){}",
             msg,
-            alloc.bytes.len(),
+            alloc.size.bytes(),
             alloc.align.bytes(),
             extra
         );
diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs
index 47289064f4d0d..0f0c422d8d3f4 100644
--- a/src/librustc_mir/interpret/snapshot.rs
+++ b/src/librustc_mir/interpret/snapshot.rs
@@ -15,7 +15,7 @@ use rustc::mir::interpret::{
 };
 
 use rustc::ty::{self, TyCtxt};
-use rustc::ty::layout::Align;
+use rustc::ty::layout::{Align, Size};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@@ -276,6 +276,7 @@ struct AllocationSnapshot<'a> {
     relocations: Relocations<(), AllocIdSnapshot<'a>>,
     undef_mask: &'a UndefMask,
     align: &'a Align,
+    size: &'a Size,
     mutability: &'a Mutability,
 }
 
@@ -285,12 +286,27 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation
     type Item = AllocationSnapshot<'a>;
 
     fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
-        let Allocation { bytes, relocations, undef_mask, align, mutability, extra: () } = self;
+        let Allocation {
+            relocations,
+            size,
+            align,
+            mutability,
+            extra: (),
+            ..
+        } = self;
+
+        let all_bytes = 0..self.len();
+        // This 'inspect' is okay since following access respects undef and relocations. This does
+        // influence interpreter exeuction, but only to detect the error of cycles in evalution
+        // dependencies.
+        let bytes = self.inspect_with_undef_and_ptr_outside_interpreter(all_bytes);
+        let undef_mask = self.undef_mask();
 
         AllocationSnapshot {
             bytes,
             undef_mask,
             align,
+            size,
             mutability,
             relocations: relocations.snapshot(ctx),
         }

From 7b941e368fac6612eacf3423eac0149ef5ca3bb3 Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Wed, 14 Aug 2019 02:26:18 +0200
Subject: [PATCH 077/943] Expose encapsulated undef mask as immutable

---
 src/librustc/mir/interpret/allocation.rs | 5 +++++
 src/librustc_mir/interpret/memory.rs     | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index bfbfffeb3b8c6..d3f87f16313d0 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -143,6 +143,11 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
     pub fn inspect_with_undef_and_ptr_outside_interpreter(&self, range: Range<usize>) -> &[u8] {
         &self.bytes[range]
     }
+
+    /// View the undef mask.
+    pub fn undef_mask(&self) -> &UndefMask {
+        &self.undef_mask
+    }
 }
 
 impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Allocation {}
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 15180265ad29f..f7576a41e0f00 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -653,7 +653,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
                 }
                 relocations.push((i, target_id));
             }
-            if alloc.undef_mask.is_range_defined(i, i + Size::from_bytes(1)).is_ok() {
+            if alloc.undef_mask().is_range_defined(i, i + Size::from_bytes(1)).is_ok() {
                 // this `as usize` is fine, since `i` came from a `usize`
                 let i = i.bytes() as usize;
 

From df58fcffbcc2dea6eb31934424ce74b3636c5b68 Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Wed, 14 Aug 2019 04:40:03 +0200
Subject: [PATCH 078/943] Fix codegen with explicit allocation byte access

---
 src/librustc_codegen_llvm/consts.rs | 55 +++++++++++++++++++++++++----
 1 file changed, 48 insertions(+), 7 deletions(-)

diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 0077df3cf5eea..26eb870cfc0d4 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -35,11 +35,21 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll
         assert_eq!(offset as usize as u64, offset);
         let offset = offset as usize;
         if offset > next_offset {
-            llvals.push(cx.const_bytes(&alloc.bytes[next_offset..offset]));
+            // This `inspect` is okay since we have check that it is not within a relocation, it is
+            // within the bounds of the allocation, and it doesn't affect interpreter execution (we
+            // inspect the result after interpreter execution). Any undef byte is replaced with
+            // some arbitrary byte value.
+            //
+            // FIXME: relay undef bytes to codegen as undef const bytes
+            let bytes = alloc.inspect_with_undef_and_ptr_outside_interpreter(next_offset..offset);
+            llvals.push(cx.const_bytes(bytes));
         }
         let ptr_offset = read_target_uint(
             dl.endian,
-            &alloc.bytes[offset..(offset + pointer_size)],
+            // This `inspect` is okay since it is within the bounds of the allocation, it doesn't
+            // affect interpreter execution (we inspect the result after interpreter execution),
+            // and we properly interpret the relocation as a relocation pointer offset.
+            alloc.inspect_with_undef_and_ptr_outside_interpreter(offset..(offset + pointer_size)),
         ).expect("const_alloc_to_llvm: could not read relocation pointer") as u64;
         llvals.push(cx.scalar_to_backend(
             Pointer::new(alloc_id, Size::from_bytes(ptr_offset)).into(),
@@ -51,8 +61,16 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll
         ));
         next_offset = offset + pointer_size;
     }
-    if alloc.bytes.len() >= next_offset {
-        llvals.push(cx.const_bytes(&alloc.bytes[next_offset ..]));
+    if alloc.len() >= next_offset {
+        let range = next_offset..alloc.len();
+        // This `inspect` is okay since we have check that it is after all relocations, it is
+        // within the bounds of the allocation, and it doesn't affect interpreter execution (we
+        // inspect the result after interpreter execution). Any undef byte is replaced with some
+        // arbitrary byte value.
+        //
+        // FIXME: relay undef bytes to codegen as undef const bytes
+        let bytes = alloc.inspect_with_undef_and_ptr_outside_interpreter(range);
+        llvals.push(cx.const_bytes(bytes));
     }
 
     cx.const_struct(&llvals, true)
@@ -437,7 +455,23 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
                 //
                 // We could remove this hack whenever we decide to drop macOS 10.10 support.
                 if self.tcx.sess.target.target.options.is_like_osx {
-                    let sect_name = if alloc.bytes.iter().all(|b| *b == 0) {
+                    assert_eq!(alloc.relocations.len(), 0);
+
+                    let is_zeroed = {
+                        // Treats undefined bytes as if they were defined with the byte value that
+                        // happens to be currently assigned in mir. This is valid since reading
+                        // undef bytes may yield arbitrary values.
+                        //
+                        // FIXME: ignore undef bytes even with representation `!= 0`.
+                        //
+                        // The `inspect` method is okay here because we checked relocations, and
+                        // because we are doing this access to inspect the final interpreter state
+                        // (not as part of the interpreter execution).
+                        alloc.inspect_with_undef_and_ptr_outside_interpreter(0..alloc.len())
+                            .iter()
+                            .all(|b| *b == 0)
+                    };
+                    let sect_name = if is_zeroed {
                         CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_bss\0")
                     } else {
                         CStr::from_bytes_with_nul_unchecked(b"__DATA,__thread_data\0")
@@ -456,10 +490,17 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
                         section.as_str().as_ptr() as *const _,
                         section.as_str().len() as c_uint,
                     );
+                    assert!(alloc.relocations.is_empty());
+
+                    // The `inspect` method is okay here because we checked relocations, and
+                    // because we are doing this access to inspect the final interpreter state (not
+                    // as part of the interpreter execution).
+                    let bytes = alloc.inspect_with_undef_and_ptr_outside_interpreter(
+                        0..alloc.len());
                     let alloc = llvm::LLVMMDStringInContext(
                         self.llcx,
-                        alloc.bytes.as_ptr() as *const _,
-                        alloc.bytes.len() as c_uint,
+                        bytes.as_ptr() as *const _,
+                        bytes.len() as c_uint,
                     );
                     let data = [section, alloc];
                     let meta = llvm::LLVMMDNodeInContext(self.llcx, data.as_ptr(), 2);

From fe2dc919726d17dbe3568f1cb9de34c73b7f1dff Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Wed, 21 Aug 2019 12:53:11 +0300
Subject: [PATCH 079/943] Add a regression test for issue #63460

---
 src/test/ui/hygiene/eager-from-opaque-2.rs | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 src/test/ui/hygiene/eager-from-opaque-2.rs

diff --git a/src/test/ui/hygiene/eager-from-opaque-2.rs b/src/test/ui/hygiene/eager-from-opaque-2.rs
new file mode 100644
index 0000000000000..220e5526745c3
--- /dev/null
+++ b/src/test/ui/hygiene/eager-from-opaque-2.rs
@@ -0,0 +1,22 @@
+// Regression test for the issue #63460.
+
+// check-pass
+
+#[macro_export]
+macro_rules! separator {
+    () => { "/" };
+}
+
+#[macro_export]
+macro_rules! concat_separator {
+    ( $e:literal, $($other:literal),+ ) => {
+        concat!($e, $crate::separator!(), $crate::concat_separator!($($other),+))
+    };
+    ( $e:literal ) => {
+        $e
+    }
+}
+
+fn main() {
+    println!("{}", concat_separator!(2, 3, 4))
+}

From 5cf43bdd54a3e25c8d60da9179fd1bb38213d68e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= <matti@marinelayer.io>
Date: Wed, 21 Aug 2019 12:14:00 +0200
Subject: [PATCH 080/943] Run Clippy without json-rendered flag

---
 src/bootstrap/builder.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 955809e80747b..4e49aaa16eae1 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -875,8 +875,7 @@ impl<'a> Builder<'a> {
         }
 
         if cmd == "clippy" {
-            extra_args.push_str("-Zforce-unstable-if-unmarked -Zunstable-options \
-                --json-rendered=termcolor");
+            extra_args.push_str("-Zforce-unstable-if-unmarked");
         }
 
         if !extra_args.is_empty() {

From a8d7ea74a463b0a31817c00a6bb09e9146e97834 Mon Sep 17 00:00:00 2001
From: Artem Varaksa <aymfst@gmail.com>
Date: Wed, 21 Aug 2019 13:17:59 +0300
Subject: [PATCH 081/943] improve diagnostics: break/continue wrong context

---
 src/librustc_passes/error_codes.rs            |  2 +-
 src/librustc_passes/loops.rs                  | 37 +++++++++----------
 src/test/ui/array-break-length.stderr         |  8 ++--
 ...block-control-flow-static-semantics.stderr | 16 ++++++--
 src/test/ui/break-outside-loop.stderr         | 21 +++++++----
 .../closure-array-break-length.stderr         | 12 +++---
 src/test/ui/error-codes/E0267.stderr          |  4 +-
 src/test/ui/error-codes/E0268.stderr          |  4 +-
 src/test/ui/issues/issue-28105.stderr         |  8 ++--
 src/test/ui/issues/issue-43162.stderr         |  8 ++--
 src/test/ui/issues/issue-50576.stderr         |  8 ++--
 src/test/ui/issues/issue-50581.stderr         |  4 +-
 12 files changed, 73 insertions(+), 59 deletions(-)

diff --git a/src/librustc_passes/error_codes.rs b/src/librustc_passes/error_codes.rs
index cd33943e77e20..a30cd8a627fe3 100644
--- a/src/librustc_passes/error_codes.rs
+++ b/src/librustc_passes/error_codes.rs
@@ -131,7 +131,7 @@ be taken. Erroneous code example:
 
 ```compile_fail,E0268
 fn some_func() {
-    break; // error: `break` outside of loop
+    break; // error: `break` outside of a loop
 }
 ```
 
diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index 1547e607b9c61..4549ac8c668c5 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -16,8 +16,8 @@ use errors::Applicability;
 enum Context {
     Normal,
     Loop(hir::LoopSource),
-    Closure,
-    AsyncClosure,
+    Closure(Span),
+    AsyncClosure(Span),
     LabeledBlock,
     AnonConst,
 }
@@ -58,11 +58,11 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
             hir::ExprKind::Loop(ref b, _, source) => {
                 self.with_context(Loop(source), |v| v.visit_block(&b));
             }
-            hir::ExprKind::Closure(_, ref function_decl, b, _, movability) => {
+            hir::ExprKind::Closure(_, ref function_decl, b, span, movability) => {
                 let cx = if let Some(GeneratorMovability::Static) = movability {
-                    AsyncClosure
+                    AsyncClosure(span)
                 } else {
-                    Closure
+                    Closure(span)
                 };
                 self.visit_fn_decl(&function_decl);
                 self.with_context(cx, |v| v.visit_nested_body(b));
@@ -170,23 +170,22 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
     }
 
     fn require_break_cx(&self, name: &str, span: Span) {
-        match self.cx {
-            LabeledBlock | Loop(_) => {}
-            Closure => {
-                struct_span_err!(self.sess, span, E0267, "`{}` inside of a closure", name)
-                .span_label(span, "cannot break inside of a closure")
+        let err_inside_of = |article, r#type, closure_span| {
+            struct_span_err!(self.sess, span, E0267, "`{}` inside of {} {}", name, article, r#type)
+                .span_label(span, format!("cannot `{}` inside of {} {}", name, article, r#type))
+                .span_label(closure_span, &format!("enclosing {}", r#type))
                 .emit();
-            }
-            AsyncClosure => {
-                struct_span_err!(self.sess, span, E0267, "`{}` inside of an async block", name)
-                    .span_label(span, "cannot break inside of an async block")
-                    .emit();
-            }
+        };
+
+        match self.cx {
+            LabeledBlock | Loop(_) => {},
+            Closure(closure_span) => err_inside_of("a", "closure", closure_span),
+            AsyncClosure(closure_span) => err_inside_of("an", "`async` block", closure_span),
             Normal | AnonConst => {
-                struct_span_err!(self.sess, span, E0268, "`{}` outside of loop", name)
-                .span_label(span, "cannot break outside of a loop")
+                struct_span_err!(self.sess, span, E0268, "`{}` outside of a loop", name)
+                .span_label(span, format!("cannot `{}` outside of a loop", name))
                 .emit();
-            }
+            },
         }
     }
 
diff --git a/src/test/ui/array-break-length.stderr b/src/test/ui/array-break-length.stderr
index 0e0dc8f623e68..45f529bafe728 100644
--- a/src/test/ui/array-break-length.stderr
+++ b/src/test/ui/array-break-length.stderr
@@ -1,14 +1,14 @@
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/array-break-length.rs:3:17
    |
 LL |         |_: [_; break]| {}
-   |                 ^^^^^ cannot break outside of a loop
+   |                 ^^^^^ cannot `break` outside of a loop
 
-error[E0268]: `continue` outside of loop
+error[E0268]: `continue` outside of a loop
   --> $DIR/array-break-length.rs:8:17
    |
 LL |         |_: [_; continue]| {}
-   |                 ^^^^^^^^ cannot break outside of a loop
+   |                 ^^^^^^^^ cannot `continue` outside of a loop
 
 error[E0308]: mismatched types
   --> $DIR/array-break-length.rs:3:9
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
index bc42a46ae1021..b33c8afe6b864 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -1,14 +1,22 @@
 error[E0267]: `break` inside of an async block
   --> $DIR/async-block-control-flow-static-semantics.rs:33:9
    |
-LL |         break 0u8;
-   |         ^^^^^^^^^ cannot break inside of an async block
+LL |       async {
+   |  ___________-
+LL | |         break 0u8;
+   | |         ^^^^^^^^^ cannot `break` inside of an `async` block
+LL | |     };
+   | |_____- enclosing `async` block
 
 error[E0267]: `break` inside of an async block
   --> $DIR/async-block-control-flow-static-semantics.rs:40:13
    |
-LL |             break 0u8;
-   |             ^^^^^^^^^ cannot break inside of an async block
+LL |           async {
+   |  _______________-
+LL | |             break 0u8;
+   | |             ^^^^^^^^^ cannot `break` inside of an `async` block
+LL | |         };
+   | |_________- enclosing `async` block
 
 error[E0308]: mismatched types
   --> $DIR/async-block-control-flow-static-semantics.rs:13:43
diff --git a/src/test/ui/break-outside-loop.stderr b/src/test/ui/break-outside-loop.stderr
index 8f4656ab394cd..8b686356055a3 100644
--- a/src/test/ui/break-outside-loop.stderr
+++ b/src/test/ui/break-outside-loop.stderr
@@ -1,32 +1,37 @@
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/break-outside-loop.rs:10:15
    |
 LL |     let pth = break;
-   |               ^^^^^ cannot break outside of a loop
+   |               ^^^^^ cannot `break` outside of a loop
 
-error[E0268]: `continue` outside of loop
+error[E0268]: `continue` outside of a loop
   --> $DIR/break-outside-loop.rs:11:17
    |
 LL |     if cond() { continue }
-   |                 ^^^^^^^^ cannot break outside of a loop
+   |                 ^^^^^^^^ cannot `continue` outside of a loop
 
 error[E0267]: `break` inside of a closure
   --> $DIR/break-outside-loop.rs:17:25
    |
+LL |         foo(|| {
+   |             -- enclosing closure
 LL |             if cond() { break }
-   |                         ^^^^^ cannot break inside of a closure
+   |                         ^^^^^ cannot `break` inside of a closure
 
 error[E0267]: `continue` inside of a closure
   --> $DIR/break-outside-loop.rs:18:25
    |
+LL |         foo(|| {
+   |             -- enclosing closure
+LL |             if cond() { break }
 LL |             if cond() { continue }
-   |                         ^^^^^^^^ cannot break inside of a closure
+   |                         ^^^^^^^^ cannot `continue` inside of a closure
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/break-outside-loop.rs:24:25
    |
 LL |     let unconstrained = break;
-   |                         ^^^^^ cannot break outside of a loop
+   |                         ^^^^^ cannot `break` outside of a loop
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/closures/closure-array-break-length.stderr b/src/test/ui/closures/closure-array-break-length.stderr
index 46fbd3e0fae0b..18da4a94e6f05 100644
--- a/src/test/ui/closures/closure-array-break-length.stderr
+++ b/src/test/ui/closures/closure-array-break-length.stderr
@@ -1,20 +1,20 @@
-error[E0268]: `continue` outside of loop
+error[E0268]: `continue` outside of a loop
   --> $DIR/closure-array-break-length.rs:2:13
    |
 LL |     |_: [_; continue]| {};
-   |             ^^^^^^^^ cannot break outside of a loop
+   |             ^^^^^^^^ cannot `continue` outside of a loop
 
-error[E0268]: `continue` outside of loop
+error[E0268]: `continue` outside of a loop
   --> $DIR/closure-array-break-length.rs:4:19
    |
 LL |     while |_: [_; continue]| {} {}
-   |                   ^^^^^^^^ cannot break outside of a loop
+   |                   ^^^^^^^^ cannot `continue` outside of a loop
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/closure-array-break-length.rs:7:19
    |
 LL |     while |_: [_; break]| {} {}
-   |                   ^^^^^ cannot break outside of a loop
+   |                   ^^^^^ cannot `break` outside of a loop
 
 error[E0308]: mismatched types
   --> $DIR/closure-array-break-length.rs:4:11
diff --git a/src/test/ui/error-codes/E0267.stderr b/src/test/ui/error-codes/E0267.stderr
index b14cfd1a52d47..1f8657373efec 100644
--- a/src/test/ui/error-codes/E0267.stderr
+++ b/src/test/ui/error-codes/E0267.stderr
@@ -2,7 +2,9 @@ error[E0267]: `break` inside of a closure
   --> $DIR/E0267.rs:2:18
    |
 LL |     let w = || { break; };
-   |                  ^^^^^ cannot break inside of a closure
+   |             --   ^^^^^ cannot `break` inside of a closure
+   |             |
+   |             enclosing closure
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0268.stderr b/src/test/ui/error-codes/E0268.stderr
index 3c77e7f3df2be..c926f9e487494 100644
--- a/src/test/ui/error-codes/E0268.stderr
+++ b/src/test/ui/error-codes/E0268.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/E0268.rs:2:5
    |
 LL |     break;
-   |     ^^^^^ cannot break outside of a loop
+   |     ^^^^^ cannot `break` outside of a loop
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-28105.stderr b/src/test/ui/issues/issue-28105.stderr
index 0e1b90e65209b..42ed838d7c037 100644
--- a/src/test/ui/issues/issue-28105.stderr
+++ b/src/test/ui/issues/issue-28105.stderr
@@ -1,14 +1,14 @@
-error[E0268]: `continue` outside of loop
+error[E0268]: `continue` outside of a loop
   --> $DIR/issue-28105.rs:4:5
    |
 LL |     continue
-   |     ^^^^^^^^ cannot break outside of a loop
+   |     ^^^^^^^^ cannot `continue` outside of a loop
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-28105.rs:6:5
    |
 LL |     break
-   |     ^^^^^ cannot break outside of a loop
+   |     ^^^^^ cannot `break` outside of a loop
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-43162.stderr b/src/test/ui/issues/issue-43162.stderr
index 6d3e8b5ba2323..c729c05ff229e 100644
--- a/src/test/ui/issues/issue-43162.stderr
+++ b/src/test/ui/issues/issue-43162.stderr
@@ -1,14 +1,14 @@
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-43162.rs:3:5
    |
 LL |     break true;
-   |     ^^^^^^^^^^ cannot break outside of a loop
+   |     ^^^^^^^^^^ cannot `break` outside of a loop
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-43162.rs:7:5
    |
 LL |     break {};
-   |     ^^^^^^^^ cannot break outside of a loop
+   |     ^^^^^^^^ cannot `break` outside of a loop
 
 error[E0308]: mismatched types
   --> $DIR/issue-43162.rs:1:13
diff --git a/src/test/ui/issues/issue-50576.stderr b/src/test/ui/issues/issue-50576.stderr
index 95619eeed9a46..9fea1411080f5 100644
--- a/src/test/ui/issues/issue-50576.stderr
+++ b/src/test/ui/issues/issue-50576.stderr
@@ -4,17 +4,17 @@ error[E0426]: use of undeclared label `'L`
 LL |     |bool: [u8; break 'L]| 0;
    |                       ^^ undeclared label `'L`
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-50576.rs:2:17
    |
 LL |     |bool: [u8; break 'L]| 0;
-   |                 ^^^^^^^^ cannot break outside of a loop
+   |                 ^^^^^^^^ cannot `break` outside of a loop
 
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-50576.rs:5:16
    |
 LL |     Vec::<[u8; break]>::new();
-   |                ^^^^^ cannot break outside of a loop
+   |                ^^^^^ cannot `break` outside of a loop
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-50581.stderr b/src/test/ui/issues/issue-50581.stderr
index 01a5f9b3c4432..35d6fc49cedc8 100644
--- a/src/test/ui/issues/issue-50581.stderr
+++ b/src/test/ui/issues/issue-50581.stderr
@@ -1,8 +1,8 @@
-error[E0268]: `break` outside of loop
+error[E0268]: `break` outside of a loop
   --> $DIR/issue-50581.rs:2:14
    |
 LL |     |_: [u8; break]| ();
-   |              ^^^^^ cannot break outside of a loop
+   |              ^^^^^ cannot `break` outside of a loop
 
 error: aborting due to previous error
 

From 1bd94241b756bda09c6e079f806c25440a3b2c81 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Wed, 21 Aug 2019 12:49:01 +0200
Subject: [PATCH 082/943] Replaced skipStorage with saveTheme variable

---
 src/librustdoc/html/render.rs         | 2 +-
 src/librustdoc/html/static/storage.js | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index ea97cea942820..211c4157da828 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -914,7 +914,7 @@ themePicker.onblur = handleThemeButtonsBlur;
     var but = document.createElement('button');
     but.innerHTML = item;
     but.onclick = function(el) {{
-        switchTheme(currentTheme, mainTheme, item);
+        switchTheme(currentTheme, mainTheme, item, true);
     }};
     but.onblur = handleThemeButtonsBlur;
     themes.appendChild(but);
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index 86efc7815602f..c55b1e414436c 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -86,7 +86,7 @@ function getCurrentValue(name) {
     return null;
 }
 
-function switchTheme(styleElem, mainStyleElem, newTheme, skipStorage) {
+function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
     var fullBasicCss = "rustdoc" + resourcesSuffix + ".css";
     var fullNewTheme = newTheme + resourcesSuffix + ".css";
     var newHref = mainStyleElem.href.replace(fullBasicCss, fullNewTheme);
@@ -111,7 +111,7 @@ function switchTheme(styleElem, mainStyleElem, newTheme, skipStorage) {
         styleElem.href = newHref;
         // If this new value comes from a system setting or from the previously saved theme, no
         // need to save it.
-        if (skipStorage !== true) {
+        if (saveTheme === true) {
             updateLocalStorage("rustdoc-theme", newTheme);
         }
     }
@@ -123,4 +123,4 @@ function getSystemValue() {
 
 switchTheme(currentTheme, mainTheme,
             getCurrentValue("rustdoc-theme") || getSystemValue() || "light",
-            true);
+            false);

From 3375b05cd03a60cd7e2df0e21e232c73ff8a01cb Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Wed, 21 Aug 2019 13:10:06 +0200
Subject: [PATCH 083/943] Fix confusion in theme picker functions

---
 src/librustdoc/html/render.rs      | 16 ++++++++--------
 src/librustdoc/html/static/main.js | 12 ++++++------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index ea97cea942820..ae988f6f9cafe 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -876,22 +876,22 @@ r#"var themes = document.getElementById("theme-choices");
 var themePicker = document.getElementById("theme-picker");
 
 function showThemeButtonState() {{
-    themes.style.display = "none";
-    themePicker.style.borderBottomRightRadius = "3px";
-    themePicker.style.borderBottomLeftRadius = "3px";
-}}
-
-function hideThemeButtonState() {{
     themes.style.display = "block";
     themePicker.style.borderBottomRightRadius = "0";
     themePicker.style.borderBottomLeftRadius = "0";
 }}
 
+function hideThemeButtonState() {{
+    themes.style.display = "none";
+    themePicker.style.borderBottomRightRadius = "3px";
+    themePicker.style.borderBottomLeftRadius = "3px";
+}}
+
 function switchThemeButtonState() {{
     if (themes.style.display === "block") {{
-        showThemeButtonState();
-    }} else {{
         hideThemeButtonState();
+    }} else {{
+        showThemeButtonState();
     }}
 }};
 
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 82d2c11b2497b..3d0f00095aca3 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -105,9 +105,9 @@ if (!DOMTokenList.prototype.remove) {
                 sidebar.appendChild(div);
             }
         }
-        var themePicker = document.getElementsByClassName("theme-picker");
-        if (themePicker && themePicker.length > 0) {
-            themePicker[0].style.display = "none";
+        var themePickers = document.getElementsByClassName("theme-picker");
+        if (themePickers && themePickers.length > 0) {
+            themePickers[0].style.display = "none";
         }
     }
 
@@ -123,9 +123,9 @@ if (!DOMTokenList.prototype.remove) {
             filler.remove();
         }
         document.getElementsByTagName("body")[0].style.marginTop = "";
-        var themePicker = document.getElementsByClassName("theme-picker");
-        if (themePicker && themePicker.length > 0) {
-            themePicker[0].style.display = null;
+        var themePickers = document.getElementsByClassName("theme-picker");
+        if (themePickers && themePickers.length > 0) {
+            themePickers[0].style.display = null;
         }
     }
 

From dd7082e3d259f04a11d3ae49ab2742bcecdd3a5e Mon Sep 17 00:00:00 2001
From: Artem Varaksa <aymfst@gmail.com>
Date: Wed, 21 Aug 2019 14:32:38 +0300
Subject: [PATCH 084/943] `r#type` -> `ty`

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

diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index 4549ac8c668c5..dbfbec32a6fbf 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -170,10 +170,10 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> {
     }
 
     fn require_break_cx(&self, name: &str, span: Span) {
-        let err_inside_of = |article, r#type, closure_span| {
-            struct_span_err!(self.sess, span, E0267, "`{}` inside of {} {}", name, article, r#type)
-                .span_label(span, format!("cannot `{}` inside of {} {}", name, article, r#type))
-                .span_label(closure_span, &format!("enclosing {}", r#type))
+        let err_inside_of = |article, ty, closure_span| {
+            struct_span_err!(self.sess, span, E0267, "`{}` inside of {} {}", name, article, ty)
+                .span_label(span, format!("cannot `{}` inside of {} {}", name, article, ty))
+                .span_label(closure_span, &format!("enclosing {}", ty))
                 .emit();
         };
 

From 39260d9016db6925414541ad2dce6502dded3a64 Mon Sep 17 00:00:00 2001
From: Trevor Spiteri <trevor.spiteri@um.edu.mt>
Date: Wed, 21 Aug 2019 14:10:40 +0200
Subject: [PATCH 085/943] make abs, wrapping_abs, and overflowing_abs const
 functions

---
 src/libcore/num/mod.rs | 30 +++++++++---------------------
 1 file changed, 9 insertions(+), 21 deletions(-)

diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index b46e06f8d8ada..df1c00ccd184f 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1401,12 +1401,8 @@ $EndFeature, "
 ```"),
             #[stable(feature = "no_panic_abs", since = "1.13.0")]
             #[inline]
-            pub fn wrapping_abs(self) -> Self {
-                if self.is_negative() {
-                    self.wrapping_neg()
-                } else {
-                    self
-                }
+            pub const fn wrapping_abs(self) -> Self {
+                (self ^ (self >> ($BITS - 1))).wrapping_sub(self >> ($BITS - 1))
             }
         }
 
@@ -1764,12 +1760,8 @@ $EndFeature, "
 ```"),
             #[stable(feature = "no_panic_abs", since = "1.13.0")]
             #[inline]
-            pub fn overflowing_abs(self) -> (Self, bool) {
-                if self.is_negative() {
-                    self.overflowing_neg()
-                } else {
-                    (self, false)
-                }
+            pub const fn overflowing_abs(self) -> (Self, bool) {
+                (self ^ (self >> ($BITS - 1))).overflowing_sub(self >> ($BITS - 1))
             }
         }
 
@@ -1973,15 +1965,11 @@ $EndFeature, "
             #[stable(feature = "rust1", since = "1.0.0")]
             #[inline]
             #[rustc_inherit_overflow_checks]
-            pub fn abs(self) -> Self {
-                if self.is_negative() {
-                    // Note that the #[inline] above means that the overflow
-                    // semantics of this negation depend on the crate we're being
-                    // inlined into.
-                    -self
-                } else {
-                    self
-                }
+            pub const fn abs(self) -> Self {
+                // Note that the #[inline] above means that the overflow
+                // semantics of the subtraction depend on the crate we're being
+                // inlined into.
+                (self ^ (self >> ($BITS - 1))) - (self >> ($BITS - 1))
             }
         }
 

From 600a64bdb576cde946b71faa6e7ad6d15e84ff39 Mon Sep 17 00:00:00 2001
From: Artem Varaksa <aymfst@gmail.com>
Date: Wed, 21 Aug 2019 15:13:13 +0300
Subject: [PATCH 086/943] more `--bless`ing + test error annotations fixes

---
 src/test/ui/array-break-length.rs                           | 4 ++--
 .../async-block-control-flow-static-semantics.rs            | 4 ++--
 .../async-block-control-flow-static-semantics.stderr        | 4 ++--
 src/test/ui/break-outside-loop.rs                           | 6 +++---
 src/test/ui/closures/closure-array-break-length.rs          | 6 +++---
 src/test/ui/issues/issue-28105.rs                           | 4 ++--
 6 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/test/ui/array-break-length.rs b/src/test/ui/array-break-length.rs
index 2696aea5e8993..959f4a2babbf8 100644
--- a/src/test/ui/array-break-length.rs
+++ b/src/test/ui/array-break-length.rs
@@ -1,11 +1,11 @@
 fn main() {
     loop {
-        |_: [_; break]| {} //~ ERROR: `break` outside of loop
+        |_: [_; break]| {} //~ ERROR: `break` outside of a loop
         //~^ ERROR mismatched types
     }
 
     loop {
-        |_: [_; continue]| {} //~ ERROR: `continue` outside of loop
+        |_: [_; continue]| {} //~ ERROR: `continue` outside of a loop
         //~^ ERROR mismatched types
     }
 }
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
index 90d75118f8e42..753a4e491550f 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs
@@ -30,14 +30,14 @@ async fn return_targets_async_block_not_async_fn() -> u8 {
 
 fn no_break_in_async_block() {
     async {
-        break 0u8; //~ ERROR `break` inside of an async block
+        break 0u8; //~ ERROR `break` inside of an `async` block
     };
 }
 
 fn no_break_in_async_block_even_with_outer_loop() {
     loop {
         async {
-            break 0u8; //~ ERROR `break` inside of an async block
+            break 0u8; //~ ERROR `break` inside of an `async` block
         };
     }
 }
diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
index b33c8afe6b864..c36caa5586fb0 100644
--- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
+++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr
@@ -1,4 +1,4 @@
-error[E0267]: `break` inside of an async block
+error[E0267]: `break` inside of an `async` block
   --> $DIR/async-block-control-flow-static-semantics.rs:33:9
    |
 LL |       async {
@@ -8,7 +8,7 @@ LL | |         break 0u8;
 LL | |     };
    | |_____- enclosing `async` block
 
-error[E0267]: `break` inside of an async block
+error[E0267]: `break` inside of an `async` block
   --> $DIR/async-block-control-flow-static-semantics.rs:40:13
    |
 LL |           async {
diff --git a/src/test/ui/break-outside-loop.rs b/src/test/ui/break-outside-loop.rs
index fef298f7c3919..c424c25c646bd 100644
--- a/src/test/ui/break-outside-loop.rs
+++ b/src/test/ui/break-outside-loop.rs
@@ -7,8 +7,8 @@ fn cond() -> bool { true }
 fn foo<F>(_: F) where F: FnOnce() {}
 
 fn main() {
-    let pth = break; //~ ERROR: `break` outside of loop
-    if cond() { continue } //~ ERROR: `continue` outside of loop
+    let pth = break; //~ ERROR: `break` outside of a loop
+    if cond() { continue } //~ ERROR: `continue` outside of a loop
 
     while cond() {
         if cond() { break }
@@ -21,5 +21,5 @@ fn main() {
 
     let rs: Foo = Foo{t: pth};
 
-    let unconstrained = break; //~ ERROR: `break` outside of loop
+    let unconstrained = break; //~ ERROR: `break` outside of a loop
 }
diff --git a/src/test/ui/closures/closure-array-break-length.rs b/src/test/ui/closures/closure-array-break-length.rs
index a7f16d70ba860..f3567db1fac9c 100644
--- a/src/test/ui/closures/closure-array-break-length.rs
+++ b/src/test/ui/closures/closure-array-break-length.rs
@@ -1,9 +1,9 @@
 fn main() {
-    |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
+    |_: [_; continue]| {}; //~ ERROR: `continue` outside of a loop
 
-    while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of loop
+    while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of a loop
     //~^ ERROR mismatched types
 
-    while |_: [_; break]| {} {} //~ ERROR: `break` outside of loop
+    while |_: [_; break]| {} {} //~ ERROR: `break` outside of a loop
     //~^ ERROR mismatched types
 }
diff --git a/src/test/ui/issues/issue-28105.rs b/src/test/ui/issues/issue-28105.rs
index 6026cbb82ae75..1e8d2d6ccf132 100644
--- a/src/test/ui/issues/issue-28105.rs
+++ b/src/test/ui/issues/issue-28105.rs
@@ -1,8 +1,8 @@
 // Make sure that a continue span actually contains the keyword.
 
 fn main() {
-    continue //~ ERROR `continue` outside of loop
+    continue //~ ERROR `continue` outside of a loop
     ;
-    break //~ ERROR `break` outside of loop
+    break //~ ERROR `break` outside of a loop
     ;
 }

From adee559659774054497fc36afea0076c334c0bb2 Mon Sep 17 00:00:00 2001
From: Trevor Spiteri <tspiteri@ieee.org>
Date: Wed, 21 Aug 2019 15:40:12 +0200
Subject: [PATCH 087/943] test const abs, wrapping_abs, and overflowing_abs

---
 src/test/ui/consts/const-int-overflowing-rpass.rs | 8 ++++++++
 src/test/ui/consts/const-int-sign-rpass.rs        | 6 ++++++
 src/test/ui/consts/const-int-wrapping-rpass.rs    | 8 ++++++++
 3 files changed, 22 insertions(+)

diff --git a/src/test/ui/consts/const-int-overflowing-rpass.rs b/src/test/ui/consts/const-int-overflowing-rpass.rs
index b619c7908aa22..9be87a6447cda 100644
--- a/src/test/ui/consts/const-int-overflowing-rpass.rs
+++ b/src/test/ui/consts/const-int-overflowing-rpass.rs
@@ -18,6 +18,10 @@ const SHR_B: (u32, bool) = 0x10u32.overflowing_shr(132);
 const NEG_A: (u32, bool) = 0u32.overflowing_neg();
 const NEG_B: (u32, bool) = core::u32::MAX.overflowing_neg();
 
+const ABS_POS: (i32, bool) = 10i32.overflowing_abs();
+const ABS_NEG: (i32, bool) = (-10i32).overflowing_abs();
+const ABS_MIN: (i32, bool) = i32::min_value().overflowing_abs();
+
 fn main() {
     assert_eq!(ADD_A, (7, false));
     assert_eq!(ADD_B, (0, true));
@@ -36,4 +40,8 @@ fn main() {
 
     assert_eq!(NEG_A, (0, false));
     assert_eq!(NEG_B, (1, true));
+
+    assert_eq!(ABS_POS, (10, false));
+    assert_eq!(ABS_NEG, (10, false));
+    assert_eq!(ABS_MIN, (i32::min_value(), true));
 }
diff --git a/src/test/ui/consts/const-int-sign-rpass.rs b/src/test/ui/consts/const-int-sign-rpass.rs
index 05726cb228647..dc46fce39a93c 100644
--- a/src/test/ui/consts/const-int-sign-rpass.rs
+++ b/src/test/ui/consts/const-int-sign-rpass.rs
@@ -11,6 +11,9 @@ const SIGNUM_POS: i32 = 10i32.signum();
 const SIGNUM_NIL: i32 = 0i32.signum();
 const SIGNUM_NEG: i32 = (-42i32).signum();
 
+const ABS_A: i32 = 10i32.abs();
+const ABS_B: i32 = (-10i32).abs();
+
 fn main() {
     assert!(NEGATIVE_A);
     assert!(!NEGATIVE_B);
@@ -20,4 +23,7 @@ fn main() {
     assert_eq!(SIGNUM_POS, 1);
     assert_eq!(SIGNUM_NIL, 0);
     assert_eq!(SIGNUM_NEG, -1);
+
+    assert_eq!(ABS_A, 10);
+    assert_eq!(ABS_B, 10);
 }
diff --git a/src/test/ui/consts/const-int-wrapping-rpass.rs b/src/test/ui/consts/const-int-wrapping-rpass.rs
index 73147d7912d19..2bbad99a52a90 100644
--- a/src/test/ui/consts/const-int-wrapping-rpass.rs
+++ b/src/test/ui/consts/const-int-wrapping-rpass.rs
@@ -18,6 +18,10 @@ const SHR_B: u32 = 128u32.wrapping_shr(128);
 const NEG_A: u32 = 5u32.wrapping_neg();
 const NEG_B: u32 = 1234567890u32.wrapping_neg();
 
+const ABS_POS: i32 = 10i32.wrapping_abs();
+const ABS_NEG: i32 = (-10i32).wrapping_abs();
+const ABS_MIN: i32 = i32::min_value().wrapping_abs();
+
 fn main() {
     assert_eq!(ADD_A, 255);
     assert_eq!(ADD_B, 199);
@@ -36,4 +40,8 @@ fn main() {
 
     assert_eq!(NEG_A, 4294967291);
     assert_eq!(NEG_B, 3060399406);
+
+    assert_eq!(ABS_POS, 10);
+    assert_eq!(ABS_NEG, 10);
+    assert_eq!(ABS_MIN, i32::min_value());
 }

From a47e3c077cd7f201dbbf12140c12663df0fcda6f Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Wed, 21 Aug 2019 17:57:22 +0300
Subject: [PATCH 088/943] fixes

---
 src/libstd/sys/wasi/args.rs   |  6 +--
 src/libstd/sys/wasi/ext/fs.rs |  2 +
 src/libstd/sys/wasi/ext/io.rs |  2 +-
 src/libstd/sys/wasi/fd.rs     | 76 +++++++++++++++++------------------
 src/libstd/sys/wasi/fs.rs     | 16 +++-----
 src/libstd/sys/wasi/io.rs     |  2 +-
 src/libstd/sys/wasi/mod.rs    | 27 +++++++------
 src/libstd/sys/wasi/os.rs     |  2 -
 src/libstd/sys/wasi/stdio.rs  |  4 +-
 src/libstd/sys/wasi/thread.rs |  3 +-
 src/libstd/sys/wasi/time.rs   |  3 +-
 11 files changed, 69 insertions(+), 74 deletions(-)

diff --git a/src/libstd/sys/wasi/args.rs b/src/libstd/sys/wasi/args.rs
index de9ca62469d5d..3280c4990dc66 100644
--- a/src/libstd/sys/wasi/args.rs
+++ b/src/libstd/sys/wasi/args.rs
@@ -1,10 +1,10 @@
-use crate::ffi::CStr;
-use crate::io;
 use crate::ffi::OsString;
 use crate::marker::PhantomData;
 use crate::os::wasi::ffi::OsStringExt;
 use crate::vec;
 
+use ::wasi::wasi_unstable as wasi;
+
 pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
 }
 
@@ -20,7 +20,7 @@ pub struct Args {
 pub fn args() -> Args {
     let buf = wasi::args_sizes_get().and_then(|args_sizes| {
         let mut buf = Vec::with_capacity(args_sizes.get_count());
-        wasi::get_args(args_sizes, |arg| {
+        wasi::args_get(args_sizes, |arg| {
             let arg = OsString::from_vec(arg.to_vec());
             buf.push(arg);
         })?;
diff --git a/src/libstd/sys/wasi/ext/fs.rs b/src/libstd/sys/wasi/ext/fs.rs
index ecd509f01dabd..9fa4abfd171b5 100644
--- a/src/libstd/sys/wasi/ext/fs.rs
+++ b/src/libstd/sys/wasi/ext/fs.rs
@@ -8,6 +8,8 @@ use crate::os::wasi::ffi::OsStrExt;
 use crate::path::{Path, PathBuf};
 use crate::sys_common::{AsInner, AsInnerMut, FromInner};
 
+use ::wasi::wasi_unstable as wasi;
+
 /// WASI-specific extensions to [`File`].
 ///
 /// [`File`]: ../../../../std/fs/struct.File.html
diff --git a/src/libstd/sys/wasi/ext/io.rs b/src/libstd/sys/wasi/ext/io.rs
index c843144f0c406..f1839df380112 100644
--- a/src/libstd/sys/wasi/ext/io.rs
+++ b/src/libstd/sys/wasi/ext/io.rs
@@ -8,7 +8,7 @@ use crate::sys;
 use crate::net;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 
-use wasi::wasi_unstable as wasi;
+use ::wasi::wasi_unstable as wasi;
 
 /// Raw file descriptors.
 pub type RawFd = u32;
diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs
index 93fe8add326c8..275e1319be6ad 100644
--- a/src/libstd/sys/wasi/fd.rs
+++ b/src/libstd/sys/wasi/fd.rs
@@ -3,14 +3,15 @@
 use crate::io::{self, IoSlice, IoSliceMut, SeekFrom};
 use crate::mem;
 use crate::net::Shutdown;
-use wasi::wasi_unstable as wasi;
+use super::err2io;
+use ::wasi::wasi_unstable as wasi;
 
 #[derive(Debug)]
 pub struct WasiFd {
     fd: wasi::Fd,
 }
 
-fn iovec(a: &mut [IoSliceMut<'_>]) -> &[wasi::IoVec] {
+fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::IoVec] {
     assert_eq!(
         mem::size_of::<IoSliceMut<'_>>(),
         mem::size_of::<wasi::IoVec>()
@@ -23,7 +24,7 @@ fn iovec(a: &mut [IoSliceMut<'_>]) -> &[wasi::IoVec] {
     unsafe { mem::transmute(a) }
 }
 
-fn ciovec(a: &[IoSlice<'_>]) -> &[wasi::CIoVec] {
+fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::CIoVec] {
     assert_eq!(
         mem::size_of::<IoSlice<'_>>(),
         mem::size_of::<wasi::CIoVec>()
@@ -52,23 +53,23 @@ impl WasiFd {
     }
 
     pub fn datasync(&self) -> io::Result<()> {
-        wasi::fd_datasync(self.fd).map_err(From::from)
+        wasi::fd_datasync(self.fd).map_err(err2io)
     }
 
     pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
-        wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(From::from)
+        wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io)
     }
 
     pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
-        wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(From::from)
+        wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io)
     }
 
     pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        wasi::fd_read(self.fd, iovec(bufs)).map_err(From::from)
+        wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io)
     }
 
     pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        wasi::fd_write(self.fd, ciovec(bufs)).map_err(From::from)
+        wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io)
     }
 
     pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
@@ -77,37 +78,37 @@ impl WasiFd {
             SeekFrom::End(pos) => (wasi::WHENCE_END, pos),
             SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos),
         };
-        wasi::fd_seek(self.fd, offset, whence).map_err(From::from)
+        wasi::fd_seek(self.fd, offset, whence).map_err(err2io)
     }
 
     pub fn tell(&self) -> io::Result<u64> {
-        wasi::fd_tell(self.fd).map_err(From::from)
+        wasi::fd_tell(self.fd).map_err(err2io)
     }
 
     // FIXME: __wasi_fd_fdstat_get
 
     pub fn set_flags(&self, flags: wasi::FdFlags) -> io::Result<()> {
-        wasi::fd_fdstat_set_flags(self.fd, flags).map_err(From::from)
+        wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io)
     }
 
     pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> {
-        wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(From::from)
+        wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io)
     }
 
     pub fn sync(&self) -> io::Result<()> {
-        wasi::fd_sync(self.fd).map_err(From::from)
+        wasi::fd_sync(self.fd).map_err(err2io)
     }
 
     pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
-        wasi::fd_advise(self.fd, offset, len, advice).map_err(From::from)
+        wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io)
     }
 
     pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> {
-        wasi::fd_allocate(self.fd, offset, len).map_err(From::from)
+        wasi::fd_allocate(self.fd, offset, len).map_err(err2io)
     }
 
     pub fn create_directory(&self, path: &[u8]) -> io::Result<()> {
-        wasi::path_create_directory(self.fd, path).map_err(From::from)
+        wasi::path_create_directory(self.fd, path).map_err(err2io)
     }
 
     pub fn link(
@@ -118,7 +119,7 @@ impl WasiFd {
         new_path: &[u8],
     ) -> io::Result<()> {
         wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path)
-            .map_err(From::from)
+            .map_err(err2io)
     }
 
     pub fn open(
@@ -130,7 +131,7 @@ impl WasiFd {
         fs_rights_inheriting: wasi::Rights,
         fs_flags: wasi::FdFlags,
     ) -> io::Result<WasiFd> {
-        let fd = wasi_path_open(
+        wasi::path_open(
             self.fd,
             dirflags,
             path,
@@ -138,25 +139,24 @@ impl WasiFd {
             fs_rights_base,
             fs_rights_inheriting,
             fs_flags,
-        )?;
-        Ok(WasiFd::from_raw(fd))
+        ).map(|fd| unsafe { WasiFd::from_raw(fd) }).map_err(err2io)
     }
 
     pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result<usize> {
-        wasi::fd_readdir(self.fd, buf, cookie).map_err(From::from)
+        wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io)
     }
 
     pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result<usize> {
-        wasi::path_readlink(self.fd, path, buf).map_err(From::from)
+        wasi::path_readlink(self.fd, path, buf).map_err(err2io)
     }
 
     pub fn rename(&self, old_path: &[u8], new_fd: &WasiFd, new_path: &[u8]) -> io::Result<()> {
         wasi::path_rename(self.fd, old_path, new_fd.fd, new_path)
-            .map_err(From::from)
+            .map_err(err2io)
     }
 
-    pub fn filestat_get(&self) -> io::Result<wasi::Filestat> {
-        wasi::fd_filestat_get(self.fd, buf).map_err(From::from)
+    pub fn filestat_get(&self) -> io::Result<wasi::FileStat> {
+        wasi::fd_filestat_get(self.fd).map_err(err2io)
     }
 
     pub fn filestat_set_times(
@@ -166,11 +166,11 @@ impl WasiFd {
         fstflags: wasi::FstFlags,
     ) -> io::Result<()> {
         wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags)
-            .map_err(From::from)
+            .map_err(err2io)
     }
 
     pub fn filestat_set_size(&self, size: u64) -> io::Result<()> {
-        wasi::fd_filestat_set_size(self.fd, size).map_err(From::from)
+        wasi::fd_filestat_set_size(self.fd, size).map_err(err2io)
     }
 
     pub fn path_filestat_get(
@@ -178,7 +178,7 @@ impl WasiFd {
         flags: wasi::LookupFlags,
         path: &[u8],
     ) -> io::Result<wasi::FileStat> {
-        wasi::path_filestat_get(self.fd, flags, path).map_err(From::from)
+        wasi::path_filestat_get(self.fd, flags, path).map_err(err2io)
     }
 
     pub fn path_filestat_set_times(
@@ -196,19 +196,19 @@ impl WasiFd {
             atim,
             mtim,
             fstflags,
-        ).map_err(From::from)
+        ).map_err(err2io)
     }
 
     pub fn symlink(&self, old_path: &[u8], new_path: &[u8]) -> io::Result<()> {
-        wasi::path_symlink(old_path, self.fd, new_path).map_err(From::from)
+        wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io)
     }
 
     pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> {
-        wasi::path_unlink_file(self.fd, path).map_err(From::from)
+        wasi::path_unlink_file(self.fd, path).map_err(err2io)
     }
 
     pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> {
-        wasi::path_remove_directory(self.fd, path).map_err(From::from)
+        wasi::path_remove_directory(self.fd, path).map_err(err2io)
     }
 
     pub fn sock_recv(
@@ -216,20 +216,20 @@ impl WasiFd {
         ri_data: &mut [IoSliceMut<'_>],
         ri_flags: wasi::RiFlags,
     ) -> io::Result<(usize, wasi::RoFlags)> {
-        wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(From::from)
+        wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io)
     }
 
     pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::SiFlags) -> io::Result<usize> {
-        wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(From::from)
+        wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io)
     }
 
     pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
         let how = match how {
-            Shutdown::Read => WASI::SHUT_RD,
-            Shutdown::Write => WASI::SHUT_WR,
-            Shutdown::Both => WASI::SHUT_WR | WASI::SHUT_RD,
+            Shutdown::Read => wasi::SHUT_RD,
+            Shutdown::Write => wasi::SHUT_WR,
+            Shutdown::Both => wasi::SHUT_WR | wasi::SHUT_RD,
         };
-        wasi::sock_shutdown(self.fd, how).map_err(From::from)
+        wasi::sock_shutdown(self.fd, how).map_err(err2io)
     }
 }
 
diff --git a/src/libstd/sys/wasi/fs.rs b/src/libstd/sys/wasi/fs.rs
index f23ecfc2bcd22..4113f6a2e09c0 100644
--- a/src/libstd/sys/wasi/fs.rs
+++ b/src/libstd/sys/wasi/fs.rs
@@ -7,7 +7,7 @@ use crate::os::wasi::ffi::{OsStrExt, OsStringExt};
 use crate::path::{Path, PathBuf};
 use crate::ptr;
 use crate::sync::Arc;
-use crate::sys::fd::{DirCookie, WasiFd};
+use crate::sys::fd::WasiFd;
 use crate::sys::time::SystemTime;
 use crate::sys::unsupported;
 use crate::sys_common::FromInner;
@@ -15,7 +15,7 @@ use crate::sys_common::FromInner;
 pub use crate::sys_common::fs::copy;
 pub use crate::sys_common::fs::remove_dir_all;
 
-use wasi::wasi_unstable as wasi;
+use ::wasi::wasi_unstable as wasi;
 
 pub struct File {
     fd: WasiFd,
@@ -28,7 +28,7 @@ pub struct FileAttr {
 
 pub struct ReadDir {
     inner: Arc<ReadDirInner>,
-    cookie: Option<DirCookie>,
+    cookie: Option<wasi::DirCookie>,
     buf: Vec<u8>,
     offset: usize,
     cap: usize,
@@ -70,12 +70,6 @@ pub struct FileType {
 pub struct DirBuilder {}
 
 impl FileAttr {
-    fn zero() -> FileAttr {
-        FileAttr {
-            meta: unsafe { mem::zeroed() },
-        }
-    }
-
     pub fn size(&self) -> u64 {
         self.meta.st_size
     }
@@ -390,7 +384,7 @@ impl File {
     }
 
     pub fn file_attr(&self) -> io::Result<FileAttr> {
-        self.fd.filestat_get().map_ok(|meta| FileAttr { meta })
+        self.fd.filestat_get().map(|meta| FileAttr { meta })
     }
 
     pub fn metadata_at(
@@ -601,7 +595,7 @@ fn metadata_at(
     path: &Path,
 ) -> io::Result<FileAttr> {
     fd.path_filestat_get(flags, path.as_os_str().as_bytes())
-        .map_ok(|meta| FileAttr { meta })
+        .map(|meta| FileAttr { meta })
 }
 
 pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> {
diff --git a/src/libstd/sys/wasi/io.rs b/src/libstd/sys/wasi/io.rs
index ebea3a03e439f..4be92faed308f 100644
--- a/src/libstd/sys/wasi/io.rs
+++ b/src/libstd/sys/wasi/io.rs
@@ -1,7 +1,7 @@
 use crate::marker::PhantomData;
 use crate::slice;
 
-use wasi::wasi_unstable as wasi;
+use ::wasi::wasi_unstable as wasi;
 use core::ffi::c_void;
 
 #[repr(transparent)]
diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs
index 28b49996d1433..89f7c887aafc0 100644
--- a/src/libstd/sys/wasi/mod.rs
+++ b/src/libstd/sys/wasi/mod.rs
@@ -14,10 +14,10 @@
 //! compiling for wasm. That way it's a compile time error for something that's
 //! guaranteed to be a runtime error!
 
-use crate::io;
+use crate::io as std_io;
 use crate::mem;
 use crate::os::raw::c_char;
-use wasi::wasi_unstable as wasi;
+use ::wasi::wasi_unstable as wasi;
 
 pub mod alloc;
 pub mod args;
@@ -56,16 +56,19 @@ pub mod ext;
 pub fn init() {
 }
 
-pub fn unsupported<T>() -> crate::io::Result<T> {
+pub fn unsupported<T>() -> std_io::Result<T> {
     Err(unsupported_err())
 }
 
-pub fn unsupported_err() -> io::Error {
-    io::Error::new(io::ErrorKind::Other, "operation not supported on wasm yet")
+pub fn unsupported_err() -> std_io::Error {
+    std_io::Error::new(
+        std_io::ErrorKind::Other,
+        "operation not supported on wasm yet",
+    )
 }
 
-pub fn decode_error_kind(_code: i32) -> io::ErrorKind {
-    io::ErrorKind::Other
+pub fn decode_error_kind(_code: i32) -> std_io::ErrorKind {
+    std_io::ErrorKind::Other
 }
 
 // This enum is used as the storage for a bunch of types which can't actually
@@ -114,16 +117,14 @@ macro_rules! impl_is_minus_one {
 
 impl_is_minus_one! { i8 i16 i32 i64 isize }
 
-pub fn cvt<T: IsMinusOne>(t: T) -> crate::io::Result<T> {
+pub fn cvt<T: IsMinusOne>(t: T) -> std_io::Result<T> {
     if t.is_minus_one() {
-        Err(io::Error::last_os_error())
+        Err(std_io::Error::last_os_error())
     } else {
         Ok(t)
     }
 }
 
-impl From<wasi::Error> for io::Error {
-    fn from(err: wasi::Error) -> Self {
-        Self::from_raw_os_error(err as i32)
-    }
+fn err2io(err: wasi::Error) -> std_io::Error {
+    std_io::Error::from_raw_os_error(err.get() as i32)
 }
diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs
index dca58179e0c8d..7ee23c9a35ec7 100644
--- a/src/libstd/sys/wasi/os.rs
+++ b/src/libstd/sys/wasi/os.rs
@@ -12,8 +12,6 @@ use crate::sys::memchr;
 use crate::sys::{cvt, unsupported, Void};
 use crate::vec;
 
-use wasi::wasi_unstable as wasi;
-
 #[cfg(not(target_feature = "atomics"))]
 pub unsafe fn env_lock() -> impl Any {
     // No need for a lock if we're single-threaded, but this function will need
diff --git a/src/libstd/sys/wasi/stdio.rs b/src/libstd/sys/wasi/stdio.rs
index dc6a6ef375a1c..1d57b9922e599 100644
--- a/src/libstd/sys/wasi/stdio.rs
+++ b/src/libstd/sys/wasi/stdio.rs
@@ -2,7 +2,7 @@ use crate::io::{self, IoSlice, IoSliceMut};
 use crate::mem::ManuallyDrop;
 use crate::sys::fd::WasiFd;
 
-use wasi::wasi_unstable as wasi;
+use ::wasi::wasi_unstable as wasi;
 
 pub struct Stdin;
 pub struct Stdout;
@@ -74,7 +74,7 @@ impl io::Write for Stderr {
 pub const STDIN_BUF_SIZE: usize = crate::sys_common::io::DEFAULT_BUF_SIZE;
 
 pub fn is_ebadf(err: &io::Error) -> bool {
-    err.raw_os_error() == Some(wasi::EBADF as i32)
+    err.raw_os_error() == Some(wasi::EBADF.get() as i32)
 }
 
 pub fn panic_output() -> Option<impl io::Write> {
diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs
index a6c8f2487013b..dc5a72e82a354 100644
--- a/src/libstd/sys/wasi/thread.rs
+++ b/src/libstd/sys/wasi/thread.rs
@@ -1,10 +1,11 @@
-use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
 use crate::sys::{unsupported, Void};
 use crate::time::Duration;
 
+use ::wasi::wasi_unstable as wasi;
+
 pub struct Thread(Void);
 
 pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
diff --git a/src/libstd/sys/wasi/time.rs b/src/libstd/sys/wasi/time.rs
index 4c89a1781b9ef..4394a22f9c233 100644
--- a/src/libstd/sys/wasi/time.rs
+++ b/src/libstd/sys/wasi/time.rs
@@ -1,6 +1,5 @@
 use crate::time::Duration;
-use crate::mem;
-use wasi::wasi_unstable as wasi;
+use ::wasi::wasi_unstable as wasi;
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
 pub struct Instant(Duration);

From a9900be9f41176003c0a1a613686b2e443342466 Mon Sep 17 00:00:00 2001
From: Mark Mansi <markm@cs.wisc.edu>
Date: Wed, 21 Aug 2019 10:16:57 -0500
Subject: [PATCH 089/943] add amanjeev

---
 src/tools/publish_toolstate.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index b8dcba3afc3a1..648838d26efe9 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -34,7 +34,7 @@
         '@ryankurte @thejpster @therealprof'
     ),
     'edition-guide': '@ehuss @Centril @steveklabnik',
-    'rustc-guide': '@mark-i-m @spastorino'
+    'rustc-guide': '@mark-i-m @spastorino @amanjeev'
 }
 
 REPOS = {

From 9f14526f738370efc519143eeee3e43101774a8b Mon Sep 17 00:00:00 2001
From: Mark Mansi <markm@cs.wisc.edu>
Date: Mon, 19 Aug 2019 11:06:15 -0500
Subject: [PATCH 090/943] update rustc-guide

---
 src/doc/rustc-guide | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide
index 6f4ba673ff9d4..6e25a3d0d3573 160000
--- a/src/doc/rustc-guide
+++ b/src/doc/rustc-guide
@@ -1 +1 @@
-Subproject commit 6f4ba673ff9d4613e98415bc095347a6a0031e9c
+Subproject commit 6e25a3d0d3573eb42b2e2339f1219e969d1b3dee

From f5b16f6212d2d72d505d4d6b1dedc2c9c61dd014 Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Wed, 21 Aug 2019 15:50:43 +0000
Subject: [PATCH 091/943] Add codegen test for integers compare

---
 src/test/codegen/integer-cmp.rs | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 src/test/codegen/integer-cmp.rs

diff --git a/src/test/codegen/integer-cmp.rs b/src/test/codegen/integer-cmp.rs
new file mode 100644
index 0000000000000..1373b12e3721c
--- /dev/null
+++ b/src/test/codegen/integer-cmp.rs
@@ -0,0 +1,28 @@
+// This is test for more optimal Ord implementation for integers.
+// See <https://github.com/rust-lang/rust/issues/63758> for more info.
+
+// compile-flags: -C opt-level=3
+
+#![crate_type = "lib"]
+
+use std::cmp::Ordering;
+
+// CHECK-LABEL: @cmp_signed
+#[no_mangle]
+pub fn cmp_signed(a: i64, b: i64) -> Ordering {
+// CHECK: icmp slt
+// CHECK: icmp sgt
+// CHECK: zext i1
+// CHECK: select i1
+    a.cmp(&b)
+}
+
+// CHECK-LABEL: @cmp_unsigned
+#[no_mangle]
+pub fn cmp_unsigned(a: u32, b: u32) -> Ordering {
+// CHECK: icmp ult
+// CHECK: icmp ugt
+// CHECK: zext i1
+// CHECK: select i1
+    a.cmp(&b)
+}

From 926f36400f1667edec92959d8b640dea5084674c Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Wed, 21 Aug 2019 19:36:12 +0300
Subject: [PATCH 092/943] move cvt

---
 src/libstd/Cargo.toml      |  1 +
 src/libstd/sys/wasi/mod.rs | 23 -----------------------
 src/libstd/sys/wasi/os.rs  | 25 ++++++++++++++++++++++++-
 3 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index bb77a5bdea493..d801b051357a4 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -24,6 +24,7 @@ compiler_builtins = { version = "0.1.16" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] }
+wasi = { git = "https://github.com/newpavlov/rust-wasi", branch = "safe_rework", features = ['rustc-dep-of-std', 'alloc'] }
 
 [dependencies.backtrace]
 version = "0.3.35"
diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs
index 89f7c887aafc0..f87e4d16fcdac 100644
--- a/src/libstd/sys/wasi/mod.rs
+++ b/src/libstd/sys/wasi/mod.rs
@@ -102,29 +102,6 @@ pub fn hashmap_random_keys() -> (u64, u64) {
     return ret
 }
 
-#[doc(hidden)]
-pub trait IsMinusOne {
-    fn is_minus_one(&self) -> bool;
-}
-
-macro_rules! impl_is_minus_one {
-    ($($t:ident)*) => ($(impl IsMinusOne for $t {
-        fn is_minus_one(&self) -> bool {
-            *self == -1
-        }
-    })*)
-}
-
-impl_is_minus_one! { i8 i16 i32 i64 isize }
-
-pub fn cvt<T: IsMinusOne>(t: T) -> std_io::Result<T> {
-    if t.is_minus_one() {
-        Err(std_io::Error::last_os_error())
-    } else {
-        Ok(t)
-    }
-}
-
 fn err2io(err: wasi::Error) -> std_io::Error {
     std_io::Error::from_raw_os_error(err.get() as i32)
 }
diff --git a/src/libstd/sys/wasi/os.rs b/src/libstd/sys/wasi/os.rs
index 7ee23c9a35ec7..feee840782550 100644
--- a/src/libstd/sys/wasi/os.rs
+++ b/src/libstd/sys/wasi/os.rs
@@ -9,7 +9,7 @@ use crate::path::{self, PathBuf};
 use crate::ptr;
 use crate::str;
 use crate::sys::memchr;
-use crate::sys::{cvt, unsupported, Void};
+use crate::sys::{unsupported, Void};
 use crate::vec;
 
 #[cfg(not(target_feature = "atomics"))]
@@ -176,3 +176,26 @@ pub fn exit(code: i32) -> ! {
 pub fn getpid() -> u32 {
     panic!("unsupported");
 }
+
+#[doc(hidden)]
+pub trait IsMinusOne {
+    fn is_minus_one(&self) -> bool;
+}
+
+macro_rules! impl_is_minus_one {
+    ($($t:ident)*) => ($(impl IsMinusOne for $t {
+        fn is_minus_one(&self) -> bool {
+            *self == -1
+        }
+    })*)
+}
+
+impl_is_minus_one! { i8 i16 i32 i64 isize }
+
+fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
+    if t.is_minus_one() {
+        Err(io::Error::last_os_error())
+    } else {
+        Ok(t)
+    }
+}

From 2ff1f45ead012271823aa8c9693717b493b72fa6 Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Wed, 21 Aug 2019 20:16:52 +0300
Subject: [PATCH 093/943] revert num_cpus change

---
 src/libtest/lib.rs | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 216112cb6e0be..5e0f19fe553d9 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -1198,6 +1198,12 @@ fn get_concurrency() -> usize {
         1
     }
 
+    #[cfg(target_os = "redox")]
+    fn num_cpus() -> usize {
+        // FIXME: Implement num_cpus on Redox
+        1
+    }
+
     #[cfg(any(
         all(target_arch = "wasm32", not(target_os = "emscripten")),
         all(target_vendor = "fortanix", target_env = "sgx")
@@ -1215,7 +1221,6 @@ fn get_concurrency() -> usize {
         target_os = "linux",
         target_os = "macos",
         target_os = "solaris",
-        target_os = "redox",
     ))]
     fn num_cpus() -> usize {
         unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize }

From 0e668e0496fcc13fa042be416b64ba6823669cca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 24 Jul 2019 17:58:29 -0700
Subject: [PATCH 094/943] Strip code to the left and right in diagnostics for
 long lines

---
 src/librustc_errors/emitter.rs                | 150 ++++++++++++++----
 src/test/ui/inline-asm-bad-operand.stderr     |   4 +-
 ...0-unused-variable-in-struct-pattern.stderr |   4 +-
 .../ui/methods/method-missing-call.stderr     |   4 +-
 ...-on-type-no-recursive-stack-closure.stderr |  10 +-
 .../ui/regions/regions-name-undeclared.stderr |   8 +-
 6 files changed, 133 insertions(+), 47 deletions(-)

diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 361b5cd935712..007c6369c7bd0 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -179,6 +179,7 @@ pub struct EmitterWriter {
     sm: Option<Lrc<SourceMapperDyn>>,
     short_message: bool,
     teach: bool,
+    strip_margin: bool,
     ui_testing: bool,
 }
 
@@ -201,6 +202,7 @@ impl EmitterWriter {
             sm: source_map,
             short_message,
             teach,
+            strip_margin: false,
             ui_testing: false,
         }
     }
@@ -217,6 +219,7 @@ impl EmitterWriter {
             sm: source_map,
             short_message,
             teach,
+            strip_margin: false,
             ui_testing: false,
         }
     }
@@ -234,12 +237,29 @@ impl EmitterWriter {
         }
     }
 
-    fn render_source_line(&self,
-                          buffer: &mut StyledBuffer,
-                          file: Lrc<SourceFile>,
-                          line: &Line,
-                          width_offset: usize,
-                          code_offset: usize) -> Vec<(usize, Style)> {
+    fn render_source_line(
+        &self,
+        buffer: &mut StyledBuffer,
+        file: Lrc<SourceFile>,
+        line: &Line,
+        width_offset: usize,
+        code_offset: usize,
+        margin: usize,
+        right_span_margin: usize
+    ) -> Vec<(usize, Style)> {
+        // Draw:
+        //
+        //   LL | ... code ...
+        //      |     ^^-^ span label
+        //      |       |
+        //      |       secondary span label
+        //
+        //   ^^ ^ ^^^ ^^^^ ^^^ we don't care about code too far to the right of a span, we trim it
+        //   |  | |   |
+        //   |  | |   actual code found in your source code and the spans we use to mark it
+        //   |  | when there's too much wasted space to the left, we trim it to focus where it matters
+        //   |  vertical divider between the column number and the code
+        //   column number
         if line.line_index == 0 {
             return Vec::new();
         }
@@ -251,12 +271,28 @@ impl EmitterWriter {
 
         let line_offset = buffer.num_lines();
 
-        // First create the source line we will highlight.
-        buffer.puts(line_offset, code_offset, &source_string, Style::Quotation);
-        buffer.puts(line_offset,
-                    0,
-                    &self.maybe_anonymized(line.line_index),
-                    Style::LineNumber);
+        let left_margin = std::cmp::min(margin, source_string.len());
+        let right_margin = if source_string.len() > right_span_margin + 120 {
+            right_span_margin + 120
+        } else {
+            source_string.len()
+        };
+        // Create the source line we will highlight.
+        buffer.puts(
+            line_offset,
+            code_offset,
+            &source_string[left_margin..right_margin], // On long lines, we strip the source line
+            Style::Quotation,
+        );
+        if margin > 0 { // We have stripped some code/whitespace from the beginning, make it clear.
+            buffer.puts(line_offset, code_offset, "...", Style::LineNumber);
+        }
+        if right_margin != source_string.len() {
+            // We have stripped some code after the right-most span end, make it clear we did so.
+            let offset = code_offset + right_margin - left_margin;
+            buffer.puts(line_offset, offset, "...", Style::LineNumber);
+        }
+        buffer.puts(line_offset, 0, &self.maybe_anonymized(line.line_index), Style::LineNumber);
 
         draw_col_separator(buffer, line_offset, width_offset - 2);
 
@@ -279,18 +315,13 @@ impl EmitterWriter {
         if line.annotations.len() == 1 {
             if let Some(ref ann) = line.annotations.get(0) {
                 if let AnnotationType::MultilineStart(depth) = ann.annotation_type {
-                    if source_string.chars()
-                                    .take(ann.start_col)
-                                    .all(|c| c.is_whitespace()) {
+                    if source_string.chars().take(ann.start_col).all(|c| c.is_whitespace()) {
                         let style = if ann.is_primary {
                             Style::UnderlinePrimary
                         } else {
                             Style::UnderlineSecondary
                         };
-                        buffer.putc(line_offset,
-                                    width_offset + depth - 1,
-                                    '/',
-                                    style);
+                        buffer.putc(line_offset, width_offset + depth - 1, '/', style);
                         return vec![(depth, style)];
                     }
                 }
@@ -515,13 +546,13 @@ impl EmitterWriter {
                                '_',
                                line_offset + pos,
                                width_offset + depth,
-                               code_offset + annotation.start_col,
+                               code_offset + annotation.start_col - margin,
                                style);
                 }
                 _ if self.teach => {
                     buffer.set_style_range(line_offset,
-                                           code_offset + annotation.start_col,
-                                           code_offset + annotation.end_col,
+                                           code_offset + annotation.start_col - margin,
+                                           code_offset + annotation.end_col - margin,
                                            style,
                                            annotation.is_primary);
                 }
@@ -551,7 +582,7 @@ impl EmitterWriter {
             if pos > 1 && (annotation.has_label() || annotation.takes_space()) {
                 for p in line_offset + 1..=line_offset + pos {
                     buffer.putc(p,
-                                code_offset + annotation.start_col,
+                                code_offset + annotation.start_col - margin,
                                 '|',
                                 style);
                 }
@@ -595,9 +626,9 @@ impl EmitterWriter {
                 Style::LabelSecondary
             };
             let (pos, col) = if pos == 0 {
-                (pos + 1, annotation.end_col + 1)
+                (pos + 1, annotation.end_col + 1 - margin)
             } else {
-                (pos + 2, annotation.start_col)
+                (pos + 2, annotation.start_col - margin)
             };
             if let Some(ref label) = annotation.label {
                 buffer.puts(line_offset + pos,
@@ -639,7 +670,7 @@ impl EmitterWriter {
             };
             for p in annotation.start_col..annotation.end_col {
                 buffer.putc(line_offset + 1,
-                            code_offset + p,
+                            code_offset + p - margin,
                             underline,
                             style);
             }
@@ -1037,6 +1068,51 @@ impl EmitterWriter {
                 // Contains the vertical lines' positions for active multiline annotations
                 let mut multilines = FxHashMap::default();
 
+                // Get the left-side margin to remove it
+                let mut margin = std::usize::MAX;
+                for line_idx in 0..annotated_file.lines.len() {
+                    let file = annotated_file.file.clone();
+                    let line = &annotated_file.lines[line_idx];
+                    if let Some(source_string) = file.get_line(line.line_index - 1) {
+                        let leading_whitespace = source_string
+                            .chars()
+                            .take_while(|c| c.is_whitespace())
+                            .count();
+                        if source_string.chars().any(|c| !c.is_whitespace()) {
+                            margin = std::cmp::min(margin, leading_whitespace);
+                        }
+                    }
+                }
+                if margin >= 20 { // On errors with generous margins, trim it
+                    margin = margin - 16; // Keep at least 4 spaces margin
+                } else if margin == std::usize::MAX || !self.strip_margin {
+                    margin = 0;
+                }
+
+                // Left-most column any visible span points at.
+                let mut span_left_margin = std::usize::MAX;
+                for line in &annotated_file.lines {
+                    for ann in &line.annotations {
+                        span_left_margin = std::cmp::min(span_left_margin, ann.start_col);
+                        span_left_margin = std::cmp::min(span_left_margin, ann.end_col);
+                    }
+                }
+                if span_left_margin == std::usize::MAX {
+                    span_left_margin = 0;
+                }
+                if span_left_margin > 160 {
+                    margin = std::cmp::max(margin, span_left_margin - 100);
+                }
+
+                // Right-most column any visible span points at.
+                let mut span_right_margin = 0;
+                for line in &annotated_file.lines {
+                    for ann in &line.annotations {
+                        span_right_margin = std::cmp::max(span_right_margin, ann.start_col);
+                        span_right_margin = std::cmp::max(span_right_margin, ann.end_col);
+                    }
+                }
+
                 // Next, output the annotate source for this file
                 for line_idx in 0..annotated_file.lines.len() {
                     let previous_buffer_line = buffer.num_lines();
@@ -1048,11 +1124,15 @@ impl EmitterWriter {
                         width_offset + annotated_file.multiline_depth + 1
                     };
 
-                    let depths = self.render_source_line(&mut buffer,
-                                                         annotated_file.file.clone(),
-                                                         &annotated_file.lines[line_idx],
-                                                         width_offset,
-                                                         code_offset);
+                    let depths = self.render_source_line(
+                        &mut buffer,
+                        annotated_file.file.clone(),
+                        &annotated_file.lines[line_idx],
+                        width_offset,
+                        code_offset,
+                        margin,
+                        span_right_margin,
+                    );
 
                     let mut to_add = FxHashMap::default();
 
@@ -1107,9 +1187,15 @@ impl EmitterWriter {
                             draw_col_separator(&mut buffer,
                                                last_buffer_line_num,
                                                1 + max_line_num_len);
+                            let left_margin = std::cmp::min(margin, unannotated_line.len());
+                            let right_margin = if unannotated_line.len() > span_right_margin + 120 {
+                                span_right_margin + 120
+                            } else {
+                                unannotated_line.len()
+                            };
                             buffer.puts(last_buffer_line_num,
                                         code_offset,
-                                        &unannotated_line,
+                                        &unannotated_line[left_margin..right_margin],
                                         Style::Quotation);
 
                             for (depth, style) in &multilines {
diff --git a/src/test/ui/inline-asm-bad-operand.stderr b/src/test/ui/inline-asm-bad-operand.stderr
index 4554da7b798ea..d5c1cf51dafaa 100644
--- a/src/test/ui/inline-asm-bad-operand.stderr
+++ b/src/test/ui/inline-asm-bad-operand.stderr
@@ -37,8 +37,8 @@ LL |         asm!("mov sp, $0"::"r"(addr),
 error[E0669]: invalid value for constraint in inline assembly
   --> $DIR/inline-asm-bad-operand.rs:56:32
    |
-LL |                            "r"("hello e0669"));
-   |                                ^^^^^^^^^^^^^
+LL | ...             "r"("hello e0669"));
+   |                     ^^^^^^^^^^^^^
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
index a0b34d220c8d9..3262662a2a5e6 100644
--- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
@@ -38,8 +38,8 @@ LL |     if let SoulHistory { corridors_of_light,
 warning: variable `hours_are_suns` is assigned to, but never used
   --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:30
    |
-LL |                          mut hours_are_suns,
-   |                              ^^^^^^^^^^^^^^
+LL | ...             mut hours_are_suns,
+   |                     ^^^^^^^^^^^^^^
    |
    = note: consider using `_hours_are_suns` instead
 
diff --git a/src/test/ui/methods/method-missing-call.stderr b/src/test/ui/methods/method-missing-call.stderr
index 3ab5f66a0c3f6..fe44d3a29dab5 100644
--- a/src/test/ui/methods/method-missing-call.stderr
+++ b/src/test/ui/methods/method-missing-call.stderr
@@ -1,8 +1,8 @@
 error[E0615]: attempted to take value of method `get_x` on type `Point`
   --> $DIR/method-missing-call.rs:22:26
    |
-LL |                         .get_x;
-   |                          ^^^^^ help: use parentheses to call the method: `get_x()`
+LL | ...             .get_x;
+   |                  ^^^^^ help: use parentheses to call the method: `get_x()`
 
 error[E0615]: attempted to take value of method `filter_map` on type `std::iter::Filter<std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@$DIR/method-missing-call.rs:27:20: 27:25]>, [closure@$DIR/method-missing-call.rs:28:23: 28:35]>`
   --> $DIR/method-missing-call.rs:29:16
diff --git a/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr b/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
index 483c364752b7b..6eff7b06d53a5 100644
--- a/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
+++ b/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
@@ -1,11 +1,11 @@
 error[E0499]: cannot borrow `*f` as mutable more than once at a time
   --> $DIR/moves-based-on-type-no-recursive-stack-closure.rs:20:27
    |
-LL |                     (f.c)(f, true);
-   |                     ----- ^ second mutable borrow occurs here
-   |                     |
-   |                     first mutable borrow occurs here
-   |                     first borrow later used by call
+LL | ...             (f.c)(f, true);
+   |                 ----- ^ second mutable borrow occurs here
+   |                 |
+   |                 first mutable borrow occurs here
+   |                 first borrow later used by call
 
 error[E0382]: borrow of moved value: `f`
   --> $DIR/moves-based-on-type-no-recursive-stack-closure.rs:32:5
diff --git a/src/test/ui/regions/regions-name-undeclared.stderr b/src/test/ui/regions/regions-name-undeclared.stderr
index 4840d751f7f57..fe0345c3a380c 100644
--- a/src/test/ui/regions/regions-name-undeclared.stderr
+++ b/src/test/ui/regions/regions-name-undeclared.stderr
@@ -49,14 +49,14 @@ LL | fn fn_types(a: &'a isize,
 error[E0261]: use of undeclared lifetime name `'b`
   --> $DIR/regions-name-undeclared.rs:42:36
    |
-LL |                                   &'b isize,
-   |                                    ^^ undeclared lifetime
+LL | ...             &'b isize,
+   |                  ^^ undeclared lifetime
 
 error[E0261]: use of undeclared lifetime name `'b`
   --> $DIR/regions-name-undeclared.rs:45:36
    |
-LL |                                   &'b isize)>,
-   |                                    ^^ undeclared lifetime
+LL | ...             &'b isize)>,
+   |                  ^^ undeclared lifetime
 
 error[E0261]: use of undeclared lifetime name `'a`
   --> $DIR/regions-name-undeclared.rs:46:17

From 266b878334cecce3a0636ddbb95318f7a5669f45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 13 Aug 2019 19:09:28 -0700
Subject: [PATCH 095/943] clean up

---
 src/librustc_errors/emitter.rs                | 220 +++++++++++++-----
 ...-on-type-no-recursive-stack-closure.stderr |  10 +-
 2 files changed, 162 insertions(+), 68 deletions(-)

diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 007c6369c7bd0..b7615fef04909 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -57,6 +57,80 @@ impl HumanReadableErrorType {
     }
 }
 
+#[derive(Clone, Copy, Debug)]
+struct Margin {
+    pub whitespace_left: usize,
+    pub span_left: usize,
+    pub span_right: usize,
+    pub line_len: usize,
+    pub computed_left: usize,
+    pub computed_right: usize,
+    pub column_width: usize,
+    pub label_right: usize,
+}
+
+impl Margin {
+    fn new(
+        whitespace_left: usize,
+        span_left: usize,
+        span_right: usize,
+        label_right: usize,
+    ) -> Self {
+        Margin {
+            whitespace_left,
+            span_left,
+            span_right,
+            line_len: 0,
+            computed_left: 0,
+            computed_right: 0,
+            column_width: 140,
+            label_right,
+        }
+    }
+
+    fn was_cut_left(&self) -> bool {
+        self.computed_left > 0
+    }
+
+    fn was_cut_right(&self) -> bool {
+        self.computed_right < self.line_len
+    }
+
+    fn compute(&mut self) {
+        self.computed_left = if self.whitespace_left > 20 {
+            self.whitespace_left - 16 // We want some padding.
+        } else {
+            0
+        };
+        self.computed_right = self.column_width + self.computed_left;
+
+        if self.computed_right - self.computed_left > self.column_width {
+            // Trimming only whitespace isn't enough, let's get craftier.
+            if self.label_right - self.whitespace_left <= self.column_width {
+                self.computed_left = self.whitespace_left;
+                self.computed_right = self.computed_left + self.column_width;
+            } else if self.label_right - self.span_left - 20 <= self.column_width {
+                self.computed_left = self.span_left - 20;
+                self.computed_right = self.computed_left + self.column_width;
+            } else if self.label_right - self.span_left <= self.column_width {
+                self.computed_left = self.span_left;
+                self.computed_right = self.computed_left + self.column_width;
+            } else if self.span_right - self.span_left <= self.column_width {
+                self.computed_left = self.span_left;
+                self.computed_right = self.computed_left + self.column_width;
+            } else { // mostly give up but still don't show the full line
+                self.computed_left = self.span_left;
+                self.computed_right = self.span_right;
+            }
+        }
+        self.computed_left = std::cmp::min(self.computed_left, self.line_len);
+        if self.computed_right > self.line_len {
+            self.computed_right = self.line_len;
+        }
+        self.computed_right = std::cmp::min(self.computed_right, self.line_len);
+    }
+}
+
 const ANONYMIZED_LINE_NUM: &str = "LL";
 
 /// Emitter trait for emitting errors.
@@ -179,7 +253,6 @@ pub struct EmitterWriter {
     sm: Option<Lrc<SourceMapperDyn>>,
     short_message: bool,
     teach: bool,
-    strip_margin: bool,
     ui_testing: bool,
 }
 
@@ -202,7 +275,6 @@ impl EmitterWriter {
             sm: source_map,
             short_message,
             teach,
-            strip_margin: false,
             ui_testing: false,
         }
     }
@@ -219,7 +291,6 @@ impl EmitterWriter {
             sm: source_map,
             short_message,
             teach,
-            strip_margin: false,
             ui_testing: false,
         }
     }
@@ -244,8 +315,7 @@ impl EmitterWriter {
         line: &Line,
         width_offset: usize,
         code_offset: usize,
-        margin: usize,
-        right_span_margin: usize
+        mut margin: Margin,
     ) -> Vec<(usize, Style)> {
         // Draw:
         //
@@ -260,6 +330,7 @@ impl EmitterWriter {
         //   |  | when there's too much wasted space to the left, we trim it to focus where it matters
         //   |  vertical divider between the column number and the code
         //   column number
+
         if line.line_index == 0 {
             return Vec::new();
         }
@@ -271,26 +342,27 @@ impl EmitterWriter {
 
         let line_offset = buffer.num_lines();
 
-        let left_margin = std::cmp::min(margin, source_string.len());
-        let right_margin = if source_string.len() > right_span_margin + 120 {
-            right_span_margin + 120
-        } else {
-            source_string.len()
-        };
+        margin.line_len = source_string.len();
+        margin.compute();
         // Create the source line we will highlight.
         buffer.puts(
             line_offset,
             code_offset,
-            &source_string[left_margin..right_margin], // On long lines, we strip the source line
+            // On long lines, we strip the source line
+            &source_string[margin.computed_left..margin.computed_right],
             Style::Quotation,
         );
-        if margin > 0 { // We have stripped some code/whitespace from the beginning, make it clear.
+        if margin.was_cut_left() { // We have stripped some code/whitespace from the beginning, make it clear.
             buffer.puts(line_offset, code_offset, "...", Style::LineNumber);
         }
-        if right_margin != source_string.len() {
+        if margin.was_cut_right() {
             // We have stripped some code after the right-most span end, make it clear we did so.
-            let offset = code_offset + right_margin - left_margin;
-            buffer.puts(line_offset, offset, "...", Style::LineNumber);
+            buffer.puts(
+                line_offset,
+                margin.computed_right - margin.computed_left + code_offset,
+                "...",
+                Style::LineNumber,
+            );
         }
         buffer.puts(line_offset, 0, &self.maybe_anonymized(line.line_index), Style::LineNumber);
 
@@ -546,13 +618,13 @@ impl EmitterWriter {
                                '_',
                                line_offset + pos,
                                width_offset + depth,
-                               code_offset + annotation.start_col - margin,
+                               code_offset + annotation.start_col - margin.computed_left,
                                style);
                 }
                 _ if self.teach => {
                     buffer.set_style_range(line_offset,
-                                           code_offset + annotation.start_col - margin,
-                                           code_offset + annotation.end_col - margin,
+                                           code_offset + annotation.start_col - margin.computed_left,
+                                           code_offset + annotation.end_col - margin.computed_left,
                                            style,
                                            annotation.is_primary);
                 }
@@ -582,7 +654,7 @@ impl EmitterWriter {
             if pos > 1 && (annotation.has_label() || annotation.takes_space()) {
                 for p in line_offset + 1..=line_offset + pos {
                     buffer.putc(p,
-                                code_offset + annotation.start_col - margin,
+                                code_offset + annotation.start_col - margin.computed_left,
                                 '|',
                                 style);
                 }
@@ -626,9 +698,9 @@ impl EmitterWriter {
                 Style::LabelSecondary
             };
             let (pos, col) = if pos == 0 {
-                (pos + 1, annotation.end_col + 1 - margin)
+                (pos + 1, annotation.end_col + 1 - margin.computed_left)
             } else {
-                (pos + 2, annotation.start_col - margin)
+                (pos + 2, annotation.start_col - margin.computed_left)
             };
             if let Some(ref label) = annotation.label {
                 buffer.puts(line_offset + pos,
@@ -670,7 +742,7 @@ impl EmitterWriter {
             };
             for p in annotation.start_col..annotation.end_col {
                 buffer.putc(line_offset + 1,
-                            code_offset + p - margin,
+                            code_offset + p - margin.computed_left,
                             underline,
                             style);
             }
@@ -1010,22 +1082,30 @@ impl EmitterWriter {
                     let buffer_msg_line_offset = buffer.num_lines();
 
                     buffer.prepend(buffer_msg_line_offset, "--> ", Style::LineNumber);
-                    buffer.append(buffer_msg_line_offset,
-                                  &format!("{}:{}:{}",
-                                           loc.file.name,
-                                           sm.doctest_offset_line(&loc.file.name, loc.line),
-                                           loc.col.0 + 1),
-                                  Style::LineAndColumn);
+                    buffer.append(
+                        buffer_msg_line_offset,
+                        &format!(
+                            "{}:{}:{}",
+                            loc.file.name,
+                            sm.doctest_offset_line(&loc.file.name, loc.line),
+                            loc.col.0 + 1,
+                        ),
+                        Style::LineAndColumn,
+                    );
                     for _ in 0..max_line_num_len {
                         buffer.prepend(buffer_msg_line_offset, " ", Style::NoStyle);
                     }
                 } else {
-                    buffer.prepend(0,
-                                   &format!("{}:{}:{}: ",
-                                            loc.file.name,
-                                            sm.doctest_offset_line(&loc.file.name, loc.line),
-                                            loc.col.0 + 1),
-                                   Style::LineAndColumn);
+                    buffer.prepend(
+                        0,
+                        &format!(
+                            "{}:{}:{}: ",
+                            loc.file.name,
+                            sm.doctest_offset_line(&loc.file.name, loc.line),
+                            loc.col.0 + 1,
+                        ),
+                        Style::LineAndColumn,
+                    );
                 }
             } else if !self.short_message {
                 // remember where we are in the output buffer for easy reference
@@ -1069,7 +1149,7 @@ impl EmitterWriter {
                 let mut multilines = FxHashMap::default();
 
                 // Get the left-side margin to remove it
-                let mut margin = std::usize::MAX;
+                let mut whitespace_margin = std::usize::MAX;
                 for line_idx in 0..annotated_file.lines.len() {
                     let file = annotated_file.file.clone();
                     let line = &annotated_file.lines[line_idx];
@@ -1079,14 +1159,15 @@ impl EmitterWriter {
                             .take_while(|c| c.is_whitespace())
                             .count();
                         if source_string.chars().any(|c| !c.is_whitespace()) {
-                            margin = std::cmp::min(margin, leading_whitespace);
+                            whitespace_margin = std::cmp::min(
+                                whitespace_margin,
+                                leading_whitespace,
+                            );
                         }
                     }
                 }
-                if margin >= 20 { // On errors with generous margins, trim it
-                    margin = margin - 16; // Keep at least 4 spaces margin
-                } else if margin == std::usize::MAX || !self.strip_margin {
-                    margin = 0;
+                if whitespace_margin == std::usize::MAX {
+                    whitespace_margin = 0;
                 }
 
                 // Left-most column any visible span points at.
@@ -1100,18 +1181,27 @@ impl EmitterWriter {
                 if span_left_margin == std::usize::MAX {
                     span_left_margin = 0;
                 }
-                if span_left_margin > 160 {
-                    margin = std::cmp::max(margin, span_left_margin - 100);
-                }
 
                 // Right-most column any visible span points at.
                 let mut span_right_margin = 0;
+                let mut label_right_margin = 0;
                 for line in &annotated_file.lines {
                     for ann in &line.annotations {
                         span_right_margin = std::cmp::max(span_right_margin, ann.start_col);
                         span_right_margin = std::cmp::max(span_right_margin, ann.end_col);
+                        label_right_margin = std::cmp::max(
+                            label_right_margin,
+                            // TODO: account for labels not in the same line
+                            ann.end_col + ann.label.as_ref().map(|l| l.len() + 1).unwrap_or(0),
+                        );
                     }
                 }
+                let margin = Margin::new(
+                    whitespace_margin,
+                    span_left_margin,
+                    span_right_margin,
+                    label_right_margin,
+                );
 
                 // Next, output the annotate source for this file
                 for line_idx in 0..annotated_file.lines.len() {
@@ -1131,7 +1221,6 @@ impl EmitterWriter {
                         width_offset,
                         code_offset,
                         margin,
-                        span_right_margin,
                     );
 
                     let mut to_add = FxHashMap::default();
@@ -1179,24 +1268,29 @@ impl EmitterWriter {
 
                             let last_buffer_line_num = buffer.num_lines();
 
-                            buffer.puts(last_buffer_line_num,
-                                        0,
-                                        &self.maybe_anonymized(annotated_file.lines[line_idx + 1]
-                                                                             .line_index - 1),
-                                        Style::LineNumber);
-                            draw_col_separator(&mut buffer,
-                                               last_buffer_line_num,
-                                               1 + max_line_num_len);
-                            let left_margin = std::cmp::min(margin, unannotated_line.len());
-                            let right_margin = if unannotated_line.len() > span_right_margin + 120 {
-                                span_right_margin + 120
-                            } else {
-                                unannotated_line.len()
-                            };
-                            buffer.puts(last_buffer_line_num,
-                                        code_offset,
-                                        &unannotated_line[left_margin..right_margin],
-                                        Style::Quotation);
+                            buffer.puts(
+                                last_buffer_line_num,
+                                0,
+                                &self.maybe_anonymized(
+                                    annotated_file.lines[line_idx + 1].line_index - 1,
+                                ),
+                                Style::LineNumber,
+                            );
+                            draw_col_separator(
+                                &mut buffer,
+                                last_buffer_line_num,
+                                1 + max_line_num_len,
+                            );
+
+                            let mut margin = margin;
+                            margin.line_len = unannotated_line.len();
+                            margin.compute();
+                            buffer.puts(
+                                last_buffer_line_num,
+                                code_offset,
+                                &unannotated_line[margin.computed_left..margin.computed_right],
+                                Style::Quotation,
+                            );
 
                             for (depth, style) in &multilines {
                                 draw_multiline_line(&mut buffer,
diff --git a/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr b/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
index 6eff7b06d53a5..483c364752b7b 100644
--- a/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
+++ b/src/test/ui/moves/moves-based-on-type-no-recursive-stack-closure.stderr
@@ -1,11 +1,11 @@
 error[E0499]: cannot borrow `*f` as mutable more than once at a time
   --> $DIR/moves-based-on-type-no-recursive-stack-closure.rs:20:27
    |
-LL | ...             (f.c)(f, true);
-   |                 ----- ^ second mutable borrow occurs here
-   |                 |
-   |                 first mutable borrow occurs here
-   |                 first borrow later used by call
+LL |                     (f.c)(f, true);
+   |                     ----- ^ second mutable borrow occurs here
+   |                     |
+   |                     first mutable borrow occurs here
+   |                     first borrow later used by call
 
 error[E0382]: borrow of moved value: `f`
   --> $DIR/moves-based-on-type-no-recursive-stack-closure.rs:32:5

From f08b036cc78ca225a8d3e25fc138ed3a210c611f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 14 Aug 2019 09:34:09 -0700
Subject: [PATCH 096/943] Introduce `term-size` dependency and consider term
 width when trimming

---
 Cargo.lock                                    |  12 +
 src/librustc_errors/Cargo.toml                |   1 +
 src/librustc_errors/emitter.rs                | 252 +++++++++++-------
 src/test/ui/inline-asm-bad-operand.stderr     |   4 +-
 ...0-unused-variable-in-struct-pattern.stderr |   4 +-
 .../ui/lint/lint-stability-deprecated.stderr  |  36 +--
 .../ui/methods/method-missing-call.stderr     |   4 +-
 .../ui/regions/regions-name-undeclared.stderr |   8 +-
 .../non-whitespace-trimming-2.rs              |   6 +
 .../non-whitespace-trimming-2.stderr          |  12 +
 .../terminal-width/non-whitespace-trimming.rs |   6 +
 .../non-whitespace-trimming.stderr            |  12 +
 .../terminal-width/whitespace-trimming-2.rs   |   8 +
 .../whitespace-trimming-2.stderr              |  14 +
 .../ui/terminal-width/whitespace-trimming.rs  |   6 +
 .../terminal-width/whitespace-trimming.stderr |  12 +
 src/tools/tidy/src/deps.rs                    |   1 +
 17 files changed, 277 insertions(+), 121 deletions(-)
 create mode 100644 src/test/ui/terminal-width/non-whitespace-trimming-2.rs
 create mode 100644 src/test/ui/terminal-width/non-whitespace-trimming-2.stderr
 create mode 100644 src/test/ui/terminal-width/non-whitespace-trimming.rs
 create mode 100644 src/test/ui/terminal-width/non-whitespace-trimming.stderr
 create mode 100644 src/test/ui/terminal-width/whitespace-trimming-2.rs
 create mode 100644 src/test/ui/terminal-width/whitespace-trimming-2.stderr
 create mode 100644 src/test/ui/terminal-width/whitespace-trimming.rs
 create mode 100644 src/test/ui/terminal-width/whitespace-trimming.stderr

diff --git a/Cargo.lock b/Cargo.lock
index 06c455b3c910d..16baa7436cb81 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3219,6 +3219,7 @@ dependencies = [
  "rustc_data_structures",
  "serialize",
  "syntax_pos",
+ "term_size",
  "termcolor",
  "unicode-width",
 ]
@@ -4090,6 +4091,17 @@ dependencies = [
  "winapi 0.3.6",
 ]
 
+[[package]]
+name = "term_size"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e5b9a66db815dcfd2da92db471106457082577c3c278d4138ab3e3b4e189327"
+dependencies = [
+ "kernel32-sys",
+ "libc",
+ "winapi 0.2.8",
+]
+
 [[package]]
 name = "termcolor"
 version = "1.0.4"
diff --git a/src/librustc_errors/Cargo.toml b/src/librustc_errors/Cargo.toml
index 32f121f18f689..1541845bb55f6 100644
--- a/src/librustc_errors/Cargo.toml
+++ b/src/librustc_errors/Cargo.toml
@@ -18,3 +18,4 @@ unicode-width = "0.1.4"
 atty = "0.2"
 termcolor = "1.0"
 annotate-snippets = "0.6.1"
+term_size = "0.3.1"
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index b7615fef04909..6bb151d19b32b 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -24,7 +24,7 @@ use rustc_data_structures::sync::Lrc;
 use std::borrow::Cow;
 use std::io::prelude::*;
 use std::io;
-use std::cmp::{min, Reverse};
+use std::cmp::{min, max, Reverse};
 use std::path::Path;
 use termcolor::{StandardStream, ColorChoice, ColorSpec, BufferWriter, Ansi};
 use termcolor::{WriteColor, Color, Buffer};
@@ -59,13 +59,20 @@ impl HumanReadableErrorType {
 
 #[derive(Clone, Copy, Debug)]
 struct Margin {
+    /// The available whitespace in the left that can be consumed when centering.
     pub whitespace_left: usize,
+    /// The column of the beginning of left-most span.
     pub span_left: usize,
+    /// The column of the end of right-most span.
     pub span_right: usize,
-    pub line_len: usize,
+    /// The beginning of the line to be displayed.
     pub computed_left: usize,
+    /// The end of the line to be displayed.
     pub computed_right: usize,
+    /// The current width of the terminal. 140 by default and in tests.
     pub column_width: usize,
+    /// The end column of a span label, including the span. Doesn't account for labels not in the
+    /// same line as the span.
     pub label_right: usize,
 }
 
@@ -75,59 +82,92 @@ impl Margin {
         span_left: usize,
         span_right: usize,
         label_right: usize,
+        column_width: usize,
+        max_line_len: usize,
     ) -> Self {
-        Margin {
-            whitespace_left,
-            span_left,
-            span_right,
-            line_len: 0,
+        // The 6 is padding to give a bit of room for `...` when displaying:
+        // ```
+        // error: message
+        //   --> file.rs:16:58
+        //    |
+        // 16 | ... fn foo(self) -> Self::Bar {
+        //    |                     ^^^^^^^^^
+        // ```
+
+        let mut m = Margin {
+            whitespace_left: if whitespace_left >= 6 { whitespace_left - 6 } else { 0 },
+            span_left: if span_left >= 6 { span_left - 6 } else { 0 },
+            span_right: span_right + 6,
             computed_left: 0,
             computed_right: 0,
-            column_width: 140,
-            label_right,
-        }
+            column_width,
+            label_right: label_right + 6,
+        };
+        m.compute(max_line_len);
+        m
     }
 
     fn was_cut_left(&self) -> bool {
         self.computed_left > 0
     }
 
-    fn was_cut_right(&self) -> bool {
-        self.computed_right < self.line_len
+    fn was_cut_right(&self, line_len: usize) -> bool {
+        let right = if self.computed_right == self.span_right ||
+            self.computed_right == self.label_right
+        {
+            // Account for the "..." padding given above. Otherwise we end up with code lines that
+            // do fit but end in "..." as if they were trimmed.
+            self.computed_right - 6
+        } else {
+            self.computed_right
+        };
+        right < line_len && line_len > self.computed_left + self.column_width
     }
 
-    fn compute(&mut self) {
+    fn compute(&mut self, max_line_len: usize) {
+        // When there's a lot of whitespace (>20), we want to trim it as it is useless.
         self.computed_left = if self.whitespace_left > 20 {
             self.whitespace_left - 16 // We want some padding.
         } else {
             0
         };
-        self.computed_right = self.column_width + self.computed_left;
+        // We want to show as much as possible, max_line_len is the right-most boundary for the
+        // relevant code.
+        self.computed_right = max(max_line_len, self.computed_left);
 
         if self.computed_right - self.computed_left > self.column_width {
             // Trimming only whitespace isn't enough, let's get craftier.
             if self.label_right - self.whitespace_left <= self.column_width {
+                // Attempt to fit the code window only trimming whitespace.
                 self.computed_left = self.whitespace_left;
                 self.computed_right = self.computed_left + self.column_width;
-            } else if self.label_right - self.span_left - 20 <= self.column_width {
-                self.computed_left = self.span_left - 20;
-                self.computed_right = self.computed_left + self.column_width;
             } else if self.label_right - self.span_left <= self.column_width {
+                // Attempt to fit the code window considering only the spans and labels.
                 self.computed_left = self.span_left;
                 self.computed_right = self.computed_left + self.column_width;
             } else if self.span_right - self.span_left <= self.column_width {
+                // Attempt to fit the code window considering the spans and labels plus padding.
                 self.computed_left = self.span_left;
                 self.computed_right = self.computed_left + self.column_width;
-            } else { // mostly give up but still don't show the full line
+            } else { // Mostly give up but still don't show the full line.
                 self.computed_left = self.span_left;
                 self.computed_right = self.span_right;
             }
         }
-        self.computed_left = std::cmp::min(self.computed_left, self.line_len);
-        if self.computed_right > self.line_len {
-            self.computed_right = self.line_len;
+    }
+
+    fn left(&self, line_len: usize) -> usize {
+        min(self.computed_left, line_len)
+    }
+
+    fn right(&self, line_len: usize) -> usize {
+        if max(line_len, self.computed_left) - self.computed_left <= self.column_width {
+            line_len
+        } else if self.computed_right > line_len {
+            line_len
+        } else {
+            self.computed_right
         }
-        self.computed_right = std::cmp::min(self.computed_right, self.line_len);
     }
 }
 
@@ -308,6 +348,42 @@ impl EmitterWriter {
         }
     }
 
+    fn draw_line(
+        &self,
+        buffer: &mut StyledBuffer,
+        source_string: &str,
+        line_index: usize,
+        line_offset: usize,
+        width_offset: usize,
+        code_offset: usize,
+        margin: Margin,
+    ) {
+        let line_len = source_string.len();
+        // Create the source line we will highlight.
+        buffer.puts(
+            line_offset,
+            code_offset,
+            // On long lines, we strip the source line
+            &source_string[margin.left(line_len)..margin.right(line_len)],
+            Style::Quotation,
+        );
+        if margin.was_cut_left() { // We have stripped some code/whitespace from the beginning, make it clear.
+            buffer.puts(line_offset, code_offset, "...", Style::LineNumber);
+        }
+        if margin.was_cut_right(line_len) {
+            // We have stripped some code after the right-most span end, make it clear we did so.
+            buffer.puts(
+                line_offset,
+                margin.right(line_len) - margin.left(line_len) + code_offset - 3,
+                "...",
+                Style::LineNumber,
+            );
+        }
+        buffer.puts(line_offset, 0, &self.maybe_anonymized(line_index), Style::LineNumber);
+
+        draw_col_separator(buffer, line_offset, width_offset - 2);
+    }
+
     fn render_source_line(
         &self,
         buffer: &mut StyledBuffer,
@@ -315,7 +391,7 @@ impl EmitterWriter {
         line: &Line,
         width_offset: usize,
         code_offset: usize,
-        mut margin: Margin,
+        margin: Margin,
     ) -> Vec<(usize, Style)> {
         // Draw:
         //
@@ -342,31 +418,15 @@ impl EmitterWriter {
 
         let line_offset = buffer.num_lines();
 
-        margin.line_len = source_string.len();
-        margin.compute();
-        // Create the source line we will highlight.
-        buffer.puts(
+        self.draw_line(
+            buffer,
+            &source_string,
+            line.line_index,
             line_offset,
+            width_offset,
             code_offset,
-            // On long lines, we strip the source line
-            &source_string[margin.computed_left..margin.computed_right],
-            Style::Quotation,
+            margin,
         );
-        if margin.was_cut_left() { // We have stripped some code/whitespace from the beginning, make it clear.
-            buffer.puts(line_offset, code_offset, "...", Style::LineNumber);
-        }
-        if margin.was_cut_right() {
-            // We have stripped some code after the right-most span end, make it clear we did so.
-            buffer.puts(
-                line_offset,
-                margin.computed_right - margin.computed_left + code_offset,
-                "...",
-                Style::LineNumber,
-            );
-        }
-        buffer.puts(line_offset, 0, &self.maybe_anonymized(line.line_index), Style::LineNumber);
-
-        draw_col_separator(buffer, line_offset, width_offset - 2);
 
         // Special case when there's only one annotation involved, it is the start of a multiline
         // span and there's no text at the beginning of the code line. Instead of doing the whole
@@ -614,19 +674,23 @@ impl EmitterWriter {
             match annotation.annotation_type {
                 AnnotationType::MultilineStart(depth) |
                 AnnotationType::MultilineEnd(depth) => {
-                    draw_range(buffer,
-                               '_',
-                               line_offset + pos,
-                               width_offset + depth,
-                               code_offset + annotation.start_col - margin.computed_left,
-                               style);
+                    draw_range(
+                        buffer,
+                        '_',
+                        line_offset + pos,
+                        width_offset + depth,
+                        code_offset + annotation.start_col - margin.computed_left,
+                        style,
+                    );
                 }
                 _ if self.teach => {
-                    buffer.set_style_range(line_offset,
-                                           code_offset + annotation.start_col - margin.computed_left,
-                                           code_offset + annotation.end_col - margin.computed_left,
-                                           style,
-                                           annotation.is_primary);
+                    buffer.set_style_range(
+                        line_offset,
+                        code_offset + annotation.start_col - margin.computed_left,
+                        code_offset + annotation.end_col - margin.computed_left,
+                        style,
+                        annotation.is_primary,
+                    );
                 }
                 _ => {}
             }
@@ -1159,7 +1223,7 @@ impl EmitterWriter {
                             .take_while(|c| c.is_whitespace())
                             .count();
                         if source_string.chars().any(|c| !c.is_whitespace()) {
-                            whitespace_margin = std::cmp::min(
+                            whitespace_margin = min(
                                 whitespace_margin,
                                 leading_whitespace,
                             );
@@ -1174,8 +1238,8 @@ impl EmitterWriter {
                 let mut span_left_margin = std::usize::MAX;
                 for line in &annotated_file.lines {
                     for ann in &line.annotations {
-                        span_left_margin = std::cmp::min(span_left_margin, ann.start_col);
-                        span_left_margin = std::cmp::min(span_left_margin, ann.end_col);
+                        span_left_margin = min(span_left_margin, ann.start_col);
+                        span_left_margin = min(span_left_margin, ann.end_col);
                     }
                 }
                 if span_left_margin == std::usize::MAX {
@@ -1185,35 +1249,49 @@ impl EmitterWriter {
                 // Right-most column any visible span points at.
                 let mut span_right_margin = 0;
                 let mut label_right_margin = 0;
+                let mut max_line_len = 0;
                 for line in &annotated_file.lines {
+                    max_line_len = max(
+                        max_line_len,
+                        annotated_file.file.get_line(line.line_index - 1).map(|s| s.len()).unwrap_or(0),
+                    );
                     for ann in &line.annotations {
-                        span_right_margin = std::cmp::max(span_right_margin, ann.start_col);
-                        span_right_margin = std::cmp::max(span_right_margin, ann.end_col);
-                        label_right_margin = std::cmp::max(
+                        span_right_margin = max(span_right_margin, ann.start_col);
+                        span_right_margin = max(span_right_margin, ann.end_col);
+                        label_right_margin = max(
                             label_right_margin,
                             // TODO: account for labels not in the same line
                             ann.end_col + ann.label.as_ref().map(|l| l.len() + 1).unwrap_or(0),
                         );
                     }
                 }
+
+                let width_offset = 3 + max_line_num_len;
+                let code_offset = if annotated_file.multiline_depth == 0 {
+                    width_offset
+                } else {
+                    width_offset + annotated_file.multiline_depth + 1
+                };
+
+                let column_width = if self.ui_testing {
+                    140
+                } else {
+                    term_size::dimensions().map(|(w, _)| w - code_offset).unwrap_or(140)
+                };
+
                 let margin = Margin::new(
                     whitespace_margin,
                     span_left_margin,
                     span_right_margin,
                     label_right_margin,
+                    column_width,
+                    max_line_len,
                 );
 
                 // Next, output the annotate source for this file
                 for line_idx in 0..annotated_file.lines.len() {
                     let previous_buffer_line = buffer.num_lines();
 
-                    let width_offset = 3 + max_line_num_len;
-                    let code_offset = if annotated_file.multiline_depth == 0 {
-                        width_offset
-                    } else {
-                        width_offset + annotated_file.multiline_depth + 1
-                    };
-
                     let depths = self.render_source_line(
                         &mut buffer,
                         annotated_file.file.clone(),
@@ -1268,36 +1346,24 @@ impl EmitterWriter {
 
                             let last_buffer_line_num = buffer.num_lines();
 
-                            buffer.puts(
-                                last_buffer_line_num,
-                                0,
-                                &self.maybe_anonymized(
-                                    annotated_file.lines[line_idx + 1].line_index - 1,
-                                ),
-                                Style::LineNumber,
-                            );
-                            draw_col_separator(
+                            self.draw_line(
                                 &mut buffer,
+                                &unannotated_line,
+                                annotated_file.lines[line_idx + 1].line_index - 1,
                                 last_buffer_line_num,
-                                1 + max_line_num_len,
-                            );
-
-                            let mut margin = margin;
-                            margin.line_len = unannotated_line.len();
-                            margin.compute();
-                            buffer.puts(
-                                last_buffer_line_num,
+                                width_offset,
                                 code_offset,
-                                &unannotated_line[margin.computed_left..margin.computed_right],
-                                Style::Quotation,
+                                margin,
                             );
 
                             for (depth, style) in &multilines {
-                                draw_multiline_line(&mut buffer,
-                                                    last_buffer_line_num,
-                                                    width_offset,
-                                                    *depth,
-                                                    *style);
+                                draw_multiline_line(
+                                    &mut buffer,
+                                    last_buffer_line_num,
+                                    width_offset,
+                                    *depth,
+                                    *style,
+                                );
                             }
                         }
                     }
diff --git a/src/test/ui/inline-asm-bad-operand.stderr b/src/test/ui/inline-asm-bad-operand.stderr
index d5c1cf51dafaa..55523bad6c507 100644
--- a/src/test/ui/inline-asm-bad-operand.stderr
+++ b/src/test/ui/inline-asm-bad-operand.stderr
@@ -37,8 +37,8 @@ LL |         asm!("mov sp, $0"::"r"(addr),
 error[E0669]: invalid value for constraint in inline assembly
   --> $DIR/inline-asm-bad-operand.rs:56:32
    |
-LL | ...             "r"("hello e0669"));
-   |                     ^^^^^^^^^^^^^
+LL | ...                   "r"("hello e0669"));
+   |                           ^^^^^^^^^^^^^
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
index 3262662a2a5e6..a0b34d220c8d9 100644
--- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
+++ b/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
@@ -38,8 +38,8 @@ LL |     if let SoulHistory { corridors_of_light,
 warning: variable `hours_are_suns` is assigned to, but never used
   --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:38:30
    |
-LL | ...             mut hours_are_suns,
-   |                     ^^^^^^^^^^^^^^
+LL |                          mut hours_are_suns,
+   |                              ^^^^^^^^^^^^^^
    |
    = note: consider using `_hours_are_suns` instead
 
diff --git a/src/test/ui/lint/lint-stability-deprecated.stderr b/src/test/ui/lint/lint-stability-deprecated.stderr
index 8132a66df8a0f..62380135b333b 100644
--- a/src/test/ui/lint/lint-stability-deprecated.stderr
+++ b/src/test/ui/lint/lint-stability-deprecated.stderr
@@ -67,14 +67,14 @@ LL |         deprecated_unstable_text();
 warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
   --> $DIR/lint-stability-deprecated.rs:57:9
    |
-LL |         Trait::trait_deprecated_unstable_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Trait::trait_deprecated_unstable_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
   --> $DIR/lint-stability-deprecated.rs:59:9
    |
-LL |         <Foo as Trait>::trait_deprecated_unstable_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_unstable_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'lint_stability::DeprecatedStruct': text
   --> $DIR/lint-stability-deprecated.rs:106:17
@@ -181,14 +181,14 @@ LL |         <Foo as Trait>::trait_deprecated_unstable(&foo);
 warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
   --> $DIR/lint-stability-deprecated.rs:155:9
    |
-LL |         Trait::trait_deprecated_unstable_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Trait::trait_deprecated_unstable_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
   --> $DIR/lint-stability-deprecated.rs:157:9
    |
-LL |         <Foo as Trait>::trait_deprecated_unstable_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo as Trait>::trait_deprecated_unstable_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'lint_stability::DeprecatedTrait': text
   --> $DIR/lint-stability-deprecated.rs:185:10
@@ -421,20 +421,20 @@ LL |         <Foo>::trait_deprecated_unstable(&foo);
 warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text
   --> $DIR/lint-stability-deprecated.rs:53:13
    |
-LL |         foo.method_deprecated_unstable_text();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   foo.method_deprecated_unstable_text();
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text
   --> $DIR/lint-stability-deprecated.rs:54:9
    |
-LL |         Foo::method_deprecated_unstable_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   Foo::method_deprecated_unstable_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'lint_stability::MethodTester::method_deprecated_unstable_text': text
   --> $DIR/lint-stability-deprecated.rs:55:9
    |
-LL |         <Foo>::method_deprecated_unstable_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::method_deprecated_unstable_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
   --> $DIR/lint-stability-deprecated.rs:56:13
@@ -445,8 +445,8 @@ LL |         foo.trait_deprecated_unstable_text();
 warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
   --> $DIR/lint-stability-deprecated.rs:58:9
    |
-LL |         <Foo>::trait_deprecated_unstable_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::trait_deprecated_unstable_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'lint_stability::DeprecatedStruct::i': text
   --> $DIR/lint-stability-deprecated.rs:107:13
@@ -505,8 +505,8 @@ LL |         foo.trait_deprecated_unstable_text();
 warning: use of deprecated item 'lint_stability::Trait::trait_deprecated_unstable_text': text
   --> $DIR/lint-stability-deprecated.rs:156:9
    |
-LL |         <Foo>::trait_deprecated_unstable_text(&foo);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | ...   <Foo>::trait_deprecated_unstable_text(&foo);
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated item 'lint_stability::Trait::trait_deprecated': text
   --> $DIR/lint-stability-deprecated.rs:173:13
diff --git a/src/test/ui/methods/method-missing-call.stderr b/src/test/ui/methods/method-missing-call.stderr
index fe44d3a29dab5..3ab5f66a0c3f6 100644
--- a/src/test/ui/methods/method-missing-call.stderr
+++ b/src/test/ui/methods/method-missing-call.stderr
@@ -1,8 +1,8 @@
 error[E0615]: attempted to take value of method `get_x` on type `Point`
   --> $DIR/method-missing-call.rs:22:26
    |
-LL | ...             .get_x;
-   |                  ^^^^^ help: use parentheses to call the method: `get_x()`
+LL |                         .get_x;
+   |                          ^^^^^ help: use parentheses to call the method: `get_x()`
 
 error[E0615]: attempted to take value of method `filter_map` on type `std::iter::Filter<std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@$DIR/method-missing-call.rs:27:20: 27:25]>, [closure@$DIR/method-missing-call.rs:28:23: 28:35]>`
   --> $DIR/method-missing-call.rs:29:16
diff --git a/src/test/ui/regions/regions-name-undeclared.stderr b/src/test/ui/regions/regions-name-undeclared.stderr
index fe0345c3a380c..5f6a48a35f368 100644
--- a/src/test/ui/regions/regions-name-undeclared.stderr
+++ b/src/test/ui/regions/regions-name-undeclared.stderr
@@ -49,14 +49,14 @@ LL | fn fn_types(a: &'a isize,
 error[E0261]: use of undeclared lifetime name `'b`
   --> $DIR/regions-name-undeclared.rs:42:36
    |
-LL | ...             &'b isize,
-   |                  ^^ undeclared lifetime
+LL | ...                   &'b isize,
+   |                        ^^ undeclared lifetime
 
 error[E0261]: use of undeclared lifetime name `'b`
   --> $DIR/regions-name-undeclared.rs:45:36
    |
-LL | ...             &'b isize)>,
-   |                  ^^ undeclared lifetime
+LL | ...                   &'b isize)>,
+   |                        ^^ undeclared lifetime
 
 error[E0261]: use of undeclared lifetime name `'a`
   --> $DIR/regions-name-undeclared.rs:46:17
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming-2.rs b/src/test/ui/terminal-width/non-whitespace-trimming-2.rs
new file mode 100644
index 0000000000000..31e979702ffd4
--- /dev/null
+++ b/src/test/ui/terminal-width/non-whitespace-trimming-2.rs
@@ -0,0 +1,6 @@
+// ignore-tidy-length 
+
+fn main() {
+    let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();
+//~^ ERROR mismatched types
+}
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming-2.stderr b/src/test/ui/terminal-width/non-whitespace-trimming-2.stderr
new file mode 100644
index 0000000000000..3821d86e23a84
--- /dev/null
+++ b/src/test/ui/terminal-width/non-whitespace-trimming-2.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/non-whitespace-trimming-2.rs:4:241
+   |
+LL | ... = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();...
+   |       ^^ expected (), found integer
+   |
+   = note: expected type `()`
+              found type `{integer}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming.rs b/src/test/ui/terminal-width/non-whitespace-trimming.rs
new file mode 100644
index 0000000000000..791e8a592d1ab
--- /dev/null
+++ b/src/test/ui/terminal-width/non-whitespace-trimming.rs
@@ -0,0 +1,6 @@
+// ignore-tidy-length 
+
+fn main() {
+    let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();
+//~^ ERROR mismatched types
+}
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming.stderr b/src/test/ui/terminal-width/non-whitespace-trimming.stderr
new file mode 100644
index 0000000000000..36e6d8045a8b6
--- /dev/null
+++ b/src/test/ui/terminal-width/non-whitespace-trimming.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/non-whitespace-trimming.rs:4:241
+   |
+LL | ... = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();
+   |       ^^ expected (), found integer
+   |
+   = note: expected type `()`
+              found type `{integer}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/terminal-width/whitespace-trimming-2.rs b/src/test/ui/terminal-width/whitespace-trimming-2.rs
new file mode 100644
index 0000000000000..bc02c685dc950
--- /dev/null
+++ b/src/test/ui/terminal-width/whitespace-trimming-2.rs
@@ -0,0 +1,8 @@
+// ignore-tidy-length 
+
+fn foo() -> usize {
+                                                                                                                                                                                          ()
+//~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/terminal-width/whitespace-trimming-2.stderr b/src/test/ui/terminal-width/whitespace-trimming-2.stderr
new file mode 100644
index 0000000000000..38df5a9e9a01f
--- /dev/null
+++ b/src/test/ui/terminal-width/whitespace-trimming-2.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/whitespace-trimming-2.rs:4:187
+   |
+LL | ...-> usize {
+   |       ----- expected `usize` because of return type
+LL | ...                                                                                                                                                                                 ()
+   |                                                                                                                                                                                     ^^ expected usize, found ()
+   |
+   = note: expected type `usize`
+              found type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/terminal-width/whitespace-trimming.rs b/src/test/ui/terminal-width/whitespace-trimming.rs
new file mode 100644
index 0000000000000..427ed1e72e48a
--- /dev/null
+++ b/src/test/ui/terminal-width/whitespace-trimming.rs
@@ -0,0 +1,6 @@
+// ignore-tidy-length 
+
+fn main() {
+                                                                                                                                                                                    let _: () = 42;
+//~^ ERROR mismatched types
+}
diff --git a/src/test/ui/terminal-width/whitespace-trimming.stderr b/src/test/ui/terminal-width/whitespace-trimming.stderr
new file mode 100644
index 0000000000000..45a804b9f6a46
--- /dev/null
+++ b/src/test/ui/terminal-width/whitespace-trimming.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/whitespace-trimming.rs:4:193
+   |
+LL | ...                   let _: () = 42;
+   |                                   ^^ expected (), found integer
+   |
+   = note: expected type `()`
+              found type `{integer}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index de54eb8f57312..92f60b2ddab73 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -159,6 +159,7 @@ const WHITELIST: &[Crate<'_>] = &[
     Crate("termcolor"),
     Crate("terminon"),
     Crate("termion"),
+    Crate("term_size"),
     Crate("thread_local"),
     Crate("ucd-util"),
     Crate("unicode-width"),

From 45a6be545891f4a8f19f0dce801b67fdccf435ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 14 Aug 2019 11:44:56 -0700
Subject: [PATCH 097/943] Fix tidy

---
 src/librustc_errors/emitter.rs                | 21 +++++++++----------
 .../non-whitespace-trimming-2.rs              |  2 +-
 .../terminal-width/non-whitespace-trimming.rs |  2 +-
 .../terminal-width/whitespace-trimming-2.rs   |  2 +-
 .../ui/terminal-width/whitespace-trimming.rs  |  2 +-
 5 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 6bb151d19b32b..a78a4365633f7 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -367,7 +367,8 @@ impl EmitterWriter {
             &source_string[margin.left(line_len)..margin.right(line_len)],
             Style::Quotation,
         );
-        if margin.was_cut_left() { // We have stripped some code/whitespace from the beginning, make it clear.
+        if margin.was_cut_left() {
+            // We have stripped some code/whitespace from the beginning, make it clear.
             buffer.puts(line_offset, code_offset, "...", Style::LineNumber);
         }
         if margin.was_cut_right(line_len) {
@@ -403,7 +404,7 @@ impl EmitterWriter {
         //   ^^ ^ ^^^ ^^^^ ^^^ we don't care about code too far to the right of a span, we trim it
         //   |  | |   |
         //   |  | |   actual code found in your source code and the spans we use to mark it
-        //   |  | when there's too much wasted space to the left, we trim it to focus where it matters
+        //   |  | when there's too much wasted space to the left, trim it
         //   |  vertical divider between the column number and the code
         //   column number
 
@@ -1251,18 +1252,16 @@ impl EmitterWriter {
                 let mut label_right_margin = 0;
                 let mut max_line_len = 0;
                 for line in &annotated_file.lines {
-                    max_line_len = max(
-                        max_line_len,
-                        annotated_file.file.get_line(line.line_index - 1).map(|s| s.len()).unwrap_or(0),
-                    );
+                    max_line_len = max(max_line_len, annotated_file.file
+                        .get_line(line.line_index - 1)
+                        .map(|s| s.len())
+                        .unwrap_or(0));
                     for ann in &line.annotations {
                         span_right_margin = max(span_right_margin, ann.start_col);
                         span_right_margin = max(span_right_margin, ann.end_col);
-                        label_right_margin = max(
-                            label_right_margin,
-                            // TODO: account for labels not in the same line
-                            ann.end_col + ann.label.as_ref().map(|l| l.len() + 1).unwrap_or(0),
-                        );
+                        // FIXME: account for labels not in the same line
+                        let label_right = ann.label.as_ref().map(|l| l.len() + 1).unwrap_or(0);
+                        label_right_margin = max(label_right_margin, ann.end_col + label_right);
                     }
                 }
 
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming-2.rs b/src/test/ui/terminal-width/non-whitespace-trimming-2.rs
index 31e979702ffd4..b1ef6b95f25ce 100644
--- a/src/test/ui/terminal-width/non-whitespace-trimming-2.rs
+++ b/src/test/ui/terminal-width/non-whitespace-trimming-2.rs
@@ -1,4 +1,4 @@
-// ignore-tidy-length 
+// ignore-tidy-linelength
 
 fn main() {
     let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming.rs b/src/test/ui/terminal-width/non-whitespace-trimming.rs
index 791e8a592d1ab..f6c8d345c652e 100644
--- a/src/test/ui/terminal-width/non-whitespace-trimming.rs
+++ b/src/test/ui/terminal-width/non-whitespace-trimming.rs
@@ -1,4 +1,4 @@
-// ignore-tidy-length 
+// ignore-tidy-linelength
 
 fn main() {
     let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();
diff --git a/src/test/ui/terminal-width/whitespace-trimming-2.rs b/src/test/ui/terminal-width/whitespace-trimming-2.rs
index bc02c685dc950..c68f678aab349 100644
--- a/src/test/ui/terminal-width/whitespace-trimming-2.rs
+++ b/src/test/ui/terminal-width/whitespace-trimming-2.rs
@@ -1,4 +1,4 @@
-// ignore-tidy-length 
+// ignore-tidy-linelength
 
 fn foo() -> usize {
                                                                                                                                                                                           ()
diff --git a/src/test/ui/terminal-width/whitespace-trimming.rs b/src/test/ui/terminal-width/whitespace-trimming.rs
index 427ed1e72e48a..f747bcf17e0b4 100644
--- a/src/test/ui/terminal-width/whitespace-trimming.rs
+++ b/src/test/ui/terminal-width/whitespace-trimming.rs
@@ -1,4 +1,4 @@
-// ignore-tidy-length 
+// ignore-tidy-linelength
 
 fn main() {
                                                                                                                                                                                     let _: () = 42;

From de2e9fe2c476021c7589d840a3b3ae870e0a75d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 14 Aug 2019 14:09:37 -0700
Subject: [PATCH 098/943] Center trim on the span labels and handle unicode

---
 src/librustc_errors/emitter.rs                | 57 ++++++++++++-------
 .../non-whitespace-trimming-2.rs              |  2 +-
 .../non-whitespace-trimming-2.stderr          |  6 +-
 .../non-whitespace-trimming.stderr            |  4 +-
 4 files changed, 41 insertions(+), 28 deletions(-)

diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index a78a4365633f7..d20e700b355a1 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -143,11 +143,13 @@ impl Margin {
                 self.computed_right = self.computed_left + self.column_width;
             } else if self.label_right - self.span_left <= self.column_width {
                 // Attempt to fit the code window considering only the spans and labels.
-                self.computed_left = self.span_left;
+                let padding_left = (self.column_width - (self.label_right - self.span_left)) / 2;
+                self.computed_left = self.span_left - padding_left;
                 self.computed_right = self.computed_left + self.column_width;
             } else if self.span_right - self.span_left <= self.column_width {
                 // Attempt to fit the code window considering the spans and labels plus padding.
-                self.computed_left = self.span_left;
+                let padding_left = (self.column_width - (self.span_right - self.span_left)) / 2;
+                self.computed_left = self.span_left - padding_left;
                 self.computed_right = self.computed_left + self.column_width;
             } else { // Mostly give up but still don't show the full line.
                 self.computed_left = self.span_left;
@@ -360,13 +362,11 @@ impl EmitterWriter {
     ) {
         let line_len = source_string.len();
         // Create the source line we will highlight.
-        buffer.puts(
-            line_offset,
-            code_offset,
-            // On long lines, we strip the source line
-            &source_string[margin.left(line_len)..margin.right(line_len)],
-            Style::Quotation,
-        );
+        let left = margin.left(line_len);
+        let right = margin.right(line_len);
+        // On long lines, we strip the source line, accounting for unicode.
+        let code: String = source_string.chars().skip(left).take(right - left).collect();
+        buffer.puts(line_offset, code_offset, &code, Style::Quotation);
         if margin.was_cut_left() {
             // We have stripped some code/whitespace from the beginning, make it clear.
             buffer.puts(line_offset, code_offset, "...", Style::LineNumber);
@@ -419,6 +419,8 @@ impl EmitterWriter {
 
         let line_offset = buffer.num_lines();
 
+        let left = margin.left(source_string.len()); // Left trim
+
         self.draw_line(
             buffer,
             &source_string,
@@ -680,15 +682,15 @@ impl EmitterWriter {
                         '_',
                         line_offset + pos,
                         width_offset + depth,
-                        code_offset + annotation.start_col - margin.computed_left,
+                        code_offset + annotation.start_col - left,
                         style,
                     );
                 }
                 _ if self.teach => {
                     buffer.set_style_range(
                         line_offset,
-                        code_offset + annotation.start_col - margin.computed_left,
-                        code_offset + annotation.end_col - margin.computed_left,
+                        code_offset + annotation.start_col - left,
+                        code_offset + annotation.end_col - left,
                         style,
                         annotation.is_primary,
                     );
@@ -763,15 +765,20 @@ impl EmitterWriter {
                 Style::LabelSecondary
             };
             let (pos, col) = if pos == 0 {
-                (pos + 1, annotation.end_col + 1 - margin.computed_left)
+                (pos + 1, if annotation.end_col + 1 > left {
+                    annotation.end_col + 1 - left
+                } else {
+                    0
+                })
             } else {
-                (pos + 2, annotation.start_col - margin.computed_left)
+                (pos + 2, if annotation.start_col > left {
+                    annotation.start_col - left
+                } else {
+                    0
+                })
             };
             if let Some(ref label) = annotation.label {
-                buffer.puts(line_offset + pos,
-                            code_offset + col,
-                            &label,
-                            style);
+                buffer.puts(line_offset + pos, code_offset + col, &label, style);
             }
         }
 
@@ -806,10 +813,16 @@ impl EmitterWriter {
                 ('-', Style::UnderlineSecondary)
             };
             for p in annotation.start_col..annotation.end_col {
-                buffer.putc(line_offset + 1,
-                            code_offset + p - margin.computed_left,
-                            underline,
-                            style);
+                buffer.putc(
+                    line_offset + 1,
+                    if code_offset + p > left {
+                        code_offset + p - left
+                    } else {
+                        0
+                    },
+                    underline,
+                    style,
+                );
             }
         }
         annotations_position.iter().filter_map(|&(_, annotation)| {
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming-2.rs b/src/test/ui/terminal-width/non-whitespace-trimming-2.rs
index b1ef6b95f25ce..abd9e189a7537 100644
--- a/src/test/ui/terminal-width/non-whitespace-trimming-2.rs
+++ b/src/test/ui/terminal-width/non-whitespace-trimming-2.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-linelength
 
 fn main() {
-    let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();
+    let _: usize = 0; let _: usize = 1; let _: usize = 2; let _: usize = 3; let _: usize = 4; let _: usize = 5; let _: usize = 6; let _: usize = 7; let _: usize = 8; let _: usize = 9; let _: usize = 10; let _: usize = 11; let _: usize = 12; let _: usize = 13; let _: usize = 14; let _: usize = 15; let _: () = 42; let _: usize = 0; let _: usize = 1; let _: usize = 2; let _: usize = 3; let _: usize = 4; let _: usize = 5; let _: usize = 6; let _: usize = 7; let _: usize = 8; let _: usize = 9; let _: usize = 10; let _: usize = 11; let _: usize = 12; let _: usize = 13; let _: usize = 14; let _: usize = 15;
 //~^ ERROR mismatched types
 }
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming-2.stderr b/src/test/ui/terminal-width/non-whitespace-trimming-2.stderr
index 3821d86e23a84..bf1699f5cabbb 100644
--- a/src/test/ui/terminal-width/non-whitespace-trimming-2.stderr
+++ b/src/test/ui/terminal-width/non-whitespace-trimming-2.stderr
@@ -1,8 +1,8 @@
 error[E0308]: mismatched types
-  --> $DIR/non-whitespace-trimming-2.rs:4:241
+  --> $DIR/non-whitespace-trimming-2.rs:4:311
    |
-LL | ... = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();...
-   |       ^^ expected (), found integer
+LL | ...; let _: usize = 14; let _: usize = 15; let _: () = 42; let _: usize = 0; let _: usize = 1; let _: usize = 2; let _: usize = 3; let _:...
+   |                                                        ^^ expected (), found integer
    |
    = note: expected type `()`
               found type `{integer}`
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming.stderr b/src/test/ui/terminal-width/non-whitespace-trimming.stderr
index 36e6d8045a8b6..622713eb5f6fc 100644
--- a/src/test/ui/terminal-width/non-whitespace-trimming.stderr
+++ b/src/test/ui/terminal-width/non-whitespace-trimming.stderr
@@ -1,8 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/non-whitespace-trimming.rs:4:241
    |
-LL | ... = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ();
-   |       ^^ expected (), found integer
+LL | ...) = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = ()...
+   |                                                        ^^ expected (), found integer
    |
    = note: expected type `()`
               found type `{integer}`

From 9980796d6d29f532e9a49a5b3767285e2a5e2d02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 14 Aug 2019 17:06:09 -0700
Subject: [PATCH 099/943] Further unicode checks

---
 src/librustc_errors/emitter.rs                | 30 ++++++++++++-------
 .../non-whitespace-trimming-unicode.rs        |  6 ++++
 .../non-whitespace-trimming-unicode.stderr    | 12 ++++++++
 3 files changed, 38 insertions(+), 10 deletions(-)
 create mode 100644 src/test/ui/terminal-width/non-whitespace-trimming-unicode.rs
 create mode 100644 src/test/ui/terminal-width/non-whitespace-trimming-unicode.stderr

diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index d20e700b355a1..83c55c0da2b4f 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -148,7 +148,7 @@ impl Margin {
                 self.computed_right = self.computed_left + self.column_width;
             } else if self.span_right - self.span_left <= self.column_width {
                 // Attempt to fit the code window considering the spans and labels plus padding.
-                let padding_left = (self.column_width - (self.span_right - self.span_left)) / 2;
+                let padding_left = (self.column_width - (self.span_right - self.span_left)) / 5 * 2;
                 self.computed_left = self.span_left - padding_left;
                 self.computed_right = self.computed_left + self.column_width;
             } else { // Mostly give up but still don't show the full line.
@@ -365,7 +365,18 @@ impl EmitterWriter {
         let left = margin.left(line_len);
         let right = margin.right(line_len);
         // On long lines, we strip the source line, accounting for unicode.
-        let code: String = source_string.chars().skip(left).take(right - left).collect();
+        let mut taken = 0;
+        let code: String = source_string.chars().skip(left).take_while(|ch| {
+            // Make sure that the trimming on the right will fall within the terminal width.
+            // FIXME: `unicode_width` sometimes disagrees with terminals on how wide a `char` is.
+            // For now, just accept that sometimes the code line will be longer than desired.
+            let next = unicode_width::UnicodeWidthChar::width(*ch).unwrap_or(1);
+            if taken + next > right - left {
+                return false;
+            }
+            taken += next;
+            true
+        }).collect();
         buffer.puts(line_offset, code_offset, &code, Style::Quotation);
         if margin.was_cut_left() {
             // We have stripped some code/whitespace from the beginning, make it clear.
@@ -373,12 +384,7 @@ impl EmitterWriter {
         }
         if margin.was_cut_right(line_len) {
             // We have stripped some code after the right-most span end, make it clear we did so.
-            buffer.puts(
-                line_offset,
-                margin.right(line_len) - margin.left(line_len) + code_offset - 3,
-                "...",
-                Style::LineNumber,
-            );
+            buffer.puts(line_offset, code_offset + taken - 3, "...", Style::LineNumber);
         }
         buffer.puts(line_offset, 0, &self.maybe_anonymized(line_index), Style::LineNumber);
 
@@ -420,6 +426,10 @@ impl EmitterWriter {
         let line_offset = buffer.num_lines();
 
         let left = margin.left(source_string.len()); // Left trim
+        // Account for unicode characters of width !=0 that were removed.
+        let left = source_string.chars().take(left).fold(0, |acc, ch| {
+            acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1)
+        });
 
         self.draw_line(
             buffer,
@@ -1465,7 +1475,7 @@ impl EmitterWriter {
                         // ...or trailing spaces. Account for substitutions containing unicode
                         // characters.
                         let sub_len = part.snippet.trim().chars().fold(0, |acc, ch| {
-                            acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0)
+                            acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1)
                         });
 
                         let underline_start = (span_start_pos + start) as isize + offset;
@@ -1488,7 +1498,7 @@ impl EmitterWriter {
 
                         // length of the code after substitution
                         let full_sub_len = part.snippet.chars().fold(0, |acc, ch| {
-                            acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(0) as isize
+                            acc + unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1) as isize
                         });
 
                         // length of the code to be substituted
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming-unicode.rs b/src/test/ui/terminal-width/non-whitespace-trimming-unicode.rs
new file mode 100644
index 0000000000000..8d4d1b1627940
--- /dev/null
+++ b/src/test/ui/terminal-width/non-whitespace-trimming-unicode.rs
@@ -0,0 +1,6 @@
+// ignore-tidy-linelength
+
+fn main() {
+    let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓  ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀🦀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42;  let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓  ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4🦀🦀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆♇♏♔♕♖♗♘♙♚♛♜♝♞♟♠♡♢♣♤♥♦♧♨♩♪♫♬♭♮♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4";
+//~^ ERROR mismatched types
+}
diff --git a/src/test/ui/terminal-width/non-whitespace-trimming-unicode.stderr b/src/test/ui/terminal-width/non-whitespace-trimming-unicode.stderr
new file mode 100644
index 0000000000000..b56b1948d9e07
--- /dev/null
+++ b/src/test/ui/terminal-width/non-whitespace-trimming-unicode.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/non-whitespace-trimming-unicode.rs:4:415
+   |
+LL | ...♯♰♱♲♳♴♵♶♷♸♹♺♻♼♽♾♿⚀⚁⚂⚃⚄⚅⚆⚈⚉4"; let _: () = 42;  let _: &str = "🦀☀☁☂☃☄★☆☇☈☉☊☋☌☍☎☏☐☑☒☓  ☖☗☘☙☚☛☜☝☞☟☠☡☢☣☤☥☦☧☨☩☪☫☬☭☮☯☰☱☲☳☴☵☶☷☸☹☺☻☼☽☾☿♀♁♂♃♄♅♆...
+   |                                               ^^ expected (), found integer
+   |
+   = note: expected type `()`
+              found type `{integer}`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.

From 21f2e9334567b64436f4e6525c5c98adafd16ca2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 14 Aug 2019 17:57:28 -0700
Subject: [PATCH 100/943] Add terminal_width debugging flag

---
 src/librustc/session/config.rs     |  2 ++
 src/librustc/session/mod.rs        |  6 ++++--
 src/librustc_driver/lib.rs         | 12 +++++++-----
 src/librustc_errors/emitter.rs     | 24 +++++++++++++++++-------
 src/librustc_errors/lib.rs         |  2 +-
 src/librustdoc/core.rs             |  1 +
 src/librustdoc/test.rs             |  2 +-
 src/libsyntax/json.rs              |  2 +-
 src/libsyntax/parse/lexer/tests.rs |  9 ++++++++-
 src/libsyntax/tests.rs             | 13 ++++++++-----
 10 files changed, 50 insertions(+), 23 deletions(-)

diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 8e3b910e0da3a..89481e9eafde5 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1292,6 +1292,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
         "show macro backtraces even for non-local macros"),
     teach: bool = (false, parse_bool, [TRACKED],
         "show extended diagnostic help"),
+    terminal_width: Option<usize> = (None, parse_opt_uint, [UNTRACKED],
+        "set the current terminal width"),
     continue_parse_after_error: bool = (false, parse_bool, [TRACKED],
         "attempt to recover from parse errors (experimental)"),
     dep_tasks: bool = (false, parse_bool, [UNTRACKED],
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 61dac678912df..f01883d9634cd 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -1055,6 +1055,7 @@ fn default_emitter(
                         Some(source_map.clone()),
                         short,
                         sopts.debugging_opts.teach,
+                        sopts.debugging_opts.terminal_width,
                     ),
                     Some(dst) => EmitterWriter::new(
                         dst,
@@ -1062,6 +1063,7 @@ fn default_emitter(
                         short,
                         false, // no teach messages when writing to a buffer
                         false, // no colors when writing to a buffer
+                        None,  // no terminal width
                     ),
                 };
                 Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing))
@@ -1375,7 +1377,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
     let emitter: Box<dyn Emitter + sync::Send> = match output {
         config::ErrorOutputType::HumanReadable(kind) => {
             let (short, color_config) = kind.unzip();
-            Box::new(EmitterWriter::stderr(color_config, None, short, false))
+            Box::new(EmitterWriter::stderr(color_config, None, short, false, None))
         }
         config::ErrorOutputType::Json { pretty, json_rendered } =>
             Box::new(JsonEmitter::basic(pretty, json_rendered)),
@@ -1389,7 +1391,7 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
     let emitter: Box<dyn Emitter + sync::Send> = match output {
         config::ErrorOutputType::HumanReadable(kind) => {
             let (short, color_config) = kind.unzip();
-            Box::new(EmitterWriter::stderr(color_config, None, short, false))
+            Box::new(EmitterWriter::stderr(color_config, None, short, false, None))
         }
         config::ErrorOutputType::Json { pretty, json_rendered } =>
             Box::new(JsonEmitter::basic(pretty, json_rendered)),
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index b19ea513b7575..3d94d51f17ec0 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -1135,11 +1135,13 @@ pub fn report_ices_to_stderr_if_any<F: FnOnce() -> R, R>(f: F) -> Result<R, Erro
             // Thread panicked without emitting a fatal diagnostic
             eprintln!("");
 
-            let emitter =
-                Box::new(errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto,
-                                                                None,
-                                                                false,
-                                                                false));
+            let emitter = Box::new(errors::emitter::EmitterWriter::stderr(
+                errors::ColorConfig::Auto,
+                None,
+                false,
+                false,
+                None,
+            ));
             let handler = errors::Handler::with_emitter(true, None, emitter);
 
             // a .span_bug or .bug call has already printed what
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 83c55c0da2b4f..77d373e7a8ca8 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -51,9 +51,11 @@ impl HumanReadableErrorType {
         dst: Box<dyn Write + Send>,
         source_map: Option<Lrc<SourceMapperDyn>>,
         teach: bool,
+        terminal_width: Option<usize>,
     ) -> EmitterWriter {
         let (short, color_config) = self.unzip();
-        EmitterWriter::new(dst, source_map, short, teach, color_config.suggests_using_colors())
+        let color = color_config.suggests_using_colors();
+        EmitterWriter::new(dst, source_map, short, teach, color, terminal_width)
     }
 }
 
@@ -296,6 +298,7 @@ pub struct EmitterWriter {
     short_message: bool,
     teach: bool,
     ui_testing: bool,
+    terminal_width: Option<usize>,
 }
 
 #[derive(Debug)]
@@ -306,11 +309,13 @@ pub struct FileWithAnnotatedLines {
 }
 
 impl EmitterWriter {
-    pub fn stderr(color_config: ColorConfig,
-                  source_map: Option<Lrc<SourceMapperDyn>>,
-                  short_message: bool,
-                  teach: bool)
-                  -> EmitterWriter {
+    pub fn stderr(
+        color_config: ColorConfig,
+        source_map: Option<Lrc<SourceMapperDyn>>,
+        short_message: bool,
+        teach: bool,
+        terminal_width: Option<usize>,
+    ) -> EmitterWriter {
         let dst = Destination::from_stderr(color_config);
         EmitterWriter {
             dst,
@@ -318,6 +323,7 @@ impl EmitterWriter {
             short_message,
             teach,
             ui_testing: false,
+            terminal_width,
         }
     }
 
@@ -327,6 +333,7 @@ impl EmitterWriter {
         short_message: bool,
         teach: bool,
         colored: bool,
+        terminal_width: Option<usize>,
     ) -> EmitterWriter {
         EmitterWriter {
             dst: Raw(dst, colored),
@@ -334,6 +341,7 @@ impl EmitterWriter {
             short_message,
             teach,
             ui_testing: false,
+            terminal_width,
         }
     }
 
@@ -1295,7 +1303,9 @@ impl EmitterWriter {
                     width_offset + annotated_file.multiline_depth + 1
                 };
 
-                let column_width = if self.ui_testing {
+                let column_width = if let Some(width) = self.terminal_width {
+                    width
+                } else if self.ui_testing {
                     140
                 } else {
                     term_size::dimensions().map(|(w, _)| w - code_offset).unwrap_or(140)
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 4018a667bf264..6585633e00af8 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -383,7 +383,7 @@ impl Handler {
                                       cm: Option<Lrc<SourceMapperDyn>>,
                                       flags: HandlerFlags)
                                       -> Handler {
-        let emitter = Box::new(EmitterWriter::stderr(color_config, cm, false, false));
+        let emitter = Box::new(EmitterWriter::stderr(color_config, cm, false, false, None));
         Handler::with_emitter_and_flags(emitter, flags)
     }
 
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 87381f224d0bb..98362464771e0 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -193,6 +193,7 @@ pub fn new_handler(error_format: ErrorOutputType,
                     source_map.map(|cm| cm as _),
                     short,
                     sessopts.debugging_opts.teach,
+                    sessopts.debugging_opts.terminal_width,
                 ).ui_testing(ui_testing)
             )
         },
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 83a8d3fc10999..8db0eb15929dc 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -427,7 +427,7 @@ pub fn make_test(s: &str,
         // Any errors in parsing should also appear when the doctest is compiled for real, so just
         // send all the errors that libsyntax emits directly into a `Sink` instead of stderr.
         let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let emitter = EmitterWriter::new(box io::sink(), None, false, false, false);
+        let emitter = EmitterWriter::new(box io::sink(), None, false, false, false, None);
         // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
         let handler = Handler::with_emitter(false, None, box emitter);
         let sess = ParseSess::with_span_handler(handler, cm);
diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs
index 83c9c692bd30c..ada46f7bc5a74 100644
--- a/src/libsyntax/json.rs
+++ b/src/libsyntax/json.rs
@@ -219,7 +219,7 @@ impl Diagnostic {
         }
         let buf = BufWriter::default();
         let output = buf.clone();
-        je.json_rendered.new_emitter(Box::new(buf), Some(je.sm.clone()), false)
+        je.json_rendered.new_emitter(Box::new(buf), Some(je.sm.clone()), false, None)
             .ui_testing(je.ui_testing).emit_diagnostic(db);
         let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap();
         let output = String::from_utf8(output).unwrap();
diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs
index a915aa42fd15a..963ad2c0b8f11 100644
--- a/src/libsyntax/parse/lexer/tests.rs
+++ b/src/libsyntax/parse/lexer/tests.rs
@@ -10,7 +10,14 @@ use errors::{Handler, emitter::EmitterWriter};
 use syntax_pos::{BytePos, Span};
 
 fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess {
-    let emitter = EmitterWriter::new(Box::new(io::sink()), Some(sm.clone()), false, false, false);
+    let emitter = errors::emitter::EmitterWriter::new(
+        Box::new(io::sink()),
+        Some(sm.clone()),
+        false,
+        false,
+        false,
+        None,
+    );
     ParseSess::with_span_handler(Handler::with_emitter(true, None, Box::new(emitter)), sm)
 }
 
diff --git a/src/libsyntax/tests.rs b/src/libsyntax/tests.rs
index 4c0e1e3704dff..c472212bc2096 100644
--- a/src/libsyntax/tests.rs
+++ b/src/libsyntax/tests.rs
@@ -144,11 +144,14 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &
             println!("text: {:?}", source_map.span_to_snippet(span));
         }
 
-        let emitter = EmitterWriter::new(Box::new(Shared { data: output.clone() }),
-                                        Some(source_map.clone()),
-                                        false,
-                                        false,
-                                        false);
+        let emitter = EmitterWriter::new(
+            Box::new(Shared { data: output.clone() }),
+            Some(source_map.clone()),
+            false,
+            false,
+            false,
+            None,
+        );
         let handler = Handler::with_emitter(true, None, Box::new(emitter));
         handler.span_err(msp, "foo");
 

From cc2272fe879f662bc2623fe6d96b358ed011e382 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 21 Aug 2019 12:00:36 -0700
Subject: [PATCH 101/943] Formatting

---
 src/libsyntax/parse/lexer/tests.rs | 69 +++++++++++++++++++-----------
 1 file changed, 45 insertions(+), 24 deletions(-)

diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs
index 963ad2c0b8f11..6faaa01321db5 100644
--- a/src/libsyntax/parse/lexer/tests.rs
+++ b/src/libsyntax/parse/lexer/tests.rs
@@ -35,10 +35,11 @@ fn t1() {
     with_default_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
-        let mut string_reader = setup(&sm,
-                                    &sh,
-                                    "/* my source file */ fn main() { println!(\"zebra\"); }\n"
-                                        .to_string());
+        let mut string_reader = setup(
+            &sm,
+            &sh,
+            "/* my source file */ fn main() { println!(\"zebra\"); }\n".to_string(),
+        );
         assert_eq!(string_reader.next_token(), token::Comment);
         assert_eq!(string_reader.next_token(), token::Whitespace);
         let tok1 = string_reader.next_token();
@@ -134,8 +135,10 @@ fn character_a() {
     with_default_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
-        assert_eq!(setup(&sm, &sh, "'a'".to_string()).next_token(),
-                    mk_lit(token::Char, "a", None));
+        assert_eq!(
+            setup(&sm, &sh, "'a'".to_string()).next_token(),
+            mk_lit(token::Char, "a", None),
+        );
     })
 }
 
@@ -144,8 +147,10 @@ fn character_space() {
     with_default_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
-        assert_eq!(setup(&sm, &sh, "' '".to_string()).next_token(),
-                    mk_lit(token::Char, " ", None));
+        assert_eq!(
+            setup(&sm, &sh, "' '".to_string()).next_token(),
+            mk_lit(token::Char, " ", None),
+        );
     })
 }
 
@@ -154,8 +159,10 @@ fn character_escaped() {
     with_default_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
-        assert_eq!(setup(&sm, &sh, "'\\n'".to_string()).next_token(),
-                    mk_lit(token::Char, "\\n", None));
+        assert_eq!(
+            setup(&sm, &sh, "'\\n'".to_string()).next_token(),
+            mk_lit(token::Char, "\\n", None),
+        );
     })
 }
 
@@ -164,8 +171,10 @@ fn lifetime_name() {
     with_default_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
-        assert_eq!(setup(&sm, &sh, "'abc".to_string()).next_token(),
-                    token::Lifetime(Symbol::intern("'abc")));
+        assert_eq!(
+            setup(&sm, &sh, "'abc".to_string()).next_token(),
+            token::Lifetime(Symbol::intern("'abc")),
+        );
     })
 }
 
@@ -174,8 +183,10 @@ fn raw_string() {
     with_default_globals(|| {
         let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let sh = mk_sess(sm.clone());
-        assert_eq!(setup(&sm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string()).next_token(),
-                    mk_lit(token::StrRaw(3), "\"#a\\b\x00c\"", None));
+        assert_eq!(
+            setup(&sm, &sh, "r###\"\"#a\\b\x00c\"\"###".to_string()).next_token(),
+            mk_lit(token::StrRaw(3), "\"#a\\b\x00c\"", None),
+        );
     })
 }
 
@@ -186,11 +197,15 @@ fn literal_suffixes() {
         let sh = mk_sess(sm.clone());
         macro_rules! test {
             ($input: expr, $tok_type: ident, $tok_contents: expr) => {{
-                assert_eq!(setup(&sm, &sh, format!("{}suffix", $input)).next_token(),
-                            mk_lit(token::$tok_type, $tok_contents, Some("suffix")));
+                assert_eq!(
+                    setup(&sm, &sh, format!("{}suffix", $input)).next_token(),
+                    mk_lit(token::$tok_type, $tok_contents, Some("suffix")),
+                );
                 // with a whitespace separator:
-                assert_eq!(setup(&sm, &sh, format!("{} suffix", $input)).next_token(),
-                            mk_lit(token::$tok_type, $tok_contents, None));
+                assert_eq!(
+                    setup(&sm, &sh, format!("{} suffix", $input)).next_token(),
+                    mk_lit(token::$tok_type, $tok_contents, None),
+                );
             }}
         }
 
@@ -204,12 +219,18 @@ fn literal_suffixes() {
         test!("1.0", Float, "1.0");
         test!("1.0e10", Float, "1.0e10");
 
-        assert_eq!(setup(&sm, &sh, "2us".to_string()).next_token(),
-                    mk_lit(token::Integer, "2", Some("us")));
-        assert_eq!(setup(&sm, &sh, "r###\"raw\"###suffix".to_string()).next_token(),
-                    mk_lit(token::StrRaw(3), "raw", Some("suffix")));
-        assert_eq!(setup(&sm, &sh, "br###\"raw\"###suffix".to_string()).next_token(),
-                    mk_lit(token::ByteStrRaw(3), "raw", Some("suffix")));
+        assert_eq!(
+            setup(&sm, &sh, "2us".to_string()).next_token(),
+            mk_lit(token::Integer, "2", Some("us")),
+        );
+        assert_eq!(
+            setup(&sm, &sh, "r###\"raw\"###suffix".to_string()).next_token(),
+            mk_lit(token::StrRaw(3), "raw", Some("suffix")),
+        );
+        assert_eq!(
+            setup(&sm, &sh, "br###\"raw\"###suffix".to_string()).next_token(),
+            mk_lit(token::ByteStrRaw(3), "raw", Some("suffix")),
+        );
     })
 }
 

From aaf4dc35e33eea8b658b82a307b81e63e8b214f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 21 Aug 2019 14:26:52 -0700
Subject: [PATCH 102/943] fix rebase

---
 src/libsyntax/parse/lexer/tests.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs
index 6faaa01321db5..652ae95c85349 100644
--- a/src/libsyntax/parse/lexer/tests.rs
+++ b/src/libsyntax/parse/lexer/tests.rs
@@ -10,7 +10,7 @@ use errors::{Handler, emitter::EmitterWriter};
 use syntax_pos::{BytePos, Span};
 
 fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess {
-    let emitter = errors::emitter::EmitterWriter::new(
+    let emitter = EmitterWriter::new(
         Box::new(io::sink()),
         Some(sm.clone()),
         false,

From 1c829877824aeda82e78ed3a0ecb12a3cb0b2d9d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 21 Aug 2019 11:46:31 -0700
Subject: [PATCH 103/943] Fix typo in E0308 if/else label

---
 src/librustc/infer/error_reporting/mod.rs |  2 +-
 src/librustc/ty/error.rs                  | 21 ++++++++++++++++-----
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 84687b8cab5c0..9be73cf3c6d16 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1650,7 +1650,7 @@ impl<'tcx> ObligationCause<'tcx> {
                 hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types",
                 _ => "match arms have compatible types",
             },
-            IfExpression { .. } => "if and else have compatible types",
+            IfExpression { .. } => "if and else have incompatible types",
             IfExpressionWithNoElse => "if missing an else returns ()",
             MainFunctionType => "`main` function has the correct type",
             StartFunctionType => "`start` function has the correct type",
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index d6d17a67e01e9..6daecd7ae941a 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -247,13 +247,15 @@ impl<'tcx> ty::TyS<'tcx> {
 }
 
 impl<'tcx> TyCtxt<'tcx> {
-    pub fn note_and_explain_type_err(self,
-                                     db: &mut DiagnosticBuilder<'_>,
-                                     err: &TypeError<'tcx>,
-                                     sp: Span) {
+    pub fn note_and_explain_type_err(
+        self,
+        db: &mut DiagnosticBuilder<'_>,
+        err: &TypeError<'tcx>,
+        sp: Span,
+    ) {
         use self::TypeError::*;
 
-        match err.clone() {
+        match err {
             Sorts(values) => {
                 let expected_str = values.expected.sort_string(self);
                 let found_str = values.found.sort_string(self);
@@ -261,6 +263,15 @@ impl<'tcx> TyCtxt<'tcx> {
                     db.note("no two closures, even if identical, have the same type");
                     db.help("consider boxing your closure and/or using it as a trait object");
                 }
+                if expected_str == found_str && expected_str == "opaque type" { // Issue #63167
+                    db.note("distinct uses of `impl Trait` result in different opaque types");
+                    let e_str = values.expected.to_string();
+                    let f_str = values.found.to_string();
+                    if &e_str == &f_str && &e_str == "impl std::future::Future" {
+                        db.help("if both futures resolve to the same type, consider `await`ing \
+                                 on both of them");
+                    }
+                }
                 if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) =
                        (&values.found.sty, &values.expected.sty) // Issue #53280
                 {

From ba8e09415b00fdfcda8feeb1cf233f2f065ef6c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 21 Aug 2019 11:49:51 -0700
Subject: [PATCH 104/943] Add clarification on E0308 about opaque types

---
 src/librustc/ty/error.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 6daecd7ae941a..c1593799286ef 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -268,6 +268,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     let e_str = values.expected.to_string();
                     let f_str = values.found.to_string();
                     if &e_str == &f_str && &e_str == "impl std::future::Future" {
+                        // FIXME: use non-string based check.
                         db.help("if both futures resolve to the same type, consider `await`ing \
                                  on both of them");
                     }

From 8c07d7814d2eb2cab14e5c57313e68880b60a14d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 15 Aug 2019 18:58:20 -0700
Subject: [PATCH 105/943] When declaring a declarative macro in an item it's
 only accessible inside it

---
 src/librustc/hir/map/mod.rs           | 13 +++---
 src/librustc_privacy/lib.rs           | 60 +++++++++++++++------------
 src/test/ui/macros/macro-in-fn.rs     |  9 ++++
 src/test/ui/macros/macro-in-fn.stderr |  8 ++++
 4 files changed, 58 insertions(+), 32 deletions(-)
 create mode 100644 src/test/ui/macros/macro-in-fn.rs
 create mode 100644 src/test/ui/macros/macro-in-fn.stderr

diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 7292428ec378c..5bf310ce8d956 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -514,8 +514,11 @@ impl<'hir> Map<'hir> {
         &self.forest.krate.attrs
     }
 
-    pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId)
-    {
+    pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId) {
+        self.get_if_module(module).expect("not a module")
+    }
+
+    pub fn get_if_module(&self, module: DefId) -> Option<(&'hir Mod, Span, HirId)> {
         let hir_id = self.as_local_hir_id(module).unwrap();
         self.read(hir_id);
         match self.find_entry(hir_id).unwrap().node {
@@ -523,9 +526,9 @@ impl<'hir> Map<'hir> {
                 span,
                 node: ItemKind::Mod(ref m),
                 ..
-            }) => (m, span, hir_id),
-            Node::Crate => (&self.forest.krate.module, self.forest.krate.span, hir_id),
-            _ => panic!("not a module")
+            }) => Some((m, span, hir_id)),
+            Node::Crate => Some((&self.forest.krate.module, self.forest.krate.span, hir_id)),
+            _ => None,
         }
     }
 
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index bca77621e553e..dc787d2253884 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -508,39 +508,45 @@ impl EmbargoVisitor<'tcx> {
         }
     }
 
-    fn update_macro_reachable_mod(
-        &mut self,
-        reachable_mod: hir::HirId,
-        defining_mod: DefId,
-    ) {
-        let module_def_id = self.tcx.hir().local_def_id(reachable_mod);
-        let module = self.tcx.hir().get_module(module_def_id).0;
-        for item_id in &module.item_ids {
-            let hir_id = item_id.id;
-            let item_def_id = self.tcx.hir().local_def_id(hir_id);
-            if let Some(def_kind) = self.tcx.def_kind(item_def_id) {
-                let item = self.tcx.hir().expect_item(hir_id);
-                let vis = ty::Visibility::from_hir(&item.vis, hir_id, self.tcx);
-                self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
+    fn update_macro_reachable_mod(&mut self, reachable_mod: hir::HirId, defining_mod: DefId) {
+        let set_vis = |this: &mut Self, hir_id: hir::HirId| {
+            let item_def_id = this.tcx.hir().local_def_id(hir_id);
+            if let Some(def_kind) = this.tcx.def_kind(item_def_id) {
+                let item = this.tcx.hir().expect_item(hir_id);
+                let vis = ty::Visibility::from_hir(&item.vis, hir_id, this.tcx);
+                this.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
             }
-        }
+        };
 
-        if let Some(exports) = self.tcx.module_exports(module_def_id) {
-            for export in exports {
-                if export.vis.is_accessible_from(defining_mod, self.tcx) {
-                    if let Res::Def(def_kind, def_id) = export.res {
-                        let vis = def_id_visibility(self.tcx, def_id).0;
-                        if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
-                            self.update_macro_reachable_def(
-                                hir_id,
-                                def_kind,
-                                vis,
-                                defining_mod,
-                            );
+        let module_def_id = self.tcx.hir().local_def_id(reachable_mod);
+        if let Some((module, _, _)) = self.tcx.hir().get_if_module(module_def_id) {
+            for item_id in &module.item_ids {
+                let hir_id = item_id.id;
+                set_vis(self, hir_id);
+            }
+            if let Some(exports) = self.tcx.module_exports(module_def_id) {
+                for export in exports {
+                    if export.vis.is_accessible_from(defining_mod, self.tcx) {
+                        if let Res::Def(def_kind, def_id) = export.res {
+                            let vis = def_id_visibility(self.tcx, def_id).0;
+                            if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
+                                self.update_macro_reachable_def(
+                                    hir_id,
+                                    def_kind,
+                                    vis,
+                                    defining_mod,
+                                );
+                            }
                         }
                     }
                 }
             }
+        } else if let Some(hir::Node::Item(hir::Item {
+            hir_id,
+            ..
+        })) = self.tcx.hir().get_if_local(module_def_id) { // #63164
+            // `macro` defined inside of an item is only visible inside of that item's scope.
+            set_vis(self, *hir_id);
         }
     }
 
diff --git a/src/test/ui/macros/macro-in-fn.rs b/src/test/ui/macros/macro-in-fn.rs
new file mode 100644
index 0000000000000..1e46346fc01ea
--- /dev/null
+++ b/src/test/ui/macros/macro-in-fn.rs
@@ -0,0 +1,9 @@
+#![feature(decl_macro)]
+
+pub fn moo() {
+    pub macro ABC() {{}}
+}
+
+fn main() {
+    ABC!(); //~ ERROR cannot find macro `ABC!` in this scope
+}
diff --git a/src/test/ui/macros/macro-in-fn.stderr b/src/test/ui/macros/macro-in-fn.stderr
new file mode 100644
index 0000000000000..0c35fe65aa285
--- /dev/null
+++ b/src/test/ui/macros/macro-in-fn.stderr
@@ -0,0 +1,8 @@
+error: cannot find macro `ABC!` in this scope
+  --> $DIR/macro-in-fn.rs:8:5
+   |
+LL |     ABC!();
+   |     ^^^
+
+error: aborting due to previous error
+

From 4971667f175e7e3d84b7a87f46633b3e069e48ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 21 Aug 2019 16:11:01 -0700
Subject: [PATCH 106/943] review comments

---
 src/librustc/hir/map/mod.rs           | 20 ++++++----
 src/librustc_privacy/lib.rs           | 54 +++++++++++----------------
 src/test/ui/macros/macro-in-fn.rs     |  5 +--
 src/test/ui/macros/macro-in-fn.stderr |  8 ----
 4 files changed, 36 insertions(+), 51 deletions(-)
 delete mode 100644 src/test/ui/macros/macro-in-fn.stderr

diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 5bf310ce8d956..f80e527dfd9b7 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -515,10 +515,6 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId) {
-        self.get_if_module(module).expect("not a module")
-    }
-
-    pub fn get_if_module(&self, module: DefId) -> Option<(&'hir Mod, Span, HirId)> {
         let hir_id = self.as_local_hir_id(module).unwrap();
         self.read(hir_id);
         match self.find_entry(hir_id).unwrap().node {
@@ -526,9 +522,9 @@ impl<'hir> Map<'hir> {
                 span,
                 node: ItemKind::Mod(ref m),
                 ..
-            }) => Some((m, span, hir_id)),
-            Node::Crate => Some((&self.forest.krate.module, self.forest.krate.span, hir_id)),
-            _ => None,
+            }) => (m, span, hir_id),
+            Node::Crate => (&self.forest.krate.module, self.forest.krate.span, hir_id),
+            node => panic!("not a module: {:?}", node),
         }
     }
 
@@ -682,6 +678,16 @@ impl<'hir> Map<'hir> {
         }
     }
 
+    /// Wether `hir_id` corresponds to a `mod` or a crate.
+    pub fn is_hir_id_module(&self, hir_id: HirId) -> bool {
+        match self.lookup(hir_id) {
+            Some(Entry { node: Node::Item(Item { node: ItemKind::Mod(_), .. }), .. }) |
+            Some(Entry { node: Node::Crate, .. }) => true,
+            _ => false,
+        }
+    }
+
+
     /// If there is some error when walking the parents (e.g., a node does not
     /// have a parent in the map or a node can't be found), then we return the
     /// last good `HirId` we found. Note that reaching the crate root (`id == 0`),
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index dc787d2253884..146058963b69d 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -509,44 +509,28 @@ impl EmbargoVisitor<'tcx> {
     }
 
     fn update_macro_reachable_mod(&mut self, reachable_mod: hir::HirId, defining_mod: DefId) {
-        let set_vis = |this: &mut Self, hir_id: hir::HirId| {
-            let item_def_id = this.tcx.hir().local_def_id(hir_id);
-            if let Some(def_kind) = this.tcx.def_kind(item_def_id) {
-                let item = this.tcx.hir().expect_item(hir_id);
-                let vis = ty::Visibility::from_hir(&item.vis, hir_id, this.tcx);
-                this.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
-            }
-        };
-
         let module_def_id = self.tcx.hir().local_def_id(reachable_mod);
-        if let Some((module, _, _)) = self.tcx.hir().get_if_module(module_def_id) {
-            for item_id in &module.item_ids {
-                let hir_id = item_id.id;
-                set_vis(self, hir_id);
+        let module = self.tcx.hir().get_module(module_def_id).0;
+        for item_id in &module.item_ids {
+            let hir_id = item_id.id;
+            let item_def_id = self.tcx.hir().local_def_id(hir_id);
+            if let Some(def_kind) = self.tcx.def_kind(item_def_id) {
+                let item = self.tcx.hir().expect_item(hir_id);
+                let vis = ty::Visibility::from_hir(&item.vis, hir_id, self.tcx);
+                self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
             }
-            if let Some(exports) = self.tcx.module_exports(module_def_id) {
-                for export in exports {
-                    if export.vis.is_accessible_from(defining_mod, self.tcx) {
-                        if let Res::Def(def_kind, def_id) = export.res {
-                            let vis = def_id_visibility(self.tcx, def_id).0;
-                            if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
-                                self.update_macro_reachable_def(
-                                    hir_id,
-                                    def_kind,
-                                    vis,
-                                    defining_mod,
-                                );
-                            }
+        }
+        if let Some(exports) = self.tcx.module_exports(module_def_id) {
+            for export in exports {
+                if export.vis.is_accessible_from(defining_mod, self.tcx) {
+                    if let Res::Def(def_kind, def_id) = export.res {
+                        let vis = def_id_visibility(self.tcx, def_id).0;
+                        if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
+                            self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod);
                         }
                     }
                 }
             }
-        } else if let Some(hir::Node::Item(hir::Item {
-            hir_id,
-            ..
-        })) = self.tcx.hir().get_if_local(module_def_id) { // #63164
-            // `macro` defined inside of an item is only visible inside of that item's scope.
-            set_vis(self, *hir_id);
         }
     }
 
@@ -898,10 +882,14 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
             self.tcx.hir().local_def_id(md.hir_id)
         ).unwrap();
         let mut module_id = self.tcx.hir().as_local_hir_id(macro_module_def_id).unwrap();
+        if !self.tcx.hir().is_hir_id_module(module_id) {
+            // `module_id` doesn't correspond to a `mod`, return early (#63164).
+            return;
+        }
         let level = if md.vis.node.is_pub() { self.get(module_id) } else { None };
         let new_level = self.update(md.hir_id, level);
         if new_level.is_none() {
-            return
+            return;
         }
 
         loop {
diff --git a/src/test/ui/macros/macro-in-fn.rs b/src/test/ui/macros/macro-in-fn.rs
index 1e46346fc01ea..d354fe4a7dbfa 100644
--- a/src/test/ui/macros/macro-in-fn.rs
+++ b/src/test/ui/macros/macro-in-fn.rs
@@ -1,9 +1,8 @@
+// run-pass
 #![feature(decl_macro)]
 
 pub fn moo() {
     pub macro ABC() {{}}
 }
 
-fn main() {
-    ABC!(); //~ ERROR cannot find macro `ABC!` in this scope
-}
+fn main() {}
diff --git a/src/test/ui/macros/macro-in-fn.stderr b/src/test/ui/macros/macro-in-fn.stderr
deleted file mode 100644
index 0c35fe65aa285..0000000000000
--- a/src/test/ui/macros/macro-in-fn.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: cannot find macro `ABC!` in this scope
-  --> $DIR/macro-in-fn.rs:8:5
-   |
-LL |     ABC!();
-   |     ^^^
-
-error: aborting due to previous error
-

From 053afa7aec67d0bc8dc23e8217d77846ca9fc3ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 5 Aug 2019 19:23:46 -0700
Subject: [PATCH 107/943] Do not complain about unused code when used in `impl`
 `Self` type

---
 src/librustc/middle/dead.rs                   | 26 ++++++++++----
 src/test/ui/derive-uninhabited-enum-38885.rs  | 11 +++---
 .../ui/derive-uninhabited-enum-38885.stderr   | 14 +++-----
 .../ui/lint/lint-dead-code-const-and-self.rs  | 35 +++++++++++++++++++
 4 files changed, 66 insertions(+), 20 deletions(-)
 create mode 100644 src/test/ui/lint/lint-dead-code-const-and-self.rs

diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs
index 8ce8bb52566c6..d4805a7c78322 100644
--- a/src/librustc/middle/dead.rs
+++ b/src/librustc/middle/dead.rs
@@ -30,10 +30,11 @@ fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
         Some(Node::Item(..)) |
         Some(Node::ImplItem(..)) |
         Some(Node::ForeignItem(..)) |
-        Some(Node::TraitItem(..)) =>
-            true,
-        _ =>
-            false
+        Some(Node::TraitItem(..)) |
+        Some(Node::Variant(..)) |
+        Some(Node::AnonConst(..)) |
+        Some(Node::Pat(..)) => true,
+        _ => false
     }
 }
 
@@ -75,7 +76,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                 self.check_def_id(res.def_id());
             }
             _ if self.in_pat => {},
-            Res::PrimTy(..) | Res::SelfTy(..) | Res::SelfCtor(..) |
+            Res::PrimTy(..) | Res::SelfCtor(..) |
             Res::Local(..) => {}
             Res::Def(DefKind::Ctor(CtorOf::Variant, ..), ctor_def_id) => {
                 let variant_id = self.tcx.parent(ctor_def_id).unwrap();
@@ -92,6 +93,14 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
                     self.check_def_id(variant_id);
                 }
             }
+            Res::SelfTy(t, i) => {
+                if let Some(t) = t {
+                    self.check_def_id(t);
+                }
+                if let Some(i) = i {
+                    self.check_def_id(i);
+                }
+            }
             Res::ToolMod | Res::NonMacroAttr(..) | Res::Err => {}
             _ => {
                 self.check_def_id(res.def_id());
@@ -271,7 +280,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
                 let res = self.tables.qpath_res(path, pat.hir_id);
                 self.handle_field_pattern_match(pat, res, fields);
             }
-            PatKind::Path(ref qpath @ hir::QPath::TypeRelative(..)) => {
+            PatKind::Path(ref qpath) => {
                 let res = self.tables.qpath_res(qpath, pat.hir_id);
                 self.handle_res(res);
             }
@@ -298,6 +307,11 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
         }
         intravisit::walk_ty(self, ty);
     }
+
+    fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) {
+        self.live_symbols.insert(c.hir_id);
+        intravisit::walk_anon_const(self, c);
+    }
 }
 
 fn has_allow_dead_code_or_lang_attr(
diff --git a/src/test/ui/derive-uninhabited-enum-38885.rs b/src/test/ui/derive-uninhabited-enum-38885.rs
index 2c4d64e4e6063..010464adf5bce 100644
--- a/src/test/ui/derive-uninhabited-enum-38885.rs
+++ b/src/test/ui/derive-uninhabited-enum-38885.rs
@@ -5,12 +5,15 @@
 // when deriving Debug on an empty enum
 
 #[derive(Debug)]
-enum Void {} //~ WARN never used
+enum Void {}
 
 #[derive(Debug)]
-enum Foo { //~ WARN never used
+enum Foo {
     Bar(u8),
-    Void(Void),
+    Void(Void), //~ WARN never used
 }
 
-fn main() {}
+fn main() {
+    let x = Foo::Bar(42);
+    println!("{:?}", x);
+}
diff --git a/src/test/ui/derive-uninhabited-enum-38885.stderr b/src/test/ui/derive-uninhabited-enum-38885.stderr
index 941c98b5506b2..a3ed6798a7039 100644
--- a/src/test/ui/derive-uninhabited-enum-38885.stderr
+++ b/src/test/ui/derive-uninhabited-enum-38885.stderr
@@ -1,14 +1,8 @@
-warning: enum is never used: `Void`
-  --> $DIR/derive-uninhabited-enum-38885.rs:8:1
+warning: variant is never constructed: `Void`
+  --> $DIR/derive-uninhabited-enum-38885.rs:13:5
    |
-LL | enum Void {}
-   | ^^^^^^^^^
+LL |     Void(Void),
+   |     ^^^^^^^^^^
    |
    = note: `-W dead-code` implied by `-W unused`
 
-warning: enum is never used: `Foo`
-  --> $DIR/derive-uninhabited-enum-38885.rs:11:1
-   |
-LL | enum Foo {
-   | ^^^^^^^^
-
diff --git a/src/test/ui/lint/lint-dead-code-const-and-self.rs b/src/test/ui/lint/lint-dead-code-const-and-self.rs
new file mode 100644
index 0000000000000..1a7b3f43cda14
--- /dev/null
+++ b/src/test/ui/lint/lint-dead-code-const-and-self.rs
@@ -0,0 +1,35 @@
+// check-pass
+
+#![deny(dead_code)]
+
+const TLC: usize = 4;
+
+trait Tr { fn doit(&self); }
+
+impl Tr for [usize; TLC] {
+    fn doit(&self) {
+        println!("called 4");
+    }
+}
+
+struct X;
+struct Y;
+struct Z;
+
+trait Foo<T> {
+    type Ty;
+    fn foo() -> Self::Ty;
+}
+
+impl Foo<Y> for X {
+    type Ty = Z;
+    fn foo() -> Self::Ty {
+        unimplemented!()
+    }
+}
+
+fn main() {
+    let s = [0,1,2,3];
+    s.doit();
+    X::foo();
+}

From 352d97e6b7a3ddfd1f4de1d592fcf95d8a507f38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 21 Aug 2019 16:30:11 -0700
Subject: [PATCH 108/943] Add more tests covering more cases

---
 .../lint-dead-code-empty-unused-enum-pub.rs   |  6 +++++
 .../lint/lint-dead-code-empty-unused-enum.rs  |  5 ++++
 .../lint-dead-code-empty-unused-enum.stderr   | 15 +++++++++++
 .../ui/lint/lint-dead-code-unused-enum.rs     | 11 ++++++++
 .../ui/lint/lint-dead-code-unused-enum.stderr | 27 +++++++++++++++++++
 .../lint/lint-dead-code-unused-variant-pub.rs | 14 ++++++++++
 .../ui/lint/lint-dead-code-unused-variant.rs  | 13 +++++++++
 .../lint/lint-dead-code-unused-variant.stderr | 15 +++++++++++
 8 files changed, 106 insertions(+)
 create mode 100644 src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs
 create mode 100644 src/test/ui/lint/lint-dead-code-empty-unused-enum.rs
 create mode 100644 src/test/ui/lint/lint-dead-code-empty-unused-enum.stderr
 create mode 100644 src/test/ui/lint/lint-dead-code-unused-enum.rs
 create mode 100644 src/test/ui/lint/lint-dead-code-unused-enum.stderr
 create mode 100644 src/test/ui/lint/lint-dead-code-unused-variant-pub.rs
 create mode 100644 src/test/ui/lint/lint-dead-code-unused-variant.rs
 create mode 100644 src/test/ui/lint/lint-dead-code-unused-variant.stderr

diff --git a/src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs b/src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs
new file mode 100644
index 0000000000000..2b06fcb69ceee
--- /dev/null
+++ b/src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs
@@ -0,0 +1,6 @@
+// run-pass
+#![deny(unused)]
+
+pub enum E {}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-dead-code-empty-unused-enum.rs b/src/test/ui/lint/lint-dead-code-empty-unused-enum.rs
new file mode 100644
index 0000000000000..834681d77e613
--- /dev/null
+++ b/src/test/ui/lint/lint-dead-code-empty-unused-enum.rs
@@ -0,0 +1,5 @@
+#![deny(unused)]
+
+enum E {} //~ ERROR enum is never used
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-dead-code-empty-unused-enum.stderr b/src/test/ui/lint/lint-dead-code-empty-unused-enum.stderr
new file mode 100644
index 0000000000000..4e3bebfc48bde
--- /dev/null
+++ b/src/test/ui/lint/lint-dead-code-empty-unused-enum.stderr
@@ -0,0 +1,15 @@
+error: enum is never used: `E`
+  --> $DIR/lint-dead-code-empty-unused-enum.rs:3:1
+   |
+LL | enum E {}
+   | ^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint-dead-code-empty-unused-enum.rs:1:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/lint-dead-code-unused-enum.rs b/src/test/ui/lint/lint-dead-code-unused-enum.rs
new file mode 100644
index 0000000000000..e57fac259c5d5
--- /dev/null
+++ b/src/test/ui/lint/lint-dead-code-unused-enum.rs
@@ -0,0 +1,11 @@
+#![deny(unused)]
+
+struct F; //~ ERROR struct is never constructed
+struct B; //~ ERROR struct is never constructed
+
+enum E { //~ ERROR enum is never used
+    Foo(F),
+    Bar(B),
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/lint-dead-code-unused-enum.stderr b/src/test/ui/lint/lint-dead-code-unused-enum.stderr
new file mode 100644
index 0000000000000..ea711e7b05ee6
--- /dev/null
+++ b/src/test/ui/lint/lint-dead-code-unused-enum.stderr
@@ -0,0 +1,27 @@
+error: struct is never constructed: `F`
+  --> $DIR/lint-dead-code-unused-enum.rs:3:1
+   |
+LL | struct F;
+   | ^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint-dead-code-unused-enum.rs:1:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
+
+error: struct is never constructed: `B`
+  --> $DIR/lint-dead-code-unused-enum.rs:4:1
+   |
+LL | struct B;
+   | ^^^^^^^^^
+
+error: enum is never used: `E`
+  --> $DIR/lint-dead-code-unused-enum.rs:6:1
+   |
+LL | enum E {
+   | ^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/lint/lint-dead-code-unused-variant-pub.rs b/src/test/ui/lint/lint-dead-code-unused-variant-pub.rs
new file mode 100644
index 0000000000000..918300ba79354
--- /dev/null
+++ b/src/test/ui/lint/lint-dead-code-unused-variant-pub.rs
@@ -0,0 +1,14 @@
+// run-pass
+#![deny(unused)]
+
+pub struct F;
+pub struct B;
+
+pub enum E {
+    Foo(F),
+    Bar(B),
+}
+
+fn main() {
+    let _ = E::Foo(F);
+}
diff --git a/src/test/ui/lint/lint-dead-code-unused-variant.rs b/src/test/ui/lint/lint-dead-code-unused-variant.rs
new file mode 100644
index 0000000000000..69ab29042e5a4
--- /dev/null
+++ b/src/test/ui/lint/lint-dead-code-unused-variant.rs
@@ -0,0 +1,13 @@
+#![deny(unused)]
+
+struct F;
+struct B;
+
+enum E {
+    Foo(F),
+    Bar(B), //~ ERROR variant is never constructed
+}
+
+fn main() {
+    let _ = E::Foo(F);
+}
diff --git a/src/test/ui/lint/lint-dead-code-unused-variant.stderr b/src/test/ui/lint/lint-dead-code-unused-variant.stderr
new file mode 100644
index 0000000000000..919996ec30020
--- /dev/null
+++ b/src/test/ui/lint/lint-dead-code-unused-variant.stderr
@@ -0,0 +1,15 @@
+error: variant is never constructed: `Bar`
+  --> $DIR/lint-dead-code-unused-variant.rs:8:5
+   |
+LL |     Bar(B),
+   |     ^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/lint-dead-code-unused-variant.rs:1:9
+   |
+LL | #![deny(unused)]
+   |         ^^^^^^
+   = note: `#[deny(dead_code)]` implied by `#[deny(unused)]`
+
+error: aborting due to previous error
+

From a710c610b2ea1550014e9f6bd20e5e4aed8a716c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 21 Aug 2019 15:35:38 -0700
Subject: [PATCH 109/943] review comments: reword and add test

---
 src/librustc/ty/error.rs                      |  4 ++--
 src/test/ui/suggestions/opaque-type-error.rs  | 24 +++++++++++++++++++
 .../ui/suggestions/opaque-type-error.stderr   | 20 ++++++++++++++++
 3 files changed, 46 insertions(+), 2 deletions(-)
 create mode 100644 src/test/ui/suggestions/opaque-type-error.rs
 create mode 100644 src/test/ui/suggestions/opaque-type-error.stderr

diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index c1593799286ef..c70006b68d69a 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -269,8 +269,8 @@ impl<'tcx> TyCtxt<'tcx> {
                     let f_str = values.found.to_string();
                     if &e_str == &f_str && &e_str == "impl std::future::Future" {
                         // FIXME: use non-string based check.
-                        db.help("if both futures resolve to the same type, consider `await`ing \
-                                 on both of them");
+                        db.help("if both `Future`s have the same `Output` type, consider \
+                                 `.await`ing on both of them");
                     }
                 }
                 if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) =
diff --git a/src/test/ui/suggestions/opaque-type-error.rs b/src/test/ui/suggestions/opaque-type-error.rs
new file mode 100644
index 0000000000000..979bb60d48c12
--- /dev/null
+++ b/src/test/ui/suggestions/opaque-type-error.rs
@@ -0,0 +1,24 @@
+// edition:2018
+use core::future::Future;
+
+async fn base_thing() -> Result<(), ()> {
+    Ok(())
+}
+
+fn thing_one() -> impl Future<Output = Result<(), ()>> {
+    base_thing()
+}
+
+fn thing_two() -> impl Future<Output = Result<(), ()>> {
+    base_thing()
+}
+
+async fn thing() -> Result<(), ()> {
+    if true {
+        thing_one()
+    } else {
+        thing_two() //~ ERROR if and else have incompatible types
+    }.await
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr
new file mode 100644
index 0000000000000..3c9ea05aeceb2
--- /dev/null
+++ b/src/test/ui/suggestions/opaque-type-error.stderr
@@ -0,0 +1,20 @@
+error[E0308]: if and else have incompatible types
+  --> $DIR/opaque-type-error.rs:20:9
+   |
+LL | /     if true {
+LL | |         thing_one()
+   | |         ----------- expected because of this
+LL | |     } else {
+LL | |         thing_two()
+   | |         ^^^^^^^^^^^ expected opaque type, found a different opaque type
+LL | |     }.await
+   | |_____- if and else have incompatible types
+   |
+   = note: expected type `impl std::future::Future` (opaque type)
+              found type `impl std::future::Future` (opaque type)
+   = note: distinct uses of `impl Trait` result in different opaque types
+   = help: if both `Future`s have the same `Output` type, consider `.await`ing on both of them
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.

From 4f613ffeb000642ef2f7f3c2e3f25b5bd1938b5a Mon Sep 17 00:00:00 2001
From: YangHau <vulxj0j8j8@gmail.com>
Date: Tue, 20 Aug 2019 19:46:23 +0800
Subject: [PATCH 110/943] Fix naming misspelling

---
 ...terger-atomic.rs => non-integer-atomic.rs} |  0
 ...tomic.stderr => non-integer-atomic.stderr} | 32 +++++++++----------
 2 files changed, 16 insertions(+), 16 deletions(-)
 rename src/test/ui/{non-interger-atomic.rs => non-integer-atomic.rs} (100%)
 rename src/test/ui/{non-interger-atomic.stderr => non-integer-atomic.stderr} (83%)

diff --git a/src/test/ui/non-interger-atomic.rs b/src/test/ui/non-integer-atomic.rs
similarity index 100%
rename from src/test/ui/non-interger-atomic.rs
rename to src/test/ui/non-integer-atomic.rs
diff --git a/src/test/ui/non-interger-atomic.stderr b/src/test/ui/non-integer-atomic.stderr
similarity index 83%
rename from src/test/ui/non-interger-atomic.stderr
rename to src/test/ui/non-integer-atomic.stderr
index 7d1130d238e2c..b3cf788d834d8 100644
--- a/src/test/ui/non-interger-atomic.stderr
+++ b/src/test/ui/non-integer-atomic.stderr
@@ -1,95 +1,95 @@
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `bool`
-  --> $DIR/non-interger-atomic.rs:13:5
+  --> $DIR/non-integer-atomic.rs:13:5
    |
 LL |     intrinsics::atomic_load(p);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `bool`
-  --> $DIR/non-interger-atomic.rs:18:5
+  --> $DIR/non-integer-atomic.rs:18:5
    |
 LL |     intrinsics::atomic_store(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `bool`
-  --> $DIR/non-interger-atomic.rs:23:5
+  --> $DIR/non-integer-atomic.rs:23:5
    |
 LL |     intrinsics::atomic_xchg(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `bool`
-  --> $DIR/non-interger-atomic.rs:28:5
+  --> $DIR/non-integer-atomic.rs:28:5
    |
 LL |     intrinsics::atomic_cxchg(p, v, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `Foo`
-  --> $DIR/non-interger-atomic.rs:33:5
+  --> $DIR/non-integer-atomic.rs:33:5
    |
 LL |     intrinsics::atomic_load(p);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `Foo`
-  --> $DIR/non-interger-atomic.rs:38:5
+  --> $DIR/non-integer-atomic.rs:38:5
    |
 LL |     intrinsics::atomic_store(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `Foo`
-  --> $DIR/non-interger-atomic.rs:43:5
+  --> $DIR/non-integer-atomic.rs:43:5
    |
 LL |     intrinsics::atomic_xchg(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `Foo`
-  --> $DIR/non-interger-atomic.rs:48:5
+  --> $DIR/non-integer-atomic.rs:48:5
    |
 LL |     intrinsics::atomic_cxchg(p, v, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()`
-  --> $DIR/non-interger-atomic.rs:53:5
+  --> $DIR/non-integer-atomic.rs:53:5
    |
 LL |     intrinsics::atomic_load(p);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()`
-  --> $DIR/non-interger-atomic.rs:58:5
+  --> $DIR/non-integer-atomic.rs:58:5
    |
 LL |     intrinsics::atomic_store(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()`
-  --> $DIR/non-interger-atomic.rs:63:5
+  --> $DIR/non-integer-atomic.rs:63:5
    |
 LL |     intrinsics::atomic_xchg(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()`
-  --> $DIR/non-interger-atomic.rs:68:5
+  --> $DIR/non-integer-atomic.rs:68:5
    |
 LL |     intrinsics::atomic_cxchg(p, v, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]`
-  --> $DIR/non-interger-atomic.rs:73:5
+  --> $DIR/non-integer-atomic.rs:73:5
    |
 LL |     intrinsics::atomic_load(p);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `[u8; 100]`
-  --> $DIR/non-interger-atomic.rs:78:5
+  --> $DIR/non-integer-atomic.rs:78:5
    |
 LL |     intrinsics::atomic_store(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `[u8; 100]`
-  --> $DIR/non-interger-atomic.rs:83:5
+  --> $DIR/non-integer-atomic.rs:83:5
    |
 LL |     intrinsics::atomic_xchg(p, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `[u8; 100]`
-  --> $DIR/non-interger-atomic.rs:88:5
+  --> $DIR/non-integer-atomic.rs:88:5
    |
 LL |     intrinsics::atomic_cxchg(p, v, v);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

From 6ce242fb6e46bad46c64ae662091e18594521a4b Mon Sep 17 00:00:00 2001
From: Jeremy Stucki <dev@jeremystucki.ch>
Date: Thu, 22 Aug 2019 10:06:25 +0200
Subject: [PATCH 111/943] Update .mailmap

---
 .mailmap | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.mailmap b/.mailmap
index c5ecfb54fca52..98902a7212099 100644
--- a/.mailmap
+++ b/.mailmap
@@ -117,6 +117,7 @@ Jason Toffaletti <toffaletti@gmail.com> Jason Toffaletti <jason@topsy.com>
 Jauhien Piatlicki <jauhien@gentoo.org> Jauhien Piatlicki <jpiatlicki@zertisa.com>
 Jay True <glacjay@gmail.com>
 Jeremy Letang <letang.jeremy@gmail.com>
+Jeremy Stucki <dev@jeremystucki.ch> <stucki.jeremy@gmail.com> <jeremy@myelin.ch>
 Jethro Beekman <github@jbeekman.nl>
 Jihyun Yu <j.yu@navercorp.com> <yjh0502@gmail.com>
 Jihyun Yu <j.yu@navercorp.com> jihyun <jihyun@nablecomm.com>

From b7ad3f9fc4b293fd5ada4b975910be26105e5847 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= <matti@marinelayer.io>
Date: Thu, 22 Aug 2019 11:44:57 +0200
Subject: [PATCH 112/943] Apply clippy::redundant_field_names suggestion

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

diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs
index a1aa18922b5c5..131d2034675e3 100644
--- a/src/build_helper/lib.rs
+++ b/src/build_helper/lib.rs
@@ -262,7 +262,7 @@ pub fn native_lib_boilerplate(
     if !up_to_date(Path::new("build.rs"), &timestamp) || !up_to_date(src_dir, &timestamp) {
         Ok(NativeLibBoilerplate {
             src_dir: src_dir.to_path_buf(),
-            out_dir: out_dir,
+            out_dir,
         })
     } else {
         Err(())

From 7f4aba40fcdc00c41438a77d202276eaf5b58a8e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= <matti@marinelayer.io>
Date: Thu, 22 Aug 2019 11:47:36 +0200
Subject: [PATCH 113/943] Apply clippy::needless_return suggestions

---
 src/libcore/iter/adapters/mod.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index a63434abd6c9f..f50781890ab22 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -1309,7 +1309,7 @@ impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator {
         Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
     {
         match self.peeked.take() {
-            Some(None) => return Try::from_ok(init),
+            Some(None) => Try::from_ok(init),
             Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
                 Ok(acc) => f(acc, v),
                 Err(e) => {
@@ -1326,7 +1326,7 @@ impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator {
         where Fold: FnMut(Acc, Self::Item) -> Acc,
     {
         match self.peeked {
-            Some(None) => return init,
+            Some(None) => init,
             Some(Some(v)) => {
                 let acc = self.iter.rfold(init, &mut fold);
                 fold(acc, v)

From edabcddf4dbcc70228ac1db03b10df60decaf83a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= <matti@marinelayer.io>
Date: Thu, 22 Aug 2019 11:51:59 +0200
Subject: [PATCH 114/943] Apply clippy::let_and_return suggestion

---
 src/libcore/slice/mod.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index bfbbb15c8d488..931768564ca3c 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -3026,8 +3026,7 @@ macro_rules! len {
         if size == 0 {
             // This _cannot_ use `unchecked_sub` because we depend on wrapping
             // to represent the length of long ZST slice iterators.
-            let diff = ($self.end as usize).wrapping_sub(start as usize);
-            diff
+            ($self.end as usize).wrapping_sub(start as usize)
         } else {
             // We know that `start <= end`, so can do better than `offset_from`,
             // which needs to deal in signed.  By setting appropriate flags here

From 666180c3242169fa40ec462617e96ebf831fc62d Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Sun, 4 Aug 2019 16:20:00 -0400
Subject: [PATCH 115/943] Move 'tcx lifetime on MirPass

---
 src/librustc_mir/transform/add_call_guards.rs            | 4 ++--
 src/librustc_mir/transform/add_moves_for_packed_drops.rs | 4 ++--
 src/librustc_mir/transform/add_retag.rs                  | 4 ++--
 src/librustc_mir/transform/cleanup_post_borrowck.rs      | 4 ++--
 src/librustc_mir/transform/const_prop.rs                 | 4 ++--
 src/librustc_mir/transform/copy_prop.rs                  | 4 ++--
 src/librustc_mir/transform/deaggregator.rs               | 4 ++--
 src/librustc_mir/transform/dump_mir.rs                   | 4 ++--
 src/librustc_mir/transform/elaborate_drops.rs            | 4 ++--
 src/librustc_mir/transform/erase_regions.rs              | 4 ++--
 src/librustc_mir/transform/generator.rs                  | 4 ++--
 src/librustc_mir/transform/inline.rs                     | 4 ++--
 src/librustc_mir/transform/instcombine.rs                | 4 ++--
 src/librustc_mir/transform/mod.rs                        | 8 ++++----
 src/librustc_mir/transform/no_landing_pads.rs            | 4 ++--
 src/librustc_mir/transform/qualify_consts.rs             | 4 ++--
 src/librustc_mir/transform/remove_noop_landing_pads.rs   | 4 ++--
 src/librustc_mir/transform/rustc_peek.rs                 | 4 ++--
 src/librustc_mir/transform/simplify.rs                   | 8 ++++----
 src/librustc_mir/transform/simplify_branches.rs          | 4 ++--
 src/librustc_mir/transform/uniform_array_move_out.rs     | 8 ++++----
 21 files changed, 48 insertions(+), 48 deletions(-)

diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs
index c08c33bc6ff8b..15ecc6c37920b 100644
--- a/src/librustc_mir/transform/add_call_guards.rs
+++ b/src/librustc_mir/transform/add_call_guards.rs
@@ -30,8 +30,8 @@ pub use self::AddCallGuards::*;
  *
  */
 
-impl MirPass for AddCallGuards {
-    fn run_pass<'tcx>(&self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for AddCallGuards {
+    fn run_pass(&self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         self.add_call_guards(body);
     }
 }
diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/src/librustc_mir/transform/add_moves_for_packed_drops.rs
index 426e16698d74d..052631ddff371 100644
--- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs
+++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs
@@ -39,8 +39,8 @@ use crate::util;
 
 pub struct AddMovesForPackedDrops;
 
-impl MirPass for AddMovesForPackedDrops {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for AddMovesForPackedDrops {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         debug!("add_moves_for_packed_drops({:?} @ {:?})", src, body.span);
         add_moves_for_packed_drops(tcx, body, src.def_id());
     }
diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index 524a19e3434f3..0fd75cd57b2ac 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -65,8 +65,8 @@ fn may_be_reference<'tcx>(ty: Ty<'tcx>) -> bool {
     }
 }
 
-impl MirPass for AddRetag {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for AddRetag {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         if !tcx.sess.opts.debugging_opts.mir_emit_retag {
             return;
         }
diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs
index 6ee14160bbd1b..ede1cb62f9451 100644
--- a/src/librustc_mir/transform/cleanup_post_borrowck.rs
+++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs
@@ -26,8 +26,8 @@ pub struct CleanupNonCodegenStatements;
 
 pub struct DeleteNonCodegenStatements;
 
-impl MirPass for CleanupNonCodegenStatements {
-    fn run_pass<'tcx>(&self, _tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements {
+    fn run_pass(&self, _tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut Body<'tcx>) {
         let mut delete = DeleteNonCodegenStatements;
         delete.visit_body(body);
     }
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 98d8ca58ee164..ac442a496e535 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -33,8 +33,8 @@ use crate::transform::{MirPass, MirSource};
 
 pub struct ConstProp;
 
-impl MirPass for ConstProp {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for ConstProp {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
         // will be evaluated by miri and produce its errors there
         if source.promoted.is_some() {
             return;
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs
index 7c9eeb5a57741..f3a523a813413 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/src/librustc_mir/transform/copy_prop.rs
@@ -29,8 +29,8 @@ use crate::util::def_use::DefUseAnalysis;
 
 pub struct CopyPropagation;
 
-impl MirPass for CopyPropagation {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for CopyPropagation {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut Body<'tcx>) {
         // We only run when the MIR optimization level is > 1.
         // This avoids a slow pass, and messing up debug info.
         if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs
index 1b42a0dffb894..1fc7ce09aa647 100644
--- a/src/librustc_mir/transform/deaggregator.rs
+++ b/src/librustc_mir/transform/deaggregator.rs
@@ -5,8 +5,8 @@ use crate::util::expand_aggregate;
 
 pub struct Deaggregator;
 
-impl MirPass for Deaggregator {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for Deaggregator {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut Body<'tcx>) {
         let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
         let local_decls = &*local_decls;
         for bb in basic_blocks {
diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs
index a6fb555f20bd0..ed0eff943a165 100644
--- a/src/librustc_mir/transform/dump_mir.rs
+++ b/src/librustc_mir/transform/dump_mir.rs
@@ -13,12 +13,12 @@ use crate::util as mir_util;
 
 pub struct Marker(pub &'static str);
 
-impl MirPass for Marker {
+impl<'tcx> MirPass<'tcx> for Marker {
     fn name(&self) -> Cow<'_, str> {
         Cow::Borrowed(self.0)
     }
 
-    fn run_pass<'tcx>(&self, _tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, _body: &mut Body<'tcx>) {
+    fn run_pass(&self, _tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, _body: &mut Body<'tcx>) {
     }
 }
 
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index 4480d1e0a05b8..7a5c00c859629 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -20,8 +20,8 @@ use syntax_pos::Span;
 
 pub struct ElaborateDrops;
 
-impl MirPass for ElaborateDrops {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for ElaborateDrops {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         debug!("elaborate_drops({:?} @ {:?})", src, body.span);
 
         let def_id = src.def_id();
diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs
index 5a29ea21a7a04..21ca339eb968b 100644
--- a/src/librustc_mir/transform/erase_regions.rs
+++ b/src/librustc_mir/transform/erase_regions.rs
@@ -49,8 +49,8 @@ impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
 
 pub struct EraseRegions;
 
-impl MirPass for EraseRegions {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for EraseRegions {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
         EraseRegionsVisitor::new(tcx).visit_body(body);
     }
 }
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index f694188024031..d87331195dd24 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -1115,8 +1115,8 @@ where
     }).collect()
 }
 
-impl MirPass for StateTransform {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for StateTransform {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
         let yield_ty = if let Some(yield_ty) = body.yield_ty {
             yield_ty
         } else {
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index bc7bd39be488e..57aac2b0eac99 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -37,8 +37,8 @@ struct CallSite<'tcx> {
     location: SourceInfo,
 }
 
-impl MirPass for Inline {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for Inline {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) {
         if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
             Inliner { tcx, source }.run_pass(body);
         }
diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs
index b2d063a1f4e10..abe41606e8079 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/src/librustc_mir/transform/instcombine.rs
@@ -11,8 +11,8 @@ use crate::transform::{MirPass, MirSource};
 
 pub struct InstCombine;
 
-impl MirPass for InstCombine {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for InstCombine {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
         // We only run when optimizing MIR (at any level).
         if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {
             return
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 61d0b1f3485b6..255635b933385 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -137,12 +137,12 @@ pub fn default_name<T: ?Sized>() -> Cow<'static, str> {
 /// A streamlined trait that you can implement to create a pass; the
 /// pass will be named after the type, and it will consist of a main
 /// loop that goes over each available MIR and applies `run_pass`.
-pub trait MirPass {
+pub trait MirPass<'tcx> {
     fn name(&self) -> Cow<'_, str> {
         default_name::<Self>()
     }
 
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>);
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>);
 }
 
 pub fn run_passes(
@@ -150,7 +150,7 @@ pub fn run_passes(
     body: &mut Body<'tcx>,
     instance: InstanceDef<'tcx>,
     mir_phase: MirPhase,
-    passes: &[&dyn MirPass],
+    passes: &[&dyn MirPass<'tcx>],
 ) {
     let phase_index = mir_phase.phase_index();
 
@@ -164,7 +164,7 @@ pub fn run_passes(
             promoted,
         };
         let mut index = 0;
-        let mut run_pass = |pass: &dyn MirPass| {
+        let mut run_pass = |pass: &dyn MirPass<'tcx>| {
             let run_hooks = |body: &_, index, is_after| {
                 dump_mir::on_mir_pass(tcx, &format_args!("{:03}-{:03}", phase_index, index),
                                       &pass.name(), source, body, is_after);
diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs
index 841db80fc7dbb..762bb5d44839f 100644
--- a/src/librustc_mir/transform/no_landing_pads.rs
+++ b/src/librustc_mir/transform/no_landing_pads.rs
@@ -8,8 +8,8 @@ use crate::transform::{MirPass, MirSource};
 
 pub struct NoLandingPads;
 
-impl MirPass for NoLandingPads {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for NoLandingPads {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
         no_landing_pads(tcx, body)
     }
 }
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 649cccc36c346..1fe45a2c4240b 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1572,8 +1572,8 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet<Local>) {
 
 pub struct QualifyAndPromoteConstants;
 
-impl MirPass for QualifyAndPromoteConstants {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         // There's not really any point in promoting errorful MIR.
         if body.return_ty().references_error() {
             tcx.sess.delay_span_bug(body.span, "QualifyAndPromoteConstants: MIR had errors");
diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs
index adba9097d12df..73089a2106f6b 100644
--- a/src/librustc_mir/transform/remove_noop_landing_pads.rs
+++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs
@@ -18,8 +18,8 @@ pub fn remove_noop_landing_pads<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>)
     RemoveNoopLandingPads.remove_nop_landing_pads(body)
 }
 
-impl MirPass for RemoveNoopLandingPads {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for RemoveNoopLandingPads {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         remove_noop_landing_pads(tcx, body);
     }
 }
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index 598de3a77e61c..1d3bf247387a7 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -23,8 +23,8 @@ use crate::dataflow::has_rustc_mir_with;
 
 pub struct SanityCheck;
 
-impl MirPass for SanityCheck {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for SanityCheck {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         let def_id = src.def_id();
         if !tcx.has_attr(def_id, sym::rustc_mir) {
             debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index 2eed9d453f233..d4599ee08aa46 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -52,12 +52,12 @@ pub fn simplify_cfg(body: &mut Body<'_>) {
     body.basic_blocks_mut().raw.shrink_to_fit();
 }
 
-impl MirPass for SimplifyCfg {
+impl<'tcx> MirPass<'tcx> for SimplifyCfg {
     fn name(&self) -> Cow<'_, str> {
         Cow::Borrowed(&self.label)
     }
 
-    fn run_pass<'tcx>(&self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+    fn run_pass(&self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, body);
         simplify_cfg(body);
     }
@@ -292,8 +292,8 @@ pub fn remove_dead_blocks(body: &mut Body<'_>) {
 
 pub struct SimplifyLocals;
 
-impl MirPass for SimplifyLocals {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for SimplifyLocals {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
         let mut marker = DeclMarker { locals: BitSet::new_empty(body.local_decls.len()) };
         marker.visit_body(body);
         // Return pointer and arguments are always live
diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs
index 9ffa3db4c2eb0..0a509666d34ae 100644
--- a/src/librustc_mir/transform/simplify_branches.rs
+++ b/src/librustc_mir/transform/simplify_branches.rs
@@ -14,12 +14,12 @@ impl SimplifyBranches {
     }
 }
 
-impl MirPass for SimplifyBranches {
+impl<'tcx> MirPass<'tcx> for SimplifyBranches {
     fn name(&self) -> Cow<'_, str> {
         Cow::Borrowed(&self.label)
     }
 
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         let param_env = tcx.param_env(src.def_id());
         for block in body.basic_blocks_mut() {
             let terminator = block.terminator_mut();
diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs
index 60489e7fa3668..8199a252e78b0 100644
--- a/src/librustc_mir/transform/uniform_array_move_out.rs
+++ b/src/librustc_mir/transform/uniform_array_move_out.rs
@@ -36,8 +36,8 @@ use crate::util::patch::MirPatch;
 
 pub struct UniformArrayMoveOut;
 
-impl MirPass for UniformArrayMoveOut {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for UniformArrayMoveOut {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         let mut patch = MirPatch::new(body);
         let param_env = tcx.param_env(src.def_id());
         {
@@ -184,8 +184,8 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
 
 pub struct RestoreSubsliceArrayMoveOut;
 
-impl MirPass for RestoreSubsliceArrayMoveOut {
-    fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
+impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut {
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         let mut patch = MirPatch::new(body);
         let param_env = tcx.param_env(src.def_id());
         {

From 73814654b29604ded9dff105e4156639980d2f2c Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Sun, 4 Aug 2019 16:20:21 -0400
Subject: [PATCH 116/943] Move promoted out of mir::Body

---
 src/librustc/arena.rs                         | 10 +++
 src/librustc/mir/mod.rs                       |  9 --
 src/librustc/query/mod.rs                     | 14 +++-
 src/librustc/ty/context.rs                    | 12 ++-
 src/librustc_metadata/cstore_impl.rs          |  9 ++
 src/librustc_metadata/decoder.rs              | 10 ++-
 src/librustc_metadata/encoder.rs              | 64 +++++++++------
 src/librustc_metadata/schema.rs               |  2 +
 src/librustc_mir/borrow_check/mod.rs          | 13 ++-
 src/librustc_mir/borrow_check/nll/mod.rs      |  8 +-
 src/librustc_mir/borrow_check/nll/renumber.rs | 19 +++--
 .../borrow_check/nll/type_check/mod.rs        | 11 ++-
 src/librustc_mir/build/mod.rs                 |  1 -
 src/librustc_mir/const_eval.rs                |  2 +-
 src/librustc_mir/monomorphize/collector.rs    | 33 ++++----
 src/librustc_mir/shim.rs                      |  4 -
 src/librustc_mir/transform/const_prop.rs      | 28 ++-----
 src/librustc_mir/transform/inline.rs          |  9 +-
 src/librustc_mir/transform/mod.rs             | 82 ++++++++++++++++---
 src/librustc_mir/transform/promote_consts.rs  | 20 +++--
 src/librustc_mir/transform/qualify_consts.rs  | 19 ++++-
 21 files changed, 253 insertions(+), 126 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index e8c3914e695ad..a38dbbdd50c57 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -25,6 +25,16 @@ macro_rules! arena_types {
             [] adt_def: rustc::ty::AdtDef,
             [] steal_mir: rustc::ty::steal::Steal<rustc::mir::Body<$tcx>>,
             [] mir: rustc::mir::Body<$tcx>,
+            [] steal_promoted: rustc::ty::steal::Steal<
+                rustc_data_structures::indexed_vec::IndexVec<
+                    rustc::mir::Promoted,
+                    rustc::mir::Body<$tcx>
+                >
+            >,
+            [] promoted: rustc_data_structures::indexed_vec::IndexVec<
+                rustc::mir::Promoted,
+                rustc::mir::Body<$tcx>
+            >,
             [] tables: rustc::ty::TypeckTables<$tcx>,
             [] const_allocs: rustc::mir::interpret::Allocation,
             [] vtable_method: Option<(
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 11701a6637744..66f5eaeeda1c7 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -108,11 +108,6 @@ pub struct Body<'tcx> {
     /// needn't) be tracked across crates.
     pub source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
 
-    /// Rvalues promoted from this function, such as borrows of constants.
-    /// Each of them is the Body of a constant with the fn's type parameters
-    /// in scope, but a separate set of locals.
-    pub promoted: IndexVec<Promoted, Body<'tcx>>,
-
     /// Yields type of the function, if it is a generator.
     pub yield_ty: Option<Ty<'tcx>>,
 
@@ -174,7 +169,6 @@ impl<'tcx> Body<'tcx> {
         basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
         source_scopes: IndexVec<SourceScope, SourceScopeData>,
         source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
-        promoted: IndexVec<Promoted, Body<'tcx>>,
         yield_ty: Option<Ty<'tcx>>,
         local_decls: LocalDecls<'tcx>,
         user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
@@ -196,7 +190,6 @@ impl<'tcx> Body<'tcx> {
             basic_blocks,
             source_scopes,
             source_scope_local_data,
-            promoted,
             yield_ty,
             generator_drop: None,
             generator_layout: None,
@@ -418,7 +411,6 @@ impl_stable_hash_for!(struct Body<'tcx> {
     basic_blocks,
     source_scopes,
     source_scope_local_data,
-    promoted,
     yield_ty,
     generator_drop,
     generator_layout,
@@ -3032,7 +3024,6 @@ BraceStructTypeFoldableImpl! {
         basic_blocks,
         source_scopes,
         source_scope_local_data,
-        promoted,
         yield_ty,
         generator_drop,
         generator_layout,
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 5ab1b90642a6a..e1dbaeb5b173d 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -110,7 +110,7 @@ rustc_queries! {
             no_hash
         }
 
-        query mir_validated(_: DefId) -> &'tcx Steal<mir::Body<'tcx>> {
+        query mir_validated(_: DefId) -> (&'tcx Steal<mir::Body<'tcx>>, &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>) {
             no_hash
         }
 
@@ -125,7 +125,17 @@ rustc_queries! {
             }
         }
 
-        query promoted_mir(key: DefId) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> { }
+        query promoted_mir(key: DefId) -> &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>> {
+            cache_on_disk_if { key.is_local() }
+            load_cached(tcx, id) {
+                let promoted: Option<
+                    rustc_data_structures::indexed_vec::IndexVec<
+                        crate::mir::Promoted,
+                        crate::mir::Body<'tcx>
+                    >> = tcx.queries.on_disk_cache.try_load_query_result(tcx, id);
+                promoted.map(|p| &*tcx.arena.alloc(p))
+            }
+        }
     }
 
     TypeChecking {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index e72efdb057ab1..9f316e93111a3 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -21,7 +21,7 @@ use crate::middle::cstore::EncodedMetadata;
 use crate::middle::lang_items;
 use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault};
 use crate::middle::stability;
-use crate::mir::{Body, interpret, ProjectionKind};
+use crate::mir::{Body, interpret, ProjectionKind, Promoted};
 use crate::mir::interpret::{ConstValue, Allocation, Scalar};
 use crate::ty::subst::{Kind, InternalSubsts, SubstsRef, Subst};
 use crate::ty::ReprOptions;
@@ -1096,6 +1096,16 @@ impl<'tcx> TyCtxt<'tcx> {
         self.arena.alloc(Steal::new(mir))
     }
 
+    pub fn alloc_steal_promoted(self, promoted: IndexVec<Promoted, Body<'tcx>>) ->
+        &'tcx Steal<IndexVec<Promoted, Body<'tcx>>> {
+        self.arena.alloc(Steal::new(promoted))
+    }
+
+    pub fn intern_promoted(self, promoted: IndexVec<Promoted, Body<'tcx>>) ->
+        &'tcx IndexVec<Promoted, Body<'tcx>> {
+        self.arena.alloc(promoted)
+    }
+
     pub fn alloc_adt_def(
         self,
         did: DefId,
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index a66da32fa4d75..7aeeef00ea934 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -136,6 +136,15 @@ provide! { <'tcx> tcx, def_id, other, cdata,
 
         mir
     }
+    promoted_mir => {
+        let promoted = cdata.maybe_get_promoted_mir(tcx, def_id.index).unwrap_or_else(|| {
+            bug!("get_promoted_mir: missing promoted MIR for `{:?}`", def_id)
+        });
+
+        let promoted = tcx.arena.alloc(promoted);
+
+        promoted
+    }
     mir_const_qualif => {
         (cdata.mir_const_qualif(def_id.index), tcx.arena.alloc(BitSet::new_empty(0)))
     }
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index da96728d2dec9..128e30be79929 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -3,6 +3,7 @@
 use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule, FullProcMacro};
 use crate::schema::*;
 
+use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::sync::{Lrc, ReadGuard};
 use rustc::hir::map::{DefKey, DefPath, DefPathData, DefPathHash};
 use rustc::hir;
@@ -17,7 +18,7 @@ use rustc::mir::interpret::AllocDecodingSession;
 use rustc::session::Session;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::codec::TyDecoder;
-use rustc::mir::Body;
+use rustc::mir::{Body, Promoted};
 use rustc::util::captures::Captures;
 
 use std::io;
@@ -923,6 +924,13 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
+    pub fn maybe_get_promoted_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Option<IndexVec<Promoted, Body<'tcx>>> {
+        match self.is_proc_macro(id) {
+            true => None,
+            false => self.entry(id).promoted_mir.map(|promoted| promoted.decode((self, tcx)),)
+        }
+    }
+
     pub fn mir_const_qualif(&self, id: DefIndex) -> u8 {
         match self.entry(id).kind {
             EntryKind::Const(qualif, _) |
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index df3320c64a960..f3863fd788ae0 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -8,6 +8,7 @@ use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId, LocalDefId,
 use rustc::hir::GenericParamKind;
 use rustc::hir::map::definitions::DefPathTable;
 use rustc_data_structures::fingerprint::Fingerprint;
+use rustc_data_structures::indexed_vec::IndexVec;
 use rustc::middle::dependency_format::Linkage;
 use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel,
                                       metadata_symbol_name};
@@ -623,6 +624,7 @@ impl EncodeContext<'tcx> {
             predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
+            promoted_mir: self.encode_promoted_mir(def_id),
         }
     }
 
@@ -677,6 +679,7 @@ impl EncodeContext<'tcx> {
             predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
+            promoted_mir: self.encode_promoted_mir(def_id),
         }
     }
 
@@ -713,7 +716,8 @@ impl EncodeContext<'tcx> {
             predicates: None,
             predicates_defined_on: None,
 
-            mir: None
+            mir: None,
+            promoted_mir: None,
         }
     }
 
@@ -748,6 +752,7 @@ impl EncodeContext<'tcx> {
             predicates_defined_on: None,
 
             mir: None,
+            promoted_mir: None,
         }
     }
 
@@ -808,6 +813,7 @@ impl EncodeContext<'tcx> {
             predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
+            promoted_mir: self.encode_promoted_mir(def_id),
         }
     }
 
@@ -923,6 +929,7 @@ impl EncodeContext<'tcx> {
             predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
+            promoted_mir: self.encode_promoted_mir(def_id),
         }
     }
 
@@ -1022,6 +1029,7 @@ impl EncodeContext<'tcx> {
             predicates_defined_on: None,
 
             mir: if mir { self.encode_optimized_mir(def_id) } else { None },
+            promoted_mir: if mir { self.encode_promoted_mir(def_id) } else { None },
         }
     }
 
@@ -1052,6 +1060,16 @@ impl EncodeContext<'tcx> {
         }
     }
 
+    fn encode_promoted_mir(&mut self, def_id: DefId) -> Option<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>> {
+        debug!("EncodeContext::encode_promoted_mir({:?})", def_id);
+        if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
+            let promoted = self.tcx.promoted_mir(def_id);
+            Some(self.lazy(promoted))
+        } else {
+            None
+        }
+    }
+
     // Encodes the inherent implementations of a structure, enumeration, or trait.
     fn encode_inherent_implementations(&mut self, def_id: DefId) -> Lazy<[DefIndex]> {
         debug!("EncodeContext::encode_inherent_implementations({:?})", def_id);
@@ -1202,6 +1220,20 @@ impl EncodeContext<'tcx> {
             hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item),
         };
 
+        let mir = match item.node {
+            hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true,
+            hir::ItemKind::Fn(_, header, ..) => {
+                let generics = tcx.generics_of(def_id);
+                let needs_inline =
+                    (generics.requires_monomorphization(tcx) ||
+                        tcx.codegen_fn_attrs(def_id).requests_inline()) &&
+                        !self.metadata_output_only();
+                let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
+                needs_inline || header.constness == hir::Constness::Const || always_encode_mir
+            }
+            _ => false,
+        };
+
         Entry {
             kind,
             visibility: self.lazy(ty::Visibility::from_hir(&item.vis, item.hir_id, tcx)),
@@ -1301,29 +1333,8 @@ impl EncodeContext<'tcx> {
                 _ => None, // not *wrong* for other kinds of items, but not needed
             },
 
-            mir: match item.node {
-                hir::ItemKind::Static(..) => {
-                    self.encode_optimized_mir(def_id)
-                }
-                hir::ItemKind::Const(..) => self.encode_optimized_mir(def_id),
-                hir::ItemKind::Fn(_, header, ..) => {
-                    let generics = tcx.generics_of(def_id);
-                    let needs_inline =
-                        (generics.requires_monomorphization(tcx) ||
-                         tcx.codegen_fn_attrs(def_id).requests_inline()) &&
-                            !self.metadata_output_only();
-                    let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
-                    if needs_inline
-                        || header.constness == hir::Constness::Const
-                        || always_encode_mir
-                    {
-                        self.encode_optimized_mir(def_id)
-                    } else {
-                        None
-                    }
-                }
-                _ => None,
-            },
+            mir: if mir { self.encode_optimized_mir(def_id) } else { None },
+            promoted_mir: if mir { self.encode_promoted_mir(def_id) } else { None },
         }
     }
 
@@ -1350,6 +1361,7 @@ impl EncodeContext<'tcx> {
             predicates: None,
             predicates_defined_on: None,
             mir: None,
+            promoted_mir: None,
         }
     }
 
@@ -1376,6 +1388,7 @@ impl EncodeContext<'tcx> {
             predicates_defined_on: None,
 
             mir: None,
+            promoted_mir: None,
         }
     }
 
@@ -1436,6 +1449,7 @@ impl EncodeContext<'tcx> {
             predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
+            promoted_mir: self.encode_promoted_mir(def_id),
         }
     }
 
@@ -1464,6 +1478,7 @@ impl EncodeContext<'tcx> {
             predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
+            promoted_mir: self.encode_promoted_mir(def_id),
         }
     }
 
@@ -1675,6 +1690,7 @@ impl EncodeContext<'tcx> {
             predicates_defined_on: None,
 
             mir: None,
+            promoted_mir: None,
         }
     }
 }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index f37877b437e15..72a4b527c93d0 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -11,6 +11,7 @@ use rustc::session::CrateDisambiguator;
 use rustc::session::config::SymbolManglingVersion;
 use rustc::ty::{self, Ty, ReprOptions};
 use rustc_target::spec::{PanicStrategy, TargetTriple};
+use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::svh::Svh;
 
 use syntax::{ast, attr};
@@ -231,6 +232,7 @@ pub struct Entry<'tcx> {
     pub predicates_defined_on: Option<Lazy<ty::GenericPredicates<'tcx>>>,
 
     pub mir: Option<Lazy<mir::Body<'tcx>>>,
+    pub promoted_mir: Option<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>>,
 }
 
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index de27aec2b2990..05b396681ac06 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -13,7 +13,7 @@ use rustc::mir::{
     ClearCrossCrate, Local, Location, Body, Mutability, Operand, Place, PlaceBase, PlaceRef,
     Static, StaticKind
 };
-use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind};
+use rustc::mir::{Field, Projection, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
 use rustc::mir::{Terminator, TerminatorKind};
 use rustc::ty::query::Providers;
 use rustc::ty::{self, TyCtxt};
@@ -22,6 +22,7 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, Level};
 use rustc_data_structures::bit_set::BitSet;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::graph::dominators::Dominators;
+use rustc_data_structures::indexed_vec::IndexVec;
 use smallvec::SmallVec;
 
 use std::collections::BTreeMap;
@@ -86,12 +87,13 @@ pub fn provide(providers: &mut Providers<'_>) {
 }
 
 fn mir_borrowck(tcx: TyCtxt<'_>, def_id: DefId) -> BorrowCheckResult<'_> {
-    let input_body = tcx.mir_validated(def_id);
+    let (input_body, promoted) = tcx.mir_validated(def_id);
     debug!("run query mir_borrowck: {}", tcx.def_path_str(def_id));
 
     let opt_closure_req = tcx.infer_ctxt().enter(|infcx| {
         let input_body: &Body<'_> = &input_body.borrow();
-        do_mir_borrowck(&infcx, input_body, def_id)
+        let promoted: &IndexVec<_, _> = &promoted.borrow();
+        do_mir_borrowck(&infcx, input_body, promoted, def_id)
     });
     debug!("mir_borrowck done");
 
@@ -101,6 +103,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def_id: DefId) -> BorrowCheckResult<'_> {
 fn do_mir_borrowck<'a, 'tcx>(
     infcx: &InferCtxt<'a, 'tcx>,
     input_body: &Body<'tcx>,
+    input_promoted: &IndexVec<Promoted, Body<'tcx>>,
     def_id: DefId,
 ) -> BorrowCheckResult<'tcx> {
     debug!("do_mir_borrowck(def_id = {:?})", def_id);
@@ -147,7 +150,8 @@ fn do_mir_borrowck<'a, 'tcx>(
     // be modified (in place) to contain non-lexical lifetimes. It
     // will have a lifetime tied to the inference context.
     let mut body: Body<'tcx> = input_body.clone();
-    let free_regions = nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body);
+    let mut promoted: IndexVec<Promoted, Body<'tcx>> = input_promoted.clone();
+    let free_regions = nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body, &mut promoted);
     let body = &body; // no further changes
     let location_table = &LocationTable::new(body);
 
@@ -184,6 +188,7 @@ fn do_mir_borrowck<'a, 'tcx>(
         def_id,
         free_regions,
         body,
+        &promoted,
         &upvars,
         location_table,
         param_env,
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index d65cdde303ca0..11ec154e5b5c1 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -11,8 +11,9 @@ use crate::transform::MirSource;
 use crate::borrow_check::Upvar;
 use rustc::hir::def_id::DefId;
 use rustc::infer::InferCtxt;
-use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Local, Body};
+use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Local, Body, Promoted};
 use rustc::ty::{self, RegionKind, RegionVid};
+use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_errors::Diagnostic;
 use std::fmt::Debug;
 use std::env;
@@ -52,6 +53,7 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
     def_id: DefId,
     param_env: ty::ParamEnv<'tcx>,
     body: &mut Body<'tcx>,
+    promoted: &mut IndexVec<Promoted, Body<'tcx>>,
 ) -> UniversalRegions<'tcx> {
     debug!("replace_regions_in_mir(def_id={:?})", def_id);
 
@@ -59,7 +61,7 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
     let universal_regions = UniversalRegions::new(infcx, def_id, param_env);
 
     // Replace all remaining regions with fresh inference variables.
-    renumber::renumber_mir(infcx, body);
+    renumber::renumber_mir(infcx, body, promoted);
 
     let source = MirSource::item(def_id);
     mir_util::dump_mir(infcx.tcx, None, "renumber", &0, source, body, |_, _| Ok(()));
@@ -75,6 +77,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
     def_id: DefId,
     universal_regions: UniversalRegions<'tcx>,
     body: &Body<'tcx>,
+    promoted: &IndexVec<Promoted, Body<'tcx>>,
     upvars: &[Upvar],
     location_table: &LocationTable,
     param_env: ty::ParamEnv<'tcx>,
@@ -105,6 +108,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
         infcx,
         param_env,
         body,
+        promoted,
         def_id,
         &universal_regions,
         location_table,
diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs
index c1d1185cf177a..4e3ffb7af1601 100644
--- a/src/librustc_mir/borrow_check/nll/renumber.rs
+++ b/src/librustc_mir/borrow_check/nll/renumber.rs
@@ -1,16 +1,18 @@
 use rustc::ty::subst::SubstsRef;
 use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable};
-use rustc::mir::{Location, Body};
+use rustc::mir::{Location, Body, Promoted};
 use rustc::mir::visit::{MutVisitor, TyContext};
 use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
+use rustc_data_structures::indexed_vec::IndexVec;
 
 /// Replaces all free regions appearing in the MIR with fresh
 /// inference variables, returning the number of variables created.
-pub fn renumber_mir<'tcx>(infcx: &InferCtxt<'_, 'tcx>, body: &mut Body<'tcx>) {
+pub fn renumber_mir<'tcx>(infcx: &InferCtxt<'_, 'tcx>, body: &mut Body<'tcx>, promoted: &mut IndexVec<Promoted, Body<'tcx>>) {
     debug!("renumber_mir()");
     debug!("renumber_mir: body.arg_count={:?}", body.arg_count);
 
     let mut visitor = NLLVisitor { infcx };
+    visitor.visit_promoted(promoted);
     visitor.visit_body(body);
 }
 
@@ -41,17 +43,16 @@ impl<'a, 'tcx> NLLVisitor<'a, 'tcx> {
     {
         renumber_regions(self.infcx, value)
     }
-}
 
-impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> {
-    fn visit_body(&mut self, body: &mut Body<'tcx>) {
-        for promoted in body.promoted.iter_mut() {
-            self.visit_body(promoted);
+    fn visit_promoted(&mut self, promoted: &mut IndexVec<Promoted, Body<'tcx>>) {
+        debug!("visiting promoted mir");
+        for body in promoted.iter_mut() {
+            self.visit_body(body);
         }
-
-        self.super_body(body);
     }
+}
 
+impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> {
     fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) {
         debug!("visit_ty(ty={:?}, ty_context={:?})", ty, ty_context);
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 9ff0c6ca6a546..4b4477756bacc 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -112,6 +112,7 @@ pub(crate) fn type_check<'tcx>(
     infcx: &InferCtxt<'_, 'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     body: &Body<'tcx>,
+    promoted: &IndexVec<Promoted, Body<'tcx>>,
     mir_def_id: DefId,
     universal_regions: &Rc<UniversalRegions<'tcx>>,
     location_table: &LocationTable,
@@ -157,6 +158,7 @@ pub(crate) fn type_check<'tcx>(
         mir_def_id,
         param_env,
         body,
+        promoted,
         &region_bound_pairs,
         implicit_region_bound,
         &mut borrowck_context,
@@ -180,6 +182,7 @@ fn type_check_internal<'a, 'tcx, R>(
     mir_def_id: DefId,
     param_env: ty::ParamEnv<'tcx>,
     body: &'a Body<'tcx>,
+    promoted: &'a IndexVec<Promoted, Body<'tcx>>,
     region_bound_pairs: &'a RegionBoundPairs<'tcx>,
     implicit_region_bound: ty::Region<'tcx>,
     borrowck_context: &'a mut BorrowCheckContext<'a, 'tcx>,
@@ -197,7 +200,7 @@ fn type_check_internal<'a, 'tcx, R>(
         universal_region_relations,
     );
     let errors_reported = {
-        let mut verifier = TypeVerifier::new(&mut checker, body);
+        let mut verifier = TypeVerifier::new(&mut checker, body, promoted);
         verifier.visit_body(body);
         verifier.errors_reported
     };
@@ -254,6 +257,7 @@ enum FieldAccessError {
 struct TypeVerifier<'a, 'b, 'tcx> {
     cx: &'a mut TypeChecker<'b, 'tcx>,
     body: &'b Body<'tcx>,
+    promoted: &'b IndexVec<Promoted, Body<'tcx>>,
     last_span: Span,
     mir_def_id: DefId,
     errors_reported: bool,
@@ -380,9 +384,10 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
 }
 
 impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
-    fn new(cx: &'a mut TypeChecker<'b, 'tcx>, body: &'b Body<'tcx>) -> Self {
+    fn new(cx: &'a mut TypeChecker<'b, 'tcx>, body: &'b Body<'tcx>, promoted: &'b IndexVec<Promoted, Body<'tcx>>) -> Self {
         TypeVerifier {
             body,
+            promoted,
             mir_def_id: cx.mir_def_id,
             cx,
             last_span: body.span,
@@ -442,7 +447,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
                     match kind {
                         StaticKind::Promoted(promoted) => {
                             if !self.errors_reported {
-                                let promoted_body = &self.body.promoted[*promoted];
+                                let promoted_body = &self.promoted[*promoted];
                                 self.sanitize_promoted(promoted_body, location);
 
                                 let promoted_ty = promoted_body.return_ty();
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 4e970aee42cf4..3e3558fc60062 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -763,7 +763,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             self.cfg.basic_blocks,
             self.source_scopes,
             ClearCrossCrate::Set(self.source_scope_local_data),
-            IndexVec::new(),
             yield_ty,
             self.local_decls,
             self.canonical_user_type_annotations,
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 76ee76a74562b..4ab5c9cc1c498 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -667,7 +667,7 @@ pub fn const_eval_raw_provider<'tcx>(
     let res = ecx.load_mir(cid.instance.def);
     res.map(|body| {
         if let Some(index) = cid.promoted {
-            &body.promoted[index]
+           &tcx.promoted_mir(def_id)[index]
         } else {
             body
         }
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 12d763bb7910a..9d80163f30f9d 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -185,7 +185,7 @@ use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind, Instance};
 use rustc::ty::print::obsolete::DefPathBasedNames;
 use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast};
 use rustc::session::config::EntryFnType;
-use rustc::mir::{self, Location, PlaceBase, Promoted, Static, StaticKind};
+use rustc::mir::{self, Location, PlaceBase, Static, StaticKind};
 use rustc::mir::visit::Visitor as MirVisitor;
 use rustc::mir::mono::{MonoItem, InstantiationMode};
 use rustc::mir::interpret::{Scalar, GlobalId, GlobalAlloc, ErrorHandled};
@@ -1222,6 +1222,7 @@ fn collect_neighbours<'tcx>(
     instance: Instance<'tcx>,
     output: &mut Vec<MonoItem<'tcx>>,
 ) {
+    debug!("collect_neighbours: {:?}", instance.def_id());
     let body = tcx.instance_mir(instance.def);
 
     MirNeighborCollector {
@@ -1230,20 +1231,22 @@ fn collect_neighbours<'tcx>(
         output,
         param_substs: instance.substs,
     }.visit_body(&body);
-    let param_env = ty::ParamEnv::reveal_all();
-    for i in 0..body.promoted.len() {
-        use rustc_data_structures::indexed_vec::Idx;
-        let i = Promoted::new(i);
-        let cid = GlobalId {
-            instance,
-            promoted: Some(i),
-        };
-        match tcx.const_eval(param_env.and(cid)) {
-            Ok(val) => collect_const(tcx, val, instance.substs, output),
-            Err(ErrorHandled::Reported) => {},
-            Err(ErrorHandled::TooGeneric) => span_bug!(
-                body.promoted[i].span, "collection encountered polymorphic constant",
-            ),
+
+    if let ty::InstanceDef::Item(def_id) = instance.def {
+        let param_env = ty::ParamEnv::reveal_all();
+        let promoted = tcx.promoted_mir(def_id);
+        for (promoted, promoted_body) in promoted.iter_enumerated() {
+            let cid = GlobalId {
+                instance,
+                promoted: Some(promoted),
+            };
+            match tcx.const_eval(param_env.and(cid)) {
+                Ok(val) => collect_const(tcx, val, instance.substs, output),
+                Err(ErrorHandled::Reported) => {},
+                Err(ErrorHandled::TooGeneric) => span_bug!(
+                    promoted_body.span, "collection encountered polymorphic constant",
+                ),
+            }
         }
     }
 }
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 3e02f6c3725fd..9d31015f84558 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -201,7 +201,6 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
             SourceScopeData { span: span, parent_scope: None }, 1
         ),
         ClearCrossCrate::Clear,
-        IndexVec::new(),
         None,
         local_decls_for_sig(&sig, span),
         IndexVec::new(),
@@ -369,7 +368,6 @@ impl CloneShimBuilder<'tcx> {
                 SourceScopeData { span: self.span, parent_scope: None }, 1
             ),
             ClearCrossCrate::Clear,
-            IndexVec::new(),
             None,
             self.local_decls,
             IndexVec::new(),
@@ -813,7 +811,6 @@ fn build_call_shim<'tcx>(
             SourceScopeData { span: span, parent_scope: None }, 1
         ),
         ClearCrossCrate::Clear,
-        IndexVec::new(),
         None,
         local_decls,
         IndexVec::new(),
@@ -900,7 +897,6 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> {
             SourceScopeData { span: span, parent_scope: None }, 1
         ),
         ClearCrossCrate::Clear,
-        IndexVec::new(),
         None,
         local_decls,
         IndexVec::new(),
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index ac442a496e535..790595b4feef9 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -8,7 +8,7 @@ use rustc::mir::{
     AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue,
     Local, NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind,
     TerminatorKind, Terminator,  ClearCrossCrate, SourceInfo, BinOp, ProjectionElem,
-    SourceScope, SourceScopeLocalData, LocalDecl, Promoted,
+    SourceScope, SourceScopeLocalData, LocalDecl,
 };
 use rustc::mir::visit::{
     Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext,
@@ -64,17 +64,12 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
             &mut body.source_scope_local_data,
             ClearCrossCrate::Clear
         );
-        let promoted = std::mem::replace(
-            &mut body.promoted,
-            IndexVec::new()
-        );
 
         let dummy_body =
             &Body::new(
                 body.basic_blocks().clone(),
                 Default::default(),
                 ClearCrossCrate::Clear,
-                Default::default(),
                 None,
                 body.local_decls.clone(),
                 Default::default(),
@@ -92,22 +87,17 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
             body,
             dummy_body,
             source_scope_local_data,
-            promoted,
             tcx,
             source
         );
         optimization_finder.visit_body(body);
 
         // put back the data we stole from `mir`
-        let (source_scope_local_data, promoted) = optimization_finder.release_stolen_data();
+        let source_scope_local_data = optimization_finder.release_stolen_data();
         std::mem::replace(
             &mut body.source_scope_local_data,
             source_scope_local_data
         );
-        std::mem::replace(
-            &mut body.promoted,
-            promoted
-        );
 
         trace!("ConstProp done for {:?}", source.def_id());
     }
@@ -124,7 +114,6 @@ struct ConstPropagator<'mir, 'tcx> {
     param_env: ParamEnv<'tcx>,
     source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
     local_decls: IndexVec<Local, LocalDecl<'tcx>>,
-    promoted: IndexVec<Promoted, Body<'tcx>>,
 }
 
 impl<'mir, 'tcx> LayoutOf for ConstPropagator<'mir, 'tcx> {
@@ -155,7 +144,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         body: &Body<'tcx>,
         dummy_body: &'mir Body<'tcx>,
         source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
-        promoted: IndexVec<Promoted, Body<'tcx>>,
         tcx: TyCtxt<'tcx>,
         source: MirSource<'tcx>,
     ) -> ConstPropagator<'mir, 'tcx> {
@@ -184,17 +172,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
             source_scope_local_data,
             //FIXME(wesleywiser) we can't steal this because `Visitor::super_visit_body()` needs it
             local_decls: body.local_decls.clone(),
-            promoted,
         }
     }
 
-    fn release_stolen_data(
-        self,
-    ) -> (
-        ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
-        IndexVec<Promoted, Body<'tcx>>,
-    ) {
-        (self.source_scope_local_data, self.promoted)
+    fn release_stolen_data(self) -> ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>> {
+        self.source_scope_local_data
     }
 
     fn get_const(&self, local: Local) -> Option<Const<'tcx>> {
@@ -318,7 +300,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                     // cannot use `const_eval` here, because that would require having the MIR
                     // for the current function available, but we're producing said MIR right now
                     let res = self.use_ecx(source_info, |this| {
-                        let body = &this.promoted[*promoted];
+                        let body = &this.tcx.promoted_mir(this.source.def_id())[*promoted];
                         eval_promoted(this.tcx, cid, body, this.param_env)
                     })?;
                     trace!("evaluated promoted {:?} to {:?}", promoted, res);
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 57aac2b0eac99..19a8769ce1633 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -394,7 +394,7 @@ impl Inliner<'tcx> {
 
                 let mut local_map = IndexVec::with_capacity(callee_body.local_decls.len());
                 let mut scope_map = IndexVec::with_capacity(callee_body.source_scopes.len());
-                let mut promoted_map = IndexVec::with_capacity(callee_body.promoted.len());
+                let promoted_map = IndexVec::with_capacity(self.tcx.promoted_mir(callsite.callee).len());
 
                 for mut scope in callee_body.source_scopes.iter().cloned() {
                     if scope.parent_scope.is_none() {
@@ -420,9 +420,10 @@ impl Inliner<'tcx> {
                     local_map.push(idx);
                 }
 
-                promoted_map.extend(
-                    callee_body.promoted.iter().cloned().map(|p| caller_body.promoted.push(p))
-                );
+                //TODO fixme
+                //promoted_map.extend(
+                //    self.tcx.promoted_mir(callsite.callee).iter().cloned().map(|p| caller_body.promoted.push(p))
+                //);
 
                 // If the call is something like `a[*i] = f(i)`, where
                 // `i : &mut usize`, then just duplicating the `a[*i]`
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 255635b933385..a78e78331ee3f 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -184,13 +184,6 @@ pub fn run_passes(
     };
 
     run_passes(body, None);
-
-    for (index, promoted_body) in body.promoted.iter_enumerated_mut() {
-        run_passes(promoted_body, Some(index));
-
-        //Let's make sure we don't miss any nested instances
-        assert!(promoted_body.promoted.is_empty())
-    }
 }
 
 fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
@@ -207,7 +200,7 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
     tcx.alloc_steal_mir(body)
 }
 
-fn mir_validated(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Steal<Body<'tcx>> {
+fn mir_validated(tcx: TyCtxt<'tcx>, def_id: DefId) -> (&'tcx Steal<Body<'tcx>>, &'tcx Steal<IndexVec<Promoted, Body<'tcx>>>) {
     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
     if let hir::BodyOwnerKind::Const = tcx.hir().body_owner_kind(hir_id) {
         // Ensure that we compute the `mir_const_qualif` for constants at
@@ -216,12 +209,14 @@ fn mir_validated(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx Steal<Body<'tcx>> {
     }
 
     let mut body = tcx.mir_const(def_id).steal();
+    let qualify_and_promote_pass = qualify_consts::QualifyAndPromoteConstants::default();
     run_passes(tcx, &mut body, InstanceDef::Item(def_id), MirPhase::Validated, &[
         // What we need to run borrowck etc.
-        &qualify_consts::QualifyAndPromoteConstants,
+        &qualify_and_promote_pass,
         &simplify::SimplifyCfg::new("qualify-consts"),
     ]);
-    tcx.alloc_steal_mir(body)
+    let promoted = qualify_and_promote_pass.promoted.into_inner();
+    (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted.unwrap_or_else(|| IndexVec::new())))
 }
 
 fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> {
@@ -241,7 +236,8 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> {
         tcx.ensure().borrowck(def_id);
     }
 
-    let mut body = tcx.mir_validated(def_id).steal();
+    let (body, _) = tcx.mir_validated(def_id);
+    let mut body = body.steal();
     run_passes(tcx, &mut body, InstanceDef::Item(def_id), MirPhase::Optimized, &[
         // Remove all things only needed by analysis
         &no_landing_pads::NoLandingPads,
@@ -297,6 +293,66 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> {
 }
 
 fn promoted_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx IndexVec<Promoted, Body<'tcx>> {
-    let body = tcx.optimized_mir(def_id);
-    &body.promoted
+    if tcx.is_constructor(def_id) {
+        return tcx.intern_promoted(IndexVec::new());
+    }
+
+    tcx.ensure().mir_borrowck(def_id);
+    let (_, promoted) = tcx.mir_validated(def_id);
+    let mut promoted = promoted.steal();
+
+    for mut body in promoted.iter_mut() {
+        run_passes(tcx, &mut body, InstanceDef::Item(def_id), MirPhase::Optimized, &[
+            // Remove all things only needed by analysis
+            &no_landing_pads::NoLandingPads,
+            &simplify_branches::SimplifyBranches::new("initial"),
+            &remove_noop_landing_pads::RemoveNoopLandingPads,
+            &cleanup_post_borrowck::CleanupNonCodegenStatements,
+
+            &simplify::SimplifyCfg::new("early-opt"),
+
+            // These next passes must be executed together
+            &add_call_guards::CriticalCallEdges,
+            &elaborate_drops::ElaborateDrops,
+            &no_landing_pads::NoLandingPads,
+            // AddMovesForPackedDrops needs to run after drop
+            // elaboration.
+            &add_moves_for_packed_drops::AddMovesForPackedDrops,
+            // AddRetag needs to run after ElaborateDrops, and it needs
+            // an AllCallEdges pass right before it.  Otherwise it should
+            // run fairly late, but before optimizations begin.
+            &add_call_guards::AllCallEdges,
+            &add_retag::AddRetag,
+
+            &simplify::SimplifyCfg::new("elaborate-drops"),
+
+            // No lifetime analysis based on borrowing can be done from here on out.
+
+            // From here on out, regions are gone.
+            &erase_regions::EraseRegions,
+
+            // Optimizations begin.
+            &uniform_array_move_out::RestoreSubsliceArrayMoveOut,
+            &inline::Inline,
+
+            // Lowering generator control-flow and variables
+            // has to happen before we do anything else to them.
+            &generator::StateTransform,
+
+            &instcombine::InstCombine,
+            &const_prop::ConstProp,
+            &simplify_branches::SimplifyBranches::new("after-const-prop"),
+            &deaggregator::Deaggregator,
+            &copy_prop::CopyPropagation,
+            &simplify_branches::SimplifyBranches::new("after-copy-prop"),
+            &remove_noop_landing_pads::RemoveNoopLandingPads,
+            &simplify::SimplifyCfg::new("final"),
+            &simplify::SimplifyLocals,
+
+            &add_call_guards::CriticalCallEdges,
+            &dump_mir::Marker("PreCodegen"),
+        ]);
+    }
+
+    tcx.intern_promoted(promoted)
 }
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 3090b63a7e993..7015e2c087faa 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -293,10 +293,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
         new_temp
     }
 
-    fn promote_candidate(mut self, candidate: Candidate) {
+    fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Option<Body<'tcx>> {
         let mut operand = {
             let promoted = &mut self.promoted;
-            let promoted_id = Promoted::new(self.source.promoted.len());
+            let promoted_id = Promoted::new(next_promoted_id);
             let mut promoted_place = |ty, span| {
                 promoted.span = span;
                 promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span);
@@ -353,7 +353,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                         // a function requiring a constant argument and as that constant value
                         // providing a value whose computation contains another call to a function
                         // requiring a constant argument.
-                        TerminatorKind::Goto { .. } => return,
+                        TerminatorKind::Goto { .. } => return None,
                         _ => bug!()
                     }
                 }
@@ -368,7 +368,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
 
         let span = self.promoted.span;
         self.assign(RETURN_PLACE, Rvalue::Use(operand), span);
-        self.source.promoted.push(self.promoted);
+        Some(self.promoted)
     }
 }
 
@@ -389,10 +389,12 @@ pub fn promote_candidates<'tcx>(
     tcx: TyCtxt<'tcx>,
     mut temps: IndexVec<Local, TempState>,
     candidates: Vec<Candidate>,
-) {
+) -> IndexVec<Promoted, Body<'tcx>> {
     // Visit candidates in reverse, in case they're nested.
     debug!("promote_candidates({:?})", candidates);
 
+    let mut promotions = IndexVec::new();
+
     for candidate in candidates.into_iter().rev() {
         match candidate {
             Candidate::Repeat(Location { block, statement_index }) |
@@ -426,7 +428,6 @@ pub fn promote_candidates<'tcx>(
                 // memory usage?
                 body.source_scopes.clone(),
                 body.source_scope_local_data.clone(),
-                IndexVec::new(),
                 None,
                 initial_locals,
                 IndexVec::new(),
@@ -440,7 +441,10 @@ pub fn promote_candidates<'tcx>(
             temps: &mut temps,
             keep_original: false
         };
-        promoter.promote_candidate(candidate);
+
+        if let Some(promoted) = promoter.promote_candidate(candidate, promotions.len()) {
+            promotions.push(promoted);
+        }
     }
 
     // Eliminate assignments to, and drops of promoted temps.
@@ -474,4 +478,6 @@ pub fn promote_candidates<'tcx>(
             _ => {}
         }
     }
+
+    promotions
 }
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 1fe45a2c4240b..dd4db479cc00b 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -25,6 +25,7 @@ use syntax::feature_gate::{emit_feature_err, GateIssue};
 use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
 
+use std::cell::Cell;
 use std::fmt;
 use std::ops::{Deref, Index, IndexMut};
 use std::usize;
@@ -1570,9 +1571,19 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet<Local>) {
     Checker::new(tcx, def_id, body, Mode::Const).check_const()
 }
 
-pub struct QualifyAndPromoteConstants;
+pub struct QualifyAndPromoteConstants<'tcx> {
+    pub promoted: Cell<Option<IndexVec<Promoted, Body<'tcx>>>>,
+}
+
+impl<'tcx> Default for QualifyAndPromoteConstants<'tcx> {
+    fn default() -> Self {
+        QualifyAndPromoteConstants {
+            promoted: Cell::new(None),
+        }
+    }
+}
 
-impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants {
+impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
         // There's not really any point in promoting errorful MIR.
         if body.return_ty().references_error() {
@@ -1649,7 +1660,9 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants {
             };
 
             // Do the actual promotion, now that we know what's viable.
-            promote_consts::promote_candidates(body, tcx, temps, candidates);
+            self.promoted.set(
+                Some(promote_consts::promote_candidates(body, tcx, temps, candidates))
+            );
         } else {
             if !body.control_flow_destroyed.is_empty() {
                 let mut locals = body.vars_iter();

From f13faf58d92d2d6154acc8cf50bf5d237a3a4118 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Mon, 5 Aug 2019 20:01:59 -0400
Subject: [PATCH 117/943] Remove eval_promoted const-prop hack

---
 src/librustc_mir/const_eval.rs             | 23 +++-------------------
 src/librustc_mir/interpret/eval_context.rs |  6 +++++-
 src/librustc_mir/transform/const_prop.rs   |  7 ++-----
 3 files changed, 10 insertions(+), 26 deletions(-)

diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 4ab5c9cc1c498..67d63e52b2bfa 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -49,17 +49,6 @@ pub(crate) fn mk_eval_cx<'mir, 'tcx>(
     InterpCx::new(tcx.at(span), param_env, CompileTimeInterpreter::new(), Default::default())
 }
 
-pub(crate) fn eval_promoted<'mir, 'tcx>(
-    tcx: TyCtxt<'tcx>,
-    cid: GlobalId<'tcx>,
-    body: &'mir mir::Body<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
-    let span = tcx.def_span(cid.instance.def_id());
-    let mut ecx = mk_eval_cx(tcx, span, param_env);
-    eval_body_using_ecx(&mut ecx, cid, body, param_env)
-}
-
 fn op_to_const<'tcx>(
     ecx: &CompileTimeEvalContext<'_, 'tcx>,
     op: OpTy<'tcx>,
@@ -360,7 +349,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
             }
         }
         // This is a const fn. Call it.
-        Ok(Some(match ecx.load_mir(instance.def) {
+        Ok(Some(match ecx.load_mir(instance.def, None) {
             Ok(body) => body,
             Err(err) => {
                 if let err_unsup!(NoMirFor(ref path)) = err.kind {
@@ -664,14 +653,8 @@ pub fn const_eval_raw_provider<'tcx>(
         Default::default()
     );
 
-    let res = ecx.load_mir(cid.instance.def);
-    res.map(|body| {
-        if let Some(index) = cid.promoted {
-           &tcx.promoted_mir(def_id)[index]
-        } else {
-            body
-        }
-    }).and_then(
+    let res = ecx.load_mir(cid.instance.def, cid.promoted);
+    res.and_then(
         |body| eval_body_using_ecx(&mut ecx, cid, body, key.param_env)
     ).and_then(|place| {
         Ok(RawConst {
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 6f48396cdd7cf..ac01d436bdc9b 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -294,6 +294,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     pub fn load_mir(
         &self,
         instance: ty::InstanceDef<'tcx>,
+        promoted: Option<mir::Promoted>,
     ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
         // do not continue if typeck errors occurred (can only occur in local crate)
         let did = instance.def_id();
@@ -303,7 +304,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         {
             throw_inval!(TypeckError)
         }
-        trace!("load mir {:?}", instance);
+        trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
+        if let Some(promoted) = promoted {
+            return Ok(&self.tcx.promoted_mir(did)[promoted]);
+        }
         match instance {
             ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) {
                 Ok(self.tcx.optimized_mir(did))
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 790595b4feef9..9aeef16ba1e38 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -27,7 +27,7 @@ use crate::interpret::{
     ImmTy, MemoryKind, StackPopCleanup, LocalValue, LocalState,
 };
 use crate::const_eval::{
-    CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx,
+    CompileTimeInterpreter, error_to_const_error, mk_eval_cx,
 };
 use crate::transform::{MirPass, MirSource};
 
@@ -297,11 +297,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                         instance,
                         promoted: Some(*promoted),
                     };
-                    // cannot use `const_eval` here, because that would require having the MIR
-                    // for the current function available, but we're producing said MIR right now
                     let res = self.use_ecx(source_info, |this| {
-                        let body = &this.tcx.promoted_mir(this.source.def_id())[*promoted];
-                        eval_promoted(this.tcx, cid, body, this.param_env)
+                        this.ecx.const_eval_raw(cid)
                     })?;
                     trace!("evaluated promoted {:?} to {:?}", promoted, res);
                     res.into()

From 4d62545687d0c10577eb75c058c0662e6b261395 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Mon, 5 Aug 2019 21:11:55 -0400
Subject: [PATCH 118/943] Move def_id out add substsref

---
 src/librustc/mir/mod.rs                       | 18 ++++----
 src/librustc/mir/visit.rs                     |  2 +-
 src/librustc_codegen_ssa/mir/block.rs         |  6 ++-
 src/librustc_codegen_ssa/mir/place.rs         | 21 +++++++---
 .../borrow_check/error_reporting.rs           |  8 ++--
 src/librustc_mir/borrow_check/mod.rs          |  9 ++--
 .../borrow_check/mutability_errors.rs         |  5 ++-
 .../borrow_check/nll/type_check/mod.rs        |  8 ++--
 src/librustc_mir/borrow_check/place_ext.rs    |  4 +-
 .../borrow_check/places_conflict.rs           |  8 ++--
 src/librustc_mir/build/expr/as_place.rs       |  3 +-
 src/librustc_mir/interpret/place.rs           |  6 +--
 src/librustc_mir/monomorphize/collector.rs    | 41 +++++++++----------
 src/librustc_mir/transform/check_unsafety.rs  |  4 +-
 src/librustc_mir/transform/const_prop.rs      |  2 +-
 src/librustc_mir/transform/inline.rs          | 24 ++++-------
 src/librustc_mir/transform/promote_consts.rs  | 41 +++++++++++++++----
 src/librustc_mir/transform/qualify_consts.rs  | 16 ++++----
 .../transform/qualify_min_const_fn.rs         |  4 +-
 19 files changed, 134 insertions(+), 96 deletions(-)

diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 66f5eaeeda1c7..69e98583b191c 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1732,20 +1732,22 @@ pub enum PlaceBase<'tcx> {
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
 pub struct Static<'tcx> {
     pub ty: Ty<'tcx>,
-    pub kind: StaticKind,
+    pub kind: StaticKind<'tcx>,
+    pub def_id: DefId,
 }
 
 #[derive(
     Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable,
 )]
-pub enum StaticKind {
-    Promoted(Promoted),
-    Static(DefId),
+pub enum StaticKind<'tcx> {
+    Promoted(Promoted, SubstsRef<'tcx>),
+    Static,
 }
 
 impl_stable_hash_for!(struct Static<'tcx> {
     ty,
-    kind
+    kind,
+    def_id
 });
 
 /// The `Projection` data structure defines things of the form `base.x`, `*b` or `b[index]`.
@@ -2106,10 +2108,12 @@ impl Debug for PlaceBase<'_> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
         match *self {
             PlaceBase::Local(id) => write!(fmt, "{:?}", id),
-            PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static(def_id) }) => {
+            PlaceBase::Static(box self::Static { ty, kind: StaticKind::Static, def_id }) => {
                 write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.def_path_str(def_id)), ty)
             }
-            PlaceBase::Static(box self::Static { ty, kind: StaticKind::Promoted(promoted) }) => {
+            PlaceBase::Static(box self::Static {
+                ty, kind: StaticKind::Promoted(promoted, _), def_id: _
+            }) => {
                 write!(fmt, "({:?}: {:?})", promoted, ty)
             }
         }
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 2d16e7bcc8371..ac0e784d8bd12 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -708,7 +708,7 @@ macro_rules! make_mir_visitor {
                     PlaceBase::Local(local) => {
                         self.visit_local(local, context, location);
                     }
-                    PlaceBase::Static(box Static { kind: _, ty }) => {
+                    PlaceBase::Static(box Static { kind: _, ty, def_id: _ }) => {
                         self.visit_ty(& $($mutability)? *ty, TyContext::Location(location));
                     }
                 }
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index dbce5ce4896a7..d2a7571fde1e2 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -609,8 +609,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         mir::Operand::Copy(
                             Place {
                                 base: PlaceBase::Static(box Static {
-                                    kind: StaticKind::Promoted(promoted),
+                                    kind: StaticKind::Promoted(promoted, _),
                                     ty,
+                                    def_id: _,
                                 }),
                                 projection: None,
                             }
@@ -618,8 +619,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         mir::Operand::Move(
                             Place {
                                 base: PlaceBase::Static(box Static {
-                                    kind: StaticKind::Promoted(promoted),
+                                    kind: StaticKind::Promoted(promoted, _),
                                     ty,
+                                    def_id: _,
                                 }),
                                 projection: None,
                             }
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index a632838ba2442..f7b94ea134cfc 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -1,4 +1,5 @@
-use rustc::ty::{self, Ty};
+use rustc::ty::{self, Instance, Ty};
+use rustc::ty::subst::Subst;
 use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt};
 use rustc::mir;
 use rustc::mir::tcx::PlaceTy;
@@ -454,16 +455,25 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::PlaceRef {
                 base: mir::PlaceBase::Static(box mir::Static {
                     ty,
-                    kind: mir::StaticKind::Promoted(promoted),
+                    kind: mir::StaticKind::Promoted(promoted, substs),
+                    def_id,
                 }),
                 projection: None,
             } => {
+                debug!("promoted={:?}, def_id={:?}, substs={:?}, self_substs={:?}", promoted, def_id, substs, self.instance.substs);
                 let param_env = ty::ParamEnv::reveal_all();
+                let instance = Instance::new(*def_id, substs.subst(bx.tcx(), self.instance.substs));
+                debug!("instance: {:?}", instance);
                 let cid = mir::interpret::GlobalId {
-                    instance: self.instance,
+                    instance: instance,
                     promoted: Some(*promoted),
                 };
-                let layout = cx.layout_of(self.monomorphize(&ty));
+                let mono_ty = tcx.subst_and_normalize_erasing_regions(
+                    instance.substs,
+                    param_env,
+                    ty,
+                );
+                let layout = cx.layout_of(mono_ty);
                 match bx.tcx().const_eval(param_env.and(cid)) {
                     Ok(val) => match val.val {
                         mir::interpret::ConstValue::ByRef { alloc, offset } => {
@@ -487,7 +497,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::PlaceRef {
                 base: mir::PlaceBase::Static(box mir::Static {
                     ty,
-                    kind: mir::StaticKind::Static(def_id),
+                    kind: mir::StaticKind::Static,
+                    def_id,
                 }),
                 projection: None,
             } => {
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 99899aa390c4a..251d4b727c754 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -159,7 +159,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             PlaceRef {
                 base:
                     PlaceBase::Static(box Static {
-                        kind: StaticKind::Promoted(_),
+                        kind: StaticKind::Promoted(..),
                         ..
                     }),
                 projection: None,
@@ -169,7 +169,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             PlaceRef {
                 base:
                     PlaceBase::Static(box Static {
-                        kind: StaticKind::Static(def_id),
+                        kind: StaticKind::Static,
+                        def_id,
                         ..
                     }),
                 projection: None,
@@ -440,7 +441,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     pub fn is_place_thread_local(&self, place_ref: PlaceRef<'cx, 'tcx>) -> bool {
         if let PlaceRef {
             base: PlaceBase::Static(box Static {
-                kind: StaticKind::Static(def_id),
+                kind: StaticKind::Static,
+                def_id,
                 ..
             }),
             projection: None,
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 05b396681ac06..33cec78f3dfd5 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -1467,13 +1467,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         assert!(root_place.projection.is_none());
         let (might_be_alive, will_be_dropped) = match root_place.base {
             PlaceBase::Static(box Static {
-                kind: StaticKind::Promoted(_),
+                kind: StaticKind::Promoted(..),
                 ..
             }) => {
                 (true, false)
             }
             PlaceBase::Static(box Static {
-                kind: StaticKind::Static(_),
+                kind: StaticKind::Static,
                 ..
             }) => {
                 // Thread-locals might be dropped after the function exits, but
@@ -2155,7 +2155,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             // `Place::Promoted` if the promotion weren't 100% legal. So we just forward this
             PlaceRef {
                 base: PlaceBase::Static(box Static {
-                    kind: StaticKind::Promoted(_),
+                    kind: StaticKind::Promoted(..),
                     ..
                 }),
                 projection: None,
@@ -2167,7 +2167,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 }),
             PlaceRef {
                 base: PlaceBase::Static(box Static {
-                    kind: StaticKind::Static(def_id),
+                    kind: StaticKind::Static,
+                    def_id,
                     ..
                 }),
                 projection: None,
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 937c6383be341..091b3eeb05f6c 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -149,7 +149,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             PlaceRef {
                 base:
                     PlaceBase::Static(box Static {
-                        kind: StaticKind::Promoted(_),
+                        kind: StaticKind::Promoted(..),
                         ..
                     }),
                 projection: None,
@@ -158,7 +158,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             PlaceRef {
                 base:
                     PlaceBase::Static(box Static {
-                        kind: StaticKind::Static(def_id),
+                        kind: StaticKind::Static,
+                        def_id,
                         ..
                     }),
                 projection: None,
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 4b4477756bacc..35dd5b5d7eb19 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -421,7 +421,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
             let mut place_ty = match place_base {
                 PlaceBase::Local(index) =>
                     PlaceTy::from_ty(self.body.local_decls[*index].ty),
-                PlaceBase::Static(box Static { kind, ty: sty }) => {
+                PlaceBase::Static(box Static { kind, ty: sty, def_id }) => {
                     let sty = self.sanitize_type(place, sty);
                     let check_err =
                         |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
@@ -445,7 +445,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
                             };
                         };
                     match kind {
-                        StaticKind::Promoted(promoted) => {
+                        StaticKind::Promoted(promoted, _) => {
                             if !self.errors_reported {
                                 let promoted_body = &self.promoted[*promoted];
                                 self.sanitize_promoted(promoted_body, location);
@@ -454,7 +454,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
                                 check_err(self, place, promoted_ty, sty);
                             }
                         }
-                        StaticKind::Static(def_id) => {
+                        StaticKind::Static => {
                             let ty = self.tcx().type_of(*def_id);
                             let ty = self.cx.normalize(ty, location);
 
@@ -471,7 +471,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
                     let is_promoted = match place {
                         Place {
                             base: PlaceBase::Static(box Static {
-                                kind: StaticKind::Promoted(_),
+                                kind: StaticKind::Promoted(..),
                                 ..
                             }),
                             projection: None,
diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs
index 72d5588c34120..5caba637ccc4a 100644
--- a/src/librustc_mir/borrow_check/place_ext.rs
+++ b/src/librustc_mir/borrow_check/place_ext.rs
@@ -46,9 +46,9 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
                         }
                     }
                 }
-                PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. }) =>
+                PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_, _), .. }) =>
                     false,
-                PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) => {
+                PlaceBase::Static(box Static{ kind: StaticKind::Static, def_id, .. }) => {
                     tcx.is_mutable_static(*def_id)
                 }
             };
diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs
index 4dd2794f11301..4f469174b392d 100644
--- a/src/librustc_mir/borrow_check/places_conflict.rs
+++ b/src/librustc_mir/borrow_check/places_conflict.rs
@@ -329,11 +329,11 @@ fn place_base_conflict<'tcx>(
         }
         (PlaceBase::Static(s1), PlaceBase::Static(s2)) => {
             match (&s1.kind, &s2.kind) {
-                (StaticKind::Static(def_id_1), StaticKind::Static(def_id_2)) => {
-                    if def_id_1 != def_id_2 {
+                (StaticKind::Static, StaticKind::Static) => {
+                    if s1.def_id != s2.def_id {
                         debug!("place_element_conflict: DISJOINT-STATIC");
                         Overlap::Disjoint
-                    } else if tcx.is_mutable_static(*def_id_1) {
+                    } else if tcx.is_mutable_static(s1.def_id) {
                         // We ignore mutable statics - they can only be unsafe code.
                         debug!("place_element_conflict: IGNORE-STATIC-MUT");
                         Overlap::Disjoint
@@ -342,7 +342,7 @@ fn place_base_conflict<'tcx>(
                         Overlap::EqualOrDisjoint
                     }
                 },
-                (StaticKind::Promoted(promoted_1), StaticKind::Promoted(promoted_2)) => {
+                (StaticKind::Promoted(promoted_1, _), StaticKind::Promoted(promoted_2, _)) => {
                     if promoted_1 == promoted_2 {
                         if let ty::Array(_, len) = s1.ty.sty {
                             if let Some(0) = len.try_eval_usize(tcx, param_env) {
diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs
index 7005f274e0e7d..98cf4bba1c75f 100644
--- a/src/librustc_mir/build/expr/as_place.rs
+++ b/src/librustc_mir/build/expr/as_place.rs
@@ -126,7 +126,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             ExprKind::StaticRef { id } => block.and(Place {
                 base: PlaceBase::Static(Box::new(Static {
                     ty: expr.ty,
-                    kind: StaticKind::Static(id),
+                    kind: StaticKind::Static,
+                    def_id: id,
                 })),
                 projection: None,
             }),
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 85f9cbd37589a..23c9e7fdf67ce 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -585,7 +585,7 @@ where
         use rustc::mir::StaticKind;
 
         Ok(match place_static.kind {
-            StaticKind::Promoted(promoted) => {
+            StaticKind::Promoted(promoted, _) => {
                 let instance = self.frame().instance;
                 self.const_eval_raw(GlobalId {
                     instance,
@@ -593,11 +593,11 @@ where
                 })?
             }
 
-            StaticKind::Static(def_id) => {
+            StaticKind::Static => {
                 let ty = place_static.ty;
                 assert!(!ty.needs_subst());
                 let layout = self.layout_of(ty)?;
-                let instance = ty::Instance::mono(*self.tcx, def_id);
+                let instance = ty::Instance::mono(*self.tcx, place_static.def_id);
                 let cid = GlobalId {
                     instance,
                     promoted: None
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 9d80163f30f9d..512ace1a4728c 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -180,7 +180,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::mir::interpret::{AllocId, ConstValue};
 use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
-use rustc::ty::subst::{InternalSubsts, SubstsRef};
+use rustc::ty::subst::{InternalSubsts, Subst, SubstsRef};
 use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind, Instance};
 use rustc::ty::print::obsolete::DefPathBasedNames;
 use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast};
@@ -661,7 +661,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
                         _context: mir::visit::PlaceContext,
                         location: Location) {
         match place_base {
-            PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) => {
+            PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }) => {
                 debug!("visiting static {:?} @ {:?}", def_id, location);
 
                 let tcx = self.tcx;
@@ -670,8 +670,23 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
                     self.output.push(MonoItem::Static(*def_id));
                 }
             }
-            PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => {
-                // FIXME: should we handle promoteds here instead of eagerly in collect_neighbours?
+            PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted, substs), def_id, .. }) => {
+                debug!("collecting promoted(def_id: {:?}, promoted: {:?}, substs: {:?})", def_id, promoted, substs);
+                debug!("param_substs: {:?}", self.param_substs);
+                let param_env = ty::ParamEnv::reveal_all();
+                let cid = GlobalId {
+                    instance: Instance::new(*def_id, substs.subst(self.tcx, self.param_substs)),
+                    promoted: Some(*promoted),
+                };
+                debug!("cid: {:?}", cid);
+                match self.tcx.const_eval(param_env.and(cid)) {
+                    Ok(val) => collect_const(self.tcx, val, substs, self.output),
+                    Err(ErrorHandled::Reported) => {},
+                    Err(ErrorHandled::TooGeneric) => {
+                        let span = self.tcx.promoted_mir(*def_id)[*promoted].span;
+                        span_bug!(span, "collection encountered polymorphic constant")
+                    },
+                }
             }
             PlaceBase::Local(_) => {
                 // Locals have no relevance for collector
@@ -1231,24 +1246,6 @@ fn collect_neighbours<'tcx>(
         output,
         param_substs: instance.substs,
     }.visit_body(&body);
-
-    if let ty::InstanceDef::Item(def_id) = instance.def {
-        let param_env = ty::ParamEnv::reveal_all();
-        let promoted = tcx.promoted_mir(def_id);
-        for (promoted, promoted_body) in promoted.iter_enumerated() {
-            let cid = GlobalId {
-                instance,
-                promoted: Some(promoted),
-            };
-            match tcx.const_eval(param_env.and(cid)) {
-                Ok(val) => collect_const(tcx, val, instance.substs, output),
-                Err(ErrorHandled::Reported) => {},
-                Err(ErrorHandled::TooGeneric) => span_bug!(
-                    promoted_body.span, "collection encountered polymorphic constant",
-                ),
-            }
-        }
-    }
 }
 
 fn def_id_to_string(tcx: TyCtxt<'_>, def_id: DefId) -> String {
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index d5c5267a119d3..539922c54d12d 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -205,10 +205,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                 PlaceBase::Local(..) => {
                     // Locals are safe.
                 }
-                PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => {
+                PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => {
                     bug!("unsafety checking should happen before promotion")
                 }
-                PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), .. }) => {
+                PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }) => {
                     if self.tcx.is_mutable_static(*def_id) {
                         self.require_unsafe("use of mutable static",
                             "mutable statics can be mutated by multiple threads: aliasing \
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 9aeef16ba1e38..b6146b6b7227d 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -285,7 +285,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         place.iterate(|place_base, place_projection| {
             let mut eval = match place_base {
                 PlaceBase::Local(loc) => self.get_const(*loc).clone()?,
-                PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted), ..}) => {
+                PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted, _), ..}) => {
                     let generics = self.tcx.generics_of(self.source.def_id());
                     if generics.requires_monomorphization(self.tcx) {
                         // FIXME: can't handle code with generics
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 19a8769ce1633..533e08f5e1fd3 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -394,7 +394,6 @@ impl Inliner<'tcx> {
 
                 let mut local_map = IndexVec::with_capacity(callee_body.local_decls.len());
                 let mut scope_map = IndexVec::with_capacity(callee_body.source_scopes.len());
-                let promoted_map = IndexVec::with_capacity(self.tcx.promoted_mir(callsite.callee).len());
 
                 for mut scope in callee_body.source_scopes.iter().cloned() {
                     if scope.parent_scope.is_none() {
@@ -420,11 +419,6 @@ impl Inliner<'tcx> {
                     local_map.push(idx);
                 }
 
-                //TODO fixme
-                //promoted_map.extend(
-                //    self.tcx.promoted_mir(callsite.callee).iter().cloned().map(|p| caller_body.promoted.push(p))
-                //);
-
                 // If the call is something like `a[*i] = f(i)`, where
                 // `i : &mut usize`, then just duplicating the `a[*i]`
                 // Place could result in two different locations if `f`
@@ -485,12 +479,12 @@ impl Inliner<'tcx> {
                     args: &args,
                     local_map,
                     scope_map,
-                    promoted_map,
-                    _callsite: callsite,
+                    callsite,
                     destination: dest,
                     return_block,
                     cleanup_block: cleanup,
-                    in_cleanup_block: false
+                    in_cleanup_block: false,
+                    tcx: self.tcx,
                 };
 
 
@@ -645,12 +639,12 @@ struct Integrator<'a, 'tcx> {
     args: &'a [Local],
     local_map: IndexVec<Local, Local>,
     scope_map: IndexVec<SourceScope, SourceScope>,
-    promoted_map: IndexVec<Promoted, Promoted>,
-    _callsite: CallSite<'tcx>,
+    callsite: CallSite<'tcx>,
     destination: Place<'tcx>,
     return_block: BasicBlock,
     cleanup_block: Option<BasicBlock>,
     in_cleanup_block: bool,
+    tcx: TyCtxt<'tcx>,
 }
 
 impl<'a, 'tcx> Integrator<'a, 'tcx> {
@@ -701,14 +695,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
             },
             Place {
                 base: PlaceBase::Static(box Static {
-                    kind: StaticKind::Promoted(promoted),
+                    kind: StaticKind::Promoted(_, substs),
                     ..
                 }),
                 projection: None,
             } => {
-                if let Some(p) = self.promoted_map.get(*promoted).cloned() {
-                    *promoted = p;
-                }
+                let adjusted_substs = substs.subst(self.tcx, self.callsite.substs);
+                debug!("replacing substs {:?} with {:?}", substs, adjusted_substs);
+                *substs = adjusted_substs;
             },
             _ => self.super_place(place, _ctxt, _location)
         }
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 7015e2c087faa..cb0ce77d5c014 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -12,9 +12,11 @@
 //! initialization and can otherwise silence errors, if
 //! move analysis runs after promotion on broken MIR.
 
+use rustc::hir::def_id::DefId;
 use rustc::mir::*;
 use rustc::mir::visit::{PlaceContext, MutatingUseContext, MutVisitor, Visitor};
 use rustc::mir::traversal::ReversePostorder;
+use rustc::ty::subst::InternalSubsts;
 use rustc::ty::TyCtxt;
 use syntax_pos::Span;
 
@@ -293,17 +295,18 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
         new_temp
     }
 
-    fn promote_candidate(mut self, candidate: Candidate, next_promoted_id: usize) -> Option<Body<'tcx>> {
+    fn promote_candidate(mut self, def_id: DefId, candidate: Candidate, next_promoted_id: usize) -> Option<Body<'tcx>> {
         let mut operand = {
             let promoted = &mut self.promoted;
             let promoted_id = Promoted::new(next_promoted_id);
-            let mut promoted_place = |ty, span| {
+            let mut promoted_place = |ty, substs, span| {
                 promoted.span = span;
                 promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span);
                 Place {
                     base: PlaceBase::Static(box Static {
-                        kind: StaticKind::Promoted(promoted_id),
-                        ty
+                        kind: StaticKind::Promoted(promoted_id, substs),
+                        ty,
+                        def_id,
                     }),
                     projection: None,
                 }
@@ -319,7 +322,14 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                             let span = statement.source_info.span;
 
                             Operand::Move(Place {
-                                base: mem::replace(&mut place.base, promoted_place(ty, span).base),
+                                base: mem::replace(
+                                    &mut place.base,
+                                    promoted_place(
+                                        ty,
+                                        InternalSubsts::identity_for_item(self.tcx, def_id),
+                                        span,
+                                    ).base
+                                ),
                                 projection: None,
                             })
                         }
@@ -332,7 +342,16 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                         StatementKind::Assign(_, box Rvalue::Repeat(ref mut operand, _)) => {
                             let ty = operand.ty(local_decls, self.tcx);
                             let span = statement.source_info.span;
-                            mem::replace(operand, Operand::Copy(promoted_place(ty, span)))
+                            mem::replace(
+                                operand,
+                                Operand::Copy(
+                                    promoted_place(
+                                        ty,
+                                        InternalSubsts::identity_for_item(self.tcx, def_id),
+                                        span,
+                                    )
+                                )
+                            )
                         }
                         _ => bug!()
                     }
@@ -343,7 +362,12 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                         TerminatorKind::Call { ref mut args, .. } => {
                             let ty = args[index].ty(local_decls, self.tcx);
                             let span = terminator.source_info.span;
-                            let operand = Operand::Copy(promoted_place(ty, span));
+                            let operand =
+                                Operand::Copy(
+                                    promoted_place(
+                                        ty,
+                                        InternalSubsts::identity_for_item(self.tcx, def_id),
+                                        span));
                             mem::replace(&mut args[index], operand)
                         }
                         // We expected a `TerminatorKind::Call` for which we'd like to promote an
@@ -385,6 +409,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> {
 }
 
 pub fn promote_candidates<'tcx>(
+    def_id: DefId,
     body: &mut Body<'tcx>,
     tcx: TyCtxt<'tcx>,
     mut temps: IndexVec<Local, TempState>,
@@ -442,7 +467,7 @@ pub fn promote_candidates<'tcx>(
             keep_original: false
         };
 
-        if let Some(promoted) = promoter.promote_candidate(candidate, promotions.len()) {
+        if let Some(promoted) = promoter.promote_candidate(def_id, candidate, promotions.len()) {
             promotions.push(promoted);
         }
     }
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index dd4db479cc00b..70a394ad98330 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -223,7 +223,7 @@ trait Qualif {
             } => Self::in_local(cx, *local),
             PlaceRef {
                 base: PlaceBase::Static(box Static {
-                    kind: StaticKind::Promoted(_),
+                    kind: StaticKind::Promoted(..),
                     ..
                 }),
                 projection: None,
@@ -434,13 +434,13 @@ impl Qualif for IsNotPromotable {
 
     fn in_static(cx: &ConstCx<'_, 'tcx>, static_: &Static<'tcx>) -> bool {
         match static_.kind {
-            StaticKind::Promoted(_) => unreachable!(),
-            StaticKind::Static(def_id) => {
+            StaticKind::Promoted(_, _) => unreachable!(),
+            StaticKind::Static => {
                 // Only allow statics (not consts) to refer to other statics.
                 let allowed = cx.mode == Mode::Static || cx.mode == Mode::StaticMut;
 
                 !allowed ||
-                    cx.tcx.get_attrs(def_id).iter().any(
+                    cx.tcx.get_attrs(static_.def_id).iter().any(
                         |attr| attr.check_name(sym::thread_local)
                     )
             }
@@ -873,7 +873,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                     dest_projection = &proj.base;
                 },
                 (&PlaceBase::Static(box Static {
-                    kind: StaticKind::Promoted(_),
+                    kind: StaticKind::Promoted(..),
                     ..
                 }), None) => bug!("promoteds don't exist yet during promotion"),
                 (&PlaceBase::Static(box Static{ kind: _, .. }), None) => {
@@ -1028,10 +1028,10 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
         self.super_place_base(place_base, context, location);
         match place_base {
             PlaceBase::Local(_) => {}
-            PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_), .. }) => {
+            PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_, _), .. }) => {
                 unreachable!()
             }
-            PlaceBase::Static(box Static{ kind: StaticKind::Static(def_id), .. }) => {
+            PlaceBase::Static(box Static{ kind: StaticKind::Static, def_id, .. }) => {
                 if self.tcx
                         .get_attrs(*def_id)
                         .iter()
@@ -1661,7 +1661,7 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
 
             // Do the actual promotion, now that we know what's viable.
             self.promoted.set(
-                Some(promote_consts::promote_candidates(body, tcx, temps, candidates))
+                Some(promote_consts::promote_candidates(def_id, body, tcx, temps, candidates))
             );
         } else {
             if !body.control_flow_destroyed.is_empty() {
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index 334d0cee9fbe7..56093527aee24 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -264,11 +264,11 @@ fn check_place(
         }
 
         match place_base {
-            PlaceBase::Static(box Static { kind: StaticKind::Static(_), .. }) => {
+            PlaceBase::Static(box Static { kind: StaticKind::Static, .. }) => {
                 Err((span, "cannot access `static` items in const fn".into()))
             }
             PlaceBase::Local(_)
-            | PlaceBase::Static(box Static { kind: StaticKind::Promoted(_), .. }) => Ok(()),
+            | PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => Ok(()),
         }
     })
 }

From 34fe28bc67817db6743654f8eef8bbf8244f57bf Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Wed, 14 Aug 2019 08:08:17 -0400
Subject: [PATCH 119/943] Fix tidy

---
 src/librustc/query/mod.rs                           |  6 +++++-
 src/librustc_codegen_ssa/mir/place.rs               |  1 -
 src/librustc_metadata/decoder.rs                    |  3 ++-
 src/librustc_metadata/encoder.rs                    |  3 ++-
 src/librustc_mir/borrow_check/mod.rs                |  3 ++-
 src/librustc_mir/borrow_check/nll/renumber.rs       |  6 +++++-
 src/librustc_mir/borrow_check/nll/type_check/mod.rs |  6 +++++-
 src/librustc_mir/monomorphize/collector.rs          |  9 +++++----
 src/librustc_mir/transform/mod.rs                   | 10 +++++++---
 src/librustc_mir/transform/promote_consts.rs        |  7 ++++++-
 10 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index e1dbaeb5b173d..c4f7ca51f4a7a 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -110,7 +110,11 @@ rustc_queries! {
             no_hash
         }
 
-        query mir_validated(_: DefId) -> (&'tcx Steal<mir::Body<'tcx>>, &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>) {
+        query mir_validated(_: DefId) ->
+            (
+                &'tcx Steal<mir::Body<'tcx>>,
+                &'tcx Steal<IndexVec<mir::Promoted, mir::Body<'tcx>>>
+            ) {
             no_hash
         }
 
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index f7b94ea134cfc..b08093c3a71eb 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -460,7 +460,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 }),
                 projection: None,
             } => {
-                debug!("promoted={:?}, def_id={:?}, substs={:?}, self_substs={:?}", promoted, def_id, substs, self.instance.substs);
                 let param_env = ty::ParamEnv::reveal_all();
                 let instance = Instance::new(*def_id, substs.subst(bx.tcx(), self.instance.substs));
                 debug!("instance: {:?}", instance);
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 128e30be79929..2add8bf918398 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -924,7 +924,8 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    pub fn maybe_get_promoted_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Option<IndexVec<Promoted, Body<'tcx>>> {
+    pub fn maybe_get_promoted_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) ->
+        Option<IndexVec<Promoted, Body<'tcx>>> {
         match self.is_proc_macro(id) {
             true => None,
             false => self.entry(id).promoted_mir.map(|promoted| promoted.decode((self, tcx)),)
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index f3863fd788ae0..0b8d2438752fa 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1060,7 +1060,8 @@ impl EncodeContext<'tcx> {
         }
     }
 
-    fn encode_promoted_mir(&mut self, def_id: DefId) -> Option<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>> {
+    fn encode_promoted_mir(&mut self, def_id: DefId) ->
+        Option<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>> {
         debug!("EncodeContext::encode_promoted_mir({:?})", def_id);
         if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
             let promoted = self.tcx.promoted_mir(def_id);
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 33cec78f3dfd5..8ded539e7205a 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -151,7 +151,8 @@ fn do_mir_borrowck<'a, 'tcx>(
     // will have a lifetime tied to the inference context.
     let mut body: Body<'tcx> = input_body.clone();
     let mut promoted: IndexVec<Promoted, Body<'tcx>> = input_promoted.clone();
-    let free_regions = nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body, &mut promoted);
+    let free_regions =
+        nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body, &mut promoted);
     let body = &body; // no further changes
     let location_table = &LocationTable::new(body);
 
diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs
index 4e3ffb7af1601..c6a5c6fdfd0f2 100644
--- a/src/librustc_mir/borrow_check/nll/renumber.rs
+++ b/src/librustc_mir/borrow_check/nll/renumber.rs
@@ -7,7 +7,11 @@ use rustc_data_structures::indexed_vec::IndexVec;
 
 /// Replaces all free regions appearing in the MIR with fresh
 /// inference variables, returning the number of variables created.
-pub fn renumber_mir<'tcx>(infcx: &InferCtxt<'_, 'tcx>, body: &mut Body<'tcx>, promoted: &mut IndexVec<Promoted, Body<'tcx>>) {
+pub fn renumber_mir<'tcx>(
+    infcx: &InferCtxt<'_, 'tcx>,
+    body: &mut Body<'tcx>,
+    promoted: &mut IndexVec<Promoted, Body<'tcx>>,
+) {
     debug!("renumber_mir()");
     debug!("renumber_mir: body.arg_count={:?}", body.arg_count);
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 35dd5b5d7eb19..da1f64b05151b 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -384,7 +384,11 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
 }
 
 impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
-    fn new(cx: &'a mut TypeChecker<'b, 'tcx>, body: &'b Body<'tcx>, promoted: &'b IndexVec<Promoted, Body<'tcx>>) -> Self {
+    fn new(
+        cx: &'a mut TypeChecker<'b, 'tcx>,
+        body: &'b Body<'tcx>,
+        promoted: &'b IndexVec<Promoted, Body<'tcx>>,
+    ) -> Self {
         TypeVerifier {
             body,
             promoted,
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 512ace1a4728c..11f9df625285f 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -670,15 +670,16 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
                     self.output.push(MonoItem::Static(*def_id));
                 }
             }
-            PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted, substs), def_id, .. }) => {
-                debug!("collecting promoted(def_id: {:?}, promoted: {:?}, substs: {:?})", def_id, promoted, substs);
-                debug!("param_substs: {:?}", self.param_substs);
+            PlaceBase::Static(box Static {
+                kind: StaticKind::Promoted(promoted, substs),
+                def_id,
+                ..
+            }) => {
                 let param_env = ty::ParamEnv::reveal_all();
                 let cid = GlobalId {
                     instance: Instance::new(*def_id, substs.subst(self.tcx, self.param_substs)),
                     promoted: Some(*promoted),
                 };
-                debug!("cid: {:?}", cid);
                 match self.tcx.const_eval(param_env.and(cid)) {
                     Ok(val) => collect_const(self.tcx, val, substs, self.output),
                     Err(ErrorHandled::Reported) => {},
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index a78e78331ee3f..f59ad6bae0298 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -200,7 +200,10 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
     tcx.alloc_steal_mir(body)
 }
 
-fn mir_validated(tcx: TyCtxt<'tcx>, def_id: DefId) -> (&'tcx Steal<Body<'tcx>>, &'tcx Steal<IndexVec<Promoted, Body<'tcx>>>) {
+fn mir_validated(
+    tcx: TyCtxt<'tcx>,
+    def_id: DefId,
+) -> (&'tcx Steal<Body<'tcx>>, &'tcx Steal<IndexVec<Promoted, Body<'tcx>>>) {
     let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
     if let hir::BodyOwnerKind::Const = tcx.hir().body_owner_kind(hir_id) {
         // Ensure that we compute the `mir_const_qualif` for constants at
@@ -215,8 +218,9 @@ fn mir_validated(tcx: TyCtxt<'tcx>, def_id: DefId) -> (&'tcx Steal<Body<'tcx>>,
         &qualify_and_promote_pass,
         &simplify::SimplifyCfg::new("qualify-consts"),
     ]);
-    let promoted = qualify_and_promote_pass.promoted.into_inner();
-    (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted.unwrap_or_else(|| IndexVec::new())))
+    let promoted =
+        qualify_and_promote_pass.promoted.into_inner().unwrap_or_else(|| IndexVec::new());
+    (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
 }
 
 fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> {
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index cb0ce77d5c014..fd5b6c2a32825 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -295,7 +295,12 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
         new_temp
     }
 
-    fn promote_candidate(mut self, def_id: DefId, candidate: Candidate, next_promoted_id: usize) -> Option<Body<'tcx>> {
+    fn promote_candidate(
+        mut self,
+        def_id: DefId,
+        candidate: Candidate,
+        next_promoted_id: usize,
+    ) -> Option<Body<'tcx>> {
         let mut operand = {
             let promoted = &mut self.promoted;
             let promoted_id = Promoted::new(next_promoted_id);

From 9fdf5b555181ee6438a9cb01bb38ae5a52049475 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Wed, 14 Aug 2019 08:16:06 -0400
Subject: [PATCH 120/943] Remove unnecessary Option

---
 src/librustc_mir/transform/mod.rs            | 3 +--
 src/librustc_mir/transform/qualify_consts.rs | 6 +++---
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index f59ad6bae0298..c9bcdbe1bef50 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -218,8 +218,7 @@ fn mir_validated(
         &qualify_and_promote_pass,
         &simplify::SimplifyCfg::new("qualify-consts"),
     ]);
-    let promoted =
-        qualify_and_promote_pass.promoted.into_inner().unwrap_or_else(|| IndexVec::new());
+    let promoted = qualify_and_promote_pass.promoted.into_inner();
     (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
 }
 
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 70a394ad98330..7f8ae88342934 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1572,13 +1572,13 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> (u8, &BitSet<Local>) {
 }
 
 pub struct QualifyAndPromoteConstants<'tcx> {
-    pub promoted: Cell<Option<IndexVec<Promoted, Body<'tcx>>>>,
+    pub promoted: Cell<IndexVec<Promoted, Body<'tcx>>>,
 }
 
 impl<'tcx> Default for QualifyAndPromoteConstants<'tcx> {
     fn default() -> Self {
         QualifyAndPromoteConstants {
-            promoted: Cell::new(None),
+            promoted: Cell::new(IndexVec::new()),
         }
     }
 }
@@ -1661,7 +1661,7 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
 
             // Do the actual promotion, now that we know what's viable.
             self.promoted.set(
-                Some(promote_consts::promote_candidates(def_id, body, tcx, temps, candidates))
+                promote_consts::promote_candidates(def_id, body, tcx, temps, candidates)
             );
         } else {
             if !body.control_flow_destroyed.is_empty() {

From e63b9920302e860b4f50968eb332f534d62b8055 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Thu, 15 Aug 2019 06:39:31 -0400
Subject: [PATCH 121/943] Resolve PR comments

---
 src/librustc_metadata/decoder.rs              |   7 +-
 src/librustc_metadata/encoder.rs              |   6 +-
 src/librustc_mir/borrow_check/nll/renumber.rs |  13 +-
 src/librustc_mir/shim.rs                      |   2 +-
 src/librustc_mir/transform/mod.rs             | 153 +++++++-----------
 src/librustc_mir/transform/promote_consts.rs  |  31 ++--
 6 files changed, 81 insertions(+), 131 deletions(-)

diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 2add8bf918398..5b9cb966af235 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -924,8 +924,11 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    pub fn maybe_get_promoted_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) ->
-        Option<IndexVec<Promoted, Body<'tcx>>> {
+    pub fn maybe_get_promoted_mir(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        id: DefIndex,
+    ) -> Option<IndexVec<Promoted, Body<'tcx>>> {
         match self.is_proc_macro(id) {
             true => None,
             false => self.entry(id).promoted_mir.map(|promoted| promoted.decode((self, tcx)),)
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 0b8d2438752fa..1797d77461567 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1060,8 +1060,10 @@ impl EncodeContext<'tcx> {
         }
     }
 
-    fn encode_promoted_mir(&mut self, def_id: DefId) ->
-        Option<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>> {
+    fn encode_promoted_mir(
+        &mut self,
+        def_id: DefId,
+    ) -> Option<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>> {
         debug!("EncodeContext::encode_promoted_mir({:?})", def_id);
         if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
             let promoted = self.tcx.promoted_mir(def_id);
diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs
index c6a5c6fdfd0f2..c479c38f30c7e 100644
--- a/src/librustc_mir/borrow_check/nll/renumber.rs
+++ b/src/librustc_mir/borrow_check/nll/renumber.rs
@@ -16,7 +16,11 @@ pub fn renumber_mir<'tcx>(
     debug!("renumber_mir: body.arg_count={:?}", body.arg_count);
 
     let mut visitor = NLLVisitor { infcx };
-    visitor.visit_promoted(promoted);
+
+    for body in promoted.iter_mut() {
+        visitor.visit_body(body);
+    }
+
     visitor.visit_body(body);
 }
 
@@ -47,13 +51,6 @@ impl<'a, 'tcx> NLLVisitor<'a, 'tcx> {
     {
         renumber_regions(self.infcx, value)
     }
-
-    fn visit_promoted(&mut self, promoted: &mut IndexVec<Promoted, Body<'tcx>>) {
-        debug!("visiting promoted mir");
-        for body in promoted.iter_mut() {
-            self.visit_body(body);
-        }
-    }
 }
 
 impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> {
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 9d31015f84558..aa83255bf62f4 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -112,7 +112,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
     };
     debug!("make_shim({:?}) = untransformed {:?}", instance, result);
 
-    run_passes(tcx, &mut result, instance, MirPhase::Const, &[
+    run_passes(tcx, &mut result, instance, None, MirPhase::Const, &[
         &add_moves_for_packed_drops::AddMovesForPackedDrops,
         &no_landing_pads::NoLandingPads,
         &remove_noop_landing_pads::RemoveNoopLandingPads,
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index c9bcdbe1bef50..ac291c2996d06 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -149,41 +149,38 @@ pub fn run_passes(
     tcx: TyCtxt<'tcx>,
     body: &mut Body<'tcx>,
     instance: InstanceDef<'tcx>,
+    promoted: Option<Promoted>,
     mir_phase: MirPhase,
     passes: &[&dyn MirPass<'tcx>],
 ) {
     let phase_index = mir_phase.phase_index();
 
-    let run_passes = |body: &mut Body<'tcx>, promoted| {
-        if body.phase >= mir_phase {
-            return;
-        }
+    if body.phase >= mir_phase {
+        return;
+    }
 
-        let source = MirSource {
-            instance,
-            promoted,
-        };
-        let mut index = 0;
-        let mut run_pass = |pass: &dyn MirPass<'tcx>| {
-            let run_hooks = |body: &_, index, is_after| {
-                dump_mir::on_mir_pass(tcx, &format_args!("{:03}-{:03}", phase_index, index),
-                                      &pass.name(), source, body, is_after);
-            };
-            run_hooks(body, index, false);
-            pass.run_pass(tcx, source, body);
-            run_hooks(body, index, true);
-
-            index += 1;
+    let source = MirSource {
+        instance,
+        promoted,
+    };
+    let mut index = 0;
+    let mut run_pass = |pass: &dyn MirPass<'tcx>| {
+        let run_hooks = |body: &_, index, is_after| {
+            dump_mir::on_mir_pass(tcx, &format_args!("{:03}-{:03}", phase_index, index),
+                                    &pass.name(), source, body, is_after);
         };
+        run_hooks(body, index, false);
+        pass.run_pass(tcx, source, body);
+        run_hooks(body, index, true);
 
-        for pass in passes {
-            run_pass(*pass);
-        }
-
-        body.phase = mir_phase;
+        index += 1;
     };
 
-    run_passes(body, None);
+    for pass in passes {
+        run_pass(*pass);
+    }
+
+    body.phase = mir_phase;
 }
 
 fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
@@ -191,7 +188,7 @@ fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<Body<'_>> {
     let _ = tcx.unsafety_check_result(def_id);
 
     let mut body = tcx.mir_built(def_id).steal();
-    run_passes(tcx, &mut body, InstanceDef::Item(def_id), MirPhase::Const, &[
+    run_passes(tcx, &mut body, InstanceDef::Item(def_id), None, MirPhase::Const, &[
         // What we need to do constant evaluation.
         &simplify::SimplifyCfg::new("initial"),
         &rustc_peek::SanityCheck,
@@ -213,7 +210,7 @@ fn mir_validated(
 
     let mut body = tcx.mir_const(def_id).steal();
     let qualify_and_promote_pass = qualify_consts::QualifyAndPromoteConstants::default();
-    run_passes(tcx, &mut body, InstanceDef::Item(def_id), MirPhase::Validated, &[
+    run_passes(tcx, &mut body, InstanceDef::Item(def_id), None, MirPhase::Validated, &[
         // What we need to run borrowck etc.
         &qualify_and_promote_pass,
         &simplify::SimplifyCfg::new("qualify-consts"),
@@ -222,26 +219,13 @@ fn mir_validated(
     (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
 }
 
-fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> {
-    if tcx.is_constructor(def_id) {
-        // There's no reason to run all of the MIR passes on constructors when
-        // we can just output the MIR we want directly. This also saves const
-        // qualification and borrow checking the trouble of special casing
-        // constructors.
-        return shim::build_adt_ctor(tcx, def_id);
-    }
-
-    // (Mir-)Borrowck uses `mir_validated`, so we have to force it to
-    // execute before we can steal.
-    tcx.ensure().mir_borrowck(def_id);
-
-    if tcx.use_ast_borrowck() {
-        tcx.ensure().borrowck(def_id);
-    }
-
-    let (body, _) = tcx.mir_validated(def_id);
-    let mut body = body.steal();
-    run_passes(tcx, &mut body, InstanceDef::Item(def_id), MirPhase::Optimized, &[
+fn run_optimization_passes<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    body: &mut Body<'tcx>,
+    def_id: DefId,
+    promoted: Option<Promoted>,
+) {
+    run_passes(tcx, body, InstanceDef::Item(def_id), promoted, MirPhase::Optimized, &[
         // Remove all things only needed by analysis
         &no_landing_pads::NoLandingPads,
         &simplify_branches::SimplifyBranches::new("initial"),
@@ -292,6 +276,28 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> {
         &add_call_guards::CriticalCallEdges,
         &dump_mir::Marker("PreCodegen"),
     ]);
+}
+
+fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> {
+    if tcx.is_constructor(def_id) {
+        // There's no reason to run all of the MIR passes on constructors when
+        // we can just output the MIR we want directly. This also saves const
+        // qualification and borrow checking the trouble of special casing
+        // constructors.
+        return shim::build_adt_ctor(tcx, def_id);
+    }
+
+    // (Mir-)Borrowck uses `mir_validated`, so we have to force it to
+    // execute before we can steal.
+    tcx.ensure().mir_borrowck(def_id);
+
+    if tcx.use_ast_borrowck() {
+        tcx.ensure().borrowck(def_id);
+    }
+
+    let (body, _) = tcx.mir_validated(def_id);
+    let mut body = body.steal();
+    run_optimization_passes(tcx, &mut body, def_id, None);
     tcx.arena.alloc(body)
 }
 
@@ -304,57 +310,8 @@ fn promoted_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx IndexVec<Promot
     let (_, promoted) = tcx.mir_validated(def_id);
     let mut promoted = promoted.steal();
 
-    for mut body in promoted.iter_mut() {
-        run_passes(tcx, &mut body, InstanceDef::Item(def_id), MirPhase::Optimized, &[
-            // Remove all things only needed by analysis
-            &no_landing_pads::NoLandingPads,
-            &simplify_branches::SimplifyBranches::new("initial"),
-            &remove_noop_landing_pads::RemoveNoopLandingPads,
-            &cleanup_post_borrowck::CleanupNonCodegenStatements,
-
-            &simplify::SimplifyCfg::new("early-opt"),
-
-            // These next passes must be executed together
-            &add_call_guards::CriticalCallEdges,
-            &elaborate_drops::ElaborateDrops,
-            &no_landing_pads::NoLandingPads,
-            // AddMovesForPackedDrops needs to run after drop
-            // elaboration.
-            &add_moves_for_packed_drops::AddMovesForPackedDrops,
-            // AddRetag needs to run after ElaborateDrops, and it needs
-            // an AllCallEdges pass right before it.  Otherwise it should
-            // run fairly late, but before optimizations begin.
-            &add_call_guards::AllCallEdges,
-            &add_retag::AddRetag,
-
-            &simplify::SimplifyCfg::new("elaborate-drops"),
-
-            // No lifetime analysis based on borrowing can be done from here on out.
-
-            // From here on out, regions are gone.
-            &erase_regions::EraseRegions,
-
-            // Optimizations begin.
-            &uniform_array_move_out::RestoreSubsliceArrayMoveOut,
-            &inline::Inline,
-
-            // Lowering generator control-flow and variables
-            // has to happen before we do anything else to them.
-            &generator::StateTransform,
-
-            &instcombine::InstCombine,
-            &const_prop::ConstProp,
-            &simplify_branches::SimplifyBranches::new("after-const-prop"),
-            &deaggregator::Deaggregator,
-            &copy_prop::CopyPropagation,
-            &simplify_branches::SimplifyBranches::new("after-copy-prop"),
-            &remove_noop_landing_pads::RemoveNoopLandingPads,
-            &simplify::SimplifyCfg::new("final"),
-            &simplify::SimplifyLocals,
-
-            &add_call_guards::CriticalCallEdges,
-            &dump_mir::Marker("PreCodegen"),
-        ]);
+    for (p, mut body) in promoted.iter_enumerated_mut() {
+        run_optimization_passes(tcx, &mut body, def_id, Some(p));
     }
 
     tcx.intern_promoted(promoted)
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index fd5b6c2a32825..cdccdfea39943 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -304,12 +304,17 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
         let mut operand = {
             let promoted = &mut self.promoted;
             let promoted_id = Promoted::new(next_promoted_id);
-            let mut promoted_place = |ty, substs, span| {
+            let tcx = self.tcx;
+            let mut promoted_place = |ty, span| {
                 promoted.span = span;
                 promoted.local_decls[RETURN_PLACE] = LocalDecl::new_return_place(ty, span);
                 Place {
                     base: PlaceBase::Static(box Static {
-                        kind: StaticKind::Promoted(promoted_id, substs),
+                        kind:
+                            StaticKind::Promoted(
+                                promoted_id,
+                                InternalSubsts::identity_for_item(tcx, def_id),
+                            ),
                         ty,
                         def_id,
                     }),
@@ -329,11 +334,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                             Operand::Move(Place {
                                 base: mem::replace(
                                     &mut place.base,
-                                    promoted_place(
-                                        ty,
-                                        InternalSubsts::identity_for_item(self.tcx, def_id),
-                                        span,
-                                    ).base
+                                    promoted_place(ty, span).base
                                 ),
                                 projection: None,
                             })
@@ -349,13 +350,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                             let span = statement.source_info.span;
                             mem::replace(
                                 operand,
-                                Operand::Copy(
-                                    promoted_place(
-                                        ty,
-                                        InternalSubsts::identity_for_item(self.tcx, def_id),
-                                        span,
-                                    )
-                                )
+                                Operand::Copy(promoted_place(ty, span))
                             )
                         }
                         _ => bug!()
@@ -367,12 +362,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                         TerminatorKind::Call { ref mut args, .. } => {
                             let ty = args[index].ty(local_decls, self.tcx);
                             let span = terminator.source_info.span;
-                            let operand =
-                                Operand::Copy(
-                                    promoted_place(
-                                        ty,
-                                        InternalSubsts::identity_for_item(self.tcx, def_id),
-                                        span));
+                            let operand = Operand::Copy(promoted_place(ty, span));
                             mem::replace(&mut args[index], operand)
                         }
                         // We expected a `TerminatorKind::Call` for which we'd like to promote an
@@ -472,6 +462,7 @@ pub fn promote_candidates<'tcx>(
             keep_original: false
         };
 
+        //FIXME(oli-obk): having a `maybe_push()` method on `IndexVec` might be nice
         if let Some(promoted) = promoter.promote_candidate(def_id, candidate, promotions.len()) {
             promotions.push(promoted);
         }

From 84556502e69e1741938610e4af5800fe0cee9975 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Fri, 16 Aug 2019 20:31:28 -0400
Subject: [PATCH 122/943] Handle statics in `Subst::subst()` by implementing
 `TypeFoldable`

---
 src/librustc/mir/mod.rs               | 58 +++++++++++++++++++++++++--
 src/librustc_codegen_ssa/mir/place.rs | 11 +----
 src/librustc_mir/transform/inline.rs  | 15 -------
 3 files changed, 56 insertions(+), 28 deletions(-)

diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 69e98583b191c..60efeaab97602 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1729,7 +1729,7 @@ pub enum PlaceBase<'tcx> {
 }
 
 /// We store the normalized type to avoid requiring normalization when reading MIR
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
 pub struct Static<'tcx> {
     pub ty: Ty<'tcx>,
     pub kind: StaticKind<'tcx>,
@@ -1737,7 +1737,7 @@ pub struct Static<'tcx> {
 }
 
 #[derive(
-    Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable,
+    Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable,
 )]
 pub enum StaticKind<'tcx> {
     Promoted(Promoted, SubstsRef<'tcx>),
@@ -3221,13 +3221,63 @@ impl<'tcx> TypeFoldable<'tcx> for Terminator<'tcx> {
 impl<'tcx> TypeFoldable<'tcx> for Place<'tcx> {
     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         Place {
-            base: self.base.clone(),
+            base: self.base.fold_with(folder),
             projection: self.projection.fold_with(folder),
         }
     }
 
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.projection.visit_with(visitor)
+        self.base.visit_with(visitor) || self.projection.visit_with(visitor)
+    }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for PlaceBase<'tcx> {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
+        match self {
+            PlaceBase::Local(local) => PlaceBase::Local(local.fold_with(folder)),
+            PlaceBase::Static(static_) => PlaceBase::Static(static_.fold_with(folder)),
+        }
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        match self {
+            PlaceBase::Local(local) => local.visit_with(visitor),
+            PlaceBase::Static(static_) => (**static_).visit_with(visitor),
+        }
+    }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for Static<'tcx> {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
+        Static {
+            ty: self.ty.fold_with(folder),
+            kind: self.kind.fold_with(folder),
+            def_id: self.def_id,
+        }
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        let Static { ty, kind, def_id: _ } = self;
+
+        ty.visit_with(visitor) || kind.visit_with(visitor)
+    }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for StaticKind<'tcx> {
+    fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
+        match self {
+            StaticKind::Promoted(promoted, substs) =>
+                StaticKind::Promoted(promoted.fold_with(folder), substs.fold_with(folder)),
+            StaticKind::Static => StaticKind::Static
+        }
+    }
+
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
+        match self {
+            StaticKind::Promoted(promoted, substs) =>
+                promoted.visit_with(visitor) || substs.visit_with(visitor),
+            StaticKind::Static => { false }
+        }
     }
 }
 
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index b08093c3a71eb..ac72928a89677 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -1,5 +1,4 @@
 use rustc::ty::{self, Instance, Ty};
-use rustc::ty::subst::Subst;
 use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt};
 use rustc::mir;
 use rustc::mir::tcx::PlaceTy;
@@ -461,18 +460,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 projection: None,
             } => {
                 let param_env = ty::ParamEnv::reveal_all();
-                let instance = Instance::new(*def_id, substs.subst(bx.tcx(), self.instance.substs));
-                debug!("instance: {:?}", instance);
+                let instance = Instance::new(*def_id, self.monomorphize(substs));
                 let cid = mir::interpret::GlobalId {
                     instance: instance,
                     promoted: Some(*promoted),
                 };
-                let mono_ty = tcx.subst_and_normalize_erasing_regions(
-                    instance.substs,
-                    param_env,
-                    ty,
-                );
-                let layout = cx.layout_of(mono_ty);
+                let layout = cx.layout_of(self.monomorphize(&ty));
                 match bx.tcx().const_eval(param_env.and(cid)) {
                     Ok(val) => match val.val {
                         mir::interpret::ConstValue::ByRef { alloc, offset } => {
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 533e08f5e1fd3..f31303c642faa 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -479,12 +479,10 @@ impl Inliner<'tcx> {
                     args: &args,
                     local_map,
                     scope_map,
-                    callsite,
                     destination: dest,
                     return_block,
                     cleanup_block: cleanup,
                     in_cleanup_block: false,
-                    tcx: self.tcx,
                 };
 
 
@@ -639,12 +637,10 @@ struct Integrator<'a, 'tcx> {
     args: &'a [Local],
     local_map: IndexVec<Local, Local>,
     scope_map: IndexVec<SourceScope, SourceScope>,
-    callsite: CallSite<'tcx>,
     destination: Place<'tcx>,
     return_block: BasicBlock,
     cleanup_block: Option<BasicBlock>,
     in_cleanup_block: bool,
-    tcx: TyCtxt<'tcx>,
 }
 
 impl<'a, 'tcx> Integrator<'a, 'tcx> {
@@ -693,17 +689,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
                 // Return pointer; update the place itself
                 *place = self.destination.clone();
             },
-            Place {
-                base: PlaceBase::Static(box Static {
-                    kind: StaticKind::Promoted(_, substs),
-                    ..
-                }),
-                projection: None,
-            } => {
-                let adjusted_substs = substs.subst(self.tcx, self.callsite.substs);
-                debug!("replacing substs {:?} with {:?}", substs, adjusted_substs);
-                *substs = adjusted_substs;
-            },
             _ => self.super_place(place, _ctxt, _location)
         }
     }

From 5c45420bdad8d3bf950ff3c46e1856348a7ddc7b Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Sun, 4 Aug 2019 22:23:32 -0400
Subject: [PATCH 123/943] Changed tests

---
 src/test/incremental/hashes/for_loops.rs      |  2 +-
 src/test/ui/consts/array-literal-index-oob.rs |  1 -
 .../ui/consts/array-literal-index-oob.stderr  |  8 +----
 .../ui/consts/const-eval/issue-43197.stderr   |  8 ++---
 .../ui/consts/const-eval/promoted_errors.rs   |  6 ++--
 .../consts/const-eval/promoted_errors.stderr  | 30 ++++++-------------
 6 files changed, 17 insertions(+), 38 deletions(-)

diff --git a/src/test/incremental/hashes/for_loops.rs b/src/test/incremental/hashes/for_loops.rs
index ca45d36a6b0e4..5d0b8b867b22f 100644
--- a/src/test/incremental/hashes/for_loops.rs
+++ b/src/test/incremental/hashes/for_loops.rs
@@ -94,7 +94,7 @@ pub fn change_iterable() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, optimized_mir")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_iterable() {
     let mut _x = 0;
diff --git a/src/test/ui/consts/array-literal-index-oob.rs b/src/test/ui/consts/array-literal-index-oob.rs
index 76013c77de0c2..492182921ba34 100644
--- a/src/test/ui/consts/array-literal-index-oob.rs
+++ b/src/test/ui/consts/array-literal-index-oob.rs
@@ -2,5 +2,4 @@ fn main() {
     &{[1, 2, 3][4]};
     //~^ ERROR index out of bounds
     //~| ERROR reaching this expression at runtime will panic or abort
-    //~| ERROR this expression will panic at runtime
 }
diff --git a/src/test/ui/consts/array-literal-index-oob.stderr b/src/test/ui/consts/array-literal-index-oob.stderr
index 18a09fdda7be4..0ddc2a0e79cd3 100644
--- a/src/test/ui/consts/array-literal-index-oob.stderr
+++ b/src/test/ui/consts/array-literal-index-oob.stderr
@@ -6,12 +6,6 @@ LL |     &{[1, 2, 3][4]};
    |
    = note: `#[deny(const_err)]` on by default
 
-error: this expression will panic at runtime
-  --> $DIR/array-literal-index-oob.rs:2:5
-   |
-LL |     &{[1, 2, 3][4]};
-   |     ^^^^^^^^^^^^^^^ index out of bounds: the len is 3 but the index is 4
-
 error: reaching this expression at runtime will panic or abort
   --> $DIR/array-literal-index-oob.rs:2:7
    |
@@ -20,5 +14,5 @@ LL |     &{[1, 2, 3][4]};
    |       |
    |       index out of bounds: the len is 3 but the index is 4
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/consts/const-eval/issue-43197.stderr b/src/test/ui/consts/const-eval/issue-43197.stderr
index 478e453fe0834..d971d825f278c 100644
--- a/src/test/ui/consts/const-eval/issue-43197.stderr
+++ b/src/test/ui/consts/const-eval/issue-43197.stderr
@@ -21,16 +21,16 @@ LL |     const Y: u32 = foo(0-1);
    |                        attempt to subtract with overflow
 
 error[E0080]: evaluation of constant expression failed
-  --> $DIR/issue-43197.rs:12:26
+  --> $DIR/issue-43197.rs:12:23
    |
 LL |     println!("{} {}", X, Y);
-   |                          ^ referenced constant has errors
+   |                       ^ referenced constant has errors
 
 error[E0080]: evaluation of constant expression failed
-  --> $DIR/issue-43197.rs:12:23
+  --> $DIR/issue-43197.rs:12:26
    |
 LL |     println!("{} {}", X, Y);
-   |                       ^ referenced constant has errors
+   |                          ^ referenced constant has errors
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs
index fa8859cbb3bb6..cd989731452b3 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors.rs
@@ -7,15 +7,13 @@ fn main() {
     let _x = 0u32 - 1;
     //~^ ERROR this expression will panic at runtime [const_err]
     println!("{}", 1/(1-1));
-    //~^ ERROR this expression will panic at runtime [const_err]
-    //~| ERROR attempt to divide by zero [const_err]
+    //~^ ERROR attempt to divide by zero [const_err]
     //~| ERROR reaching this expression at runtime will panic or abort [const_err]
     let _x = 1/(1-1);
     //~^ ERROR const_err
     //~| ERROR const_err
     println!("{}", 1/(false as u32));
-    //~^ ERROR this expression will panic at runtime [const_err]
-    //~| ERROR attempt to divide by zero [const_err]
+    //~^ ERROR attempt to divide by zero [const_err]
     //~| ERROR reaching this expression at runtime will panic or abort [const_err]
     let _x = 1/(false as u32);
     //~^ ERROR const_err
diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr
index 12407accf096f..40d5c73e86679 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.stderr
@@ -16,59 +16,47 @@ error: attempt to divide by zero
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^
 
-error: this expression will panic at runtime
+error: reaching this expression at runtime will panic or abort
   --> $DIR/promoted_errors.rs:9:20
    |
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:13:14
+  --> $DIR/promoted_errors.rs:12:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:13:14
+  --> $DIR/promoted_errors.rs:12:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:16:20
+  --> $DIR/promoted_errors.rs:15:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:16:20
+error: reaching this expression at runtime will panic or abort
+  --> $DIR/promoted_errors.rs:15:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:20:14
+  --> $DIR/promoted_errors.rs:18:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:20:14
+  --> $DIR/promoted_errors.rs:18:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
-error: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:16:20
-   |
-LL |     println!("{}", 1/(false as u32));
-   |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
-
-error: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:9:20
-   |
-LL |     println!("{}", 1/(1-1));
-   |                    ^^^^^^^ attempt to divide by zero
-
-error: aborting due to 11 previous errors
+error: aborting due to 9 previous errors
 

From a078a34f057a8a6a779bf8cb0c12dcbd4ba6c0df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= <rosto@tlen.pl>
Date: Thu, 22 Aug 2019 13:04:32 +0200
Subject: [PATCH 124/943] Fix a typo.

---
 src/liballoc/collections/vec_deque.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 7315963cc8b1d..6b5e48597e4dd 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -1810,7 +1810,7 @@ impl<T> VecDeque<T> {
         other
     }
 
-    /// Moves all the elements of `other` into `Self`, leaving `other` empty.
+    /// Moves all the elements of `other` into `self`, leaving `other` empty.
     ///
     /// # Panics
     ///

From 4ee6ee0daa13d53564f64932fa1e2ad37be7d879 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= <rosto@tlen.pl>
Date: Thu, 22 Aug 2019 13:06:39 +0200
Subject: [PATCH 125/943] Fix formatting.

---
 src/liballoc/collections/vec_deque.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs
index 6b5e48597e4dd..a4a0fbb194dd4 100644
--- a/src/liballoc/collections/vec_deque.rs
+++ b/src/liballoc/collections/vec_deque.rs
@@ -1847,7 +1847,7 @@ impl<T> VecDeque<T> {
     ///
     /// let mut buf = VecDeque::new();
     /// buf.extend(1..5);
-    /// buf.retain(|&x| x%2 == 0);
+    /// buf.retain(|&x| x % 2 == 0);
     /// assert_eq!(buf, [2, 4]);
     /// ```
     ///

From 7e13679cdedab8e39275c3138e0bfa795541ab67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= <rosto@tlen.pl>
Date: Thu, 22 Aug 2019 13:12:31 +0200
Subject: [PATCH 126/943] Remove redundant `mut`.

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

diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 1f384cbada3da..fbdb577a7f060 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -191,7 +191,7 @@ impl OsString {
     /// ```
     /// use std::ffi::OsString;
     ///
-    /// let mut os_string = OsString::with_capacity(10);
+    /// let os_string = OsString::with_capacity(10);
     /// let capacity = os_string.capacity();
     ///
     /// // This push is done without reallocating

From 49dce2935f94426d4464a82b7d2e19ea0ba79460 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= <rosto@tlen.pl>
Date: Thu, 22 Aug 2019 13:14:42 +0200
Subject: [PATCH 127/943] Fix punctuation.

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

diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index fbdb577a7f060..d0e35cce6411b 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -616,7 +616,7 @@ impl OsStr {
     /// Note that this does **not** return the number of bytes in the string in
     /// OS string form.
     ///
-    /// The length returned is that of the underlying storage used by `OsStr`;
+    /// The length returned is that of the underlying storage used by `OsStr`.
     /// As discussed in the [`OsString`] introduction, [`OsString`] and `OsStr`
     /// store strings in a form best suited for cheap inter-conversion between
     /// native-platform and Rust string forms, which may differ significantly

From 3b04e91d275e9c0983814c3b7acc79f52cff3601 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= <rosto@tlen.pl>
Date: Thu, 22 Aug 2019 14:27:51 +0200
Subject: [PATCH 128/943] Change code formatting for readability.

---
 src/libcore/num/f32.rs |  2 +-
 src/libcore/num/f64.rs |  2 +-
 src/libstd/f32.rs      | 18 +++++++++---------
 src/libstd/f64.rs      | 18 +++++++++---------
 4 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 8ff78166a9f2d..22e7573eca65b 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -315,7 +315,7 @@ impl f32 {
     /// use std::f32;
     ///
     /// let x = 2.0_f32;
-    /// let abs_difference = (x.recip() - (1.0/x)).abs();
+    /// let abs_difference = (x.recip() - (1.0 / x)).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index d45c04f45afc2..bbe1d04078060 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -327,7 +327,7 @@ impl f64 {
     ///
     /// ```
     /// let x = 2.0_f64;
-    /// let abs_difference = (x.recip() - (1.0/x)).abs();
+    /// let abs_difference = (x.recip() - (1.0 / x)).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index f649170c40372..6c71a0428ef09 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -236,7 +236,7 @@ impl f32 {
     /// let b = 60.0_f32;
     ///
     /// // 100.0
-    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+    /// let abs_difference = (m.mul_add(x, b) - ((m * x) + b)).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -318,7 +318,7 @@ impl f32 {
     /// use std::f32;
     ///
     /// let x = 2.0_f32;
-    /// let abs_difference = (x.powi(2) - x*x).abs();
+    /// let abs_difference = (x.powi(2) - (x * x)).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -336,7 +336,7 @@ impl f32 {
     /// use std::f32;
     ///
     /// let x = 2.0_f32;
-    /// let abs_difference = (x.powf(2.0) - x*x).abs();
+    /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -623,7 +623,7 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let x = 2.0*f32::consts::PI;
+    /// let x = 2.0 * f32::consts::PI;
     ///
     /// let abs_difference = (x.cos() - 1.0).abs();
     ///
@@ -745,8 +745,8 @@ impl f32 {
     /// let x2 = -3.0f32;
     /// let y2 = 3.0f32;
     ///
-    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
-    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
+    /// let abs_difference_1 = (y1.atan2(x1) - (-pi / 4.0)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * pi / 4.0)).abs();
     ///
     /// assert!(abs_difference_1 <= f32::EPSILON);
     /// assert!(abs_difference_2 <= f32::EPSILON);
@@ -834,7 +834,7 @@ impl f32 {
     ///
     /// let f = x.sinh();
     /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
-    /// let g = (e*e - 1.0)/(2.0*e);
+    /// let g = ((e * e) - 1.0) / (2.0 * e);
     /// let abs_difference = (f - g).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
@@ -856,7 +856,7 @@ impl f32 {
     /// let x = 1.0f32;
     /// let f = x.cosh();
     /// // Solving cosh() at 1 gives this result
-    /// let g = (e*e + 1.0)/(2.0*e);
+    /// let g = ((e * e) + 1.0) / (2.0 * e);
     /// let abs_difference = (f - g).abs();
     ///
     /// // Same result
@@ -880,7 +880,7 @@ impl f32 {
     ///
     /// let f = x.tanh();
     /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
-    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
+    /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2));
     /// let abs_difference = (f - g).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index f61630997dcdb..43c2debe5ee38 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -212,7 +212,7 @@ impl f64 {
     /// let b = 60.0_f64;
     ///
     /// // 100.0
-    /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
+    /// let abs_difference = (m.mul_add(x, b) - ((m * x) + b)).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -291,7 +291,7 @@ impl f64 {
     ///
     /// ```
     /// let x = 2.0_f64;
-    /// let abs_difference = (x.powi(2) - x*x).abs();
+    /// let abs_difference = (x.powi(2) - (x * x)).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -307,7 +307,7 @@ impl f64 {
     ///
     /// ```
     /// let x = 2.0_f64;
-    /// let abs_difference = (x.powf(2.0) - x*x).abs();
+    /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -556,7 +556,7 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let x = 2.0*f64::consts::PI;
+    /// let x = 2.0 * f64::consts::PI;
     ///
     /// let abs_difference = (x.cos() - 1.0).abs();
     ///
@@ -672,8 +672,8 @@ impl f64 {
     /// let x2 = -3.0_f64;
     /// let y2 = 3.0_f64;
     ///
-    /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
-    /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
+    /// let abs_difference_1 = (y1.atan2(x1) - (-pi / 4.0)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * pi / 4.0)).abs();
     ///
     /// assert!(abs_difference_1 < 1e-10);
     /// assert!(abs_difference_2 < 1e-10);
@@ -759,7 +759,7 @@ impl f64 {
     ///
     /// let f = x.sinh();
     /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
-    /// let g = (e*e - 1.0)/(2.0*e);
+    /// let g = ((e * e) - 1.0) / (2.0 * e);
     /// let abs_difference = (f - g).abs();
     ///
     /// assert!(abs_difference < 1e-10);
@@ -781,7 +781,7 @@ impl f64 {
     /// let x = 1.0_f64;
     /// let f = x.cosh();
     /// // Solving cosh() at 1 gives this result
-    /// let g = (e*e + 1.0)/(2.0*e);
+    /// let g = ((e * e) + 1.0) / (2.0 * e);
     /// let abs_difference = (f - g).abs();
     ///
     /// // Same result
@@ -805,7 +805,7 @@ impl f64 {
     ///
     /// let f = x.tanh();
     /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
-    /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
+    /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2));
     /// let abs_difference = (f - g).abs();
     ///
     /// assert!(abs_difference < 1.0e-10);

From cdedd268d2d1f6e9fb376d368bb40564441474cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= <rosto@tlen.pl>
Date: Thu, 22 Aug 2019 14:59:31 +0200
Subject: [PATCH 129/943] Make use of existing constants.

f32::consts::PI / 2.0 -> f32::consts::FRAC_PI_2
f32::consts::PI / 4.0 -> f32::consts::FRAC_PI_4
f64::consts::PI / 2.0 -> f64::consts::FRAC_PI_2
f64::consts::PI / 4.0 -> f64::consts::FRAC_PI_4
---
 src/libstd/f32.rs | 19 +++++++++----------
 src/libstd/f64.rs | 19 +++++++++----------
 2 files changed, 18 insertions(+), 20 deletions(-)

diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 6c71a0428ef09..e55afc2344f79 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -600,7 +600,7 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let x = f32::consts::PI/2.0;
+    /// let x = f32::consts::FRAC_PI_2;
     ///
     /// let abs_difference = (x.sin() - 1.0).abs();
     ///
@@ -646,7 +646,7 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let x = f32::consts::PI / 4.0;
+    /// let x = f32::consts::FRAC_PI_4;
     /// let abs_difference = (x.tan() - 1.0).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
@@ -666,10 +666,10 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let f = f32::consts::PI / 2.0;
+    /// let f = f32::consts::FRAC_PI_2;
     ///
     /// // asin(sin(pi/2))
-    /// let abs_difference = (f.sin().asin() - f32::consts::PI / 2.0).abs();
+    /// let abs_difference = (f.sin().asin() - f32::consts::FRAC_PI_2).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -688,10 +688,10 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let f = f32::consts::PI / 4.0;
+    /// let f = f32::consts::FRAC_PI_4;
     ///
     /// // acos(cos(pi/4))
-    /// let abs_difference = (f.cos().acos() - f32::consts::PI / 4.0).abs();
+    /// let abs_difference = (f.cos().acos() - f32::consts::FRAC_PI_4).abs();
     ///
     /// assert!(abs_difference <= f32::EPSILON);
     /// ```
@@ -734,7 +734,6 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let pi = f32::consts::PI;
     /// // Positive angles measured counter-clockwise
     /// // from positive x axis
     /// // -pi/4 radians (45 deg clockwise)
@@ -745,8 +744,8 @@ impl f32 {
     /// let x2 = -3.0f32;
     /// let y2 = 3.0f32;
     ///
-    /// let abs_difference_1 = (y1.atan2(x1) - (-pi / 4.0)).abs();
-    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * pi / 4.0)).abs();
+    /// let abs_difference_1 = (y1.atan2(x1) - (-f32::consts::FRAC_PI_4)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * f32::consts::FRAC_PI_4)).abs();
     ///
     /// assert!(abs_difference_1 <= f32::EPSILON);
     /// assert!(abs_difference_2 <= f32::EPSILON);
@@ -765,7 +764,7 @@ impl f32 {
     /// ```
     /// use std::f32;
     ///
-    /// let x = f32::consts::PI/4.0;
+    /// let x = f32::consts::FRAC_PI_4;
     /// let f = x.sin_cos();
     ///
     /// let abs_difference_0 = (f.0 - x.sin()).abs();
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index 43c2debe5ee38..b357102630091 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -537,7 +537,7 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let x = f64::consts::PI/2.0;
+    /// let x = f64::consts::FRAC_PI_2;
     ///
     /// let abs_difference = (x.sin() - 1.0).abs();
     ///
@@ -575,7 +575,7 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let x = f64::consts::PI/4.0;
+    /// let x = f64::consts::FRAC_PI_4;
     /// let abs_difference = (x.tan() - 1.0).abs();
     ///
     /// assert!(abs_difference < 1e-14);
@@ -595,10 +595,10 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let f = f64::consts::PI / 2.0;
+    /// let f = f64::consts::FRAC_PI_2;
     ///
     /// // asin(sin(pi/2))
-    /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
+    /// let abs_difference = (f.sin().asin() - f64::consts::FRAC_PI_2).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -617,10 +617,10 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let f = f64::consts::PI / 4.0;
+    /// let f = f64::consts::FRAC_PI_4;
     ///
     /// // acos(cos(pi/4))
-    /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
+    /// let abs_difference = (f.cos().acos() - f64::consts::FRAC_PI_4).abs();
     ///
     /// assert!(abs_difference < 1e-10);
     /// ```
@@ -661,7 +661,6 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let pi = f64::consts::PI;
     /// // Positive angles measured counter-clockwise
     /// // from positive x axis
     /// // -pi/4 radians (45 deg clockwise)
@@ -672,8 +671,8 @@ impl f64 {
     /// let x2 = -3.0_f64;
     /// let y2 = 3.0_f64;
     ///
-    /// let abs_difference_1 = (y1.atan2(x1) - (-pi / 4.0)).abs();
-    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * pi / 4.0)).abs();
+    /// let abs_difference_1 = (y1.atan2(x1) - (-f64::consts::FRAC_PI_4)).abs();
+    /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * f64::consts::FRAC_PI_4)).abs();
     ///
     /// assert!(abs_difference_1 < 1e-10);
     /// assert!(abs_difference_2 < 1e-10);
@@ -692,7 +691,7 @@ impl f64 {
     /// ```
     /// use std::f64;
     ///
-    /// let x = f64::consts::PI/4.0;
+    /// let x = f64::consts::FRAC_PI_4;
     /// let f = x.sin_cos();
     ///
     /// let abs_difference_0 = (f.0 - x.sin()).abs();

From eae5d77995488ffc316a7ff8344c4eaa81d67932 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= <rosto@tlen.pl>
Date: Thu, 22 Aug 2019 15:09:03 +0200
Subject: [PATCH 130/943] Change variables names to be more consistent.

Changed all instances of `c_str` into `cstr` in the documentation examples. This is also consistent with the module source code.
---
 src/libstd/ffi/c_str.rs | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 512839a12c0e4..65f4e0cafe09e 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -572,8 +572,8 @@ impl CString {
     /// use std::ffi::{CString, CStr};
     ///
     /// let c_string = CString::new(b"foo".to_vec()).expect("CString::new failed");
-    /// let c_str = c_string.as_c_str();
-    /// assert_eq!(c_str,
+    /// let cstr = c_string.as_c_str();
+    /// assert_eq!(cstr,
     ///            CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"));
     /// ```
     #[inline]
@@ -994,8 +994,8 @@ impl CStr {
     /// ```
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"hello");
-    /// assert!(c_str.is_err());
+    /// let cstr = CStr::from_bytes_with_nul(b"hello");
+    /// assert!(cstr.is_err());
     /// ```
     ///
     /// Creating a `CStr` with an interior nul byte is an error:
@@ -1003,8 +1003,8 @@ impl CStr {
     /// ```
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"he\0llo\0");
-    /// assert!(c_str.is_err());
+    /// let cstr = CStr::from_bytes_with_nul(b"he\0llo\0");
+    /// assert!(cstr.is_err());
     /// ```
     #[stable(feature = "cstr_from_bytes", since = "1.10.0")]
     pub fn from_bytes_with_nul(bytes: &[u8])
@@ -1111,8 +1111,8 @@ impl CStr {
     /// ```
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
-    /// assert_eq!(c_str.to_bytes(), b"foo");
+    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
+    /// assert_eq!(cstr.to_bytes(), b"foo");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1137,8 +1137,8 @@ impl CStr {
     /// ```
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
-    /// assert_eq!(c_str.to_bytes_with_nul(), b"foo\0");
+    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
+    /// assert_eq!(cstr.to_bytes_with_nul(), b"foo\0");
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1164,8 +1164,8 @@ impl CStr {
     /// ```
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
-    /// assert_eq!(c_str.to_str(), Ok("foo"));
+    /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed");
+    /// assert_eq!(cstr.to_str(), Ok("foo"));
     /// ```
     #[stable(feature = "cstr_to_str", since = "1.4.0")]
     pub fn to_str(&self) -> Result<&str, str::Utf8Error> {
@@ -1205,9 +1205,9 @@ impl CStr {
     /// use std::borrow::Cow;
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"Hello World\0")
+    /// let cstr = CStr::from_bytes_with_nul(b"Hello World\0")
     ///                  .expect("CStr::from_bytes_with_nul failed");
-    /// assert_eq!(c_str.to_string_lossy(), Cow::Borrowed("Hello World"));
+    /// assert_eq!(cstr.to_string_lossy(), Cow::Borrowed("Hello World"));
     /// ```
     ///
     /// Calling `to_string_lossy` on a `CStr` containing invalid UTF-8:
@@ -1216,10 +1216,10 @@ impl CStr {
     /// use std::borrow::Cow;
     /// use std::ffi::CStr;
     ///
-    /// let c_str = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0")
+    /// let cstr = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0")
     ///                  .expect("CStr::from_bytes_with_nul failed");
     /// assert_eq!(
-    ///     c_str.to_string_lossy(),
+    ///     cstr.to_string_lossy(),
     ///     Cow::Owned(String::from("Hello �World")) as Cow<'_, str>
     /// );
     /// ```

From 2f790ee5d210f79219dad4ef129285fa2bdd88a4 Mon Sep 17 00:00:00 2001
From: Jeremy Stucki <dev@jeremystucki.ch>
Date: Thu, 22 Aug 2019 16:47:42 +0200
Subject: [PATCH 131/943] Update .mailmap

---
 .mailmap | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/.mailmap b/.mailmap
index 98902a7212099..72c76006f7cb9 100644
--- a/.mailmap
+++ b/.mailmap
@@ -117,7 +117,9 @@ Jason Toffaletti <toffaletti@gmail.com> Jason Toffaletti <jason@topsy.com>
 Jauhien Piatlicki <jauhien@gentoo.org> Jauhien Piatlicki <jpiatlicki@zertisa.com>
 Jay True <glacjay@gmail.com>
 Jeremy Letang <letang.jeremy@gmail.com>
-Jeremy Stucki <dev@jeremystucki.ch> <stucki.jeremy@gmail.com> <jeremy@myelin.ch>
+Jeremy Stucki <dev@jeremystucki.ch> <stucki.jeremy@gmail.com>
+Jeremy Stucki <dev@jeremystucki.ch> <jeremy@myelin.ch>
+Jeremy Stucki <dev@jeremystucki.ch>
 Jethro Beekman <github@jbeekman.nl>
 Jihyun Yu <j.yu@navercorp.com> <yjh0502@gmail.com>
 Jihyun Yu <j.yu@navercorp.com> jihyun <jihyun@nablecomm.com>

From 2d438d6993017ae2b991cd92ea243112e2357c02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 22 Aug 2019 10:15:57 -0700
Subject: [PATCH 132/943] Correctly suggest adding bounds to `impl Trait`
 argument

---
 src/librustc_typeck/check/method/suggest.rs   | 14 +++++++++++--
 ...ait-with-missing-trait-bounds-in-arg.fixed | 20 +++++++++++++++++++
 ...-trait-with-missing-trait-bounds-in-arg.rs | 20 +++++++++++++++++++
 ...it-with-missing-trait-bounds-in-arg.stderr | 15 ++++++++++++++
 4 files changed, 67 insertions(+), 2 deletions(-)
 create mode 100644 src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.fixed
 create mode 100644 src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.rs
 create mode 100644 src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr

diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 53024d97c3b13..9f4fed23697ab 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -743,8 +743,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // We do this to avoid suggesting code that ends up as `T: FooBar`,
                         // instead we suggest `T: Foo + Bar` in that case.
                         let mut has_bounds = false;
+                        let mut impl_trait = false;
                         if let Node::GenericParam(ref param) = hir.get(id) {
-                            has_bounds = !param.bounds.is_empty();
+                            match param.kind {
+                                hir::GenericParamKind::Type { synthetic: Some(_), .. } => {
+                                    impl_trait = true;  // #63706
+                                    has_bounds = param.bounds.len() > 1;
+                                }
+                                _ => {
+                                    has_bounds = !param.bounds.is_empty();
+                                }
+                            }
                         }
                         let sp = hir.span(id);
                         // `sp` only covers `T`, change it so that it covers
@@ -765,8 +774,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             sp,
                             &msg[..],
                             candidates.iter().map(|t| format!(
-                                "{}: {}{}",
+                                "{}{} {}{}",
                                 param,
+                                if impl_trait { " +" } else { ":" },
                                 self.tcx.def_path_str(t.def_id),
                                 if has_bounds { " +"} else { "" },
                             )),
diff --git a/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.fixed b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.fixed
new file mode 100644
index 0000000000000..5109511f95a6b
--- /dev/null
+++ b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.fixed
@@ -0,0 +1,20 @@
+// run-rustfix
+
+trait Foo {}
+
+trait Bar {
+    fn hello(&self) {}
+}
+
+struct S;
+
+impl Foo for S {}
+impl Bar for S {}
+
+fn test(foo: impl Foo + Bar) {
+    foo.hello(); //~ ERROR E0599
+}
+
+fn main() {
+    test(S);
+}
diff --git a/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.rs b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.rs
new file mode 100644
index 0000000000000..cd05b77386192
--- /dev/null
+++ b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.rs
@@ -0,0 +1,20 @@
+// run-rustfix
+
+trait Foo {}
+
+trait Bar {
+    fn hello(&self) {}
+}
+
+struct S;
+
+impl Foo for S {}
+impl Bar for S {}
+
+fn test(foo: impl Foo) {
+    foo.hello(); //~ ERROR E0599
+}
+
+fn main() {
+    test(S);
+}
diff --git a/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr
new file mode 100644
index 0000000000000..48c2503e8eb32
--- /dev/null
+++ b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no method named `hello` found for type `impl Foo` in the current scope
+  --> $DIR/impl-trait-with-missing-trait-bounds-in-arg.rs:15:9
+   |
+LL |     foo.hello();
+   |         ^^^^^
+   |
+   = help: items from traits can only be used if the type parameter is bounded by the trait
+help: the following trait defines an item `hello`, perhaps you need to restrict type parameter `impl Foo` with it:
+   |
+LL | fn test(foo: impl Foo + Bar) {
+   |              ^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.

From d9f3258186cc221b41d2d869671d47fd4b716bbe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= <rosto@tlen.pl>
Date: Thu, 22 Aug 2019 19:27:16 +0200
Subject: [PATCH 133/943] Fix for 7e13679.

---
 src/libstd/ffi/os_str.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index d0e35cce6411b..6cf062d4f30c0 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -191,7 +191,7 @@ impl OsString {
     /// ```
     /// use std::ffi::OsString;
     ///
-    /// let os_string = OsString::with_capacity(10);
+    /// let mut os_string = OsString::with_capacity(10);
     /// let capacity = os_string.capacity();
     ///
     /// // This push is done without reallocating
@@ -233,7 +233,7 @@ impl OsString {
     /// ```
     /// use std::ffi::OsString;
     ///
-    /// let mut os_string = OsString::with_capacity(10);
+    /// let os_string = OsString::with_capacity(10);
     /// assert!(os_string.capacity() >= 10);
     /// ```
     #[stable(feature = "osstring_simple_functions", since = "1.9.0")]

From 03507a1688e4ce5c3bf99973addd75beb1bc9ec0 Mon Sep 17 00:00:00 2001
From: Sebastian Martinez <7912302+sebastinez@users.noreply.github.com>
Date: Thu, 22 Aug 2019 16:16:22 -0300
Subject: [PATCH 134/943] Update occurences of as_slice

Update occurences of as_slice to as_str
---
 src/libstd/primitive_docs.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs
index d9a3da66a6786..45816ffd229f0 100644
--- a/src/libstd/primitive_docs.rs
+++ b/src/libstd/primitive_docs.rs
@@ -655,7 +655,7 @@ mod prim_slice { }
 /// [`len`]: #method.len
 ///
 /// Note: This example shows the internals of `&str`. `unsafe` should not be
-/// used to get a string slice under normal circumstances. Use `as_slice`
+/// used to get a string slice under normal circumstances. Use `as_str`
 /// instead.
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_str { }

From 1acb53753be395f6b5bd880617ddceaa4bfadcfa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 22 Aug 2019 10:38:09 -0700
Subject: [PATCH 135/943] Do not suggest `.try_into()` on `i32::from(x)`

---
 src/librustc_typeck/check/demand.rs           | 24 +++++++++++++++++++
 .../mismatched-types-numeric-from.rs          |  3 +++
 .../mismatched-types-numeric-from.stderr      |  9 +++++++
 3 files changed, 36 insertions(+)
 create mode 100644 src/test/ui/suggestions/mismatched-types-numeric-from.rs
 create mode 100644 src/test/ui/suggestions/mismatched-types-numeric-from.stderr

diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index de5ba8bc8eb42..0efc433341c1f 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -587,6 +587,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 return false;
             }
         }
+        if let hir::ExprKind::Call(path, args) = &expr.node {
+            if let (
+                hir::ExprKind::Path(hir::QPath::TypeRelative(base_ty, path_segment)),
+                1,
+            ) = (&path.node, args.len()) {
+                // `expr` is a conversion like `u32::from(val)`, do not suggest anything (#63697).
+                if let (
+                    hir::TyKind::Path(hir::QPath::Resolved(None, base_ty_path)),
+                    sym::from,
+                ) = (&base_ty.node, path_segment.ident.name) {
+                    if let Some(ident) = &base_ty_path.segments.iter().map(|s| s.ident).next() {
+                        match ident.name {
+                            sym::i128 | sym::i64 | sym::i32 | sym::i16 | sym::i8 |
+                            sym::u128 | sym::u64 | sym::u32 | sym::u16 | sym::u8 |
+                            sym::isize | sym::usize
+                            if base_ty_path.segments.len() == 1 => {
+                                return false;
+                            }
+                            _ => {}
+                        }
+                    }
+                }
+            }
+        }
 
         let msg = format!("you can convert an `{}` to `{}`", checked_ty, expected_ty);
         let cast_msg = format!("you can cast an `{} to `{}`", checked_ty, expected_ty);
diff --git a/src/test/ui/suggestions/mismatched-types-numeric-from.rs b/src/test/ui/suggestions/mismatched-types-numeric-from.rs
new file mode 100644
index 0000000000000..56549da9c7358
--- /dev/null
+++ b/src/test/ui/suggestions/mismatched-types-numeric-from.rs
@@ -0,0 +1,3 @@
+fn main() {
+    let _: u32 = i32::from(0_u8); //~ ERROR mismatched types
+}
diff --git a/src/test/ui/suggestions/mismatched-types-numeric-from.stderr b/src/test/ui/suggestions/mismatched-types-numeric-from.stderr
new file mode 100644
index 0000000000000..223b6747322c1
--- /dev/null
+++ b/src/test/ui/suggestions/mismatched-types-numeric-from.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+  --> $DIR/mismatched-types-numeric-from.rs:2:18
+   |
+LL |     let _: u32 = i32::from(0_u8);
+   |                  ^^^^^^^^^^^^^^^ expected u32, found i32
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.

From 98bd60c2814e5d90c9eddcd25ea571ad032a0c74 Mon Sep 17 00:00:00 2001
From: Naja Melan <najamelan@autistici.org>
Date: Thu, 22 Aug 2019 22:39:21 +0000
Subject: [PATCH 136/943] Update single-use-lifetimes

When using this, rustc emits a warning that the lint has been renamed (to having an 's' at the end)
---
 src/doc/rustc/src/lints/listing/allowed-by-default.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md
index a6e4e166d7bc6..d3dfc3197e2f6 100644
--- a/src/doc/rustc/src/lints/listing/allowed-by-default.md
+++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md
@@ -208,7 +208,7 @@ error: missing documentation for a function
 
 To fix the lint, add documentation to all items.
 
-## single-use-lifetime
+## single-use-lifetimes
 
 This lint detects lifetimes that are only used once. Some example code that
 triggers this lint:

From 0fb01d219c7b7de142ad4097dd1e5cf708e7a27f Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Wed, 21 Aug 2019 21:28:22 +0300
Subject: [PATCH 137/943] Audit uses of `apply_mark` in built-in macros

Replace them with equivalents of `Span::{def_site,call_site}` from proc macro API.
The new API is much less error prone and doesn't rely on macros having default transparency.
---
 src/libsyntax/ext/base.rs                | 30 ++++++++++++++++++------
 src/libsyntax/ext/expand.rs              |  1 -
 src/libsyntax/ext/proc_macro_server.rs   | 11 ++-------
 src/libsyntax_ext/asm.rs                 |  2 +-
 src/libsyntax_ext/assert.rs              |  2 +-
 src/libsyntax_ext/cfg.rs                 |  2 +-
 src/libsyntax_ext/concat.rs              |  2 +-
 src/libsyntax_ext/concat_idents.rs       |  2 +-
 src/libsyntax_ext/deriving/clone.rs      |  2 +-
 src/libsyntax_ext/deriving/cmp/eq.rs     |  2 +-
 src/libsyntax_ext/deriving/debug.rs      |  2 +-
 src/libsyntax_ext/deriving/generic/ty.rs |  2 +-
 src/libsyntax_ext/deriving/mod.rs        |  5 +++-
 src/libsyntax_ext/env.rs                 |  2 +-
 src/libsyntax_ext/format.rs              | 11 ++++-----
 src/libsyntax_ext/global_allocator.rs    |  3 +--
 src/libsyntax_ext/global_asm.rs          |  2 +-
 src/libsyntax_ext/test.rs                |  6 ++---
 src/libsyntax_pos/lib.rs                 |  8 +++++++
 19 files changed, 56 insertions(+), 41 deletions(-)

diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 075e6a8001336..004ae1cf96541 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -3,7 +3,7 @@ use crate::attr::{HasAttrs, Stability, Deprecation};
 use crate::source_map::SourceMap;
 use crate::edition::Edition;
 use crate::ext::expand::{self, AstFragment, Invocation};
-use crate::ext::hygiene::{ExpnId, SyntaxContext, Transparency};
+use crate::ext::hygiene::{ExpnId, Transparency};
 use crate::mut_visit::{self, MutVisitor};
 use crate::parse::{self, parser, DirectoryOwnership};
 use crate::parse::token;
@@ -760,23 +760,39 @@ impl<'a> ExtCtxt<'a> {
     pub fn call_site(&self) -> Span {
         self.current_expansion.id.expn_data().call_site
     }
-    pub fn backtrace(&self) -> SyntaxContext {
-        SyntaxContext::root().apply_mark(self.current_expansion.id)
+
+    /// Equivalent of `Span::def_site` from the proc macro API,
+    /// except that the location is taken from the span passed as an argument.
+    pub fn with_def_site_ctxt(&self, span: Span) -> Span {
+        span.with_ctxt_from_mark(self.current_expansion.id, Transparency::Opaque)
+    }
+
+    /// Equivalent of `Span::call_site` from the proc macro API,
+    /// except that the location is taken from the span passed as an argument.
+    pub fn with_call_site_ctxt(&self, span: Span) -> Span {
+        span.with_ctxt_from_mark(self.current_expansion.id, Transparency::Transparent)
+    }
+
+    /// Span with a context reproducing `macro_rules` hygiene (hygienic locals, unhygienic items).
+    /// FIXME: This should be eventually replaced either with `with_def_site_ctxt` (preferably),
+    /// or with `with_call_site_ctxt` (where necessary).
+    pub fn with_legacy_ctxt(&self, span: Span) -> Span {
+        span.with_ctxt_from_mark(self.current_expansion.id, Transparency::SemiTransparent)
     }
 
     /// Returns span for the macro which originally caused the current expansion to happen.
     ///
     /// Stops backtracing at include! boundary.
     pub fn expansion_cause(&self) -> Option<Span> {
-        let mut ctxt = self.backtrace();
+        let mut expn_id = self.current_expansion.id;
         let mut last_macro = None;
         loop {
-            let expn_data = ctxt.outer_expn_data();
+            let expn_data = expn_id.expn_data();
             // Stop going up the backtrace once include! is encountered
             if expn_data.is_root() || expn_data.kind.descr() == sym::include {
                 break;
             }
-            ctxt = expn_data.call_site.ctxt();
+            expn_id = expn_data.call_site.ctxt().outer_expn();
             last_macro = Some(expn_data.call_site);
         }
         last_macro
@@ -865,7 +881,7 @@ impl<'a> ExtCtxt<'a> {
         ast::Ident::from_str(st)
     }
     pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> {
-        let def_site = DUMMY_SP.apply_mark(self.current_expansion.id);
+        let def_site = self.with_def_site_ctxt(DUMMY_SP);
         iter::once(Ident::new(kw::DollarCrate, def_site))
             .chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
             .collect()
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 72f2c1375e7a2..4965cb097dbee 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -565,7 +565,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         return fragment_kind.dummy(span);
                     }
                     let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span, path };
-                    let span = span.with_ctxt(self.cx.backtrace());
                     let items = expander.expand(self.cx, span, &meta, item);
                     fragment_kind.expect_from_annotatables(items)
                 }
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index 1619fa6994198..b1bbd2aaac971 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -7,7 +7,6 @@ use crate::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}
 use errors::{Diagnostic, DiagnosticBuilder};
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
-use syntax_pos::hygiene::{SyntaxContext, Transparency};
 use syntax_pos::symbol::{kw, sym, Symbol};
 
 use proc_macro::{Delimiter, Level, LineColumn, Spacing};
@@ -363,16 +362,10 @@ impl<'a> Rustc<'a> {
     pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
         // No way to determine def location for a proc macro right now, so use call location.
         let location = cx.current_expansion.id.expn_data().call_site;
-        let to_span = |transparency| {
-            location.with_ctxt(
-                SyntaxContext::root()
-                    .apply_mark_with_transparency(cx.current_expansion.id, transparency),
-            )
-        };
         Rustc {
             sess: cx.parse_sess,
-            def_site: to_span(Transparency::Opaque),
-            call_site: to_span(Transparency::Transparent),
+            def_site: cx.with_def_site_ctxt(location),
+            call_site: cx.with_call_site_ctxt(location),
         }
     }
 
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 644a44f1989db..28f907441d872 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -63,7 +63,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
     MacEager::expr(P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
         node: ast::ExprKind::InlineAsm(P(inline_asm)),
-        span: sp.with_ctxt(cx.backtrace()),
+        span: cx.with_legacy_ctxt(sp),
         attrs: ThinVec::new(),
     }))
 }
diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs
index 6301283460ac7..84583d0e5eca7 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -23,7 +23,7 @@ pub fn expand_assert<'cx>(
         }
     };
 
-    let sp = sp.apply_mark(cx.current_expansion.id);
+    let sp = cx.with_legacy_ctxt(sp);
     let panic_call = Mac {
         path: Path::from_ident(Ident::new(sym::panic, sp)),
         tts: custom_message.unwrap_or_else(|| {
diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs
index 0e52c1af9086f..21cee8ae1cb9c 100644
--- a/src/libsyntax_ext/cfg.rs
+++ b/src/libsyntax_ext/cfg.rs
@@ -16,7 +16,7 @@ pub fn expand_cfg(
     sp: Span,
     tts: &[tokenstream::TokenTree],
 ) -> Box<dyn base::MacResult + 'static> {
-    let sp = sp.apply_mark(cx.current_expansion.id);
+    let sp = cx.with_legacy_ctxt(sp);
 
     match parse_cfg(cx, sp, tts) {
         Ok(cfg) => {
diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs
index 4cd17531a4500..ffa5154ca0c36 100644
--- a/src/libsyntax_ext/concat.rs
+++ b/src/libsyntax_ext/concat.rs
@@ -59,6 +59,6 @@ pub fn expand_syntax_ext(
     } else if has_errors {
         return DummyResult::any(sp);
     }
-    let sp = sp.apply_mark(cx.current_expansion.id);
+    let sp = cx.with_legacy_ctxt(sp);
     base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
 }
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index 8184fc442676d..96677072d1b80 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -39,7 +39,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
         }
     }
 
-    let ident = ast::Ident::new(Symbol::intern(&res_str), sp.apply_mark(cx.current_expansion.id));
+    let ident = ast::Ident::new(Symbol::intern(&res_str), cx.with_legacy_ctxt(sp));
 
     struct ConcatIdentsResult { ident: ast::Ident }
 
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index d030ea4a56ebb..4dd0ecfebefd4 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -112,7 +112,7 @@ fn cs_clone_shallow(name: &str,
                         ty: P<ast::Ty>, span: Span, helper_name: &str) {
         // Generate statement `let _: helper_name<ty>;`,
         // set the expn ID so we can use the unstable struct.
-        let span = span.with_ctxt(cx.backtrace());
+        let span = cx.with_def_site_ctxt(span);
         let assert_path = cx.path_all(span, true,
                                         cx.std_path(&[sym::clone, Symbol::intern(helper_name)]),
                                         vec![GenericArg::Type(ty)], vec![]);
diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs
index 54027c600b4cd..32ab47969ada4 100644
--- a/src/libsyntax_ext/deriving/cmp/eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/eq.rs
@@ -53,7 +53,7 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt<'_>,
                         ty: P<ast::Ty>, span: Span, helper_name: &str) {
         // Generate statement `let _: helper_name<ty>;`,
         // set the expn ID so we can use the unstable struct.
-        let span = span.with_ctxt(cx.backtrace());
+        let span = cx.with_def_site_ctxt(span);
         let assert_path = cx.path_all(span, true,
                                         cx.std_path(&[sym::cmp, Symbol::intern(helper_name)]),
                                         vec![GenericArg::Type(ty)], vec![]);
diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs
index 441535410480b..781645a574e9a 100644
--- a/src/libsyntax_ext/deriving/debug.rs
+++ b/src/libsyntax_ext/deriving/debug.rs
@@ -60,7 +60,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
     };
 
     // We want to make sure we have the ctxt set so that we can use unstable methods
-    let span = span.with_ctxt(cx.backtrace());
+    let span = cx.with_def_site_ctxt(span);
     let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
     let builder = Ident::from_str_and_span("debug_trait_builder", span);
     let builder_expr = cx.expr_ident(span, builder.clone());
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index 7fcf036fc8176..cb1c7b21fee0d 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -85,7 +85,7 @@ impl<'a> Path<'a> {
             PathKind::Global => cx.path_all(span, true, idents, params, Vec::new()),
             PathKind::Local => cx.path_all(span, false, idents, params, Vec::new()),
             PathKind::Std => {
-                let def_site = DUMMY_SP.apply_mark(cx.current_expansion.id);
+                let def_site = cx.with_def_site_ctxt(DUMMY_SP);
                 idents.insert(0, Ident::new(kw::DollarCrate, def_site));
                 cx.path_all(span, false, idents, params, Vec::new())
             }
diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs
index da68eea0c50e7..60b6eba7a4b53 100644
--- a/src/libsyntax_ext/deriving/mod.rs
+++ b/src/libsyntax_ext/deriving/mod.rs
@@ -48,6 +48,9 @@ impl MultiItemModifier for BuiltinDerive {
               meta_item: &MetaItem,
               item: Annotatable)
               -> Vec<Annotatable> {
+        // FIXME: Built-in derives often forget to give spans contexts,
+        // so we are doing it here in a centralized way.
+        let span = ecx.with_def_site_ctxt(span);
         let mut items = Vec::new();
         (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a));
         items
@@ -60,7 +63,7 @@ fn call_intrinsic(cx: &ExtCtxt<'_>,
                   intrinsic: &str,
                   args: Vec<P<ast::Expr>>)
                   -> P<ast::Expr> {
-    let span = span.with_ctxt(cx.backtrace());
+    let span = cx.with_def_site_ctxt(span);
     let path = cx.std_path(&[sym::intrinsics, Symbol::intern(intrinsic)]);
     let call = cx.expr_call_global(span, path, args);
 
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 9834130fa23f0..6343d218de829 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -20,7 +20,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
         Some(v) => v,
     };
 
-    let sp = sp.apply_mark(cx.current_expansion.id);
+    let sp = cx.with_legacy_ctxt(sp);
     let e = match env::var(&*var.as_str()) {
         Err(..) => {
             let lt = cx.lifetime(sp, Ident::with_dummy_span(kw::StaticLifetime));
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 83764205a198e..47394c02b4186 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -12,7 +12,7 @@ use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::symbol::{Symbol, sym};
 use syntax::tokenstream;
-use syntax_pos::{MultiSpan, Span, DUMMY_SP};
+use syntax_pos::{MultiSpan, Span};
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use std::borrow::Cow;
@@ -666,8 +666,7 @@ impl<'a, 'b> Context<'a, 'b> {
         // passed to this function.
         for (i, e) in self.args.into_iter().enumerate() {
             let name = names_pos[i];
-            let span =
-                DUMMY_SP.with_ctxt(e.span.ctxt().apply_mark(self.ecx.current_expansion.id));
+            let span = self.ecx.with_def_site_ctxt(e.span);
             pats.push(self.ecx.pat_ident(span, name));
             for ref arg_ty in self.arg_unique_types[i].iter() {
                 locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, name));
@@ -745,7 +744,7 @@ impl<'a, 'b> Context<'a, 'b> {
         ty: &ArgumentType,
         arg: ast::Ident,
     ) -> P<ast::Expr> {
-        sp = sp.apply_mark(ecx.current_expansion.id);
+        sp = ecx.with_def_site_ctxt(sp);
         let arg = ecx.expr_ident(sp, arg);
         let trait_ = match *ty {
             Placeholder(ref tyname) => {
@@ -798,7 +797,7 @@ fn expand_format_args_impl<'cx>(
     tts: &[tokenstream::TokenTree],
     nl: bool,
 ) -> Box<dyn base::MacResult + 'cx> {
-    sp = sp.apply_mark(ecx.current_expansion.id);
+    sp = ecx.with_def_site_ctxt(sp);
     match parse_args(ecx, sp, tts) {
         Ok((efmt, args, names)) => {
             MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, nl))
@@ -842,7 +841,7 @@ pub fn expand_preparsed_format_args(
     let arg_unique_types: Vec<_> = (0..args.len()).map(|_| Vec::new()).collect();
 
     let mut macsp = ecx.call_site();
-    macsp = macsp.with_ctxt(ecx.backtrace());
+    macsp = ecx.with_def_site_ctxt(macsp);
 
     let msg = "format argument must be a string literal";
     let fmt_sp = efmt.span;
diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs
index d2121abe3b466..97b8087ad1581 100644
--- a/src/libsyntax_ext/global_allocator.rs
+++ b/src/libsyntax_ext/global_allocator.rs
@@ -3,7 +3,6 @@ use syntax::ast::{self, Arg, Attribute, Expr, FnHeader, Generics, Ident};
 use syntax::attr::check_builtin_macro_attribute;
 use syntax::ext::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
 use syntax::ext::base::{Annotatable, ExtCtxt};
-use syntax::ext::hygiene::SyntaxContext;
 use syntax::ptr::P;
 use syntax::symbol::{kw, sym, Symbol};
 use syntax_pos::Span;
@@ -29,7 +28,7 @@ pub fn expand(
     };
 
     // Generate a bunch of new items using the AllocFnFactory
-    let span = item.span.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id));
+    let span = ecx.with_legacy_ctxt(item.span);
     let f = AllocFnFactory {
         span,
         kind: AllocatorKind::Global,
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 73ebeaec45497..a8b61593db749 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -30,7 +30,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                 id: ast::DUMMY_NODE_ID,
                 node: ast::ItemKind::GlobalAsm(P(global_asm)),
                 vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
-                span: sp.with_ctxt(cx.backtrace()),
+                span: cx.with_legacy_ctxt(sp),
                 tokens: None,
             })])
         }
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index 08582e714ccb2..5fd87d3a0e5c6 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -4,7 +4,6 @@
 use syntax::ast;
 use syntax::attr::{self, check_builtin_macro_attribute};
 use syntax::ext::base::*;
-use syntax::ext::hygiene::SyntaxContext;
 use syntax::print::pprust;
 use syntax::source_map::respan;
 use syntax::symbol::{Symbol, sym};
@@ -29,7 +28,7 @@ pub fn expand_test_case(
 
     if !ecx.ecfg.should_test { return vec![]; }
 
-    let sp = attr_sp.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id));
+    let sp = ecx.with_legacy_ctxt(attr_sp);
     let mut item = anno_item.expect_item();
     item = item.map(|mut item| {
         item.vis = respan(item.vis.span, ast::VisibilityKind::Public);
@@ -93,8 +92,7 @@ pub fn expand_test_or_bench(
         return vec![Annotatable::Item(item)];
     }
 
-    let ctxt = SyntaxContext::root().apply_mark(cx.current_expansion.id);
-    let (sp, attr_sp) = (item.span.with_ctxt(ctxt), attr_sp.with_ctxt(ctxt));
+    let (sp, attr_sp) = (cx.with_legacy_ctxt(item.span), cx.with_legacy_ctxt(attr_sp));
 
     // Gensym "test" so we can extern crate without conflicting with any local names
     let test_id = cx.ident_of("test").gensym();
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index a17cd7625fb19..6fffefd0d6cbb 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -22,6 +22,7 @@ pub mod edition;
 use edition::Edition;
 pub mod hygiene;
 pub use hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind, MacroKind, DesugaringKind};
+use hygiene::Transparency;
 
 mod span_encoding;
 pub use span_encoding::{Span, DUMMY_SP};
@@ -512,6 +513,13 @@ impl Span {
                   span.ctxt)
     }
 
+    /// Produces a span with the same location as `self` and context produced by a macro with the
+    /// given ID and transparency, assuming that macro was defined directly and not produced by
+    /// some other macro (which is the case for built-in and procedural macros).
+    pub fn with_ctxt_from_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span {
+        self.with_ctxt(SyntaxContext::root().apply_mark_with_transparency(expn_id, transparency))
+    }
+
     #[inline]
     pub fn apply_mark(self, mark: ExpnId) -> Span {
         let span = self.data();

From bf345dd6e320a3f22396d4fbdd2ed078248105d4 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Thu, 22 Aug 2019 01:29:34 +0300
Subject: [PATCH 138/943] resolve: Do not rely on default transparency when
 detecting proc macro derives

---
 src/librustc_resolve/build_reduced_graph.rs |  2 +-
 src/librustc_resolve/lib.rs                 | 12 ++++++++----
 src/libsyntax_pos/hygiene.rs                | 12 ------------
 3 files changed, 9 insertions(+), 17 deletions(-)

diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 42428456b6eec..9a794ade729c2 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -145,7 +145,7 @@ impl<'a> Resolver<'a> {
         }
     }
 
-    fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
+    crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
         if let Some(ext) = self.macro_map.get(&def_id) {
             return Some(ext.clone());
         }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 2dd0ad13c526d..875ae449d94e0 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1647,10 +1647,14 @@ impl<'a> Resolver<'a> {
             if module.expansion != parent.expansion &&
             module.expansion.is_descendant_of(parent.expansion) {
                 // The macro is a proc macro derive
-                if module.expansion.looks_like_proc_macro_derive() {
-                    if parent.expansion.outer_expn_is_descendant_of(span.ctxt()) {
-                        *poisoned = Some(node_id);
-                        return module.parent;
+                if let Some(&def_id) = self.macro_defs.get(&module.expansion) {
+                    if let Some(ext) = self.get_macro_by_def_id(def_id) {
+                        if !ext.is_builtin && ext.macro_kind() == MacroKind::Derive {
+                            if parent.expansion.outer_expn_is_descendant_of(span.ctxt()) {
+                                *poisoned = Some(node_id);
+                                return module.parent;
+                            }
+                        }
                     }
                 }
             }
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index ebfb0764fa2b2..db739c9a8c569 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -119,18 +119,6 @@ impl ExpnId {
     pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
         HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt)))
     }
-
-    // Used for enabling some compatibility fallback in resolve.
-    #[inline]
-    pub fn looks_like_proc_macro_derive(self) -> bool {
-        HygieneData::with(|data| {
-            let expn_data = data.expn_data(self);
-            if let ExpnKind::Macro(MacroKind::Derive, _) = expn_data.kind {
-                return expn_data.default_transparency == Transparency::Opaque;
-            }
-            false
-        })
-    }
 }
 
 #[derive(Debug)]

From b0c4d0f8cbb703c90b9dc3cd1b48d2d550508ef8 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Fri, 23 Aug 2019 00:27:46 +0300
Subject: [PATCH 139/943] incremental: Do not rely on default transparency when
 decoding syntax contexts

Using `ExpnId`s default transparency here instead of the mark's real transparency was actually incorrect.
---
 src/librustc/ty/query/on_disk_cache.rs | 20 ++++++++++----------
 src/libsyntax_pos/hygiene.rs           | 26 +++++++++++++++++---------
 2 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 8bf01970eb592..c21639d0dcaee 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -23,7 +23,7 @@ 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::{ExpnId, SyntaxContext, ExpnData};
+use syntax_pos::hygiene::{ExpnId, SyntaxContext};
 
 const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE;
 
@@ -593,8 +593,8 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
         // don't seem to be used after HIR lowering, so everything should be fine
         // as long as incremental compilation does not kick in before that.
         let location = || Span::with_root_ctxt(lo, hi);
-        let recover_from_expn_data = |this: &Self, expn_data, pos| {
-            let span = location().fresh_expansion(expn_data);
+        let recover_from_expn_data = |this: &Self, expn_data, transparency, pos| {
+            let span = location().fresh_expansion_with_transparency(expn_data, transparency);
             this.synthetic_syntax_contexts.borrow_mut().insert(pos, span.ctxt());
             span
         };
@@ -603,9 +603,9 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
                 location()
             }
             TAG_EXPN_DATA_INLINE => {
-                let expn_data = Decodable::decode(self)?;
+                let (expn_data, transparency) = Decodable::decode(self)?;
                 recover_from_expn_data(
-                    self, expn_data, AbsoluteBytePos::new(self.opaque.position())
+                    self, expn_data, transparency, AbsoluteBytePos::new(self.opaque.position())
                 )
             }
             TAG_EXPN_DATA_SHORTHAND => {
@@ -614,9 +614,9 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
                 if let Some(ctxt) = cached_ctxt {
                     Span::new(lo, hi, ctxt)
                 } else {
-                    let expn_data =
-                        self.with_position(pos.to_usize(), |this| ExpnData::decode(this))?;
-                    recover_from_expn_data(self, expn_data, pos)
+                    let (expn_data, transparency) =
+                        self.with_position(pos.to_usize(), |this| Decodable::decode(this))?;
+                    recover_from_expn_data(self, expn_data, transparency, pos)
                 }
             }
             _ => {
@@ -819,7 +819,7 @@ where
         if span_data.ctxt == SyntaxContext::root() {
             TAG_NO_EXPN_DATA.encode(self)
         } else {
-            let (expn_id, expn_data) = span_data.ctxt.outer_expn_with_data();
+            let (expn_id, transparency, expn_data) = span_data.ctxt.outer_mark_with_data();
             if let Some(pos) = self.expn_data_shorthands.get(&expn_id).cloned() {
                 TAG_EXPN_DATA_SHORTHAND.encode(self)?;
                 pos.encode(self)
@@ -827,7 +827,7 @@ where
                 TAG_EXPN_DATA_INLINE.encode(self)?;
                 let pos = AbsoluteBytePos::new(self.position());
                 self.expn_data_shorthands.insert(expn_id, pos);
-                expn_data.encode(self)
+                (expn_data, transparency).encode(self)
             }
         }
     }
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index db739c9a8c569..c4a0e16d931f2 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -183,8 +183,9 @@ impl HygieneData {
         self.syntax_context_data[ctxt.0 as usize].outer_expn
     }
 
-    fn outer_transparency(&self, ctxt: SyntaxContext) -> Transparency {
-        self.syntax_context_data[ctxt.0 as usize].outer_transparency
+    fn outer_mark(&self, ctxt: SyntaxContext) -> (ExpnId, Transparency) {
+        let data = &self.syntax_context_data[ctxt.0 as usize];
+        (data.outer_expn, data.outer_transparency)
     }
 
     fn parent_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContext {
@@ -200,7 +201,7 @@ impl HygieneData {
     fn marks(&self, mut ctxt: SyntaxContext) -> Vec<(ExpnId, Transparency)> {
         let mut marks = Vec::new();
         while ctxt != SyntaxContext::root() {
-            marks.push((self.outer_expn(ctxt), self.outer_transparency(ctxt)));
+            marks.push(self.outer_mark(ctxt));
             ctxt = self.parent_ctxt(ctxt);
         }
         marks.reverse();
@@ -535,13 +536,11 @@ impl SyntaxContext {
         HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone())
     }
 
-    /// `ctxt.outer_expn_with_data()` is equivalent to but faster than
-    /// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_data()) }`.
     #[inline]
-    pub fn outer_expn_with_data(self) -> (ExpnId, ExpnData) {
+    pub fn outer_mark_with_data(self) -> (ExpnId, Transparency, ExpnData) {
         HygieneData::with(|data| {
-            let outer = data.outer_expn(self);
-            (outer, data.expn_data(outer).clone())
+            let (expn_id, transparency) = data.outer_mark(self);
+            (expn_id, transparency, data.expn_data(expn_id).clone())
         })
     }
 
@@ -563,9 +562,18 @@ impl Span {
     /// The returned span belongs to the created expansion and has the new properties,
     /// but its location is inherited from the current span.
     pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
+        let transparency = expn_data.default_transparency;
+        self.fresh_expansion_with_transparency(expn_data, transparency)
+    }
+
+    pub fn fresh_expansion_with_transparency(
+        self, expn_data: ExpnData, transparency: Transparency
+    ) -> Span {
         HygieneData::with(|data| {
             let expn_id = data.fresh_expn(Some(expn_data));
-            self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id))
+            self.with_ctxt(data.apply_mark_with_transparency(
+                SyntaxContext::root(), expn_id, transparency
+            ))
         })
     }
 }

From cf9db76454838988620acf6ba7db7bc8654b6f57 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Fri, 23 Aug 2019 01:31:01 +0300
Subject: [PATCH 140/943] hygiene: Require passing transparency explicitly to
 `apply_mark`

---
 src/libsyntax/ext/expand.rs         | 14 ---------
 src/libsyntax/ext/tt/macro_rules.rs | 21 ++++++++-----
 src/libsyntax/ext/tt/transcribe.rs  | 44 ++++++++++++++++++++-------
 src/libsyntax/tokenstream.rs        |  9 +-----
 src/libsyntax_pos/hygiene.rs        | 46 ++++++++++-------------------
 src/libsyntax_pos/lib.rs            |  6 ++--
 6 files changed, 66 insertions(+), 74 deletions(-)

diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 4965cb097dbee..c8c0f4ce36e8e 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1388,17 +1388,3 @@ impl<'feat> ExpansionConfig<'feat> {
         self.features.map_or(false, |features| features.custom_inner_attributes)
     }
 }
-
-// A Marker adds the given mark to the syntax context.
-#[derive(Debug)]
-pub struct Marker(pub ExpnId);
-
-impl MutVisitor for Marker {
-    fn visit_span(&mut self, span: &mut Span) {
-        *span = span.apply_mark(self.0)
-    }
-
-    fn visit_mac(&mut self, mac: &mut ast::Mac) {
-        noop_visit_mac(mac, self)
-    }
-}
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index b057a9ad44d0b..9292ce334b819 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -19,6 +19,7 @@ use crate::{ast, attr, attr::TransparencyError};
 
 use errors::{DiagnosticBuilder, FatalError};
 use log::debug;
+use syntax_pos::hygiene::Transparency;
 use syntax_pos::Span;
 
 use rustc_data_structures::fx::FxHashMap;
@@ -128,6 +129,7 @@ impl<'a> ParserAnyMacro<'a> {
 struct MacroRulesMacroExpander {
     name: ast::Ident,
     span: Span,
+    transparency: Transparency,
     lhses: Vec<quoted::TokenTree>,
     rhses: Vec<quoted::TokenTree>,
     valid: bool,
@@ -143,7 +145,9 @@ impl TTMacroExpander for MacroRulesMacroExpander {
         if !self.valid {
             return DummyResult::any(sp);
         }
-        generic_extension(cx, sp, self.span, self.name, input, &self.lhses, &self.rhses)
+        generic_extension(
+            cx, sp, self.span, self.name, self.transparency, input, &self.lhses, &self.rhses
+        )
     }
 }
 
@@ -158,6 +162,7 @@ fn generic_extension<'cx>(
     sp: Span,
     def_span: Span,
     name: ast::Ident,
+    transparency: Transparency,
     arg: TokenStream,
     lhses: &[quoted::TokenTree],
     rhses: &[quoted::TokenTree],
@@ -187,7 +192,7 @@ fn generic_extension<'cx>(
 
                 let rhs_spans = rhs.iter().map(|t| t.span()).collect::<Vec<_>>();
                 // rhs has holes ( `$id` and `$(...)` that need filled)
-                let mut tts = transcribe(cx, &named_matches, rhs);
+                let mut tts = transcribe(cx, &named_matches, rhs, transparency);
 
                 // Replace all the tokens for the corresponding positions in the macro, to maintain
                 // proper positions in error reporting, while maintaining the macro_backtrace.
@@ -415,11 +420,7 @@ pub fn compile(
     // that is not lint-checked and trigger the "failed to process buffered lint here" bug.
     valid &= macro_check::check_meta_variables(sess, ast::CRATE_NODE_ID, def.span, &lhses, &rhses);
 
-    let expander: Box<_> =
-        Box::new(MacroRulesMacroExpander { name: def.ident, span: def.span, lhses, rhses, valid });
-
-    let (default_transparency, transparency_error) =
-        attr::find_transparency(&def.attrs, body.legacy);
+    let (transparency, transparency_error) = attr::find_transparency(&def.attrs, body.legacy);
     match transparency_error {
         Some(TransparencyError::UnknownTransparency(value, span)) =>
             sess.span_diagnostic.span_err(
@@ -432,6 +433,10 @@ pub fn compile(
         None => {}
     }
 
+    let expander: Box<_> = Box::new(MacroRulesMacroExpander {
+        name: def.ident, span: def.span, transparency, lhses, rhses, valid
+    });
+
     let allow_internal_unstable =
         attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| {
             attr.meta_item_list()
@@ -473,7 +478,7 @@ pub fn compile(
     SyntaxExtension {
         kind: SyntaxExtensionKind::LegacyBang(expander),
         span: def.span,
-        default_transparency,
+        default_transparency: transparency,
         allow_internal_unstable,
         allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe),
         local_inner_macros,
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 214e721fd1506..30d5df13dcedb 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -1,9 +1,8 @@
-use crate::ast::Ident;
+use crate::ast::{Ident, Mac};
 use crate::ext::base::ExtCtxt;
-use crate::ext::expand::Marker;
 use crate::ext::tt::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch};
 use crate::ext::tt::quoted;
-use crate::mut_visit::noop_visit_tt;
+use crate::mut_visit::{self, MutVisitor};
 use crate::parse::token::{self, NtTT, Token};
 use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 
@@ -11,8 +10,31 @@ use smallvec::{smallvec, SmallVec};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
+use syntax_pos::hygiene::{ExpnId, Transparency};
+use syntax_pos::Span;
+
 use std::mem;
 
+// A Marker adds the given mark to the syntax context.
+struct Marker(ExpnId, Transparency);
+
+impl MutVisitor for Marker {
+    fn visit_span(&mut self, span: &mut Span) {
+        *span = span.apply_mark(self.0, self.1)
+    }
+
+    fn visit_mac(&mut self, mac: &mut Mac) {
+        mut_visit::noop_visit_mac(mac, self)
+    }
+}
+
+impl Marker {
+    fn visit_delim_span(&mut self, dspan: &mut DelimSpan) {
+        self.visit_span(&mut dspan.open);
+        self.visit_span(&mut dspan.close);
+    }
+}
+
 /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
 enum Frame {
     Delimited { forest: Lrc<quoted::Delimited>, idx: usize, span: DelimSpan },
@@ -68,6 +90,7 @@ pub(super) fn transcribe(
     cx: &ExtCtxt<'_>,
     interp: &FxHashMap<Ident, NamedMatch>,
     src: Vec<quoted::TokenTree>,
+    transparency: Transparency,
 ) -> TokenStream {
     // Nothing for us to transcribe...
     if src.is_empty() {
@@ -96,6 +119,7 @@ pub(super) fn transcribe(
     // again, and we are done transcribing.
     let mut result: Vec<TreeAndJoint> = Vec::new();
     let mut result_stack = Vec::new();
+    let mut marker = Marker(cx.current_expansion.id, transparency);
 
     loop {
         // Look at the last frame on the stack.
@@ -207,7 +231,7 @@ pub(super) fn transcribe(
             }
 
             // Replace the meta-var with the matched token tree from the invocation.
-            quoted::TokenTree::MetaVar(mut sp, ident) => {
+            quoted::TokenTree::MetaVar(mut sp, mut ident) => {
                 // Find the matched nonterminal from the macro invocation, and use it to replace
                 // the meta-var.
                 if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) {
@@ -218,7 +242,7 @@ pub(super) fn transcribe(
                         if let NtTT(ref tt) = **nt {
                             result.push(tt.clone().into());
                         } else {
-                            sp = sp.apply_mark(cx.current_expansion.id);
+                            marker.visit_span(&mut sp);
                             let token = TokenTree::token(token::Interpolated(nt.clone()), sp);
                             result.push(token.into());
                         }
@@ -232,9 +256,8 @@ pub(super) fn transcribe(
                 } else {
                     // If we aren't able to match the meta-var, we push it back into the result but
                     // with modified syntax context. (I believe this supports nested macros).
-                    let ident =
-                        Ident::new(ident.name, ident.span.apply_mark(cx.current_expansion.id));
-                    sp = sp.apply_mark(cx.current_expansion.id);
+                    marker.visit_span(&mut sp);
+                    marker.visit_ident(&mut ident);
                     result.push(TokenTree::token(token::Dollar, sp).into());
                     result.push(TokenTree::Token(Token::from_ast_ident(ident)).into());
                 }
@@ -246,7 +269,7 @@ pub(super) fn transcribe(
             // jump back out of the Delimited, pop the result_stack and add the new results back to
             // the previous results (from outside the Delimited).
             quoted::TokenTree::Delimited(mut span, delimited) => {
-                span = span.apply_mark(cx.current_expansion.id);
+                marker.visit_delim_span(&mut span);
                 stack.push(Frame::Delimited { forest: delimited, idx: 0, span });
                 result_stack.push(mem::take(&mut result));
             }
@@ -254,9 +277,8 @@ pub(super) fn transcribe(
             // Nothing much to do here. Just push the token to the result, being careful to
             // preserve syntax context.
             quoted::TokenTree::Token(token) => {
-                let mut marker = Marker(cx.current_expansion.id);
                 let mut tt = TokenTree::Token(token);
-                noop_visit_tt(&mut tt, &mut marker);
+                marker.visit_tt(&mut tt);
                 result.push(tt.into());
             }
 
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 09a1b93c7bb19..0d9f3769ce904 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -19,7 +19,7 @@ use crate::parse::Directory;
 use crate::parse::token::{self, DelimToken, Token, TokenKind};
 use crate::print::pprust;
 
-use syntax_pos::{BytePos, ExpnId, Span, DUMMY_SP};
+use syntax_pos::{BytePos, Span, DUMMY_SP};
 #[cfg(target_arch = "x86_64")]
 use rustc_data_structures::static_assert_size;
 use rustc_data_structures::sync::Lrc;
@@ -547,11 +547,4 @@ impl DelimSpan {
     pub fn entire(self) -> Span {
         self.open.with_hi(self.close.hi())
     }
-
-    pub fn apply_mark(self, expn_id: ExpnId) -> Self {
-        DelimSpan {
-            open: self.open.apply_mark(expn_id),
-            close: self.close.apply_mark(expn_id),
-        }
-    }
 }
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index c4a0e16d931f2..fa84dcdb7bf89 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -192,10 +192,10 @@ impl HygieneData {
         self.syntax_context_data[ctxt.0 as usize].parent
     }
 
-    fn remove_mark(&self, ctxt: &mut SyntaxContext) -> ExpnId {
-        let outer_expn = self.outer_expn(*ctxt);
+    fn remove_mark(&self, ctxt: &mut SyntaxContext) -> (ExpnId, Transparency) {
+        let outer_mark = self.outer_mark(*ctxt);
         *ctxt = self.parent_ctxt(*ctxt);
-        outer_expn
+        outer_mark
     }
 
     fn marks(&self, mut ctxt: SyntaxContext) -> Vec<(ExpnId, Transparency)> {
@@ -218,20 +218,14 @@ impl HygieneData {
     fn adjust(&self, ctxt: &mut SyntaxContext, expn_id: ExpnId) -> Option<ExpnId> {
         let mut scope = None;
         while !self.is_descendant_of(expn_id, self.outer_expn(*ctxt)) {
-            scope = Some(self.remove_mark(ctxt));
+            scope = Some(self.remove_mark(ctxt).0);
         }
         scope
     }
 
-    fn apply_mark(&mut self, ctxt: SyntaxContext, expn_id: ExpnId) -> SyntaxContext {
-        assert_ne!(expn_id, ExpnId::root());
-        self.apply_mark_with_transparency(
-            ctxt, expn_id, self.expn_data(expn_id).default_transparency
-        )
-    }
-
-    fn apply_mark_with_transparency(&mut self, ctxt: SyntaxContext, expn_id: ExpnId,
-                                    transparency: Transparency) -> SyntaxContext {
+    fn apply_mark(
+        &mut self, ctxt: SyntaxContext, expn_id: ExpnId, transparency: Transparency
+    ) -> SyntaxContext {
         assert_ne!(expn_id, ExpnId::root());
         if transparency == Transparency::Opaque {
             return self.apply_mark_internal(ctxt, expn_id, transparency);
@@ -365,15 +359,9 @@ impl SyntaxContext {
         SyntaxContext(raw)
     }
 
-    /// Extend a syntax context with a given expansion and default transparency for that expansion.
-    pub fn apply_mark(self, expn_id: ExpnId) -> SyntaxContext {
-        HygieneData::with(|data| data.apply_mark(self, expn_id))
-    }
-
     /// Extend a syntax context with a given expansion and transparency.
-    pub fn apply_mark_with_transparency(self, expn_id: ExpnId, transparency: Transparency)
-                                        -> SyntaxContext {
-        HygieneData::with(|data| data.apply_mark_with_transparency(self, expn_id, transparency))
+    pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext {
+        HygieneData::with(|data| data.apply_mark(self, expn_id, transparency))
     }
 
     /// Pulls a single mark off of the syntax context. This effectively moves the
@@ -393,7 +381,7 @@ impl SyntaxContext {
     /// invocation of f that created g1.
     /// Returns the mark that was removed.
     pub fn remove_mark(&mut self) -> ExpnId {
-        HygieneData::with(|data| data.remove_mark(self))
+        HygieneData::with(|data| data.remove_mark(self).0)
     }
 
     pub fn marks(self) -> Vec<(ExpnId, Transparency)> {
@@ -466,8 +454,8 @@ impl SyntaxContext {
             let mut scope = None;
             let mut glob_ctxt = data.modern(glob_span.ctxt());
             while !data.is_descendant_of(expn_id, data.outer_expn(glob_ctxt)) {
-                scope = Some(data.remove_mark(&mut glob_ctxt));
-                if data.remove_mark(self) != scope.unwrap() {
+                scope = Some(data.remove_mark(&mut glob_ctxt).0);
+                if data.remove_mark(self).0 != scope.unwrap() {
                     return None;
                 }
             }
@@ -498,9 +486,9 @@ impl SyntaxContext {
                 marks.push(data.remove_mark(&mut glob_ctxt));
             }
 
-            let scope = marks.last().cloned();
-            while let Some(mark) = marks.pop() {
-                *self = data.apply_mark(*self, mark);
+            let scope = marks.last().map(|mark| mark.0);
+            while let Some((expn_id, transparency)) = marks.pop() {
+                *self = data.apply_mark(*self, expn_id, transparency);
             }
             Some(scope)
         })
@@ -571,9 +559,7 @@ impl Span {
     ) -> Span {
         HygieneData::with(|data| {
             let expn_id = data.fresh_expn(Some(expn_data));
-            self.with_ctxt(data.apply_mark_with_transparency(
-                SyntaxContext::root(), expn_id, transparency
-            ))
+            self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id, transparency))
         })
     }
 }
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 6fffefd0d6cbb..3d8bfc77a8950 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -517,13 +517,13 @@ impl Span {
     /// given ID and transparency, assuming that macro was defined directly and not produced by
     /// some other macro (which is the case for built-in and procedural macros).
     pub fn with_ctxt_from_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span {
-        self.with_ctxt(SyntaxContext::root().apply_mark_with_transparency(expn_id, transparency))
+        self.with_ctxt(SyntaxContext::root().apply_mark(expn_id, transparency))
     }
 
     #[inline]
-    pub fn apply_mark(self, mark: ExpnId) -> Span {
+    pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span {
         let span = self.data();
-        span.with_ctxt(span.ctxt.apply_mark(mark))
+        span.with_ctxt(span.ctxt.apply_mark(expn_id, transparency))
     }
 
     #[inline]

From 181ed55e96e589afe565e5ad4e7f1cd6a8000894 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Fri, 23 Aug 2019 00:48:52 +0200
Subject: [PATCH 141/943] Simplify eager normalization of constants

---
 src/librustc/traits/project.rs                | 36 +-----------------
 src/librustc/traits/query/normalize.rs        | 38 +------------------
 src/test/ui/consts/const-size_of-cycle.stderr | 10 ++---
 src/test/ui/issues/issue-44415.stderr         | 10 ++---
 4 files changed, 13 insertions(+), 81 deletions(-)

diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 72df45df92314..87a23f655a8f3 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -15,7 +15,6 @@ use super::util;
 use crate::hir::def_id::DefId;
 use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use crate::mir::interpret::{GlobalId, ConstValue};
 use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
 use rustc_macros::HashStable;
 use syntax::ast::Ident;
@@ -397,40 +396,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
     }
 
     fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
-        if let ConstValue::Unevaluated(def_id, substs) = constant.val {
-            let tcx = self.selcx.tcx().global_tcx();
-            let param_env = self.param_env;
-            if !param_env.has_local_value() {
-                if substs.needs_infer() || substs.has_placeholders() {
-                    let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
-                    let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
-                    if let Some(instance) = instance {
-                        let cid = GlobalId {
-                            instance,
-                            promoted: None
-                        };
-                        if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
-                            let evaluated = evaluated.subst(tcx, substs);
-                            return evaluated;
-                        }
-                    }
-                } else {
-                    if !substs.has_local_value() {
-                        let instance = ty::Instance::resolve(tcx, param_env, def_id, substs);
-                        if let Some(instance) = instance {
-                            let cid = GlobalId {
-                                instance,
-                                promoted: None
-                            };
-                            if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
-                                return evaluated;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        constant
+        constant.eval(self.selcx.tcx(), self.param_env)
     }
 }
 
diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs
index 2ffcd0fd4d941..c31ff3ab1b55d 100644
--- a/src/librustc/traits/query/normalize.rs
+++ b/src/librustc/traits/query/normalize.rs
@@ -5,11 +5,10 @@
 use crate::infer::at::At;
 use crate::infer::canonical::OriginalQueryValues;
 use crate::infer::{InferCtxt, InferOk};
-use crate::mir::interpret::{GlobalId, ConstValue};
 use crate::traits::project::Normalized;
 use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
 use crate::ty::fold::{TypeFoldable, TypeFolder};
-use crate::ty::subst::{Subst, InternalSubsts};
+use crate::ty::subst::Subst;
 use crate::ty::{self, Ty, TyCtxt};
 
 use super::NoSolution;
@@ -191,40 +190,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
     }
 
     fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
-        if let ConstValue::Unevaluated(def_id, substs) = constant.val {
-            let tcx = self.infcx.tcx.global_tcx();
-            let param_env = self.param_env;
-            if !param_env.has_local_value() {
-                if substs.needs_infer() || substs.has_placeholders() {
-                    let identity_substs = InternalSubsts::identity_for_item(tcx, def_id);
-                    let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
-                    if let Some(instance) = instance {
-                        let cid = GlobalId {
-                            instance,
-                            promoted: None,
-                        };
-                        if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
-                            let evaluated = evaluated.subst(tcx, substs);
-                            return evaluated;
-                        }
-                    }
-                } else {
-                    if !substs.has_local_value() {
-                        let instance = ty::Instance::resolve(tcx, param_env, def_id, substs);
-                        if let Some(instance) = instance {
-                            let cid = GlobalId {
-                                instance,
-                                promoted: None,
-                            };
-                            if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) {
-                                return evaluated;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        constant
+        constant.eval(self.infcx.tcx, self.param_env)
     }
 }
 
diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr
index 113ec29239616..fdba359e7464a 100644
--- a/src/test/ui/consts/const-size_of-cycle.stderr
+++ b/src/test/ui/consts/const-size_of-cycle.stderr
@@ -4,6 +4,11 @@ error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{con
 LL |     bytes: [u8; std::mem::size_of::<Foo>()]
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
+note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...
+  --> $DIR/const-size_of-cycle.rs:6:17
+   |
+LL |     bytes: [u8; std::mem::size_of::<Foo>()]
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`...
   --> $SRC_DIR/libcore/mem/mod.rs:LL:COL
    |
@@ -11,11 +16,6 @@ LL |     intrinsics::size_of::<T>()
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires computing layout of `Foo`...
    = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
-note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...
-  --> $DIR/const-size_of-cycle.rs:6:17
-   |
-LL |     bytes: [u8; std::mem::size_of::<Foo>()]
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle
 note: cycle used when processing `Foo`
   --> $DIR/const-size_of-cycle.rs:5:1
diff --git a/src/test/ui/issues/issue-44415.stderr b/src/test/ui/issues/issue-44415.stderr
index df8e804c87a3f..8008e53f65f4d 100644
--- a/src/test/ui/issues/issue-44415.stderr
+++ b/src/test/ui/issues/issue-44415.stderr
@@ -4,6 +4,11 @@ error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{con
 LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
    |                 ^^^^^^
    |
+note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...
+  --> $DIR/issue-44415.rs:6:17
+   |
+LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
+   |                 ^^^^^^
 note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`...
   --> $DIR/issue-44415.rs:6:26
    |
@@ -11,11 +16,6 @@ LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires computing layout of `Foo`...
    = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
-note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...
-  --> $DIR/issue-44415.rs:6:17
-   |
-LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
-   |                 ^^^^^^
    = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle
 note: cycle used when processing `Foo`
   --> $DIR/issue-44415.rs:5:1

From 6548a5fa5d1f6d1794592945837111f7264ae598 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Fri, 23 Aug 2019 01:44:18 +0300
Subject: [PATCH 142/943] Remove default macro transparencies

All transparancies are passed explicitly now.
Also remove `#[rustc_macro_transparency]` annotations from built-in macros, they are no longer used.
`#[rustc_macro_transparency]` only makes sense for declarative macros now.
---
 src/libcore/macros.rs               |  8 --------
 src/librustc/ich/impls_syntax.rs    |  1 -
 src/libsyntax/ext/base.rs           | 20 --------------------
 src/libsyntax/ext/tt/macro_rules.rs |  1 -
 src/libsyntax_pos/hygiene.rs        |  6 +-----
 5 files changed, 1 insertion(+), 35 deletions(-)

diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 6c88a766a2f10..ffaca029a8a78 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -734,7 +734,6 @@ pub(crate) mod builtin {
     #[allow_internal_unstable(fmt_internals)]
     #[rustc_builtin_macro]
     #[macro_export]
-    #[rustc_macro_transparency = "opaque"]
     macro_rules! format_args {
         ($fmt:expr) => ({ /* compiler built-in */ });
         ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
@@ -747,7 +746,6 @@ pub(crate) mod builtin {
     #[allow_internal_unstable(fmt_internals)]
     #[rustc_builtin_macro]
     #[macro_export]
-    #[rustc_macro_transparency = "opaque"]
     macro_rules! format_args_nl {
         ($fmt:expr) => ({ /* compiler built-in */ });
         ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
@@ -1235,7 +1233,6 @@ pub(crate) mod builtin {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow_internal_unstable(test, rustc_attrs)]
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
     pub macro test($item:item) { /* compiler built-in */ }
 
     /// Attribute macro applied to a function to turn it into a benchmark test.
@@ -1243,7 +1240,6 @@ pub(crate) mod builtin {
                reason = "`bench` is a part of custom test frameworks which are unstable")]
     #[allow_internal_unstable(test, rustc_attrs)]
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
     pub macro bench($item:item) { /* compiler built-in */ }
 
     /// An implementation detail of the `#[test]` and `#[bench]` macros.
@@ -1251,26 +1247,22 @@ pub(crate) mod builtin {
                reason = "custom test frameworks are an unstable feature")]
     #[allow_internal_unstable(test, rustc_attrs)]
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
     pub macro test_case($item:item) { /* compiler built-in */ }
 
     /// Attribute macro applied to a static to register it as a global allocator.
     #[stable(feature = "global_allocator", since = "1.28.0")]
     #[allow_internal_unstable(rustc_attrs)]
     #[rustc_builtin_macro]
-    #[rustc_macro_transparency = "semitransparent"]
     pub macro global_allocator($item:item) { /* compiler built-in */ }
 
     /// Unstable implementation detail of the `rustc` compiler, do not use.
     #[rustc_builtin_macro]
-    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow_internal_unstable(core_intrinsics, libstd_sys_internals)]
     pub macro RustcDecodable($item:item) { /* compiler built-in */ }
 
     /// Unstable implementation detail of the `rustc` compiler, do not use.
     #[rustc_builtin_macro]
-    #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[allow_internal_unstable(core_intrinsics)]
     pub macro RustcEncodable($item:item) { /* compiler built-in */ }
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 7003f71c8baa0..05e2c7854b49c 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -402,7 +402,6 @@ impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData {
     parent -> _,
     call_site,
     def_site,
-    default_transparency,
     allow_internal_unstable,
     allow_internal_unsafe,
     local_inner_macros,
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 004ae1cf96541..a63c4181d5e03 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -549,8 +549,6 @@ pub struct SyntaxExtension {
     pub kind: SyntaxExtensionKind,
     /// Span of the macro definition.
     pub span: Span,
-    /// Hygienic properties of spans produced by this macro by default.
-    pub default_transparency: Transparency,
     /// Whitelist of unstable features that are treated as stable inside this macro.
     pub allow_internal_unstable: Option<Lrc<[Symbol]>>,
     /// Suppresses the `unsafe_code` lint for code produced by this macro.
@@ -572,22 +570,6 @@ pub struct SyntaxExtension {
     pub is_derive_copy: bool,
 }
 
-impl SyntaxExtensionKind {
-    /// When a syntax extension is constructed,
-    /// its transparency can often be inferred from its kind.
-    fn default_transparency(&self) -> Transparency {
-        match self {
-            SyntaxExtensionKind::Bang(..) |
-            SyntaxExtensionKind::Attr(..) |
-            SyntaxExtensionKind::Derive(..) |
-            SyntaxExtensionKind::NonMacroAttr { .. } => Transparency::Opaque,
-            SyntaxExtensionKind::LegacyBang(..) |
-            SyntaxExtensionKind::LegacyAttr(..) |
-            SyntaxExtensionKind::LegacyDerive(..) => Transparency::SemiTransparent,
-        }
-    }
-}
-
 impl SyntaxExtension {
     /// Returns which kind of macro calls this syntax extension.
     pub fn macro_kind(&self) -> MacroKind {
@@ -606,7 +588,6 @@ impl SyntaxExtension {
     pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension {
         SyntaxExtension {
             span: DUMMY_SP,
-            default_transparency: kind.default_transparency(),
             allow_internal_unstable: None,
             allow_internal_unsafe: false,
             local_inner_macros: false,
@@ -646,7 +627,6 @@ impl SyntaxExtension {
             parent,
             call_site,
             def_site: self.span,
-            default_transparency: self.default_transparency,
             allow_internal_unstable: self.allow_internal_unstable.clone(),
             allow_internal_unsafe: self.allow_internal_unsafe,
             local_inner_macros: self.local_inner_macros,
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 9292ce334b819..37cb8467ff5ee 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -478,7 +478,6 @@ pub fn compile(
     SyntaxExtension {
         kind: SyntaxExtensionKind::LegacyBang(expander),
         span: def.span,
-        default_transparency: transparency,
         allow_internal_unstable,
         allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe),
         local_inner_macros,
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index fa84dcdb7bf89..733f6f0449065 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -550,8 +550,7 @@ impl Span {
     /// The returned span belongs to the created expansion and has the new properties,
     /// but its location is inherited from the current span.
     pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
-        let transparency = expn_data.default_transparency;
-        self.fresh_expansion_with_transparency(expn_data, transparency)
+        self.fresh_expansion_with_transparency(expn_data, Transparency::SemiTransparent)
     }
 
     pub fn fresh_expansion_with_transparency(
@@ -591,8 +590,6 @@ pub struct ExpnData {
     /// The span of the macro definition (possibly dummy).
     /// This span serves only informational purpose and is not used for resolution.
     pub def_site: Span,
-    /// Transparency used by `apply_mark` for the expansion with this expansion data by default.
-    pub default_transparency: Transparency,
     /// List of #[unstable]/feature-gated features that the macro is allowed to use
     /// internally without forcing the whole crate to opt-in
     /// to them.
@@ -615,7 +612,6 @@ impl ExpnData {
             parent: ExpnId::root(),
             call_site,
             def_site: DUMMY_SP,
-            default_transparency: Transparency::SemiTransparent,
             allow_internal_unstable: None,
             allow_internal_unsafe: false,
             local_inner_macros: false,

From 54f80a5b7c254d1df302680eac6552665b4c8945 Mon Sep 17 00:00:00 2001
From: nathanwhit <nathan.whitaker01@gmail.com>
Date: Thu, 22 Aug 2019 12:01:37 -0400
Subject: [PATCH 143/943] Add header flag to check run-pass test output

---
 src/tools/compiletest/src/header.rs | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 076ad87c70fc4..dcd4f14f354d1 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -326,6 +326,8 @@ pub struct TestProps {
     pub force_host: bool,
     // Check stdout for error-pattern output as well as stderr
     pub check_stdout: bool,
+    // Check stdout & stderr for output of run-pass test
+    pub check_run_results: bool,
     // For UI tests, allows compiler to generate arbitrary output to stdout
     pub dont_check_compiler_stdout: bool,
     // For UI tests, allows compiler to generate arbitrary output to stderr
@@ -388,6 +390,7 @@ impl TestProps {
             build_aux_docs: false,
             force_host: false,
             check_stdout: false,
+            check_run_results: false,
             dont_check_compiler_stdout: false,
             dont_check_compiler_stderr: false,
             no_prefer_dynamic: false,
@@ -468,6 +471,10 @@ impl TestProps {
                 self.check_stdout = config.parse_check_stdout(ln);
             }
 
+            if !self.check_run_results {
+                self.check_run_results = config.parse_check_run_results(ln);
+            }
+
             if !self.dont_check_compiler_stdout {
                 self.dont_check_compiler_stdout = config.parse_dont_check_compiler_stdout(ln);
             }
@@ -712,6 +719,10 @@ impl Config {
         self.parse_name_directive(line, "check-stdout")
     }
 
+    fn parse_check_run_results(&self, line: &str) -> bool {
+        self.parse_name_directive(line, "check-run-results")
+    }
+
     fn parse_dont_check_compiler_stdout(&self, line: &str) -> bool {
         self.parse_name_directive(line, "dont-check-compiler-stdout")
     }

From 0c379dff2919321944440cfe7c306c2d35bffaaa Mon Sep 17 00:00:00 2001
From: Nathan <nathan.whitaker01@gmail.com>
Date: Thu, 22 Aug 2019 19:02:13 -0400
Subject: [PATCH 144/943] Extract loading and comparison of compiletest outputs
 to new fn

Moved into ```fn load_compare_outputs(&self, proc_res: &ProcRes, explicit_format: bool) -> usize```
---
 src/tools/compiletest/src/runtest.rs | 35 ++++++++++++++++------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 3da6be74129f4..86c5e4ac89dd6 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2934,33 +2934,20 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    fn run_ui_test(&self) {
-        // if the user specified a format in the ui test
-        // print the output to the stderr file, otherwise extract
-        // the rendered error messages from json and print them
-        let explicit = self
-            .props
-            .compile_flags
-            .iter()
-            .any(|s| s.contains("--error-format"));
-        let proc_res = self.compile_test();
-        self.check_if_test_should_compile(&proc_res);
-
+    fn load_compare_outputs(&self, proc_res: &ProcRes, explicit_format: bool) -> usize {
         let expected_stderr = self.load_expected_output(UI_STDERR);
         let expected_stdout = self.load_expected_output(UI_STDOUT);
-        let expected_fixed = self.load_expected_output(UI_FIXED);
 
         let normalized_stdout =
             self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout);
 
-        let stderr = if explicit {
+        let stderr = if explicit_format {
             proc_res.stderr.clone()
         } else {
             json::extract_rendered(&proc_res.stderr)
         };
 
         let normalized_stderr = self.normalize_output(&stderr, &self.props.normalize_stderr);
-
         let mut errors = 0;
         if !self.props.dont_check_compiler_stdout {
             errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout);
@@ -2968,10 +2955,28 @@ impl<'test> TestCx<'test> {
         if !self.props.dont_check_compiler_stderr {
             errors += self.compare_output("stderr", &normalized_stderr, &expected_stderr);
         }
+        errors
+    }
+
+    fn run_ui_test(&self) {
+        // if the user specified a format in the ui test
+        // print the output to the stderr file, otherwise extract
+        // the rendered error messages from json and print them
+        let explicit = self
+            .props
+            .compile_flags
+            .iter()
+            .any(|s| s.contains("--error-format"));
+        let proc_res = self.compile_test();
+        self.check_if_test_should_compile(&proc_res);
+
+        let expected_fixed = self.load_expected_output(UI_FIXED);
 
         let modes_to_prune = vec![CompareMode::Nll];
         self.prune_duplicate_outputs(&modes_to_prune);
 
+        let mut errors = self.load_compare_outputs(&proc_res, explicit);
+
         if self.config.compare_mode.is_some() {
             // don't test rustfix with nll right now
         } else if self.config.rustfix_coverage {

From b9ba8f9596ac282b3254edbb9a7176771fb6ba24 Mon Sep 17 00:00:00 2001
From: Nathan <nathan.whitaker01@gmail.com>
Date: Thu, 22 Aug 2019 19:08:51 -0400
Subject: [PATCH 145/943] Compare run-pass outputs if `check-run-results` flag
 enabled

Addresses #63751
---
 src/tools/compiletest/src/runtest.rs | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 86c5e4ac89dd6..c1f8caa474e2d 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2975,7 +2975,14 @@ impl<'test> TestCx<'test> {
         let modes_to_prune = vec![CompareMode::Nll];
         self.prune_duplicate_outputs(&modes_to_prune);
 
-        let mut errors = self.load_compare_outputs(&proc_res, explicit);
+        // if the user specified to check the results of the
+        // run-pass test, delay loading and comparing output
+        // until execution of the binary
+        let mut errors = if !self.props.check_run_results {
+            self.load_compare_outputs(&proc_res, explicit)
+        } else {
+            0
+        };
 
         if self.config.compare_mode.is_some() {
             // don't test rustfix with nll right now
@@ -3054,7 +3061,17 @@ impl<'test> TestCx<'test> {
 
         if self.should_run_successfully() {
             let proc_res = self.exec_compiled_test();
-
+            let run_output_errors = if self.props.check_run_results {
+                self.load_compare_outputs(&proc_res, explicit)
+            } else {
+                0
+            };
+            if run_output_errors > 0 {
+                self.fatal_proc_rec(
+                    &format!("{} errors occured comparing run output.", run_output_errors),
+                    &proc_res,
+                );
+            }
             if !proc_res.status.success() {
                 self.fatal_proc_rec("test run failed!", &proc_res);
             }

From b873743c024d018b00e1e8c863a01d2c48bcdb1b Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 20 Aug 2019 18:40:53 +0200
Subject: [PATCH 146/943] syntax: extract `accepted.rs` feature gates.

---
 src/libsyntax/feature_gate.rs          | 234 +-----------------------
 src/libsyntax/feature_gate/accepted.rs | 236 +++++++++++++++++++++++++
 2 files changed, 239 insertions(+), 231 deletions(-)
 create mode 100644 src/libsyntax/feature_gate/accepted.rs

diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index fad4f3da3de70..32fef2fc8ddb7 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -12,6 +12,9 @@
 //! gate usage is added, *do not remove it again* even once the feature
 //! becomes stable.
 
+mod accepted;
+use accepted::ACCEPTED_FEATURES;
+
 use AttributeType::*;
 use AttributeGate::*;
 
@@ -94,13 +97,6 @@ macro_rules! declare_features {
             $((sym::$feature, $ver, $issue, None)),+
         ];
     };
-
-    ($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
-        /// Those language feature has since been Accepted (it was once Active)
-        const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, None)),+
-        ];
-    }
 }
 
 // If you change this, please modify `src/doc/unstable-book` as well.
@@ -638,230 +634,6 @@ declare_features! (
     (stable_removed, no_stack_check, "1.0.0", None, None),
 );
 
-declare_features! (
-    // -------------------------------------------------------------------------
-    // feature-group-start: for testing purposes
-    // -------------------------------------------------------------------------
-
-    // A temporary feature gate used to enable parser extensions needed
-    // to bootstrap fix for #5723.
-    (accepted, issue_5723_bootstrap, "1.0.0", None, None),
-    // These are used to test this portion of the compiler,
-    // they don't actually mean anything.
-    (accepted, test_accepted_feature, "1.0.0", None, None),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: for testing purposes
-    // -------------------------------------------------------------------------
-
-    // -------------------------------------------------------------------------
-    // feature-group-start: accepted features
-    // -------------------------------------------------------------------------
-
-    // Allows using associated `type`s in `trait`s.
-    (accepted, associated_types, "1.0.0", None, None),
-    // Allows using assigning a default type to type parameters in algebraic data type definitions.
-    (accepted, default_type_params, "1.0.0", None, None),
-    // FIXME: explain `globs`.
-    (accepted, globs, "1.0.0", None, None),
-    // Allows `macro_rules!` items.
-    (accepted, macro_rules, "1.0.0", None, None),
-    // Allows use of `&foo[a..b]` as a slicing syntax.
-    (accepted, slicing_syntax, "1.0.0", None, None),
-    // Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418).
-    (accepted, struct_variant, "1.0.0", None, None),
-    // Allows indexing tuples.
-    (accepted, tuple_indexing, "1.0.0", None, None),
-    // Allows the use of `if let` expressions.
-    (accepted, if_let, "1.0.0", None, None),
-    // Allows the use of `while let` expressions.
-    (accepted, while_let, "1.0.0", None, None),
-    // Allows using `#![no_std]`.
-    (accepted, no_std, "1.6.0", None, None),
-    // Allows overloading augmented assignment operations like `a += b`.
-    (accepted, augmented_assignments, "1.8.0", Some(28235), None),
-    // Allows empty structs and enum variants with braces.
-    (accepted, braced_empty_structs, "1.8.0", Some(29720), None),
-    // Allows `#[deprecated]` attribute.
-    (accepted, deprecated, "1.9.0", Some(29935), None),
-    // Allows macros to appear in the type position.
-    (accepted, type_macros, "1.13.0", Some(27245), None),
-    // Allows use of the postfix `?` operator in expressions.
-    (accepted, question_mark, "1.13.0", Some(31436), None),
-    // Allows `..` in tuple (struct) patterns.
-    (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None),
-    // Allows some increased flexibility in the name resolution rules,
-    // especially around globs and shadowing (RFC 1560).
-    (accepted, item_like_imports, "1.15.0", Some(35120), None),
-    // Allows using `Self` and associated types in struct expressions and patterns.
-    (accepted, more_struct_aliases, "1.16.0", Some(37544), None),
-    // Allows elision of `'static` lifetimes in `static`s and `const`s.
-    (accepted, static_in_const, "1.17.0", Some(35897), None),
-    // Allows field shorthands (`x` meaning `x: x`) in struct literal expressions.
-    (accepted, field_init_shorthand, "1.17.0", Some(37340), None),
-    // Allows the definition recursive static items.
-    (accepted, static_recursion, "1.17.0", Some(29719), None),
-    // Allows `pub(restricted)` visibilities (RFC 1422).
-    (accepted, pub_restricted, "1.18.0", Some(32409), None),
-    // Allows `#![windows_subsystem]`.
-    (accepted, windows_subsystem, "1.18.0", Some(37499), None),
-    // Allows `break {expr}` with a value inside `loop`s.
-    (accepted, loop_break_value, "1.19.0", Some(37339), None),
-    // Allows numeric fields in struct expressions and patterns.
-    (accepted, relaxed_adts, "1.19.0", Some(35626), None),
-    // Allows coercing non capturing closures to function pointers.
-    (accepted, closure_to_fn_coercion, "1.19.0", Some(39817), None),
-    // Allows attributes on struct literal fields.
-    (accepted, struct_field_attributes, "1.20.0", Some(38814), None),
-    // Allows the definition of associated constants in `trait` or `impl` blocks.
-    (accepted, associated_consts, "1.20.0", Some(29646), None),
-    // Allows usage of the `compile_error!` macro.
-    (accepted, compile_error, "1.20.0", Some(40872), None),
-    // Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
-    (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None),
-    // Allows `Drop` types in constants (RFC 1440).
-    (accepted, drop_types_in_const, "1.22.0", Some(33156), None),
-    // Allows the sysV64 ABI to be specified on all platforms
-    // instead of just the platforms on which it is the C ABI.
-    (accepted, abi_sysv64, "1.24.0", Some(36167), None),
-    // Allows `repr(align(16))` struct attribute (RFC 1358).
-    (accepted, repr_align, "1.25.0", Some(33626), None),
-    // Allows '|' at beginning of match arms (RFC 1925).
-    (accepted, match_beginning_vert, "1.25.0", Some(44101), None),
-    // Allows nested groups in `use` items (RFC 2128).
-    (accepted, use_nested_groups, "1.25.0", Some(44494), None),
-    // Allows indexing into constant arrays.
-    (accepted, const_indexing, "1.26.0", Some(29947), None),
-    // Allows using `a..=b` and `..=b` as inclusive range syntaxes.
-    (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None),
-    // Allows `..=` in patterns (RFC 1192).
-    (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None),
-    // Allows `fn main()` with return types which implements `Termination` (RFC 1937).
-    (accepted, termination_trait, "1.26.0", Some(43301), None),
-    // Allows implementing `Clone` for closures where possible (RFC 2132).
-    (accepted, clone_closures, "1.26.0", Some(44490), None),
-    // Allows implementing `Copy` for closures where possible (RFC 2132).
-    (accepted, copy_closures, "1.26.0", Some(44490), None),
-    // Allows `impl Trait` in function arguments.
-    (accepted, universal_impl_trait, "1.26.0", Some(34511), None),
-    // Allows `impl Trait` in function return types.
-    (accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
-    // Allows using the `u128` and `i128` types.
-    (accepted, i128_type, "1.26.0", Some(35118), None),
-    // Allows default match binding modes (RFC 2005).
-    (accepted, match_default_bindings, "1.26.0", Some(42640), None),
-    // Allows `'_` placeholder lifetimes.
-    (accepted, underscore_lifetimes, "1.26.0", Some(44524), None),
-    // Allows attributes on lifetime/type formal parameters in generics (RFC 1327).
-    (accepted, generic_param_attrs, "1.27.0", Some(48848), None),
-    // Allows `cfg(target_feature = "...")`.
-    (accepted, cfg_target_feature, "1.27.0", Some(29717), None),
-    // Allows `#[target_feature(...)]`.
-    (accepted, target_feature, "1.27.0", None, None),
-    // Allows using `dyn Trait` as a syntax for trait objects.
-    (accepted, dyn_trait, "1.27.0", Some(44662), None),
-    // Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940).
-    (accepted, fn_must_use, "1.27.0", Some(43302), None),
-    // Allows use of the `:lifetime` macro fragment specifier.
-    (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None),
-    // Allows `#[test]` functions where the return type implements `Termination` (RFC 1937).
-    (accepted, termination_trait_test, "1.27.0", Some(48854), None),
-    // Allows the `#[global_allocator]` attribute.
-    (accepted, global_allocator, "1.28.0", Some(27389), None),
-    // Allows `#[repr(transparent)]` attribute on newtype structs.
-    (accepted, repr_transparent, "1.28.0", Some(43036), None),
-    // Allows procedural macros in `proc-macro` crates.
-    (accepted, proc_macro, "1.29.0", Some(38356), None),
-    // Allows `foo.rs` as an alternative to `foo/mod.rs`.
-    (accepted, non_modrs_mods, "1.30.0", Some(44660), None),
-    // Allows use of the `:vis` macro fragment specifier
-    (accepted, macro_vis_matcher, "1.30.0", Some(41022), None),
-    // Allows importing and reexporting macros with `use`,
-    // enables macro modularization in general.
-    (accepted, use_extern_macros, "1.30.0", Some(35896), None),
-    // Allows keywords to be escaped for use as identifiers.
-    (accepted, raw_identifiers, "1.30.0", Some(48589), None),
-    // Allows attributes scoped to tools.
-    (accepted, tool_attributes, "1.30.0", Some(44690), None),
-    // Allows multi-segment paths in attributes and derives.
-    (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None),
-    // Allows all literals in attribute lists and values of key-value pairs.
-    (accepted, attr_literals, "1.30.0", Some(34981), None),
-    // Allows inferring outlives requirements (RFC 2093).
-    (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None),
-    // Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`.
-    // This defines the behavior of panics.
-    (accepted, panic_handler, "1.30.0", Some(44489), None),
-    // Allows `#[used]` to preserve symbols (see llvm.used).
-    (accepted, used, "1.30.0", Some(40289), None),
-    // Allows `crate` in paths.
-    (accepted, crate_in_paths, "1.30.0", Some(45477), None),
-    // Allows resolving absolute paths as paths from other crates.
-    (accepted, extern_absolute_paths, "1.30.0", Some(44660), None),
-    // Allows access to crate names passed via `--extern` through prelude.
-    (accepted, extern_prelude, "1.30.0", Some(44660), None),
-    // Allows parentheses in patterns.
-    (accepted, pattern_parentheses, "1.31.0", Some(51087), None),
-    // Allows the definition of `const fn` functions.
-    (accepted, min_const_fn, "1.31.0", Some(53555), None),
-    // Allows scoped lints.
-    (accepted, tool_lints, "1.31.0", Some(44690), None),
-    // Allows lifetime elision in `impl` headers. For example:
-    // + `impl<I:Iterator> Iterator for &mut Iterator`
-    // + `impl Debug for Foo<'_>`
-    (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None),
-    // Allows `extern crate foo as bar;`. This puts `bar` into extern prelude.
-    (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
-    // Allows use of the `:literal` macro fragment specifier (RFC 1576).
-    (accepted, macro_literal_matcher, "1.32.0", Some(35625), None),
-    // Allows use of `?` as the Kleene "at most one" operator in macros.
-    (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
-    // Allows `Self` struct constructor (RFC 2302).
-    (accepted, self_struct_ctor, "1.32.0", Some(51994), None),
-    // Allows `Self` in type definitions (RFC 2300).
-    (accepted, self_in_typedefs, "1.32.0", Some(49303), None),
-    // Allows `use x::y;` to search `x` in the current scope.
-    (accepted, uniform_paths, "1.32.0", Some(53130), None),
-    // Allows integer match exhaustiveness checking (RFC 2591).
-    (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None),
-    // Allows `use path as _;` and `extern crate c as _;`.
-    (accepted, underscore_imports, "1.33.0", Some(48216), None),
-    // Allows `#[repr(packed(N))]` attribute on structs.
-    (accepted, repr_packed, "1.33.0", Some(33158), None),
-    // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
-    (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None),
-    // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
-    (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
-    // Allows let bindings, assignments and destructuring in `const` functions and constants.
-    // As long as control flow is not implemented in const eval, `&&` and `||` may not be used
-    // at the same time as let bindings.
-    (accepted, const_let, "1.33.0", Some(48821), None),
-    // Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
-    (accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
-    // Allows top level or-patterns (`p | q`) in `if let` and `while let`.
-    (accepted, if_while_or_patterns, "1.33.0", Some(48215), None),
-    // Allows `cfg(target_vendor = "...")`.
-    (accepted, cfg_target_vendor, "1.33.0", Some(29718), None),
-    // Allows `extern crate self as foo;`.
-    // This puts local crate root into extern prelude under name `foo`.
-    (accepted, extern_crate_self, "1.34.0", Some(56409), None),
-    // Allows arbitrary delimited token streams in non-macro attributes.
-    (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
-    // Allows paths to enum variants on type aliases including `Self`.
-    (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None),
-    // Allows using `#[repr(align(X))]` on enums with equivalent semantics
-    // to wrapping an enum in a wrapper struct with `#[repr(align(X))]`.
-    (accepted, repr_align_enum, "1.37.0", Some(57996), None),
-    // Allows `const _: TYPE = VALUE`.
-    (accepted, underscore_const_names, "1.37.0", Some(54912), None),
-    // Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
-    (accepted, async_await, "1.39.0", Some(50547), None),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: accepted features
-    // -------------------------------------------------------------------------
-);
-
 // If you change this, please modify `src/doc/unstable-book` as well. You must
 // move that documentation into the relevant place in the other docs, and
 // remove the chapter on the flag.
diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs
new file mode 100644
index 0000000000000..32a0b76d5f0d8
--- /dev/null
+++ b/src/libsyntax/feature_gate/accepted.rs
@@ -0,0 +1,236 @@
+//! List of the accepted feature gates.
+
+use crate::symbol::{Symbol, sym};
+
+macro_rules! declare_features {
+    ($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
+        /// Those language feature has since been Accepted (it was once Active)
+        pub const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, None)),+
+        ];
+    }
+}
+
+declare_features! (
+    // -------------------------------------------------------------------------
+    // feature-group-start: for testing purposes
+    // -------------------------------------------------------------------------
+
+    // A temporary feature gate used to enable parser extensions needed
+    // to bootstrap fix for #5723.
+    (accepted, issue_5723_bootstrap, "1.0.0", None, None),
+    // These are used to test this portion of the compiler,
+    // they don't actually mean anything.
+    (accepted, test_accepted_feature, "1.0.0", None, None),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: for testing purposes
+    // -------------------------------------------------------------------------
+
+    // -------------------------------------------------------------------------
+    // feature-group-start: accepted features
+    // -------------------------------------------------------------------------
+
+    // Allows using associated `type`s in `trait`s.
+    (accepted, associated_types, "1.0.0", None, None),
+    // Allows using assigning a default type to type parameters in algebraic data type definitions.
+    (accepted, default_type_params, "1.0.0", None, None),
+    // FIXME: explain `globs`.
+    (accepted, globs, "1.0.0", None, None),
+    // Allows `macro_rules!` items.
+    (accepted, macro_rules, "1.0.0", None, None),
+    // Allows use of `&foo[a..b]` as a slicing syntax.
+    (accepted, slicing_syntax, "1.0.0", None, None),
+    // Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418).
+    (accepted, struct_variant, "1.0.0", None, None),
+    // Allows indexing tuples.
+    (accepted, tuple_indexing, "1.0.0", None, None),
+    // Allows the use of `if let` expressions.
+    (accepted, if_let, "1.0.0", None, None),
+    // Allows the use of `while let` expressions.
+    (accepted, while_let, "1.0.0", None, None),
+    // Allows using `#![no_std]`.
+    (accepted, no_std, "1.6.0", None, None),
+    // Allows overloading augmented assignment operations like `a += b`.
+    (accepted, augmented_assignments, "1.8.0", Some(28235), None),
+    // Allows empty structs and enum variants with braces.
+    (accepted, braced_empty_structs, "1.8.0", Some(29720), None),
+    // Allows `#[deprecated]` attribute.
+    (accepted, deprecated, "1.9.0", Some(29935), None),
+    // Allows macros to appear in the type position.
+    (accepted, type_macros, "1.13.0", Some(27245), None),
+    // Allows use of the postfix `?` operator in expressions.
+    (accepted, question_mark, "1.13.0", Some(31436), None),
+    // Allows `..` in tuple (struct) patterns.
+    (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None),
+    // Allows some increased flexibility in the name resolution rules,
+    // especially around globs and shadowing (RFC 1560).
+    (accepted, item_like_imports, "1.15.0", Some(35120), None),
+    // Allows using `Self` and associated types in struct expressions and patterns.
+    (accepted, more_struct_aliases, "1.16.0", Some(37544), None),
+    // Allows elision of `'static` lifetimes in `static`s and `const`s.
+    (accepted, static_in_const, "1.17.0", Some(35897), None),
+    // Allows field shorthands (`x` meaning `x: x`) in struct literal expressions.
+    (accepted, field_init_shorthand, "1.17.0", Some(37340), None),
+    // Allows the definition recursive static items.
+    (accepted, static_recursion, "1.17.0", Some(29719), None),
+    // Allows `pub(restricted)` visibilities (RFC 1422).
+    (accepted, pub_restricted, "1.18.0", Some(32409), None),
+    // Allows `#![windows_subsystem]`.
+    (accepted, windows_subsystem, "1.18.0", Some(37499), None),
+    // Allows `break {expr}` with a value inside `loop`s.
+    (accepted, loop_break_value, "1.19.0", Some(37339), None),
+    // Allows numeric fields in struct expressions and patterns.
+    (accepted, relaxed_adts, "1.19.0", Some(35626), None),
+    // Allows coercing non capturing closures to function pointers.
+    (accepted, closure_to_fn_coercion, "1.19.0", Some(39817), None),
+    // Allows attributes on struct literal fields.
+    (accepted, struct_field_attributes, "1.20.0", Some(38814), None),
+    // Allows the definition of associated constants in `trait` or `impl` blocks.
+    (accepted, associated_consts, "1.20.0", Some(29646), None),
+    // Allows usage of the `compile_error!` macro.
+    (accepted, compile_error, "1.20.0", Some(40872), None),
+    // Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
+    (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None),
+    // Allows `Drop` types in constants (RFC 1440).
+    (accepted, drop_types_in_const, "1.22.0", Some(33156), None),
+    // Allows the sysV64 ABI to be specified on all platforms
+    // instead of just the platforms on which it is the C ABI.
+    (accepted, abi_sysv64, "1.24.0", Some(36167), None),
+    // Allows `repr(align(16))` struct attribute (RFC 1358).
+    (accepted, repr_align, "1.25.0", Some(33626), None),
+    // Allows '|' at beginning of match arms (RFC 1925).
+    (accepted, match_beginning_vert, "1.25.0", Some(44101), None),
+    // Allows nested groups in `use` items (RFC 2128).
+    (accepted, use_nested_groups, "1.25.0", Some(44494), None),
+    // Allows indexing into constant arrays.
+    (accepted, const_indexing, "1.26.0", Some(29947), None),
+    // Allows using `a..=b` and `..=b` as inclusive range syntaxes.
+    (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None),
+    // Allows `..=` in patterns (RFC 1192).
+    (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None),
+    // Allows `fn main()` with return types which implements `Termination` (RFC 1937).
+    (accepted, termination_trait, "1.26.0", Some(43301), None),
+    // Allows implementing `Clone` for closures where possible (RFC 2132).
+    (accepted, clone_closures, "1.26.0", Some(44490), None),
+    // Allows implementing `Copy` for closures where possible (RFC 2132).
+    (accepted, copy_closures, "1.26.0", Some(44490), None),
+    // Allows `impl Trait` in function arguments.
+    (accepted, universal_impl_trait, "1.26.0", Some(34511), None),
+    // Allows `impl Trait` in function return types.
+    (accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
+    // Allows using the `u128` and `i128` types.
+    (accepted, i128_type, "1.26.0", Some(35118), None),
+    // Allows default match binding modes (RFC 2005).
+    (accepted, match_default_bindings, "1.26.0", Some(42640), None),
+    // Allows `'_` placeholder lifetimes.
+    (accepted, underscore_lifetimes, "1.26.0", Some(44524), None),
+    // Allows attributes on lifetime/type formal parameters in generics (RFC 1327).
+    (accepted, generic_param_attrs, "1.27.0", Some(48848), None),
+    // Allows `cfg(target_feature = "...")`.
+    (accepted, cfg_target_feature, "1.27.0", Some(29717), None),
+    // Allows `#[target_feature(...)]`.
+    (accepted, target_feature, "1.27.0", None, None),
+    // Allows using `dyn Trait` as a syntax for trait objects.
+    (accepted, dyn_trait, "1.27.0", Some(44662), None),
+    // Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940).
+    (accepted, fn_must_use, "1.27.0", Some(43302), None),
+    // Allows use of the `:lifetime` macro fragment specifier.
+    (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None),
+    // Allows `#[test]` functions where the return type implements `Termination` (RFC 1937).
+    (accepted, termination_trait_test, "1.27.0", Some(48854), None),
+    // Allows the `#[global_allocator]` attribute.
+    (accepted, global_allocator, "1.28.0", Some(27389), None),
+    // Allows `#[repr(transparent)]` attribute on newtype structs.
+    (accepted, repr_transparent, "1.28.0", Some(43036), None),
+    // Allows procedural macros in `proc-macro` crates.
+    (accepted, proc_macro, "1.29.0", Some(38356), None),
+    // Allows `foo.rs` as an alternative to `foo/mod.rs`.
+    (accepted, non_modrs_mods, "1.30.0", Some(44660), None),
+    // Allows use of the `:vis` macro fragment specifier
+    (accepted, macro_vis_matcher, "1.30.0", Some(41022), None),
+    // Allows importing and reexporting macros with `use`,
+    // enables macro modularization in general.
+    (accepted, use_extern_macros, "1.30.0", Some(35896), None),
+    // Allows keywords to be escaped for use as identifiers.
+    (accepted, raw_identifiers, "1.30.0", Some(48589), None),
+    // Allows attributes scoped to tools.
+    (accepted, tool_attributes, "1.30.0", Some(44690), None),
+    // Allows multi-segment paths in attributes and derives.
+    (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None),
+    // Allows all literals in attribute lists and values of key-value pairs.
+    (accepted, attr_literals, "1.30.0", Some(34981), None),
+    // Allows inferring outlives requirements (RFC 2093).
+    (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None),
+    // Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`.
+    // This defines the behavior of panics.
+    (accepted, panic_handler, "1.30.0", Some(44489), None),
+    // Allows `#[used]` to preserve symbols (see llvm.used).
+    (accepted, used, "1.30.0", Some(40289), None),
+    // Allows `crate` in paths.
+    (accepted, crate_in_paths, "1.30.0", Some(45477), None),
+    // Allows resolving absolute paths as paths from other crates.
+    (accepted, extern_absolute_paths, "1.30.0", Some(44660), None),
+    // Allows access to crate names passed via `--extern` through prelude.
+    (accepted, extern_prelude, "1.30.0", Some(44660), None),
+    // Allows parentheses in patterns.
+    (accepted, pattern_parentheses, "1.31.0", Some(51087), None),
+    // Allows the definition of `const fn` functions.
+    (accepted, min_const_fn, "1.31.0", Some(53555), None),
+    // Allows scoped lints.
+    (accepted, tool_lints, "1.31.0", Some(44690), None),
+    // Allows lifetime elision in `impl` headers. For example:
+    // + `impl<I:Iterator> Iterator for &mut Iterator`
+    // + `impl Debug for Foo<'_>`
+    (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None),
+    // Allows `extern crate foo as bar;`. This puts `bar` into extern prelude.
+    (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
+    // Allows use of the `:literal` macro fragment specifier (RFC 1576).
+    (accepted, macro_literal_matcher, "1.32.0", Some(35625), None),
+    // Allows use of `?` as the Kleene "at most one" operator in macros.
+    (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
+    // Allows `Self` struct constructor (RFC 2302).
+    (accepted, self_struct_ctor, "1.32.0", Some(51994), None),
+    // Allows `Self` in type definitions (RFC 2300).
+    (accepted, self_in_typedefs, "1.32.0", Some(49303), None),
+    // Allows `use x::y;` to search `x` in the current scope.
+    (accepted, uniform_paths, "1.32.0", Some(53130), None),
+    // Allows integer match exhaustiveness checking (RFC 2591).
+    (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None),
+    // Allows `use path as _;` and `extern crate c as _;`.
+    (accepted, underscore_imports, "1.33.0", Some(48216), None),
+    // Allows `#[repr(packed(N))]` attribute on structs.
+    (accepted, repr_packed, "1.33.0", Some(33158), None),
+    // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
+    (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None),
+    // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
+    (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
+    // Allows let bindings, assignments and destructuring in `const` functions and constants.
+    // As long as control flow is not implemented in const eval, `&&` and `||` may not be used
+    // at the same time as let bindings.
+    (accepted, const_let, "1.33.0", Some(48821), None),
+    // Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
+    (accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
+    // Allows top level or-patterns (`p | q`) in `if let` and `while let`.
+    (accepted, if_while_or_patterns, "1.33.0", Some(48215), None),
+    // Allows `cfg(target_vendor = "...")`.
+    (accepted, cfg_target_vendor, "1.33.0", Some(29718), None),
+    // Allows `extern crate self as foo;`.
+    // This puts local crate root into extern prelude under name `foo`.
+    (accepted, extern_crate_self, "1.34.0", Some(56409), None),
+    // Allows arbitrary delimited token streams in non-macro attributes.
+    (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
+    // Allows paths to enum variants on type aliases including `Self`.
+    (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None),
+    // Allows using `#[repr(align(X))]` on enums with equivalent semantics
+    // to wrapping an enum in a wrapper struct with `#[repr(align(X))]`.
+    (accepted, repr_align_enum, "1.37.0", Some(57996), None),
+    // Allows `const _: TYPE = VALUE`.
+    (accepted, underscore_const_names, "1.37.0", Some(54912), None),
+    // Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
+    (accepted, async_await, "1.39.0", Some(50547), None),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: accepted features
+    // -------------------------------------------------------------------------
+);

From 975455b37dcdb6c59e47a289aa2d5f19d63a18f6 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 20 Aug 2019 18:41:18 +0200
Subject: [PATCH 147/943] syntax: extract `removed.rs` feature gates.

---
 src/libsyntax/feature_gate.rs         | 79 +-------------------------
 src/libsyntax/feature_gate/attr.rs    |  1 +
 src/libsyntax/feature_gate/removed.rs | 82 +++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 77 deletions(-)
 create mode 100644 src/libsyntax/feature_gate/attr.rs
 create mode 100644 src/libsyntax/feature_gate/removed.rs

diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 32fef2fc8ddb7..e2fa4b27f2833 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -14,6 +14,8 @@
 
 mod accepted;
 use accepted::ACCEPTED_FEATURES;
+mod removed;
+use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
 
 use AttributeType::*;
 use AttributeGate::*;
@@ -83,20 +85,6 @@ macro_rules! declare_features {
             }
         }
     };
-
-    ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => {
-        /// Represents unstable features which have since been removed (it was once Active)
-        const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, $reason)),+
-        ];
-    };
-
-    ($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
-        /// Represents stable features which have since been removed (it was once Accepted)
-        const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, None)),+
-        ];
-    };
 }
 
 // If you change this, please modify `src/doc/unstable-book` as well.
@@ -571,69 +559,6 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[
     sym::let_chains,
 ];
 
-declare_features! (
-    // -------------------------------------------------------------------------
-    // feature-group-start: removed features
-    // -------------------------------------------------------------------------
-
-    (removed, import_shadowing, "1.0.0", None, None, None),
-    (removed, managed_boxes, "1.0.0", None, None, None),
-    // Allows use of unary negate on unsigned integers, e.g., -e for e: u8
-    (removed, negate_unsigned, "1.0.0", Some(29645), None, None),
-    (removed, reflect, "1.0.0", Some(27749), None, None),
-    // A way to temporarily opt out of opt in copy. This will *never* be accepted.
-    (removed, opt_out_copy, "1.0.0", None, None, None),
-    (removed, quad_precision_float, "1.0.0", None, None, None),
-    (removed, struct_inherit, "1.0.0", None, None, None),
-    (removed, test_removed_feature, "1.0.0", None, None, None),
-    (removed, visible_private_types, "1.0.0", None, None, None),
-    (removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
-    // Allows using items which are missing stability attributes
-    (removed, unmarked_api, "1.0.0", None, None, None),
-    (removed, allocator, "1.0.0", None, None, None),
-    (removed, simd, "1.0.0", Some(27731), None,
-     Some("removed in favor of `#[repr(simd)]`")),
-    (removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
-     Some("merged into `#![feature(slice_patterns)]`")),
-    (removed, macro_reexport, "1.0.0", Some(29638), None,
-     Some("subsumed by `pub use`")),
-    (removed, pushpop_unsafe, "1.2.0", None, None, None),
-    (removed, needs_allocator, "1.4.0", Some(27389), None,
-     Some("subsumed by `#![feature(allocator_internals)]`")),
-    (removed, proc_macro_mod, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, proc_macro_expr, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, proc_macro_non_items, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, proc_macro_gen, "1.27.0", Some(54727), None,
-     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
-    (removed, panic_implementation, "1.28.0", Some(44489), None,
-     Some("subsumed by `#[panic_handler]`")),
-    // Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
-    (removed, custom_derive, "1.32.0", Some(29644), None,
-     Some("subsumed by `#[proc_macro_derive]`")),
-    // Paths of the form: `extern::foo::bar`
-    (removed, extern_in_paths, "1.33.0", Some(55600), None,
-     Some("subsumed by `::foo::bar` paths")),
-    (removed, quote, "1.33.0", Some(29601), None, None),
-    // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
-    (removed, dropck_parametricity, "1.38.0", Some(28498), None, None),
-    (removed, await_macro, "1.38.0", Some(50547), None,
-     Some("subsumed by `.await` syntax")),
-    // Allows defining `existential type`s.
-    (removed, existential_type, "1.38.0", Some(63063), None,
-     Some("removed in favor of `#![feature(type_alias_impl_trait)]`")),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: removed features
-    // -------------------------------------------------------------------------
-);
-
-declare_features! (
-    (stable_removed, no_stack_check, "1.0.0", None, None),
-);
-
 // If you change this, please modify `src/doc/unstable-book` as well. You must
 // move that documentation into the relevant place in the other docs, and
 // remove the chapter on the flag.
diff --git a/src/libsyntax/feature_gate/attr.rs b/src/libsyntax/feature_gate/attr.rs
new file mode 100644
index 0000000000000..46330df364852
--- /dev/null
+++ b/src/libsyntax/feature_gate/attr.rs
@@ -0,0 +1 @@
+//! TODO
diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs
new file mode 100644
index 0000000000000..6ebfeb29f677b
--- /dev/null
+++ b/src/libsyntax/feature_gate/removed.rs
@@ -0,0 +1,82 @@
+//! List of the removed feature gates.
+
+use crate::symbol::{Symbol, sym};
+
+macro_rules! declare_features {
+    ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => {
+        /// Represents unstable features which have since been removed (it was once Active)
+        pub const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, $reason)),+
+        ];
+    };
+
+    ($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
+        /// Represents stable features which have since been removed (it was once Accepted)
+        pub const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
+            $((sym::$feature, $ver, $issue, None)),+
+        ];
+    };
+}
+
+declare_features! (
+    // -------------------------------------------------------------------------
+    // feature-group-start: removed features
+    // -------------------------------------------------------------------------
+
+    (removed, import_shadowing, "1.0.0", None, None, None),
+    (removed, managed_boxes, "1.0.0", None, None, None),
+    // Allows use of unary negate on unsigned integers, e.g., -e for e: u8
+    (removed, negate_unsigned, "1.0.0", Some(29645), None, None),
+    (removed, reflect, "1.0.0", Some(27749), None, None),
+    // A way to temporarily opt out of opt in copy. This will *never* be accepted.
+    (removed, opt_out_copy, "1.0.0", None, None, None),
+    (removed, quad_precision_float, "1.0.0", None, None, None),
+    (removed, struct_inherit, "1.0.0", None, None, None),
+    (removed, test_removed_feature, "1.0.0", None, None, None),
+    (removed, visible_private_types, "1.0.0", None, None, None),
+    (removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
+    // Allows using items which are missing stability attributes
+    (removed, unmarked_api, "1.0.0", None, None, None),
+    (removed, allocator, "1.0.0", None, None, None),
+    (removed, simd, "1.0.0", Some(27731), None,
+     Some("removed in favor of `#[repr(simd)]`")),
+    (removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
+     Some("merged into `#![feature(slice_patterns)]`")),
+    (removed, macro_reexport, "1.0.0", Some(29638), None,
+     Some("subsumed by `pub use`")),
+    (removed, pushpop_unsafe, "1.2.0", None, None, None),
+    (removed, needs_allocator, "1.4.0", Some(27389), None,
+     Some("subsumed by `#![feature(allocator_internals)]`")),
+    (removed, proc_macro_mod, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, proc_macro_expr, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, proc_macro_non_items, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, proc_macro_gen, "1.27.0", Some(54727), None,
+     Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
+    (removed, panic_implementation, "1.28.0", Some(44489), None,
+     Some("subsumed by `#[panic_handler]`")),
+    // Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
+    (removed, custom_derive, "1.32.0", Some(29644), None,
+     Some("subsumed by `#[proc_macro_derive]`")),
+    // Paths of the form: `extern::foo::bar`
+    (removed, extern_in_paths, "1.33.0", Some(55600), None,
+     Some("subsumed by `::foo::bar` paths")),
+    (removed, quote, "1.33.0", Some(29601), None, None),
+    // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
+    (removed, dropck_parametricity, "1.38.0", Some(28498), None, None),
+    (removed, await_macro, "1.38.0", Some(50547), None,
+     Some("subsumed by `.await` syntax")),
+    // Allows defining `existential type`s.
+    (removed, existential_type, "1.38.0", Some(63063), None,
+     Some("removed in favor of `#![feature(type_alias_impl_trait)]`")),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: removed features
+    // -------------------------------------------------------------------------
+);
+
+declare_features! (
+    (stable_removed, no_stack_check, "1.0.0", None, None),
+);

From 7afb2a82ecf74e69e4b581558990464301790b90 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 20 Aug 2019 18:50:33 +0200
Subject: [PATCH 148/943] syntax: extract `active.rs` feature gates.

---
 src/libsyntax/feature_gate.rs        | 520 +-------------------------
 src/libsyntax/feature_gate/active.rs | 522 +++++++++++++++++++++++++++
 2 files changed, 525 insertions(+), 517 deletions(-)
 create mode 100644 src/libsyntax/feature_gate/active.rs

diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index e2fa4b27f2833..f01b3af7af40b 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -16,6 +16,9 @@ mod accepted;
 use accepted::ACCEPTED_FEATURES;
 mod removed;
 use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
+mod active;
+use active::{ACTIVE_FEATURES};
+pub use active::{Features, INCOMPLETE_FEATURES};
 
 use AttributeType::*;
 use AttributeGate::*;
@@ -42,523 +45,6 @@ use lazy_static::lazy_static;
 
 use std::env;
 
-macro_rules! set {
-    ($field: ident) => {{
-        fn f(features: &mut Features, _: Span) {
-            features.$field = true;
-        }
-        f as fn(&mut Features, Span)
-    }}
-}
-
-macro_rules! declare_features {
-    ($((active, $feature: ident, $ver: expr, $issue: expr, $edition: expr),)+) => {
-        /// Represents active features that are currently being implemented or
-        /// currently being considered for addition/removal.
-        const ACTIVE_FEATURES:
-            &[(Symbol, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
-            &[$((sym::$feature, $ver, $issue, $edition, set!($feature))),+];
-
-        /// A set of features to be used by later passes.
-        #[derive(Clone)]
-        pub struct Features {
-            /// `#![feature]` attrs for language features, for error reporting
-            pub declared_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
-            /// `#![feature]` attrs for non-language (library) features
-            pub declared_lib_features: Vec<(Symbol, Span)>,
-            $(pub $feature: bool),+
-        }
-
-        impl Features {
-            pub fn new() -> Features {
-                Features {
-                    declared_lang_features: Vec::new(),
-                    declared_lib_features: Vec::new(),
-                    $($feature: false),+
-                }
-            }
-
-            pub fn walk_feature_fields<F>(&self, mut f: F)
-                where F: FnMut(&str, bool)
-            {
-                $(f(stringify!($feature), self.$feature);)+
-            }
-        }
-    };
-}
-
-// If you change this, please modify `src/doc/unstable-book` as well.
-//
-// Don't ever remove anything from this list; set them to 'Removed'.
-//
-// The version numbers here correspond to the version in which the current status
-// was set. This is most important for knowing when a particular feature became
-// stable (active).
-//
-// Note that the features are grouped into internal/user-facing and then
-// sorted by version inside those groups. This is inforced with tidy.
-//
-// N.B., `tools/tidy/src/features.rs` parses this information directly out of the
-// source, so take care when modifying it.
-
-declare_features! (
-    // -------------------------------------------------------------------------
-    // feature-group-start: internal feature gates
-    // -------------------------------------------------------------------------
-
-    // no-tracking-issue-start
-
-    // Allows using compiler's own crates.
-    (active, rustc_private, "1.0.0", Some(27812), None),
-
-    // Allows using the `rust-intrinsic`'s "ABI".
-    (active, intrinsics, "1.0.0", None, None),
-
-    // Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
-    (active, lang_items, "1.0.0", None, None),
-
-    // Allows using the `#[stable]` and `#[unstable]` attributes.
-    (active, staged_api, "1.0.0", None, None),
-
-    // Allows using `#[allow_internal_unstable]`. This is an
-    // attribute on `macro_rules!` and can't use the attribute handling
-    // below (it has to be checked before expansion possibly makes
-    // macros disappear).
-    (active, allow_internal_unstable, "1.0.0", None, None),
-
-    // Allows using `#[allow_internal_unsafe]`. This is an
-    // attribute on `macro_rules!` and can't use the attribute handling
-    // below (it has to be checked before expansion possibly makes
-    // macros disappear).
-    (active, allow_internal_unsafe, "1.0.0", None, None),
-
-    // Allows using the macros:
-    // + `__diagnostic_used`
-    // + `__register_diagnostic`
-    // +`__build_diagnostic_array`
-    (active, rustc_diagnostic_macros, "1.0.0", None, None),
-
-    // Allows using `#[rustc_const_unstable(feature = "foo", ..)]` which
-    // lets a function to be `const` when opted into with `#![feature(foo)]`.
-    (active, rustc_const_unstable, "1.0.0", None, None),
-
-    // no-tracking-issue-end
-
-    // Allows using `#[link_name="llvm.*"]`.
-    (active, link_llvm_intrinsics, "1.0.0", Some(29602), None),
-
-    // Allows using `rustc_*` attributes (RFC 572).
-    (active, rustc_attrs, "1.0.0", Some(29642), None),
-
-    // Allows using `#[on_unimplemented(..)]` on traits.
-    (active, on_unimplemented, "1.0.0", Some(29628), None),
-
-    // Allows using the `box $expr` syntax.
-    (active, box_syntax, "1.0.0", Some(49733), None),
-
-    // Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls.
-    (active, main, "1.0.0", Some(29634), None),
-
-    // Allows using `#[start]` on a function indicating that it is the program entrypoint.
-    (active, start, "1.0.0", Some(29633), None),
-
-    // Allows using the `#[fundamental]` attribute.
-    (active, fundamental, "1.0.0", Some(29635), None),
-
-    // Allows using the `rust-call` ABI.
-    (active, unboxed_closures, "1.0.0", Some(29625), None),
-
-    // Allows using the `#[linkage = ".."]` attribute.
-    (active, linkage, "1.0.0", Some(29603), None),
-
-    // Allows features specific to OIBIT (auto traits).
-    (active, optin_builtin_traits, "1.0.0", Some(13231), None),
-
-    // Allows using `box` in patterns (RFC 469).
-    (active, box_patterns, "1.0.0", Some(29641), None),
-
-    // no-tracking-issue-start
-
-    // Allows using `#[prelude_import]` on glob `use` items.
-    (active, prelude_import, "1.2.0", None, None),
-
-    // no-tracking-issue-end
-
-    // no-tracking-issue-start
-
-    // Allows using `#[omit_gdb_pretty_printer_section]`.
-    (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
-
-    // Allows using the `vectorcall` ABI.
-    (active, abi_vectorcall, "1.7.0", None, None),
-
-    // no-tracking-issue-end
-
-    // Allows using `#[structural_match]` which indicates that a type is structurally matchable.
-    (active, structural_match, "1.8.0", Some(31434), None),
-
-    // Allows using the `may_dangle` attribute (RFC 1327).
-    (active, dropck_eyepatch, "1.10.0", Some(34761), None),
-
-    // Allows using the `#![panic_runtime]` attribute.
-    (active, panic_runtime, "1.10.0", Some(32837), None),
-
-    // Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
-    (active, needs_panic_runtime, "1.10.0", Some(32837), None),
-
-    // no-tracking-issue-start
-
-    // Allows identifying the `compiler_builtins` crate.
-    (active, compiler_builtins, "1.13.0", None, None),
-
-    // Allows using the `unadjusted` ABI; perma-unstable.
-    (active, abi_unadjusted, "1.16.0", None, None),
-
-    // Allows identifying crates that contain sanitizer runtimes.
-    (active, sanitizer_runtime, "1.17.0", None, None),
-
-    // Used to identify crates that contain the profiler runtime.
-    (active, profiler_runtime, "1.18.0", None, None),
-
-    // Allows using the `thiscall` ABI.
-    (active, abi_thiscall, "1.19.0", None, None),
-
-    // Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`.
-    (active, allocator_internals, "1.20.0", None, None),
-
-    // no-tracking-issue-end
-
-    // Added for testing E0705; perma-unstable.
-    (active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: internal feature gates
-    // -------------------------------------------------------------------------
-
-    // -------------------------------------------------------------------------
-    // feature-group-start: actual feature gates (target features)
-    // -------------------------------------------------------------------------
-
-    // FIXME: Document these and merge with the list below.
-
-    // Unstable `#[target_feature]` directives.
-    (active, arm_target_feature, "1.27.0", Some(44839), None),
-    (active, aarch64_target_feature, "1.27.0", Some(44839), None),
-    (active, hexagon_target_feature, "1.27.0", Some(44839), None),
-    (active, powerpc_target_feature, "1.27.0", Some(44839), None),
-    (active, mips_target_feature, "1.27.0", Some(44839), None),
-    (active, avx512_target_feature, "1.27.0", Some(44839), None),
-    (active, mmx_target_feature, "1.27.0", Some(44839), None),
-    (active, sse4a_target_feature, "1.27.0", Some(44839), None),
-    (active, tbm_target_feature, "1.27.0", Some(44839), None),
-    (active, wasm_target_feature, "1.30.0", Some(44839), None),
-    (active, adx_target_feature, "1.32.0", Some(44839), None),
-    (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None),
-    (active, movbe_target_feature, "1.34.0", Some(44839), None),
-    (active, rtm_target_feature, "1.35.0", Some(44839), None),
-    (active, f16c_target_feature, "1.36.0", Some(44839), None),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: actual feature gates (target features)
-    // -------------------------------------------------------------------------
-
-    // -------------------------------------------------------------------------
-    // feature-group-start: actual feature gates
-    // -------------------------------------------------------------------------
-
-    // Allows using the `#[link_args]` attribute.
-    (active, link_args, "1.0.0", Some(29596), None),
-
-    // Allows defining identifiers beyond ASCII.
-    (active, non_ascii_idents, "1.0.0", Some(55467), None),
-
-    // Allows using `#[plugin_registrar]` on functions.
-    (active, plugin_registrar, "1.0.0", Some(29597), None),
-
-    // Allows using `#![plugin(myplugin)]`.
-    (active, plugin, "1.0.0", Some(29597), None),
-
-    // Allows using `#[thread_local]` on `static` items.
-    (active, thread_local, "1.0.0", Some(29594), None),
-
-    // Allows the use of SIMD types in functions declared in `extern` blocks.
-    (active, simd_ffi, "1.0.0", Some(27731), None),
-
-    // Allows using custom attributes (RFC 572).
-    (active, custom_attribute, "1.0.0", Some(29642), None),
-
-    // Allows using non lexical lifetimes (RFC 2094).
-    (active, nll, "1.0.0", Some(43234), None),
-
-    // Allows using slice patterns.
-    (active, slice_patterns, "1.0.0", Some(62254), None),
-
-    // Allows the definition of `const` functions with some advanced features.
-    (active, const_fn, "1.2.0", Some(57563), None),
-
-    // Allows associated type defaults.
-    (active, associated_type_defaults, "1.2.0", Some(29661), None),
-
-    // Allows `#![no_core]`.
-    (active, no_core, "1.3.0", Some(29639), None),
-
-    // Allows default type parameters to influence type inference.
-    (active, default_type_parameter_fallback, "1.3.0", Some(27336), None),
-
-    // Allows `repr(simd)` and importing the various simd intrinsics.
-    (active, repr_simd, "1.4.0", Some(27731), None),
-
-    // Allows `extern "platform-intrinsic" { ... }`.
-    (active, platform_intrinsics, "1.4.0", Some(27731), None),
-
-    // Allows `#[unwind(..)]`.
-    //
-    // Permits specifying whether a function should permit unwinding or abort on unwind.
-    (active, unwind_attributes, "1.4.0", Some(58760), None),
-
-    // Allows `#[no_debug]`.
-    (active, no_debug, "1.5.0", Some(29721), None),
-
-    // Allows attributes on expressions and non-item statements.
-    (active, stmt_expr_attributes, "1.6.0", Some(15701), None),
-
-    // Allows the use of type ascription in expressions.
-    (active, type_ascription, "1.6.0", Some(23416), None),
-
-    // Allows `cfg(target_thread_local)`.
-    (active, cfg_target_thread_local, "1.7.0", Some(29594), None),
-
-    // Allows specialization of implementations (RFC 1210).
-    (active, specialization, "1.7.0", Some(31844), None),
-
-    // Allows using `#[naked]` on functions.
-    (active, naked_functions, "1.9.0", Some(32408), None),
-
-    // Allows `cfg(target_has_atomic = "...")`.
-    (active, cfg_target_has_atomic, "1.9.0", Some(32976), None),
-
-    // Allows `X..Y` patterns.
-    (active, exclusive_range_pattern, "1.11.0", Some(37854), None),
-
-    // Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
-    (active, never_type, "1.13.0", Some(35121), None),
-
-    // Allows exhaustive pattern matching on types that contain uninhabited types.
-    (active, exhaustive_patterns, "1.13.0", Some(51085), None),
-
-    // Allows untagged unions `union U { ... }`.
-    (active, untagged_unions, "1.13.0", Some(32836), None),
-
-    // Allows `#[link(..., cfg(..))]`.
-    (active, link_cfg, "1.14.0", Some(37406), None),
-
-    // Allows `extern "ptx-*" fn()`.
-    (active, abi_ptx, "1.15.0", Some(38788), None),
-
-    // Allows the `#[repr(i128)]` attribute for enums.
-    (active, repr128, "1.16.0", Some(35118), None),
-
-    // Allows `#[link(kind="static-nobundle"...)]`.
-    (active, static_nobundle, "1.16.0", Some(37403), None),
-
-    // Allows `extern "msp430-interrupt" fn()`.
-    (active, abi_msp430_interrupt, "1.16.0", Some(38487), None),
-
-    // Allows declarative macros 2.0 (`macro`).
-    (active, decl_macro, "1.17.0", Some(39412), None),
-
-    // Allows `extern "x86-interrupt" fn()`.
-    (active, abi_x86_interrupt, "1.17.0", Some(40180), None),
-
-    // Allows overlapping impls of marker traits.
-    (active, overlapping_marker_traits, "1.18.0", Some(29864), None),
-
-    // Allows a test to fail without failing the whole suite.
-    (active, allow_fail, "1.19.0", Some(46488), None),
-
-    // Allows unsized tuple coercion.
-    (active, unsized_tuple_coercion, "1.20.0", Some(42877), None),
-
-    // Allows defining generators.
-    (active, generators, "1.21.0", Some(43122), None),
-
-    // Allows `#[doc(cfg(...))]`.
-    (active, doc_cfg, "1.21.0", Some(43781), None),
-
-    // Allows `#[doc(masked)]`.
-    (active, doc_masked, "1.21.0", Some(44027), None),
-
-    // Allows `#[doc(spotlight)]`.
-    (active, doc_spotlight, "1.22.0", Some(45040), None),
-
-    // Allows `#[doc(include = "some-file")]`.
-    (active, external_doc, "1.22.0", Some(44732), None),
-
-    // Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008).
-    (active, non_exhaustive, "1.22.0", Some(44109), None),
-
-    // Allows using `crate` as visibility modifier, synonymous with `pub(crate)`.
-    (active, crate_visibility_modifier, "1.23.0", Some(53120), None),
-
-    // Allows defining `extern type`s.
-    (active, extern_types, "1.23.0", Some(43467), None),
-
-    // Allows trait methods with arbitrary self types.
-    (active, arbitrary_self_types, "1.23.0", Some(44874), None),
-
-    // Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
-    (active, in_band_lifetimes, "1.23.0", Some(44524), None),
-
-    // Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
-    (active, generic_associated_types, "1.23.0", Some(44265), None),
-
-    // Allows defining `trait X = A + B;` alias items.
-    (active, trait_alias, "1.24.0", Some(41517), None),
-
-    // Allows infering `'static` outlives requirements (RFC 2093).
-    (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
-
-    // Allows macro invocations in `extern {}` blocks.
-    (active, macros_in_extern, "1.27.0", Some(49476), None),
-
-    // Allows accessing fields of unions inside `const` functions.
-    (active, const_fn_union, "1.27.0", Some(51909), None),
-
-    // Allows casting raw pointers to `usize` during const eval.
-    (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None),
-
-    // Allows dereferencing raw pointers during const eval.
-    (active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
-
-    // Allows comparing raw pointers during const eval.
-    (active, const_compare_raw_pointers, "1.27.0", Some(53020), None),
-
-    // Allows `#[doc(alias = "...")]`.
-    (active, doc_alias, "1.27.0", Some(50146), None),
-
-    // Allows inconsistent bounds in where clauses.
-    (active, trivial_bounds, "1.28.0", Some(48214), None),
-
-    // Allows `'a: { break 'a; }`.
-    (active, label_break_value, "1.28.0", Some(48594), None),
-
-    // Allows using `#[doc(keyword = "...")]`.
-    (active, doc_keyword, "1.28.0", Some(51315), None),
-
-    // Allows reinterpretation of the bits of a value of one type as another type during const eval.
-    (active, const_transmute, "1.29.0", Some(53605), None),
-
-    // Allows using `try {...}` expressions.
-    (active, try_blocks, "1.29.0", Some(31436), None),
-
-    // Allows defining an `#[alloc_error_handler]`.
-    (active, alloc_error_handler, "1.29.0", Some(51540), None),
-
-    // Allows using the `amdgpu-kernel` ABI.
-    (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None),
-
-    // Allows panicking during const eval (producing compile-time errors).
-    (active, const_panic, "1.30.0", Some(51999), None),
-
-    // Allows `#[marker]` on certain traits allowing overlapping implementations.
-    (active, marker_trait_attr, "1.30.0", Some(29864), None),
-
-    // Allows macro invocations on modules expressions and statements and
-    // procedural macros to expand to non-items.
-    (active, proc_macro_hygiene, "1.30.0", Some(54727), None),
-
-    // Allows unsized rvalues at arguments and parameters.
-    (active, unsized_locals, "1.30.0", Some(48055), None),
-
-    // Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.
-    (active, custom_test_frameworks, "1.30.0", Some(50297), None),
-
-    // Allows non-builtin attributes in inner attribute position.
-    (active, custom_inner_attributes, "1.30.0", Some(54726), None),
-
-    // Allows mixing bind-by-move in patterns and references to those identifiers in guards.
-    (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None),
-
-    // Allows `impl Trait` in bindings (`let`, `const`, `static`).
-    (active, impl_trait_in_bindings, "1.30.0", Some(63065), None),
-
-    // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
-    (active, lint_reasons, "1.31.0", Some(54503), None),
-
-    // Allows exhaustive integer pattern matching on `usize` and `isize`.
-    (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
-
-    // Allows relaxing the coherence rules such that
-    // `impl<T> ForeignTrait<LocalType> for ForeignType<T> is permitted.
-    (active, re_rebalance_coherence, "1.32.0", Some(55437), None),
-
-    // Allows using `#[ffi_returns_twice]` on foreign functions.
-    (active, ffi_returns_twice, "1.34.0", Some(58314), None),
-
-    // Allows const generic types (e.g. `struct Foo<const N: usize>(...);`).
-    (active, const_generics, "1.34.0", Some(44580), None),
-
-    // Allows using `#[optimize(X)]`.
-    (active, optimize_attribute, "1.34.0", Some(54882), None),
-
-    // Allows using C-variadics.
-    (active, c_variadic, "1.34.0", Some(44930), None),
-
-    // Allows the user of associated type bounds.
-    (active, associated_type_bounds, "1.34.0", Some(52662), None),
-
-    // Attributes on formal function params.
-    (active, param_attrs, "1.36.0", Some(60406), None),
-
-    // Allows calling constructor functions in `const fn`.
-    (active, const_constructor, "1.37.0", Some(61456), None),
-
-    // Allows `if/while p && let q = r && ...` chains.
-    (active, let_chains, "1.37.0", Some(53667), None),
-
-    // Allows #[repr(transparent)] on enums (RFC 2645).
-    (active, transparent_enums, "1.37.0", Some(60405), None),
-
-    // Allows #[repr(transparent)] on unions (RFC 2645).
-    (active, transparent_unions, "1.37.0", Some(60405), None),
-
-    // Allows explicit discriminants on non-unit enum variants.
-    (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
-
-    // Allows `impl Trait` with multiple unrelated lifetimes.
-    (active, member_constraints, "1.37.0", Some(61977), None),
-
-    // Allows `async || body` closures.
-    (active, async_closure, "1.37.0", Some(62290), None),
-
-    // Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests
-    (active, cfg_doctest, "1.37.0", Some(62210), None),
-
-    // Allows `[x; N]` where `x` is a constant (RFC 2203).
-    (active, const_in_array_repeat_expressions, "1.37.0", Some(49147), None),
-
-    // Allows `impl Trait` to be used inside type aliases (RFC 2515).
-    (active, type_alias_impl_trait, "1.38.0", Some(63063), None),
-
-    // Allows the use of or-patterns, e.g. `0 | 1`.
-    (active, or_patterns, "1.38.0", Some(54883), None),
-
-    // -------------------------------------------------------------------------
-    // feature-group-end: actual feature gates
-    // -------------------------------------------------------------------------
-);
-
-/// Some features are known to be incomplete and using them is likely to have
-/// unanticipated results, such as compiler crashes. We warn the user about these
-/// to alert them.
-pub const INCOMPLETE_FEATURES: &[Symbol] = &[
-    sym::impl_trait_in_bindings,
-    sym::generic_associated_types,
-    sym::const_generics,
-    sym::or_patterns,
-    sym::let_chains,
-];
-
 // If you change this, please modify `src/doc/unstable-book` as well. You must
 // move that documentation into the relevant place in the other docs, and
 // remove the chapter on the flag.
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
new file mode 100644
index 0000000000000..0bff4ed24a4ce
--- /dev/null
+++ b/src/libsyntax/feature_gate/active.rs
@@ -0,0 +1,522 @@
+//! List of the active feature gates.
+
+use crate::edition::Edition;
+use crate::symbol::{Symbol, sym};
+use syntax_pos::Span;
+
+macro_rules! set {
+    ($field: ident) => {{
+        fn f(features: &mut Features, _: Span) {
+            features.$field = true;
+        }
+        f as fn(&mut Features, Span)
+    }}
+}
+
+macro_rules! declare_features {
+    ($((active, $feature: ident, $ver: expr, $issue: expr, $edition: expr),)+) => {
+        /// Represents active features that are currently being implemented or
+        /// currently being considered for addition/removal.
+        pub const ACTIVE_FEATURES:
+            &[(Symbol, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
+            &[$((sym::$feature, $ver, $issue, $edition, set!($feature))),+];
+
+        /// A set of features to be used by later passes.
+        #[derive(Clone)]
+        pub struct Features {
+            /// `#![feature]` attrs for language features, for error reporting
+            pub declared_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
+            /// `#![feature]` attrs for non-language (library) features
+            pub declared_lib_features: Vec<(Symbol, Span)>,
+            $(pub $feature: bool),+
+        }
+
+        impl Features {
+            pub fn new() -> Features {
+                Features {
+                    declared_lang_features: Vec::new(),
+                    declared_lib_features: Vec::new(),
+                    $($feature: false),+
+                }
+            }
+
+            pub fn walk_feature_fields<F>(&self, mut f: F)
+                where F: FnMut(&str, bool)
+            {
+                $(f(stringify!($feature), self.$feature);)+
+            }
+        }
+    };
+}
+
+// If you change this, please modify `src/doc/unstable-book` as well.
+//
+// Don't ever remove anything from this list; move them to `removed.rs`.
+//
+// The version numbers here correspond to the version in which the current status
+// was set. This is most important for knowing when a particular feature became
+// stable (active).
+//
+// Note that the features are grouped into internal/user-facing and then
+// sorted by version inside those groups. This is inforced with tidy.
+//
+// N.B., `tools/tidy/src/features.rs` parses this information directly out of the
+// source, so take care when modifying it.
+
+declare_features! (
+    // -------------------------------------------------------------------------
+    // feature-group-start: internal feature gates
+    // -------------------------------------------------------------------------
+
+    // no-tracking-issue-start
+
+    // Allows using compiler's own crates.
+    (active, rustc_private, "1.0.0", Some(27812), None),
+
+    // Allows using the `rust-intrinsic`'s "ABI".
+    (active, intrinsics, "1.0.0", None, None),
+
+    // Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
+    (active, lang_items, "1.0.0", None, None),
+
+    // Allows using the `#[stable]` and `#[unstable]` attributes.
+    (active, staged_api, "1.0.0", None, None),
+
+    // Allows using `#[allow_internal_unstable]`. This is an
+    // attribute on `macro_rules!` and can't use the attribute handling
+    // below (it has to be checked before expansion possibly makes
+    // macros disappear).
+    (active, allow_internal_unstable, "1.0.0", None, None),
+
+    // Allows using `#[allow_internal_unsafe]`. This is an
+    // attribute on `macro_rules!` and can't use the attribute handling
+    // below (it has to be checked before expansion possibly makes
+    // macros disappear).
+    (active, allow_internal_unsafe, "1.0.0", None, None),
+
+    // Allows using the macros:
+    // + `__diagnostic_used`
+    // + `__register_diagnostic`
+    // +`__build_diagnostic_array`
+    (active, rustc_diagnostic_macros, "1.0.0", None, None),
+
+    // Allows using `#[rustc_const_unstable(feature = "foo", ..)]` which
+    // lets a function to be `const` when opted into with `#![feature(foo)]`.
+    (active, rustc_const_unstable, "1.0.0", None, None),
+
+    // no-tracking-issue-end
+
+    // Allows using `#[link_name="llvm.*"]`.
+    (active, link_llvm_intrinsics, "1.0.0", Some(29602), None),
+
+    // Allows using `rustc_*` attributes (RFC 572).
+    (active, rustc_attrs, "1.0.0", Some(29642), None),
+
+    // Allows using `#[on_unimplemented(..)]` on traits.
+    (active, on_unimplemented, "1.0.0", Some(29628), None),
+
+    // Allows using the `box $expr` syntax.
+    (active, box_syntax, "1.0.0", Some(49733), None),
+
+    // Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls.
+    (active, main, "1.0.0", Some(29634), None),
+
+    // Allows using `#[start]` on a function indicating that it is the program entrypoint.
+    (active, start, "1.0.0", Some(29633), None),
+
+    // Allows using the `#[fundamental]` attribute.
+    (active, fundamental, "1.0.0", Some(29635), None),
+
+    // Allows using the `rust-call` ABI.
+    (active, unboxed_closures, "1.0.0", Some(29625), None),
+
+    // Allows using the `#[linkage = ".."]` attribute.
+    (active, linkage, "1.0.0", Some(29603), None),
+
+    // Allows features specific to OIBIT (auto traits).
+    (active, optin_builtin_traits, "1.0.0", Some(13231), None),
+
+    // Allows using `box` in patterns (RFC 469).
+    (active, box_patterns, "1.0.0", Some(29641), None),
+
+    // no-tracking-issue-start
+
+    // Allows using `#[prelude_import]` on glob `use` items.
+    (active, prelude_import, "1.2.0", None, None),
+
+    // no-tracking-issue-end
+
+    // no-tracking-issue-start
+
+    // Allows using `#[omit_gdb_pretty_printer_section]`.
+    (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
+
+    // Allows using the `vectorcall` ABI.
+    (active, abi_vectorcall, "1.7.0", None, None),
+
+    // no-tracking-issue-end
+
+    // Allows using `#[structural_match]` which indicates that a type is structurally matchable.
+    (active, structural_match, "1.8.0", Some(31434), None),
+
+    // Allows using the `may_dangle` attribute (RFC 1327).
+    (active, dropck_eyepatch, "1.10.0", Some(34761), None),
+
+    // Allows using the `#![panic_runtime]` attribute.
+    (active, panic_runtime, "1.10.0", Some(32837), None),
+
+    // Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
+    (active, needs_panic_runtime, "1.10.0", Some(32837), None),
+
+    // no-tracking-issue-start
+
+    // Allows identifying the `compiler_builtins` crate.
+    (active, compiler_builtins, "1.13.0", None, None),
+
+    // Allows using the `unadjusted` ABI; perma-unstable.
+    (active, abi_unadjusted, "1.16.0", None, None),
+
+    // Allows identifying crates that contain sanitizer runtimes.
+    (active, sanitizer_runtime, "1.17.0", None, None),
+
+    // Used to identify crates that contain the profiler runtime.
+    (active, profiler_runtime, "1.18.0", None, None),
+
+    // Allows using the `thiscall` ABI.
+    (active, abi_thiscall, "1.19.0", None, None),
+
+    // Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`.
+    (active, allocator_internals, "1.20.0", None, None),
+
+    // no-tracking-issue-end
+
+    // Added for testing E0705; perma-unstable.
+    (active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: internal feature gates
+    // -------------------------------------------------------------------------
+
+    // -------------------------------------------------------------------------
+    // feature-group-start: actual feature gates (target features)
+    // -------------------------------------------------------------------------
+
+    // FIXME: Document these and merge with the list below.
+
+    // Unstable `#[target_feature]` directives.
+    (active, arm_target_feature, "1.27.0", Some(44839), None),
+    (active, aarch64_target_feature, "1.27.0", Some(44839), None),
+    (active, hexagon_target_feature, "1.27.0", Some(44839), None),
+    (active, powerpc_target_feature, "1.27.0", Some(44839), None),
+    (active, mips_target_feature, "1.27.0", Some(44839), None),
+    (active, avx512_target_feature, "1.27.0", Some(44839), None),
+    (active, mmx_target_feature, "1.27.0", Some(44839), None),
+    (active, sse4a_target_feature, "1.27.0", Some(44839), None),
+    (active, tbm_target_feature, "1.27.0", Some(44839), None),
+    (active, wasm_target_feature, "1.30.0", Some(44839), None),
+    (active, adx_target_feature, "1.32.0", Some(44839), None),
+    (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None),
+    (active, movbe_target_feature, "1.34.0", Some(44839), None),
+    (active, rtm_target_feature, "1.35.0", Some(44839), None),
+    (active, f16c_target_feature, "1.36.0", Some(44839), None),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: actual feature gates (target features)
+    // -------------------------------------------------------------------------
+
+    // -------------------------------------------------------------------------
+    // feature-group-start: actual feature gates
+    // -------------------------------------------------------------------------
+
+    // Allows using the `#[link_args]` attribute.
+    (active, link_args, "1.0.0", Some(29596), None),
+
+    // Allows defining identifiers beyond ASCII.
+    (active, non_ascii_idents, "1.0.0", Some(55467), None),
+
+    // Allows using `#[plugin_registrar]` on functions.
+    (active, plugin_registrar, "1.0.0", Some(29597), None),
+
+    // Allows using `#![plugin(myplugin)]`.
+    (active, plugin, "1.0.0", Some(29597), None),
+
+    // Allows using `#[thread_local]` on `static` items.
+    (active, thread_local, "1.0.0", Some(29594), None),
+
+    // Allows the use of SIMD types in functions declared in `extern` blocks.
+    (active, simd_ffi, "1.0.0", Some(27731), None),
+
+    // Allows using custom attributes (RFC 572).
+    (active, custom_attribute, "1.0.0", Some(29642), None),
+
+    // Allows using non lexical lifetimes (RFC 2094).
+    (active, nll, "1.0.0", Some(43234), None),
+
+    // Allows using slice patterns.
+    (active, slice_patterns, "1.0.0", Some(62254), None),
+
+    // Allows the definition of `const` functions with some advanced features.
+    (active, const_fn, "1.2.0", Some(57563), None),
+
+    // Allows associated type defaults.
+    (active, associated_type_defaults, "1.2.0", Some(29661), None),
+
+    // Allows `#![no_core]`.
+    (active, no_core, "1.3.0", Some(29639), None),
+
+    // Allows default type parameters to influence type inference.
+    (active, default_type_parameter_fallback, "1.3.0", Some(27336), None),
+
+    // Allows `repr(simd)` and importing the various simd intrinsics.
+    (active, repr_simd, "1.4.0", Some(27731), None),
+
+    // Allows `extern "platform-intrinsic" { ... }`.
+    (active, platform_intrinsics, "1.4.0", Some(27731), None),
+
+    // Allows `#[unwind(..)]`.
+    //
+    // Permits specifying whether a function should permit unwinding or abort on unwind.
+    (active, unwind_attributes, "1.4.0", Some(58760), None),
+
+    // Allows `#[no_debug]`.
+    (active, no_debug, "1.5.0", Some(29721), None),
+
+    // Allows attributes on expressions and non-item statements.
+    (active, stmt_expr_attributes, "1.6.0", Some(15701), None),
+
+    // Allows the use of type ascription in expressions.
+    (active, type_ascription, "1.6.0", Some(23416), None),
+
+    // Allows `cfg(target_thread_local)`.
+    (active, cfg_target_thread_local, "1.7.0", Some(29594), None),
+
+    // Allows specialization of implementations (RFC 1210).
+    (active, specialization, "1.7.0", Some(31844), None),
+
+    // Allows using `#[naked]` on functions.
+    (active, naked_functions, "1.9.0", Some(32408), None),
+
+    // Allows `cfg(target_has_atomic = "...")`.
+    (active, cfg_target_has_atomic, "1.9.0", Some(32976), None),
+
+    // Allows `X..Y` patterns.
+    (active, exclusive_range_pattern, "1.11.0", Some(37854), None),
+
+    // Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
+    (active, never_type, "1.13.0", Some(35121), None),
+
+    // Allows exhaustive pattern matching on types that contain uninhabited types.
+    (active, exhaustive_patterns, "1.13.0", Some(51085), None),
+
+    // Allows untagged unions `union U { ... }`.
+    (active, untagged_unions, "1.13.0", Some(32836), None),
+
+    // Allows `#[link(..., cfg(..))]`.
+    (active, link_cfg, "1.14.0", Some(37406), None),
+
+    // Allows `extern "ptx-*" fn()`.
+    (active, abi_ptx, "1.15.0", Some(38788), None),
+
+    // Allows the `#[repr(i128)]` attribute for enums.
+    (active, repr128, "1.16.0", Some(35118), None),
+
+    // Allows `#[link(kind="static-nobundle"...)]`.
+    (active, static_nobundle, "1.16.0", Some(37403), None),
+
+    // Allows `extern "msp430-interrupt" fn()`.
+    (active, abi_msp430_interrupt, "1.16.0", Some(38487), None),
+
+    // Allows declarative macros 2.0 (`macro`).
+    (active, decl_macro, "1.17.0", Some(39412), None),
+
+    // Allows `extern "x86-interrupt" fn()`.
+    (active, abi_x86_interrupt, "1.17.0", Some(40180), None),
+
+    // Allows overlapping impls of marker traits.
+    (active, overlapping_marker_traits, "1.18.0", Some(29864), None),
+
+    // Allows a test to fail without failing the whole suite.
+    (active, allow_fail, "1.19.0", Some(46488), None),
+
+    // Allows unsized tuple coercion.
+    (active, unsized_tuple_coercion, "1.20.0", Some(42877), None),
+
+    // Allows defining generators.
+    (active, generators, "1.21.0", Some(43122), None),
+
+    // Allows `#[doc(cfg(...))]`.
+    (active, doc_cfg, "1.21.0", Some(43781), None),
+
+    // Allows `#[doc(masked)]`.
+    (active, doc_masked, "1.21.0", Some(44027), None),
+
+    // Allows `#[doc(spotlight)]`.
+    (active, doc_spotlight, "1.22.0", Some(45040), None),
+
+    // Allows `#[doc(include = "some-file")]`.
+    (active, external_doc, "1.22.0", Some(44732), None),
+
+    // Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008).
+    (active, non_exhaustive, "1.22.0", Some(44109), None),
+
+    // Allows using `crate` as visibility modifier, synonymous with `pub(crate)`.
+    (active, crate_visibility_modifier, "1.23.0", Some(53120), None),
+
+    // Allows defining `extern type`s.
+    (active, extern_types, "1.23.0", Some(43467), None),
+
+    // Allows trait methods with arbitrary self types.
+    (active, arbitrary_self_types, "1.23.0", Some(44874), None),
+
+    // Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
+    (active, in_band_lifetimes, "1.23.0", Some(44524), None),
+
+    // Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
+    (active, generic_associated_types, "1.23.0", Some(44265), None),
+
+    // Allows defining `trait X = A + B;` alias items.
+    (active, trait_alias, "1.24.0", Some(41517), None),
+
+    // Allows infering `'static` outlives requirements (RFC 2093).
+    (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
+
+    // Allows macro invocations in `extern {}` blocks.
+    (active, macros_in_extern, "1.27.0", Some(49476), None),
+
+    // Allows accessing fields of unions inside `const` functions.
+    (active, const_fn_union, "1.27.0", Some(51909), None),
+
+    // Allows casting raw pointers to `usize` during const eval.
+    (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None),
+
+    // Allows dereferencing raw pointers during const eval.
+    (active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
+
+    // Allows comparing raw pointers during const eval.
+    (active, const_compare_raw_pointers, "1.27.0", Some(53020), None),
+
+    // Allows `#[doc(alias = "...")]`.
+    (active, doc_alias, "1.27.0", Some(50146), None),
+
+    // Allows inconsistent bounds in where clauses.
+    (active, trivial_bounds, "1.28.0", Some(48214), None),
+
+    // Allows `'a: { break 'a; }`.
+    (active, label_break_value, "1.28.0", Some(48594), None),
+
+    // Allows using `#[doc(keyword = "...")]`.
+    (active, doc_keyword, "1.28.0", Some(51315), None),
+
+    // Allows reinterpretation of the bits of a value of one type as another type during const eval.
+    (active, const_transmute, "1.29.0", Some(53605), None),
+
+    // Allows using `try {...}` expressions.
+    (active, try_blocks, "1.29.0", Some(31436), None),
+
+    // Allows defining an `#[alloc_error_handler]`.
+    (active, alloc_error_handler, "1.29.0", Some(51540), None),
+
+    // Allows using the `amdgpu-kernel` ABI.
+    (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None),
+
+    // Allows panicking during const eval (producing compile-time errors).
+    (active, const_panic, "1.30.0", Some(51999), None),
+
+    // Allows `#[marker]` on certain traits allowing overlapping implementations.
+    (active, marker_trait_attr, "1.30.0", Some(29864), None),
+
+    // Allows macro invocations on modules expressions and statements and
+    // procedural macros to expand to non-items.
+    (active, proc_macro_hygiene, "1.30.0", Some(54727), None),
+
+    // Allows unsized rvalues at arguments and parameters.
+    (active, unsized_locals, "1.30.0", Some(48055), None),
+
+    // Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.
+    (active, custom_test_frameworks, "1.30.0", Some(50297), None),
+
+    // Allows non-builtin attributes in inner attribute position.
+    (active, custom_inner_attributes, "1.30.0", Some(54726), None),
+
+    // Allows mixing bind-by-move in patterns and references to those identifiers in guards.
+    (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None),
+
+    // Allows `impl Trait` in bindings (`let`, `const`, `static`).
+    (active, impl_trait_in_bindings, "1.30.0", Some(63065), None),
+
+    // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
+    (active, lint_reasons, "1.31.0", Some(54503), None),
+
+    // Allows exhaustive integer pattern matching on `usize` and `isize`.
+    (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
+
+    // Allows relaxing the coherence rules such that
+    // `impl<T> ForeignTrait<LocalType> for ForeignType<T> is permitted.
+    (active, re_rebalance_coherence, "1.32.0", Some(55437), None),
+
+    // Allows using `#[ffi_returns_twice]` on foreign functions.
+    (active, ffi_returns_twice, "1.34.0", Some(58314), None),
+
+    // Allows const generic types (e.g. `struct Foo<const N: usize>(...);`).
+    (active, const_generics, "1.34.0", Some(44580), None),
+
+    // Allows using `#[optimize(X)]`.
+    (active, optimize_attribute, "1.34.0", Some(54882), None),
+
+    // Allows using C-variadics.
+    (active, c_variadic, "1.34.0", Some(44930), None),
+
+    // Allows the user of associated type bounds.
+    (active, associated_type_bounds, "1.34.0", Some(52662), None),
+
+    // Attributes on formal function params.
+    (active, param_attrs, "1.36.0", Some(60406), None),
+
+    // Allows calling constructor functions in `const fn`.
+    (active, const_constructor, "1.37.0", Some(61456), None),
+
+    // Allows `if/while p && let q = r && ...` chains.
+    (active, let_chains, "1.37.0", Some(53667), None),
+
+    // Allows #[repr(transparent)] on enums (RFC 2645).
+    (active, transparent_enums, "1.37.0", Some(60405), None),
+
+    // Allows #[repr(transparent)] on unions (RFC 2645).
+    (active, transparent_unions, "1.37.0", Some(60405), None),
+
+    // Allows explicit discriminants on non-unit enum variants.
+    (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
+
+    // Allows `impl Trait` with multiple unrelated lifetimes.
+    (active, member_constraints, "1.37.0", Some(61977), None),
+
+    // Allows `async || body` closures.
+    (active, async_closure, "1.37.0", Some(62290), None),
+
+    // Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests
+    (active, cfg_doctest, "1.37.0", Some(62210), None),
+
+    // Allows `[x; N]` where `x` is a constant (RFC 2203).
+    (active, const_in_array_repeat_expressions, "1.37.0", Some(49147), None),
+
+    // Allows `impl Trait` to be used inside type aliases (RFC 2515).
+    (active, type_alias_impl_trait, "1.38.0", Some(63063), None),
+
+    // Allows the use of or-patterns, e.g. `0 | 1`.
+    (active, or_patterns, "1.38.0", Some(54883), None),
+
+    // -------------------------------------------------------------------------
+    // feature-group-end: actual feature gates
+    // -------------------------------------------------------------------------
+);
+
+/// Some features are known to be incomplete and using them is likely to have
+/// unanticipated results, such as compiler crashes. We warn the user about these
+/// to alert them.
+pub const INCOMPLETE_FEATURES: &[Symbol] = &[
+    sym::impl_trait_in_bindings,
+    sym::generic_associated_types,
+    sym::const_generics,
+    sym::or_patterns,
+    sym::let_chains,
+];

From 332a77e6212ccb96800c70d864a20aecce789136 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 22 Aug 2019 18:32:31 +0200
Subject: [PATCH 149/943] syntax: extract `builin_attrs.rs`.

---
 src/libsyntax/feature_gate.rs               | 722 +------------------
 src/libsyntax/feature_gate/attr.rs          |   1 -
 src/libsyntax/feature_gate/builtin_attrs.rs | 724 ++++++++++++++++++++
 3 files changed, 732 insertions(+), 715 deletions(-)
 delete mode 100644 src/libsyntax/feature_gate/attr.rs
 create mode 100644 src/libsyntax/feature_gate/builtin_attrs.rs

diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index f01b3af7af40b..0e04d4c6c2309 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -19,15 +19,18 @@ use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
 mod active;
 use active::{ACTIVE_FEATURES};
 pub use active::{Features, INCOMPLETE_FEATURES};
-
-use AttributeType::*;
-use AttributeGate::*;
+mod builtin_attrs;
+pub use builtin_attrs::{
+    AttributeGate, AttributeType, GatedCfg,
+    BuiltinAttribute, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
+    deprecated_attributes, is_builtin_attr,  is_builtin_attr_name,
+};
 
 use crate::ast::{
     self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind,
     PatKind, RangeEnd,
 };
-use crate::attr::{self, check_builtin_attribute, AttributeTemplate};
+use crate::attr::{self, check_builtin_attribute};
 use crate::source_map::Spanned;
 use crate::edition::{ALL_EDITIONS, Edition};
 use crate::visit::{self, FnKind, Visitor};
@@ -41,67 +44,9 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_target::spec::abi::Abi;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan};
 use log::debug;
-use lazy_static::lazy_static;
 
 use std::env;
 
-// If you change this, please modify `src/doc/unstable-book` as well. You must
-// move that documentation into the relevant place in the other docs, and
-// remove the chapter on the flag.
-
-#[derive(Copy, Clone, PartialEq, Debug)]
-pub enum AttributeType {
-    /// Normal, builtin attribute that is consumed
-    /// by the compiler before the unused_attribute check
-    Normal,
-
-    /// Builtin attribute that may not be consumed by the compiler
-    /// before the unused_attribute check. These attributes
-    /// will be ignored by the unused_attribute lint
-    Whitelisted,
-
-    /// Builtin attribute that is only allowed at the crate level
-    CrateLevel,
-}
-
-pub enum AttributeGate {
-    /// Is gated by a given feature gate, reason
-    /// and function to check if enabled
-    Gated(Stability, Symbol, &'static str, fn(&Features) -> bool),
-
-    /// Ungated attribute, can be used on all release channels
-    Ungated,
-}
-
-/// A convenience macro for constructing attribute templates.
-/// E.g., `template!(Word, List: "description")` means that the attribute
-/// supports forms `#[attr]` and `#[attr(description)]`.
-macro_rules! template {
-    (Word) => { template!(@ true, None, None) };
-    (List: $descr: expr) => { template!(@ false, Some($descr), None) };
-    (NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) };
-    (Word, List: $descr: expr) => { template!(@ true, Some($descr), None) };
-    (Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) };
-    (List: $descr1: expr, NameValueStr: $descr2: expr) => {
-        template!(@ false, Some($descr1), Some($descr2))
-    };
-    (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => {
-        template!(@ true, Some($descr1), Some($descr2))
-    };
-    (@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate {
-        word: $word, list: $list, name_value_str: $name_value_str
-    } };
-}
-
-impl AttributeGate {
-    fn is_deprecated(&self) -> bool {
-        match *self {
-            Gated(Stability::Deprecated(_, _), ..) => true,
-            _ => false,
-        }
-    }
-}
-
 #[derive(Copy, Clone, Debug)]
 pub enum Stability {
     Unstable,
@@ -110,657 +55,6 @@ pub enum Stability {
     Deprecated(&'static str, Option<&'static str>),
 }
 
-// fn() is not Debug
-impl std::fmt::Debug for AttributeGate {
-    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        match *self {
-            Gated(ref stab, name, expl, _) =>
-                write!(fmt, "Gated({:?}, {}, {})", stab, name, expl),
-            Ungated => write!(fmt, "Ungated")
-        }
-    }
-}
-
-macro_rules! cfg_fn {
-    ($field: ident) => {{
-        fn f(features: &Features) -> bool {
-            features.$field
-        }
-        f as fn(&Features) -> bool
-    }}
-}
-
-pub fn deprecated_attributes() -> Vec<&'static (Symbol, AttributeType,
-                                                AttributeTemplate, AttributeGate)> {
-    BUILTIN_ATTRIBUTES.iter().filter(|(.., gate)| gate.is_deprecated()).collect()
-}
-
-pub fn is_builtin_attr_name(name: ast::Name) -> bool {
-    BUILTIN_ATTRIBUTE_MAP.get(&name).is_some()
-}
-
-pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
-    attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).is_some()
-}
-
-/// Attributes that have a special meaning to rustc or rustdoc
-pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
-    // Normal attributes
-
-    (
-        sym::warn,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
-    ),
-    (
-        sym::allow,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
-    ),
-    (
-        sym::forbid,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
-    ),
-    (
-        sym::deny,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
-    ),
-
-    (sym::macro_use, Normal, template!(Word, List: "name1, name2, ..."), Ungated),
-    (sym::macro_export, Normal, template!(Word, List: "local_inner_macros"), Ungated),
-    (sym::plugin_registrar, Normal, template!(Word), Ungated),
-
-    (sym::cfg, Normal, template!(List: "predicate"), Ungated),
-    (sym::cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), Ungated),
-    (sym::main, Normal, template!(Word), Ungated),
-    (sym::start, Normal, template!(Word), Ungated),
-    (sym::repr, Normal, template!(List: "C, packed, ..."), Ungated),
-    (sym::path, Normal, template!(NameValueStr: "file"), Ungated),
-    (sym::automatically_derived, Normal, template!(Word), Ungated),
-    (sym::no_mangle, Whitelisted, template!(Word), Ungated),
-    (sym::no_link, Normal, template!(Word), Ungated),
-    (sym::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated),
-    (
-        sym::should_panic,
-        Normal,
-        template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"),
-        Ungated
-    ),
-    (sym::ignore, Normal, template!(Word, NameValueStr: "reason"), Ungated),
-    (sym::no_implicit_prelude, Normal, template!(Word), Ungated),
-    (sym::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated),
-    (sym::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable,
-                                sym::link_args,
-                                "the `link_args` attribute is experimental and not \
-                                portable across platforms, it is recommended to \
-                                use `#[link(name = \"foo\")] instead",
-                                cfg_fn!(link_args))),
-    (sym::macro_escape, Normal, template!(Word), Ungated),
-
-    // RFC #1445.
-    (sym::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::structural_match,
-                                            "the semantics of constant patterns is \
-                                            not yet settled",
-                                            cfg_fn!(structural_match))),
-
-    // RFC #2008
-    (sym::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::non_exhaustive,
-                                        "non exhaustive is an experimental feature",
-                                        cfg_fn!(non_exhaustive))),
-
-    // RFC #1268
-    (sym::marker, Normal, template!(Word), Gated(Stability::Unstable,
-                            sym::marker_trait_attr,
-                            "marker traits is an experimental feature",
-                            cfg_fn!(marker_trait_attr))),
-
-    (sym::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable,
-                                sym::plugin,
-                                "compiler plugins are experimental \
-                                and possibly buggy",
-                                cfg_fn!(plugin))),
-
-    (sym::no_std, CrateLevel, template!(Word), Ungated),
-    (sym::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable,
-                                sym::no_core,
-                                "no_core is experimental",
-                                cfg_fn!(no_core))),
-    (sym::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable,
-                        sym::lang_items,
-                        "language items are subject to change",
-                        cfg_fn!(lang_items))),
-    (sym::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
-                                Gated(Stability::Unstable,
-                                sym::linkage,
-                                "the `linkage` attribute is experimental \
-                                    and not portable across platforms",
-                                cfg_fn!(linkage))),
-    (sym::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::thread_local,
-                                        "`#[thread_local]` is an experimental feature, and does \
-                                         not currently handle destructors",
-                                        cfg_fn!(thread_local))),
-
-    (sym::rustc_on_unimplemented, Whitelisted, template!(List:
-                        r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
-                        NameValueStr: "message"),
-                                            Gated(Stability::Unstable,
-                                            sym::on_unimplemented,
-                                            "the `#[rustc_on_unimplemented]` attribute \
-                                            is an experimental feature",
-                                            cfg_fn!(on_unimplemented))),
-    (sym::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
-                                            Gated(Stability::Unstable,
-                                            sym::rustc_const_unstable,
-                                            "the `#[rustc_const_unstable]` attribute \
-                                            is an internal feature",
-                                            cfg_fn!(rustc_const_unstable))),
-    (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::allocator_internals,
-                                            "the `#[default_lib_allocator]` \
-                                            attribute is an experimental feature",
-                                            cfg_fn!(allocator_internals))),
-    (sym::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::allocator_internals,
-                                    "the `#[needs_allocator]` \
-                                    attribute is an experimental \
-                                    feature",
-                                    cfg_fn!(allocator_internals))),
-    (sym::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::panic_runtime,
-                                        "the `#[panic_runtime]` attribute is \
-                                        an experimental feature",
-                                        cfg_fn!(panic_runtime))),
-    (sym::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::needs_panic_runtime,
-                                            "the `#[needs_panic_runtime]` \
-                                                attribute is an experimental \
-                                                feature",
-                                            cfg_fn!(needs_panic_runtime))),
-    (sym::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_outlives]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_variance]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_layout, Normal, template!(List: "field1, field2, ..."),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_layout]` attribute \
-            is just used for rustc unit tests \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_layout_scalar_valid_range_start]` attribute \
-            is just used to enable niche optimizations in libcore \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_layout_scalar_valid_range_end]` attribute \
-            is just used to enable niche optimizations in libcore \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_nonnull_optimization_guaranteed, Whitelisted, template!(Word),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_nonnull_optimization_guaranteed]` attribute \
-            is just used to enable niche optimizations in libcore \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_regions]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_error]` attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "this attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"),
-                                                Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "the `#[rustc_if_this_changed]` attribute \
-                                                is just used for rustc unit tests \
-                                                and will never be stable",
-                                                cfg_fn!(rustc_attrs))),
-    (sym::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"),
-                                                    Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_if_this_changed]` attribute \
-                                                    is just used for rustc unit tests \
-                                                    and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
-                                                    /*opt*/ except = "...""#),
-                                    Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_dirty]` attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
-                                                    /*opt*/ except = "...""#),
-                                    Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_clean]` attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (
-        sym::rustc_partition_reused,
-        Whitelisted,
-        template!(List: r#"cfg = "...", module = "...""#),
-        Gated(
-            Stability::Unstable,
-            sym::rustc_attrs,
-            "this attribute \
-            is just used for rustc unit tests \
-            and will never be stable",
-            cfg_fn!(rustc_attrs)
-        )
-    ),
-    (
-        sym::rustc_partition_codegened,
-        Whitelisted,
-        template!(List: r#"cfg = "...", module = "...""#),
-        Gated(
-            Stability::Unstable,
-            sym::rustc_attrs,
-            "this attribute \
-            is just used for rustc unit tests \
-            and will never be stable",
-            cfg_fn!(rustc_attrs),
-        )
-    ),
-    (sym::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...",
-                                                            kind = "...""#),
-                                                    Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "this attribute \
-                                                    is just used for rustc unit tests \
-                                                    and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "this attribute \
-                                                    is just used for rustc unit tests \
-                                                    and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::rustc_attrs,
-                                            "internal rustc attributes will never be stable",
-                                            cfg_fn!(rustc_attrs))),
-    (sym::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::rustc_attrs,
-                                        "internal rustc attributes will never be stable",
-                                        cfg_fn!(rustc_attrs))),
-    (sym::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_mir]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (
-        sym::rustc_inherit_overflow_checks,
-        Whitelisted,
-        template!(Word),
-        Gated(
-            Stability::Unstable,
-            sym::rustc_attrs,
-            "the `#[rustc_inherit_overflow_checks]` \
-            attribute is just used to control \
-            overflow checking behavior of several \
-            libcore functions that are inlined \
-            across crates and will never be stable",
-            cfg_fn!(rustc_attrs),
-        )
-    ),
-
-    (sym::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_dump_program_clauses]` \
-                                                    attribute is just used for rustc unit \
-                                                    tests and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_dump_env_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_dump_env_program_clauses]` \
-                                                    attribute is just used for rustc unit \
-                                                    tests and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_object_lifetime_default, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_object_lifetime_default]` \
-                                                    attribute is just used for rustc unit \
-                                                    tests and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_test_marker]` attribute \
-                                    is used internally to track tests",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_macro_transparency, Whitelisted, template!(NameValueStr:
-                                                           "transparent|semitransparent|opaque"),
-                                                Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "used internally for testing macro hygiene",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::compiler_builtins,
-                                            "the `#[compiler_builtins]` attribute is used to \
-                                            identify the `compiler_builtins` crate which \
-                                            contains compiler-rt intrinsics and will never be \
-                                            stable",
-                                        cfg_fn!(compiler_builtins))),
-    (sym::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::sanitizer_runtime,
-                                            "the `#[sanitizer_runtime]` attribute is used to \
-                                            identify crates that contain the runtime of a \
-                                            sanitizer and will never be stable",
-                                            cfg_fn!(sanitizer_runtime))),
-    (sym::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::profiler_runtime,
-                                            "the `#[profiler_runtime]` attribute is used to \
-                                            identify the `profiler_builtins` crate which \
-                                            contains the profiler runtime and will never be \
-                                            stable",
-                                            cfg_fn!(profiler_runtime))),
-
-    (sym::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
-                                            Gated(Stability::Unstable,
-                                            sym::allow_internal_unstable,
-                                            EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
-                                            cfg_fn!(allow_internal_unstable))),
-
-    (sym::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable,
-                                            sym::allow_internal_unsafe,
-                                            EXPLAIN_ALLOW_INTERNAL_UNSAFE,
-                                            cfg_fn!(allow_internal_unsafe))),
-
-    (sym::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::fundamental,
-                                    "the `#[fundamental]` attribute \
-                                        is an experimental feature",
-                                    cfg_fn!(fundamental))),
-
-    (sym::proc_macro_derive, Normal, template!(List: "TraitName, \
-                                                /*opt*/ attributes(name1, name2, ...)"),
-                                    Ungated),
-
-    (sym::rustc_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_allocator_nounwind, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_builtin_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_promotable, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_allow_const_fn_ptr, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_dummy, Normal, template!(Word /* doesn't matter*/), Gated(Stability::Unstable,
-                                         sym::rustc_attrs,
-                                         "used by the test suite",
-                                         cfg_fn!(rustc_attrs))),
-
-    // FIXME: #14408 whitelist docs since rustdoc looks at them
-    (
-        sym::doc,
-        Whitelisted,
-        template!(List: "hidden|inline|...", NameValueStr: "string"),
-        Ungated
-    ),
-
-    // FIXME: #14406 these are processed in codegen, which happens after the
-    // lint pass
-    (sym::cold, Whitelisted, template!(Word), Ungated),
-    (sym::naked, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                sym::naked_functions,
-                                "the `#[naked]` attribute \
-                                is an experimental feature",
-                                cfg_fn!(naked_functions))),
-    (sym::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                sym::ffi_returns_twice,
-                                "the `#[ffi_returns_twice]` attribute \
-                                is an experimental feature",
-                                cfg_fn!(ffi_returns_twice))),
-    (sym::target_feature, Whitelisted, template!(List: r#"enable = "name""#), Ungated),
-    (sym::export_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (sym::inline, Whitelisted, template!(Word, List: "always|never"), Ungated),
-    (sym::link, Whitelisted, template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...",
-                                               /*opt*/ cfg = "...""#), Ungated),
-    (sym::link_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (sym::link_section, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (sym::no_builtins, Whitelisted, template!(Word), Ungated),
-    (sym::no_debug, Whitelisted, template!(Word), Gated(
-        Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None),
-        sym::no_debug,
-        "the `#[no_debug]` attribute was an experimental feature that has been \
-        deprecated due to lack of demand",
-        cfg_fn!(no_debug))),
-    (
-        sym::omit_gdb_pretty_printer_section,
-        Whitelisted,
-        template!(Word),
-        Gated(
-            Stability::Unstable,
-            sym::omit_gdb_pretty_printer_section,
-            "the `#[omit_gdb_pretty_printer_section]` \
-                attribute is just used for the Rust test \
-                suite",
-            cfg_fn!(omit_gdb_pretty_printer_section)
-        )
-    ),
-    (sym::may_dangle,
-    Normal,
-    template!(Word),
-    Gated(Stability::Unstable,
-        sym::dropck_eyepatch,
-        "`may_dangle` has unstable semantics and may be removed in the future",
-        cfg_fn!(dropck_eyepatch))),
-    (sym::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable,
-                                sym::unwind_attributes,
-                                "`#[unwind]` is experimental",
-                                cfg_fn!(unwind_attributes))),
-    (sym::used, Whitelisted, template!(Word), Ungated),
-
-    // used in resolve
-    (sym::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::prelude_import,
-                                        "`#[prelude_import]` is for use by rustc only",
-                                        cfg_fn!(prelude_import))),
-
-    // FIXME: #14407 these are only looked at on-demand so we can't
-    // guarantee they'll have already been checked
-    (
-        sym::rustc_deprecated,
-        Whitelisted,
-        template!(List: r#"since = "version", reason = "...""#),
-        Ungated
-    ),
-    (sym::must_use, Whitelisted, template!(Word, NameValueStr: "reason"), Ungated),
-    (
-        sym::stable,
-        Whitelisted,
-        template!(List: r#"feature = "name", since = "version""#),
-        Ungated
-    ),
-    (
-        sym::unstable,
-        Whitelisted,
-        template!(List: r#"feature = "name", reason = "...", issue = "N""#),
-        Ungated
-    ),
-    (sym::deprecated,
-        Normal,
-        template!(
-            Word,
-            List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#,
-            NameValueStr: "reason"
-        ),
-        Ungated
-    ),
-
-    (sym::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable,
-                                        sym::unboxed_closures,
-                                        "unboxed_closures are still evolving",
-                                        cfg_fn!(unboxed_closures))),
-
-    (sym::windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console"), Ungated),
-
-    (sym::proc_macro_attribute, Normal, template!(Word), Ungated),
-    (sym::proc_macro, Normal, template!(Word), Ungated),
-
-    (sym::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable,
-                                            sym::rustc_attrs,
-                                            "used internally by rustc",
-                                            cfg_fn!(rustc_attrs))),
-
-    (sym::allow_fail, Normal, template!(Word), Gated(Stability::Unstable,
-                                sym::allow_fail,
-                                "allow_fail attribute is currently unstable",
-                                cfg_fn!(allow_fail))),
-
-    (sym::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "this is an internal attribute that will \
-                                    never be stable",
-                                    cfg_fn!(rustc_attrs))),
-
-    // whitelists "identity-like" conversion methods to suggest on type mismatch
-    (sym::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "this is an internal attribute that will \
-                                                        never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-
-    (
-        sym::rustc_args_required_const,
-        Whitelisted,
-        template!(List: "N"),
-        Gated(Stability::Unstable, sym::rustc_attrs, "never will be stable",
-           cfg_fn!(rustc_attrs))
-    ),
-    // RFC 2070
-    (sym::panic_handler, Normal, template!(Word), Ungated),
-
-    (sym::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable,
-                        sym::alloc_error_handler,
-                        "`#[alloc_error_handler]` is an unstable feature",
-                        cfg_fn!(alloc_error_handler))),
-
-    // RFC 2412
-    (sym::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable,
-                            sym::optimize_attribute,
-                            "`#[optimize]` attribute is an unstable feature",
-                            cfg_fn!(optimize_attribute))),
-
-    // Crate level attributes
-    (sym::crate_name, CrateLevel, template!(NameValueStr: "name"), Ungated),
-    (sym::crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated),
-    (sym::crate_id, CrateLevel, template!(NameValueStr: "ignored"), Ungated),
-    (sym::feature, CrateLevel, template!(List: "name1, name1, ..."), Ungated),
-    (sym::no_start, CrateLevel, template!(Word), Ungated),
-    (sym::no_main, CrateLevel, template!(Word), Ungated),
-    (sym::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
-    (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
-    (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable,
-                    sym::custom_test_frameworks,
-                    "custom test frameworks are an unstable feature",
-                    cfg_fn!(custom_test_frameworks))),
-];
-
-pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
-
-lazy_static! {
-    pub static ref BUILTIN_ATTRIBUTE_MAP: FxHashMap<Symbol, &'static BuiltinAttribute> = {
-        let mut map = FxHashMap::default();
-        for attr in BUILTIN_ATTRIBUTES.iter() {
-            if map.insert(attr.0, attr).is_some() {
-                panic!("duplicate builtin attribute `{}`", attr.0);
-            }
-        }
-        map
-    };
-}
-
-// cfg(...)'s that are feature gated
-const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[
-    // (name in cfg, feature, function to check if the feature is enabled)
-    (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
-    (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
-    (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)),
-    (sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)),
-];
-
-#[derive(Debug)]
-pub struct GatedCfg {
-    span: Span,
-    index: usize,
-}
-
-impl GatedCfg {
-    pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> {
-        GATED_CFGS.iter()
-                  .position(|info| cfg.check_name(info.0))
-                  .map(|idx| {
-                      GatedCfg {
-                          span: cfg.span,
-                          index: idx
-                      }
-                  })
-    }
-
-    pub fn check_and_emit(&self, sess: &ParseSess, features: &Features) {
-        let (cfg, feature, has_feature) = GATED_CFGS[self.index];
-        if !has_feature(features) && !self.span.allows_unstable(feature) {
-            let explain = format!("`cfg({})` is experimental and subject to change", cfg);
-            emit_feature_err(sess, feature, self.span, GateIssue::Language, &explain);
-        }
-    }
-}
-
 struct Context<'a> {
     features: &'a Features,
     parse_sess: &'a ParseSess,
@@ -800,7 +94,7 @@ impl<'a> Context<'a> {
     ) {
         debug!("check_attribute(attr = {:?})", attr);
         if let Some(&(name, ty, _template, ref gateage)) = attr_info {
-            if let Gated(_, name, desc, ref has_feature) = *gateage {
+            if let AttributeGate::Gated(_, name, desc, ref has_feature) = *gateage {
                 if !attr.span.allows_unstable(name) {
                     gate_feature_fn!(
                         self, has_feature, attr.span, name, desc, GateStrength::Hard
diff --git a/src/libsyntax/feature_gate/attr.rs b/src/libsyntax/feature_gate/attr.rs
deleted file mode 100644
index 46330df364852..0000000000000
--- a/src/libsyntax/feature_gate/attr.rs
+++ /dev/null
@@ -1 +0,0 @@
-//! TODO
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
new file mode 100644
index 0000000000000..17e58df89e137
--- /dev/null
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -0,0 +1,724 @@
+//! Built-in attributes and `cfg` flag gating.
+
+use AttributeType::*;
+use AttributeGate::*;
+
+use super::{emit_feature_err, GateIssue};
+use super::{Stability, EXPLAIN_ALLOW_INTERNAL_UNSAFE, EXPLAIN_ALLOW_INTERNAL_UNSTABLE};
+use super::active::Features;
+
+use crate::ast;
+use crate::attr::AttributeTemplate;
+use crate::symbol::{Symbol, sym};
+use crate::parse::ParseSess;
+
+use syntax_pos::Span;
+use rustc_data_structures::fx::FxHashMap;
+use lazy_static::lazy_static;
+
+macro_rules! cfg_fn {
+    ($field: ident) => {{
+        fn f(features: &Features) -> bool {
+            features.$field
+        }
+        f as fn(&Features) -> bool
+    }}
+}
+
+// cfg(...)'s that are feature gated
+const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[
+    // (name in cfg, feature, function to check if the feature is enabled)
+    (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
+    (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
+    (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)),
+    (sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)),
+];
+
+#[derive(Debug)]
+pub struct GatedCfg {
+    span: Span,
+    index: usize,
+}
+
+impl GatedCfg {
+    pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> {
+        GATED_CFGS.iter()
+                  .position(|info| cfg.check_name(info.0))
+                  .map(|idx| {
+                      GatedCfg {
+                          span: cfg.span,
+                          index: idx
+                      }
+                  })
+    }
+
+    pub fn check_and_emit(&self, sess: &ParseSess, features: &Features) {
+        let (cfg, feature, has_feature) = GATED_CFGS[self.index];
+        if !has_feature(features) && !self.span.allows_unstable(feature) {
+            let explain = format!("`cfg({})` is experimental and subject to change", cfg);
+            emit_feature_err(sess, feature, self.span, GateIssue::Language, &explain);
+        }
+    }
+}
+
+// If you change this, please modify `src/doc/unstable-book` as well. You must
+// move that documentation into the relevant place in the other docs, and
+// remove the chapter on the flag.
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum AttributeType {
+    /// Normal, builtin attribute that is consumed
+    /// by the compiler before the unused_attribute check
+    Normal,
+
+    /// Builtin attribute that may not be consumed by the compiler
+    /// before the unused_attribute check. These attributes
+    /// will be ignored by the unused_attribute lint
+    Whitelisted,
+
+    /// Builtin attribute that is only allowed at the crate level
+    CrateLevel,
+}
+
+pub enum AttributeGate {
+    /// Is gated by a given feature gate, reason
+    /// and function to check if enabled
+    Gated(Stability, Symbol, &'static str, fn(&Features) -> bool),
+
+    /// Ungated attribute, can be used on all release channels
+    Ungated,
+}
+
+// fn() is not Debug
+impl std::fmt::Debug for AttributeGate {
+    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match *self {
+            Self::Gated(ref stab, name, expl, _) =>
+                write!(fmt, "Gated({:?}, {}, {})", stab, name, expl),
+            Self::Ungated => write!(fmt, "Ungated")
+        }
+    }
+}
+
+impl AttributeGate {
+    fn is_deprecated(&self) -> bool {
+        match *self {
+            Self::Gated(Stability::Deprecated(_, _), ..) => true,
+            _ => false,
+        }
+    }
+}
+
+/// A convenience macro for constructing attribute templates.
+/// E.g., `template!(Word, List: "description")` means that the attribute
+/// supports forms `#[attr]` and `#[attr(description)]`.
+macro_rules! template {
+    (Word) => { template!(@ true, None, None) };
+    (List: $descr: expr) => { template!(@ false, Some($descr), None) };
+    (NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) };
+    (Word, List: $descr: expr) => { template!(@ true, Some($descr), None) };
+    (Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) };
+    (List: $descr1: expr, NameValueStr: $descr2: expr) => {
+        template!(@ false, Some($descr1), Some($descr2))
+    };
+    (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => {
+        template!(@ true, Some($descr1), Some($descr2))
+    };
+    (@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate {
+        word: $word, list: $list, name_value_str: $name_value_str
+    } };
+}
+
+pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
+
+/// Attributes that have a special meaning to rustc or rustdoc
+pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
+    // Normal attributes
+
+    (
+        sym::warn,
+        Normal,
+        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
+        Ungated
+    ),
+    (
+        sym::allow,
+        Normal,
+        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
+        Ungated
+    ),
+    (
+        sym::forbid,
+        Normal,
+        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
+        Ungated
+    ),
+    (
+        sym::deny,
+        Normal,
+        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
+        Ungated
+    ),
+
+    (sym::macro_use, Normal, template!(Word, List: "name1, name2, ..."), Ungated),
+    (sym::macro_export, Normal, template!(Word, List: "local_inner_macros"), Ungated),
+    (sym::plugin_registrar, Normal, template!(Word), Ungated),
+
+    (sym::cfg, Normal, template!(List: "predicate"), Ungated),
+    (sym::cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), Ungated),
+    (sym::main, Normal, template!(Word), Ungated),
+    (sym::start, Normal, template!(Word), Ungated),
+    (sym::repr, Normal, template!(List: "C, packed, ..."), Ungated),
+    (sym::path, Normal, template!(NameValueStr: "file"), Ungated),
+    (sym::automatically_derived, Normal, template!(Word), Ungated),
+    (sym::no_mangle, Whitelisted, template!(Word), Ungated),
+    (sym::no_link, Normal, template!(Word), Ungated),
+    (sym::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated),
+    (
+        sym::should_panic,
+        Normal,
+        template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"),
+        Ungated
+    ),
+    (sym::ignore, Normal, template!(Word, NameValueStr: "reason"), Ungated),
+    (sym::no_implicit_prelude, Normal, template!(Word), Ungated),
+    (sym::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated),
+    (sym::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable,
+                                sym::link_args,
+                                "the `link_args` attribute is experimental and not \
+                                portable across platforms, it is recommended to \
+                                use `#[link(name = \"foo\")] instead",
+                                cfg_fn!(link_args))),
+    (sym::macro_escape, Normal, template!(Word), Ungated),
+
+    // RFC #1445.
+    (sym::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::structural_match,
+                                            "the semantics of constant patterns is \
+                                            not yet settled",
+                                            cfg_fn!(structural_match))),
+
+    // RFC #2008
+    (sym::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                        sym::non_exhaustive,
+                                        "non exhaustive is an experimental feature",
+                                        cfg_fn!(non_exhaustive))),
+
+    // RFC #1268
+    (sym::marker, Normal, template!(Word), Gated(Stability::Unstable,
+                            sym::marker_trait_attr,
+                            "marker traits is an experimental feature",
+                            cfg_fn!(marker_trait_attr))),
+
+    (sym::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable,
+                                sym::plugin,
+                                "compiler plugins are experimental \
+                                and possibly buggy",
+                                cfg_fn!(plugin))),
+
+    (sym::no_std, CrateLevel, template!(Word), Ungated),
+    (sym::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable,
+                                sym::no_core,
+                                "no_core is experimental",
+                                cfg_fn!(no_core))),
+    (sym::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable,
+                        sym::lang_items,
+                        "language items are subject to change",
+                        cfg_fn!(lang_items))),
+    (sym::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
+                                Gated(Stability::Unstable,
+                                sym::linkage,
+                                "the `linkage` attribute is experimental \
+                                    and not portable across platforms",
+                                cfg_fn!(linkage))),
+    (sym::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                        sym::thread_local,
+                                        "`#[thread_local]` is an experimental feature, and does \
+                                         not currently handle destructors",
+                                        cfg_fn!(thread_local))),
+
+    (sym::rustc_on_unimplemented, Whitelisted, template!(List:
+                        r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
+                        NameValueStr: "message"),
+                                            Gated(Stability::Unstable,
+                                            sym::on_unimplemented,
+                                            "the `#[rustc_on_unimplemented]` attribute \
+                                            is an experimental feature",
+                                            cfg_fn!(on_unimplemented))),
+    (sym::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
+                                            Gated(Stability::Unstable,
+                                            sym::rustc_const_unstable,
+                                            "the `#[rustc_const_unstable]` attribute \
+                                            is an internal feature",
+                                            cfg_fn!(rustc_const_unstable))),
+    (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::allocator_internals,
+                                            "the `#[default_lib_allocator]` \
+                                            attribute is an experimental feature",
+                                            cfg_fn!(allocator_internals))),
+    (sym::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable,
+                                    sym::allocator_internals,
+                                    "the `#[needs_allocator]` \
+                                    attribute is an experimental \
+                                    feature",
+                                    cfg_fn!(allocator_internals))),
+    (sym::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                        sym::panic_runtime,
+                                        "the `#[panic_runtime]` attribute is \
+                                        an experimental feature",
+                                        cfg_fn!(panic_runtime))),
+    (sym::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::needs_panic_runtime,
+                                            "the `#[needs_panic_runtime]` \
+                                                attribute is an experimental \
+                                                feature",
+                                            cfg_fn!(needs_panic_runtime))),
+    (sym::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
+                                    "the `#[rustc_outlives]` attribute \
+                                    is just used for rustc unit tests \
+                                    and will never be stable",
+                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
+                                    "the `#[rustc_variance]` attribute \
+                                    is just used for rustc unit tests \
+                                    and will never be stable",
+                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_layout, Normal, template!(List: "field1, field2, ..."),
+    Gated(Stability::Unstable,
+        sym::rustc_attrs,
+        "the `#[rustc_layout]` attribute \
+            is just used for rustc unit tests \
+            and will never be stable",
+        cfg_fn!(rustc_attrs))),
+    (sym::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
+    Gated(Stability::Unstable,
+        sym::rustc_attrs,
+        "the `#[rustc_layout_scalar_valid_range_start]` attribute \
+            is just used to enable niche optimizations in libcore \
+            and will never be stable",
+        cfg_fn!(rustc_attrs))),
+    (sym::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
+    Gated(Stability::Unstable,
+        sym::rustc_attrs,
+        "the `#[rustc_layout_scalar_valid_range_end]` attribute \
+            is just used to enable niche optimizations in libcore \
+            and will never be stable",
+        cfg_fn!(rustc_attrs))),
+    (sym::rustc_nonnull_optimization_guaranteed, Whitelisted, template!(Word),
+    Gated(Stability::Unstable,
+        sym::rustc_attrs,
+        "the `#[rustc_nonnull_optimization_guaranteed]` attribute \
+            is just used to enable niche optimizations in libcore \
+            and will never be stable",
+        cfg_fn!(rustc_attrs))),
+    (sym::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
+                                    "the `#[rustc_regions]` attribute \
+                                    is just used for rustc unit tests \
+                                    and will never be stable",
+                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
+                                    "the `#[rustc_error]` attribute \
+                                        is just used for rustc unit tests \
+                                        and will never be stable",
+                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
+                                    "this attribute \
+                                        is just used for rustc unit tests \
+                                        and will never be stable",
+                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"),
+                                                Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
+                                                "the `#[rustc_if_this_changed]` attribute \
+                                                is just used for rustc unit tests \
+                                                and will never be stable",
+                                                cfg_fn!(rustc_attrs))),
+    (sym::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"),
+                                                    Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
+                                                    "the `#[rustc_if_this_changed]` attribute \
+                                                    is just used for rustc unit tests \
+                                                    and will never be stable",
+                                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
+                                                    /*opt*/ except = "...""#),
+                                    Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
+                                    "the `#[rustc_dirty]` attribute \
+                                        is just used for rustc unit tests \
+                                        and will never be stable",
+                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
+                                                    /*opt*/ except = "...""#),
+                                    Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
+                                    "the `#[rustc_clean]` attribute \
+                                        is just used for rustc unit tests \
+                                        and will never be stable",
+                                    cfg_fn!(rustc_attrs))),
+    (
+        sym::rustc_partition_reused,
+        Whitelisted,
+        template!(List: r#"cfg = "...", module = "...""#),
+        Gated(
+            Stability::Unstable,
+            sym::rustc_attrs,
+            "this attribute \
+            is just used for rustc unit tests \
+            and will never be stable",
+            cfg_fn!(rustc_attrs)
+        )
+    ),
+    (
+        sym::rustc_partition_codegened,
+        Whitelisted,
+        template!(List: r#"cfg = "...", module = "...""#),
+        Gated(
+            Stability::Unstable,
+            sym::rustc_attrs,
+            "this attribute \
+            is just used for rustc unit tests \
+            and will never be stable",
+            cfg_fn!(rustc_attrs),
+        )
+    ),
+    (sym::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...",
+                                                            kind = "...""#),
+                                                    Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
+                                                    "this attribute \
+                                                    is just used for rustc unit tests \
+                                                    and will never be stable",
+                                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
+                                                    "this attribute \
+                                                    is just used for rustc unit tests \
+                                                    and will never be stable",
+                                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::rustc_attrs,
+                                            "internal rustc attributes will never be stable",
+                                            cfg_fn!(rustc_attrs))),
+    (sym::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                        sym::rustc_attrs,
+                                        "internal rustc attributes will never be stable",
+                                        cfg_fn!(rustc_attrs))),
+    (sym::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
+                                    "the `#[rustc_mir]` attribute \
+                                    is just used for rustc unit tests \
+                                    and will never be stable",
+                                    cfg_fn!(rustc_attrs))),
+    (
+        sym::rustc_inherit_overflow_checks,
+        Whitelisted,
+        template!(Word),
+        Gated(
+            Stability::Unstable,
+            sym::rustc_attrs,
+            "the `#[rustc_inherit_overflow_checks]` \
+            attribute is just used to control \
+            overflow checking behavior of several \
+            libcore functions that are inlined \
+            across crates and will never be stable",
+            cfg_fn!(rustc_attrs),
+        )
+    ),
+
+    (sym::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
+                                                    "the `#[rustc_dump_program_clauses]` \
+                                                    attribute is just used for rustc unit \
+                                                    tests and will never be stable",
+                                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_dump_env_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
+                                                    "the `#[rustc_dump_env_program_clauses]` \
+                                                    attribute is just used for rustc unit \
+                                                    tests and will never be stable",
+                                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_object_lifetime_default, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
+                                                    "the `#[rustc_object_lifetime_default]` \
+                                                    attribute is just used for rustc unit \
+                                                    tests and will never be stable",
+                                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
+                                    "the `#[rustc_test_marker]` attribute \
+                                    is used internally to track tests",
+                                    cfg_fn!(rustc_attrs))),
+    (sym::rustc_macro_transparency, Whitelisted, template!(NameValueStr:
+                                                           "transparent|semitransparent|opaque"),
+                                                Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
+                                                "used internally for testing macro hygiene",
+                                                    cfg_fn!(rustc_attrs))),
+    (sym::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::compiler_builtins,
+                                            "the `#[compiler_builtins]` attribute is used to \
+                                            identify the `compiler_builtins` crate which \
+                                            contains compiler-rt intrinsics and will never be \
+                                            stable",
+                                        cfg_fn!(compiler_builtins))),
+    (sym::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::sanitizer_runtime,
+                                            "the `#[sanitizer_runtime]` attribute is used to \
+                                            identify crates that contain the runtime of a \
+                                            sanitizer and will never be stable",
+                                            cfg_fn!(sanitizer_runtime))),
+    (sym::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                            sym::profiler_runtime,
+                                            "the `#[profiler_runtime]` attribute is used to \
+                                            identify the `profiler_builtins` crate which \
+                                            contains the profiler runtime and will never be \
+                                            stable",
+                                            cfg_fn!(profiler_runtime))),
+
+    (sym::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
+                                            Gated(Stability::Unstable,
+                                            sym::allow_internal_unstable,
+                                            EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
+                                            cfg_fn!(allow_internal_unstable))),
+
+    (sym::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable,
+                                            sym::allow_internal_unsafe,
+                                            EXPLAIN_ALLOW_INTERNAL_UNSAFE,
+                                            cfg_fn!(allow_internal_unsafe))),
+
+    (sym::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                    sym::fundamental,
+                                    "the `#[fundamental]` attribute \
+                                        is an experimental feature",
+                                    cfg_fn!(fundamental))),
+
+    (sym::proc_macro_derive, Normal, template!(List: "TraitName, \
+                                                /*opt*/ attributes(name1, name2, ...)"),
+                                    Ungated),
+
+    (sym::rustc_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
+                                                "internal implementation detail",
+                                                cfg_fn!(rustc_attrs))),
+
+    (sym::rustc_allocator_nounwind, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
+                                                "internal implementation detail",
+                                                cfg_fn!(rustc_attrs))),
+
+    (sym::rustc_builtin_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
+                                                "internal implementation detail",
+                                                cfg_fn!(rustc_attrs))),
+
+    (sym::rustc_promotable, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
+                                                "internal implementation detail",
+                                                cfg_fn!(rustc_attrs))),
+
+    (sym::rustc_allow_const_fn_ptr, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                sym::rustc_attrs,
+                                                "internal implementation detail",
+                                                cfg_fn!(rustc_attrs))),
+
+    (sym::rustc_dummy, Normal, template!(Word /* doesn't matter*/), Gated(Stability::Unstable,
+                                         sym::rustc_attrs,
+                                         "used by the test suite",
+                                         cfg_fn!(rustc_attrs))),
+
+    // FIXME: #14408 whitelist docs since rustdoc looks at them
+    (
+        sym::doc,
+        Whitelisted,
+        template!(List: "hidden|inline|...", NameValueStr: "string"),
+        Ungated
+    ),
+
+    // FIXME: #14406 these are processed in codegen, which happens after the
+    // lint pass
+    (sym::cold, Whitelisted, template!(Word), Ungated),
+    (sym::naked, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                sym::naked_functions,
+                                "the `#[naked]` attribute \
+                                is an experimental feature",
+                                cfg_fn!(naked_functions))),
+    (sym::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                sym::ffi_returns_twice,
+                                "the `#[ffi_returns_twice]` attribute \
+                                is an experimental feature",
+                                cfg_fn!(ffi_returns_twice))),
+    (sym::target_feature, Whitelisted, template!(List: r#"enable = "name""#), Ungated),
+    (sym::export_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
+    (sym::inline, Whitelisted, template!(Word, List: "always|never"), Ungated),
+    (sym::link, Whitelisted, template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...",
+                                               /*opt*/ cfg = "...""#), Ungated),
+    (sym::link_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
+    (sym::link_section, Whitelisted, template!(NameValueStr: "name"), Ungated),
+    (sym::no_builtins, Whitelisted, template!(Word), Ungated),
+    (sym::no_debug, Whitelisted, template!(Word), Gated(
+        Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None),
+        sym::no_debug,
+        "the `#[no_debug]` attribute was an experimental feature that has been \
+        deprecated due to lack of demand",
+        cfg_fn!(no_debug))),
+    (
+        sym::omit_gdb_pretty_printer_section,
+        Whitelisted,
+        template!(Word),
+        Gated(
+            Stability::Unstable,
+            sym::omit_gdb_pretty_printer_section,
+            "the `#[omit_gdb_pretty_printer_section]` \
+                attribute is just used for the Rust test \
+                suite",
+            cfg_fn!(omit_gdb_pretty_printer_section)
+        )
+    ),
+    (sym::may_dangle,
+    Normal,
+    template!(Word),
+    Gated(Stability::Unstable,
+        sym::dropck_eyepatch,
+        "`may_dangle` has unstable semantics and may be removed in the future",
+        cfg_fn!(dropck_eyepatch))),
+    (sym::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable,
+                                sym::unwind_attributes,
+                                "`#[unwind]` is experimental",
+                                cfg_fn!(unwind_attributes))),
+    (sym::used, Whitelisted, template!(Word), Ungated),
+
+    // used in resolve
+    (sym::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                        sym::prelude_import,
+                                        "`#[prelude_import]` is for use by rustc only",
+                                        cfg_fn!(prelude_import))),
+
+    // FIXME: #14407 these are only looked at on-demand so we can't
+    // guarantee they'll have already been checked
+    (
+        sym::rustc_deprecated,
+        Whitelisted,
+        template!(List: r#"since = "version", reason = "...""#),
+        Ungated
+    ),
+    (sym::must_use, Whitelisted, template!(Word, NameValueStr: "reason"), Ungated),
+    (
+        sym::stable,
+        Whitelisted,
+        template!(List: r#"feature = "name", since = "version""#),
+        Ungated
+    ),
+    (
+        sym::unstable,
+        Whitelisted,
+        template!(List: r#"feature = "name", reason = "...", issue = "N""#),
+        Ungated
+    ),
+    (sym::deprecated,
+        Normal,
+        template!(
+            Word,
+            List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#,
+            NameValueStr: "reason"
+        ),
+        Ungated
+    ),
+
+    (sym::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable,
+                                        sym::unboxed_closures,
+                                        "unboxed_closures are still evolving",
+                                        cfg_fn!(unboxed_closures))),
+
+    (sym::windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console"), Ungated),
+
+    (sym::proc_macro_attribute, Normal, template!(Word), Ungated),
+    (sym::proc_macro, Normal, template!(Word), Ungated),
+
+    (sym::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable,
+                                            sym::rustc_attrs,
+                                            "used internally by rustc",
+                                            cfg_fn!(rustc_attrs))),
+
+    (sym::allow_fail, Normal, template!(Word), Gated(Stability::Unstable,
+                                sym::allow_fail,
+                                "allow_fail attribute is currently unstable",
+                                cfg_fn!(allow_fail))),
+
+    (sym::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                    sym::rustc_attrs,
+                                    "this is an internal attribute that will \
+                                    never be stable",
+                                    cfg_fn!(rustc_attrs))),
+
+    // whitelists "identity-like" conversion methods to suggest on type mismatch
+    (sym::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable,
+                                                    sym::rustc_attrs,
+                                                    "this is an internal attribute that will \
+                                                        never be stable",
+                                                    cfg_fn!(rustc_attrs))),
+
+    (
+        sym::rustc_args_required_const,
+        Whitelisted,
+        template!(List: "N"),
+        Gated(Stability::Unstable, sym::rustc_attrs, "never will be stable",
+           cfg_fn!(rustc_attrs))
+    ),
+    // RFC 2070
+    (sym::panic_handler, Normal, template!(Word), Ungated),
+
+    (sym::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable,
+                        sym::alloc_error_handler,
+                        "`#[alloc_error_handler]` is an unstable feature",
+                        cfg_fn!(alloc_error_handler))),
+
+    // RFC 2412
+    (sym::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable,
+                            sym::optimize_attribute,
+                            "`#[optimize]` attribute is an unstable feature",
+                            cfg_fn!(optimize_attribute))),
+
+    // Crate level attributes
+    (sym::crate_name, CrateLevel, template!(NameValueStr: "name"), Ungated),
+    (sym::crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated),
+    (sym::crate_id, CrateLevel, template!(NameValueStr: "ignored"), Ungated),
+    (sym::feature, CrateLevel, template!(List: "name1, name1, ..."), Ungated),
+    (sym::no_start, CrateLevel, template!(Word), Ungated),
+    (sym::no_main, CrateLevel, template!(Word), Ungated),
+    (sym::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
+    (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
+    (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable,
+                    sym::custom_test_frameworks,
+                    "custom test frameworks are an unstable feature",
+                    cfg_fn!(custom_test_frameworks))),
+];
+
+pub fn deprecated_attributes() -> Vec<&'static BuiltinAttribute> {
+    BUILTIN_ATTRIBUTES.iter().filter(|(.., gate)| gate.is_deprecated()).collect()
+}
+
+pub fn is_builtin_attr_name(name: ast::Name) -> bool {
+    BUILTIN_ATTRIBUTE_MAP.get(&name).is_some()
+}
+
+pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
+    attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).is_some()
+}
+
+lazy_static! {
+    pub static ref BUILTIN_ATTRIBUTE_MAP: FxHashMap<Symbol, &'static BuiltinAttribute> = {
+        let mut map = FxHashMap::default();
+        for attr in BUILTIN_ATTRIBUTES.iter() {
+            if map.insert(attr.0, attr).is_some() {
+                panic!("duplicate builtin attribute `{}`", attr.0);
+            }
+        }
+        map
+    };
+}

From 1c979ad55256d065a6d035a01910726a16644223 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 22 Aug 2019 18:37:28 +0200
Subject: [PATCH 150/943] builtin_attrs.rs: simplify `cfg_fn`.

---
 src/libsyntax/feature_gate/builtin_attrs.rs | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index 17e58df89e137..7cd295b1b2cbf 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -16,17 +16,16 @@ use syntax_pos::Span;
 use rustc_data_structures::fx::FxHashMap;
 use lazy_static::lazy_static;
 
+type GateFn = fn(&Features) -> bool;
+
 macro_rules! cfg_fn {
-    ($field: ident) => {{
-        fn f(features: &Features) -> bool {
-            features.$field
-        }
-        f as fn(&Features) -> bool
-    }}
+    ($field: ident) => {
+        (|features| { features.$field }) as GateFn
+    }
 }
 
-// cfg(...)'s that are feature gated
-const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[
+/// `cfg(...)`'s that are feature gated.
+const GATED_CFGS: &[(Symbol, Symbol, GateFn)] = &[
     // (name in cfg, feature, function to check if the feature is enabled)
     (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
     (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),

From 0d19d1d7752bfed460bf7899171865441d6a2d87 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 22 Aug 2019 19:37:04 +0200
Subject: [PATCH 151/943] builtin_attrs.rs: refactor `rustc_attrs` entries.

---
 src/libsyntax/feature_gate/builtin_attrs.rs | 342 +++++++-------------
 1 file changed, 109 insertions(+), 233 deletions(-)

diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index 7cd295b1b2cbf..ad2e6a3feac6f 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -128,6 +128,21 @@ macro_rules! template {
     } };
 }
 
+macro_rules! rustc_attr {
+    (TEST, $gate:ident, $typ:expr, $tpl:expr $(,)?) => {
+        rustc_attr!(
+            $gate, $typ, $tpl,
+            concat!("the `#[", stringify!($gate), "]` attribute is just used for rustc unit tests \
+                and will never be stable",
+            ),
+        )
+    };
+    ($gate:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => {
+        (sym::$gate, $typ, $tpl,
+         Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)))
+    };
+}
+
 pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
 
 /// Attributes that have a special meaning to rustc or rustdoc
@@ -272,193 +287,78 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
                                                 attribute is an experimental \
                                                 feature",
                                             cfg_fn!(needs_panic_runtime))),
-    (sym::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_outlives]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_variance]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_layout, Normal, template!(List: "field1, field2, ..."),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_layout]` attribute \
-            is just used for rustc unit tests \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_layout_scalar_valid_range_start]` attribute \
-            is just used to enable niche optimizations in libcore \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_layout_scalar_valid_range_end]` attribute \
-            is just used to enable niche optimizations in libcore \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_nonnull_optimization_guaranteed, Whitelisted, template!(Word),
-    Gated(Stability::Unstable,
-        sym::rustc_attrs,
-        "the `#[rustc_nonnull_optimization_guaranteed]` attribute \
-            is just used to enable niche optimizations in libcore \
-            and will never be stable",
-        cfg_fn!(rustc_attrs))),
-    (sym::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_regions]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_error]` attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "this attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"),
-                                                Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "the `#[rustc_if_this_changed]` attribute \
-                                                is just used for rustc unit tests \
-                                                and will never be stable",
-                                                cfg_fn!(rustc_attrs))),
-    (sym::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"),
-                                                    Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_if_this_changed]` attribute \
-                                                    is just used for rustc unit tests \
-                                                    and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
-                                                    /*opt*/ except = "...""#),
-                                    Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_dirty]` attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...",
-                                                    /*opt*/ except = "...""#),
-                                    Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_clean]` attribute \
-                                        is just used for rustc unit tests \
-                                        and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (
-        sym::rustc_partition_reused,
-        Whitelisted,
+
+    rustc_attr!(TEST, rustc_outlives, Normal, template!(Word)),
+    rustc_attr!(TEST, rustc_variance, Normal, template!(Word)),
+    rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")),
+    rustc_attr!(
+        rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
+        "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \
+        niche optimizations in libcore and will never be stable",
+    ),
+    rustc_attr!(
+        rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
+        "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
+        niche optimizations in libcore and will never be stable",
+    ),
+    rustc_attr!(
+        rustc_nonnull_optimization_guaranteed, Whitelisted, template!(Word),
+        "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \
+        niche optimizations in libcore and will never be stable",
+    ),
+    rustc_attr!(TEST, rustc_regions, Normal, template!(Word)),
+    rustc_attr!(TEST, rustc_error, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_dump_user_substs, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode")),
+    rustc_attr!(TEST, rustc_then_this_would_need, Whitelisted, template!(List: "DepNode")),
+    rustc_attr!(
+        TEST, rustc_dirty, Whitelisted,
+        template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
+    ),
+    rustc_attr!(
+        TEST, rustc_clean, Whitelisted,
+        template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
+    ),
+    rustc_attr!(
+        TEST, rustc_partition_reused, Whitelisted,
         template!(List: r#"cfg = "...", module = "...""#),
-        Gated(
-            Stability::Unstable,
-            sym::rustc_attrs,
-            "this attribute \
-            is just used for rustc unit tests \
-            and will never be stable",
-            cfg_fn!(rustc_attrs)
-        )
     ),
-    (
-        sym::rustc_partition_codegened,
-        Whitelisted,
+    rustc_attr!(
+        TEST, rustc_partition_codegened, Whitelisted,
         template!(List: r#"cfg = "...", module = "...""#),
-        Gated(
-            Stability::Unstable,
-            sym::rustc_attrs,
-            "this attribute \
-            is just used for rustc unit tests \
-            and will never be stable",
-            cfg_fn!(rustc_attrs),
-        )
     ),
-    (sym::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...",
-                                                            kind = "...""#),
-                                                    Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "this attribute \
-                                                    is just used for rustc unit tests \
-                                                    and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "this attribute \
-                                                    is just used for rustc unit tests \
-                                                    and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::rustc_attrs,
-                                            "internal rustc attributes will never be stable",
-                                            cfg_fn!(rustc_attrs))),
-    (sym::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::rustc_attrs,
-                                        "internal rustc attributes will never be stable",
-                                        cfg_fn!(rustc_attrs))),
-    (sym::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_mir]` attribute \
-                                    is just used for rustc unit tests \
-                                    and will never be stable",
-                                    cfg_fn!(rustc_attrs))),
-    (
-        sym::rustc_inherit_overflow_checks,
-        Whitelisted,
-        template!(Word),
-        Gated(
-            Stability::Unstable,
-            sym::rustc_attrs,
-            "the `#[rustc_inherit_overflow_checks]` \
-            attribute is just used to control \
-            overflow checking behavior of several \
-            libcore functions that are inlined \
-            across crates and will never be stable",
-            cfg_fn!(rustc_attrs),
-        )
+    rustc_attr!(
+        TEST, rustc_expected_cgu_reuse, Whitelisted,
+        template!(List: r#"cfg = "...", module = "...", kind = "...""#),
+    ),
+    rustc_attr!(TEST, rustc_synthetic, Whitelisted, template!(Word)),
+    rustc_attr!(
+        rustc_symbol_name, Whitelisted, template!(Word),
+        "internal rustc attributes will never be stable",
+    ),
+    rustc_attr!(
+        rustc_def_path, Whitelisted, template!(Word),
+        "internal rustc attributes will never be stable",
+    ),
+    rustc_attr!(TEST, rustc_mir, Whitelisted, template!(List: "arg1, arg2, ...")),
+    rustc_attr!(
+        rustc_inherit_overflow_checks, Whitelisted, template!(Word),
+        "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \
+        overflow checking behavior of several libcore functions that are inlined \
+        across crates and will never be stable",
+    ),
+    rustc_attr!(TEST, rustc_dump_program_clauses, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_dump_env_program_clauses, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_object_lifetime_default, Whitelisted, template!(Word)),
+    rustc_attr!(
+        rustc_test_marker, Normal, template!(Word),
+        "the `#[rustc_test_marker]` attribute is used internally to track tests",
+    ),
+    rustc_attr!(
+        rustc_macro_transparency, Whitelisted,
+        template!(NameValueStr: "transparent|semitransparent|opaque"),
+        "used internally for testing macro hygiene",
     ),
-
-    (sym::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_dump_program_clauses]` \
-                                                    attribute is just used for rustc unit \
-                                                    tests and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_dump_env_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_dump_env_program_clauses]` \
-                                                    attribute is just used for rustc unit \
-                                                    tests and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_object_lifetime_default, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "the `#[rustc_object_lifetime_default]` \
-                                                    attribute is just used for rustc unit \
-                                                    tests and will never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "the `#[rustc_test_marker]` attribute \
-                                    is used internally to track tests",
-                                    cfg_fn!(rustc_attrs))),
-    (sym::rustc_macro_transparency, Whitelisted, template!(NameValueStr:
-                                                           "transparent|semitransparent|opaque"),
-                                                Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "used internally for testing macro hygiene",
-                                                    cfg_fn!(rustc_attrs))),
     (sym::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable,
                                             sym::compiler_builtins,
                                             "the `#[compiler_builtins]` attribute is used to \
@@ -501,35 +401,21 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
                                                 /*opt*/ attributes(name1, name2, ...)"),
                                     Ungated),
 
-    (sym::rustc_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_allocator_nounwind, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_builtin_macro, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_promotable, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_allow_const_fn_ptr, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                sym::rustc_attrs,
-                                                "internal implementation detail",
-                                                cfg_fn!(rustc_attrs))),
-
-    (sym::rustc_dummy, Normal, template!(Word /* doesn't matter*/), Gated(Stability::Unstable,
-                                         sym::rustc_attrs,
-                                         "used by the test suite",
-                                         cfg_fn!(rustc_attrs))),
+    rustc_attr!(rustc_allocator, Whitelisted, template!(Word), "internal implementation detail"),
+    rustc_attr!(
+        rustc_allocator_nounwind, Whitelisted, template!(Word),
+        "internal implementation detail",
+    ),
+    rustc_attr!(
+        rustc_builtin_macro, Whitelisted, template!(Word),
+        "internal implementation detail"
+    ),
+    rustc_attr!(rustc_promotable, Whitelisted, template!(Word), "internal implementation detail"),
+    rustc_attr!(
+        rustc_allow_const_fn_ptr, Whitelisted, template!(Word),
+        "internal implementation detail",
+    ),
+    rustc_attr!(rustc_dummy, Normal, template!(Word /* doesn't matter*/), "used by the test suite"),
 
     // FIXME: #14408 whitelist docs since rustdoc looks at them
     (
@@ -639,35 +525,25 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     (sym::proc_macro_attribute, Normal, template!(Word), Ungated),
     (sym::proc_macro, Normal, template!(Word), Ungated),
 
-    (sym::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable,
-                                            sym::rustc_attrs,
-                                            "used internally by rustc",
-                                            cfg_fn!(rustc_attrs))),
+    rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), "used internally by rustc"),
 
     (sym::allow_fail, Normal, template!(Word), Gated(Stability::Unstable,
                                 sym::allow_fail,
                                 "allow_fail attribute is currently unstable",
                                 cfg_fn!(allow_fail))),
 
-    (sym::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::rustc_attrs,
-                                    "this is an internal attribute that will \
-                                    never be stable",
-                                    cfg_fn!(rustc_attrs))),
-
+    rustc_attr!(
+        rustc_std_internal_symbol, Whitelisted, template!(Word),
+        "this is an internal attribute that will never be stable",
+    ),
     // whitelists "identity-like" conversion methods to suggest on type mismatch
-    (sym::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                                    sym::rustc_attrs,
-                                                    "this is an internal attribute that will \
-                                                        never be stable",
-                                                    cfg_fn!(rustc_attrs))),
-
-    (
-        sym::rustc_args_required_const,
-        Whitelisted,
-        template!(List: "N"),
-        Gated(Stability::Unstable, sym::rustc_attrs, "never will be stable",
-           cfg_fn!(rustc_attrs))
+    rustc_attr!(
+        rustc_conversion_suggestion, Whitelisted, template!(Word),
+        "this is an internal attribute that will never be stable",
+    ),
+    rustc_attr!(
+        rustc_args_required_const, Whitelisted, template!(List: "N"),
+        "this is an internal attribute that will never be stable",
     ),
     // RFC 2070
     (sym::panic_handler, Normal, template!(Word), Ungated),

From 584388c4aac430fbf41114d94b9c6debfe191e62 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 22 Aug 2019 20:40:50 +0200
Subject: [PATCH 152/943] builtin_attrs.rs: cleanup with `(un)gated!`.

---
 src/libsyntax/feature_gate/builtin_attrs.rs | 517 +++++++++-----------
 1 file changed, 229 insertions(+), 288 deletions(-)

diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index ad2e6a3feac6f..3188e92ed78d5 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -128,17 +128,32 @@ macro_rules! template {
     } };
 }
 
+macro_rules! ungated {
+    ($attr:ident, $typ:expr, $tpl:expr $(,)?) => {
+        (sym::$attr, $typ, $tpl, Ungated)
+    };
+}
+
+macro_rules! gated {
+    ($attr:ident, $typ:expr, $tpl:expr, $gate:ident, $msg:expr $(,)?) => {
+        (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate)))
+    };
+    ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => {
+        (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr)))
+    };
+}
+
 macro_rules! rustc_attr {
-    (TEST, $gate:ident, $typ:expr, $tpl:expr $(,)?) => {
+    (TEST, $attr:ident, $typ:expr, $tpl:expr $(,)?) => {
         rustc_attr!(
-            $gate, $typ, $tpl,
-            concat!("the `#[", stringify!($gate), "]` attribute is just used for rustc unit tests \
+            $attr, $typ, $tpl,
+            concat!("the `#[", stringify!($attr), "]` attribute is just used for rustc unit tests \
                 and will never be stable",
             ),
         )
     };
-    ($gate:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => {
-        (sym::$gate, $typ, $tpl,
+    ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => {
+        (sym::$attr, $typ, $tpl,
          Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs)))
     };
 }
@@ -149,145 +164,106 @@ pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, Attribute
 pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // Normal attributes
 
-    (
-        sym::warn,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
-    ),
-    (
-        sym::allow,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
+    ungated!(warn, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
+    ungated!(allow, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
+    ungated!(forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
+    ungated!(deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
+
+    ungated!(macro_use, Normal, template!(Word, List: "name1, name2, ...")),
+    ungated!(macro_export, Normal, template!(Word, List: "local_inner_macros")),
+    ungated!(plugin_registrar, Normal, template!(Word)),
+
+    ungated!(cfg, Normal, template!(List: "predicate")),
+    ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ...")),
+    ungated!(main, Normal, template!(Word)),
+    ungated!(start, Normal, template!(Word)),
+    ungated!(repr, Normal, template!(List: "C, packed, ...")),
+    ungated!(path, Normal, template!(NameValueStr: "file")),
+    ungated!(automatically_derived, Normal, template!(Word)),
+    ungated!(no_mangle, Whitelisted, template!(Word)),
+    ungated!(no_link, Normal, template!(Word)),
+    ungated!(derive, Normal, template!(List: "Trait1, Trait2, ...")),
+    ungated!(
+        should_panic, Normal,
+        template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"),
     ),
-    (
-        sym::forbid,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
+    ungated!(ignore, Normal, template!(Word, NameValueStr: "reason")),
+    ungated!(no_implicit_prelude, Normal, template!(Word)),
+    ungated!(reexport_test_harness_main, Normal, template!(NameValueStr: "name")),
+    gated!(
+        link_args, Normal, template!(NameValueStr: "args"),
+        "the `link_args` attribute is experimental and not portable across platforms, \
+        it is recommended to use `#[link(name = \"foo\")] instead",
     ),
-    (
-        sym::deny,
-        Normal,
-        template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
-        Ungated
-    ),
-
-    (sym::macro_use, Normal, template!(Word, List: "name1, name2, ..."), Ungated),
-    (sym::macro_export, Normal, template!(Word, List: "local_inner_macros"), Ungated),
-    (sym::plugin_registrar, Normal, template!(Word), Ungated),
-
-    (sym::cfg, Normal, template!(List: "predicate"), Ungated),
-    (sym::cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), Ungated),
-    (sym::main, Normal, template!(Word), Ungated),
-    (sym::start, Normal, template!(Word), Ungated),
-    (sym::repr, Normal, template!(List: "C, packed, ..."), Ungated),
-    (sym::path, Normal, template!(NameValueStr: "file"), Ungated),
-    (sym::automatically_derived, Normal, template!(Word), Ungated),
-    (sym::no_mangle, Whitelisted, template!(Word), Ungated),
-    (sym::no_link, Normal, template!(Word), Ungated),
-    (sym::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated),
-    (
-        sym::should_panic,
-        Normal,
-        template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"),
-        Ungated
-    ),
-    (sym::ignore, Normal, template!(Word, NameValueStr: "reason"), Ungated),
-    (sym::no_implicit_prelude, Normal, template!(Word), Ungated),
-    (sym::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated),
-    (sym::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable,
-                                sym::link_args,
-                                "the `link_args` attribute is experimental and not \
-                                portable across platforms, it is recommended to \
-                                use `#[link(name = \"foo\")] instead",
-                                cfg_fn!(link_args))),
-    (sym::macro_escape, Normal, template!(Word), Ungated),
+    ungated!(macro_escape, Normal, template!(Word)),
 
     // RFC #1445.
-    (sym::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::structural_match,
-                                            "the semantics of constant patterns is \
-                                            not yet settled",
-                                            cfg_fn!(structural_match))),
+    gated!(
+        structural_match, Whitelisted, template!(Word),
+        "the semantics of constant patterns is not yet settled",
+    ),
 
     // RFC #2008
-    (sym::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::non_exhaustive,
-                                        "non exhaustive is an experimental feature",
-                                        cfg_fn!(non_exhaustive))),
+    gated!(
+        non_exhaustive, Whitelisted, template!(Word),
+        "non exhaustive is an experimental feature",
+    ),
 
     // RFC #1268
-    (sym::marker, Normal, template!(Word), Gated(Stability::Unstable,
-                            sym::marker_trait_attr,
-                            "marker traits is an experimental feature",
-                            cfg_fn!(marker_trait_attr))),
-
-    (sym::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable,
-                                sym::plugin,
-                                "compiler plugins are experimental \
-                                and possibly buggy",
-                                cfg_fn!(plugin))),
-
-    (sym::no_std, CrateLevel, template!(Word), Ungated),
-    (sym::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable,
-                                sym::no_core,
-                                "no_core is experimental",
-                                cfg_fn!(no_core))),
-    (sym::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable,
-                        sym::lang_items,
-                        "language items are subject to change",
-                        cfg_fn!(lang_items))),
-    (sym::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
-                                Gated(Stability::Unstable,
-                                sym::linkage,
-                                "the `linkage` attribute is experimental \
-                                    and not portable across platforms",
-                                cfg_fn!(linkage))),
-    (sym::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::thread_local,
-                                        "`#[thread_local]` is an experimental feature, and does \
-                                         not currently handle destructors",
-                                        cfg_fn!(thread_local))),
-
-    (sym::rustc_on_unimplemented, Whitelisted, template!(List:
-                        r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
-                        NameValueStr: "message"),
-                                            Gated(Stability::Unstable,
-                                            sym::on_unimplemented,
-                                            "the `#[rustc_on_unimplemented]` attribute \
-                                            is an experimental feature",
-                                            cfg_fn!(on_unimplemented))),
-    (sym::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
-                                            Gated(Stability::Unstable,
-                                            sym::rustc_const_unstable,
-                                            "the `#[rustc_const_unstable]` attribute \
-                                            is an internal feature",
-                                            cfg_fn!(rustc_const_unstable))),
-    (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::allocator_internals,
-                                            "the `#[default_lib_allocator]` \
-                                            attribute is an experimental feature",
-                                            cfg_fn!(allocator_internals))),
-    (sym::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable,
-                                    sym::allocator_internals,
-                                    "the `#[needs_allocator]` \
-                                    attribute is an experimental \
-                                    feature",
-                                    cfg_fn!(allocator_internals))),
-    (sym::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::panic_runtime,
-                                        "the `#[panic_runtime]` attribute is \
-                                        an experimental feature",
-                                        cfg_fn!(panic_runtime))),
-    (sym::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::needs_panic_runtime,
-                                            "the `#[needs_panic_runtime]` \
-                                                attribute is an experimental \
-                                                feature",
-                                            cfg_fn!(needs_panic_runtime))),
+    gated!(
+        marker, Normal, template!(Word), marker_trait_attr,
+        "marker traits is an experimental feature",
+    ),
+
+    gated!(
+        plugin, CrateLevel, template!(List: "name|name(args)"),
+        "compiler plugins are experimental and possibly buggy",
+    ),
+
+    ungated!(no_std, CrateLevel, template!(Word)),
+    gated!(no_core, CrateLevel, template!(Word), "no_core is experimental"),
+    gated!(
+        lang, Normal, template!(NameValueStr: "name"), lang_items,
+        "language items are subject to change",
+    ),
+    gated!(
+        linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
+        "the `linkage` attribute is experimental and not portable across platforms",
+    ),
+    gated!(
+        thread_local, Whitelisted, template!(Word),
+        "`#[thread_local]` is an experimental feature, and does not currently handle destructors",
+    ),
 
+    gated!(
+        rustc_on_unimplemented, Whitelisted,
+        template!(
+            List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
+            NameValueStr: "message"
+        ),
+        on_unimplemented,
+        "the `#[rustc_on_unimplemented]` attribute is an experimental feature",
+    ),
+    gated!(
+        rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
+        "the `#[rustc_const_unstable]` attribute is an internal feature",
+    ),
+    gated!(
+        default_lib_allocator, Whitelisted, template!(Word), allocator_internals,
+        "the `#[default_lib_allocator]` attribute is an experimental feature",
+    ),
+    gated!(
+        needs_allocator, Normal, template!(Word), allocator_internals,
+        "the `#[needs_allocator]` attribute is an experimental feature",
+    ),
+    gated!(
+        panic_runtime, Whitelisted, template!(Word),
+        "the `#[panic_runtime]` attribute is an experimental feature",
+    ),
+    gated!(
+        needs_panic_runtime, Whitelisted, template!(Word),
+        "the `#[needs_panic_runtime]` attribute is an experimental feature",
+    ),
     rustc_attr!(TEST, rustc_outlives, Normal, template!(Word)),
     rustc_attr!(TEST, rustc_variance, Normal, template!(Word)),
     rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")),
@@ -359,47 +335,38 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         template!(NameValueStr: "transparent|semitransparent|opaque"),
         "used internally for testing macro hygiene",
     ),
-    (sym::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::compiler_builtins,
-                                            "the `#[compiler_builtins]` attribute is used to \
-                                            identify the `compiler_builtins` crate which \
-                                            contains compiler-rt intrinsics and will never be \
-                                            stable",
-                                        cfg_fn!(compiler_builtins))),
-    (sym::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::sanitizer_runtime,
-                                            "the `#[sanitizer_runtime]` attribute is used to \
-                                            identify crates that contain the runtime of a \
-                                            sanitizer and will never be stable",
-                                            cfg_fn!(sanitizer_runtime))),
-    (sym::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                            sym::profiler_runtime,
-                                            "the `#[profiler_runtime]` attribute is used to \
-                                            identify the `profiler_builtins` crate which \
-                                            contains the profiler runtime and will never be \
-                                            stable",
-                                            cfg_fn!(profiler_runtime))),
-
-    (sym::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
-                                            Gated(Stability::Unstable,
-                                            sym::allow_internal_unstable,
-                                            EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
-                                            cfg_fn!(allow_internal_unstable))),
-
-    (sym::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable,
-                                            sym::allow_internal_unsafe,
-                                            EXPLAIN_ALLOW_INTERNAL_UNSAFE,
-                                            cfg_fn!(allow_internal_unsafe))),
-
-    (sym::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                    sym::fundamental,
-                                    "the `#[fundamental]` attribute \
-                                        is an experimental feature",
-                                    cfg_fn!(fundamental))),
-
-    (sym::proc_macro_derive, Normal, template!(List: "TraitName, \
-                                                /*opt*/ attributes(name1, name2, ...)"),
-                                    Ungated),
+
+    gated!(
+        compiler_builtins, Whitelisted, template!(Word),
+        "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
+        which contains compiler-rt intrinsics and will never be stable",
+    ),
+    gated!(
+        sanitizer_runtime, Whitelisted, template!(Word),
+        "the `#[sanitizer_runtime]` attribute is used to identify crates that contain the runtime \
+        of a sanitizer and will never be stable",
+    ),
+    gated!(
+        profiler_runtime, Whitelisted, template!(Word),
+        "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \
+        which contains the profiler runtime and will never be stable",
+    ),
+
+    gated!(
+        allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
+        EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
+    ),
+    gated!(allow_internal_unsafe, Normal, template!(Word), EXPLAIN_ALLOW_INTERNAL_UNSAFE),
+
+    gated!(
+        fundamental, Whitelisted, template!(Word),
+        "the `#[fundamental]` attribute is an experimental feature",
+    ),
+
+    ungated!(
+        proc_macro_derive, Normal,
+        template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"),
+    ),
 
     rustc_attr!(rustc_allocator, Whitelisted, template!(Word), "internal implementation detail"),
     rustc_attr!(
@@ -418,119 +385,93 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     rustc_attr!(rustc_dummy, Normal, template!(Word /* doesn't matter*/), "used by the test suite"),
 
     // FIXME: #14408 whitelist docs since rustdoc looks at them
+    ungated!(doc, Whitelisted, template!(List: "hidden|inline|...", NameValueStr: "string")),
+
+    // FIXME: #14406 these are processed in codegen, which happens after the lint pass
+
+    ungated!(cold, Whitelisted, template!(Word)),
+    gated!(
+        naked, Whitelisted, template!(Word), naked_functions,
+        "the `#[naked]` attribute is an experimental feature",
+    ),
+    gated!(
+        ffi_returns_twice, Whitelisted, template!(Word),
+        "the `#[ffi_returns_twice]` attribute is an experimental feature",
+    ),
+    ungated!(target_feature, Whitelisted, template!(List: r#"enable = "name""#)),
+    ungated!(export_name, Whitelisted, template!(NameValueStr: "name")),
+    ungated!(inline, Whitelisted, template!(Word, List: "always|never")),
+    ungated!(
+        link, Whitelisted,
+        template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...""#),
+    ),
+    ungated!(link_name, Whitelisted, template!(NameValueStr: "name")),
+    ungated!(link_section, Whitelisted, template!(NameValueStr: "name")),
+    ungated!(no_builtins, Whitelisted, template!(Word)),
     (
-        sym::doc,
-        Whitelisted,
-        template!(List: "hidden|inline|...", NameValueStr: "string"),
-        Ungated
-    ),
-
-    // FIXME: #14406 these are processed in codegen, which happens after the
-    // lint pass
-    (sym::cold, Whitelisted, template!(Word), Ungated),
-    (sym::naked, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                sym::naked_functions,
-                                "the `#[naked]` attribute \
-                                is an experimental feature",
-                                cfg_fn!(naked_functions))),
-    (sym::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                sym::ffi_returns_twice,
-                                "the `#[ffi_returns_twice]` attribute \
-                                is an experimental feature",
-                                cfg_fn!(ffi_returns_twice))),
-    (sym::target_feature, Whitelisted, template!(List: r#"enable = "name""#), Ungated),
-    (sym::export_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (sym::inline, Whitelisted, template!(Word, List: "always|never"), Ungated),
-    (sym::link, Whitelisted, template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...",
-                                               /*opt*/ cfg = "...""#), Ungated),
-    (sym::link_name, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (sym::link_section, Whitelisted, template!(NameValueStr: "name"), Ungated),
-    (sym::no_builtins, Whitelisted, template!(Word), Ungated),
-    (sym::no_debug, Whitelisted, template!(Word), Gated(
-        Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None),
-        sym::no_debug,
-        "the `#[no_debug]` attribute was an experimental feature that has been \
-        deprecated due to lack of demand",
-        cfg_fn!(no_debug))),
-    (
-        sym::omit_gdb_pretty_printer_section,
-        Whitelisted,
-        template!(Word),
+        sym::no_debug, Whitelisted, template!(Word),
         Gated(
-            Stability::Unstable,
-            sym::omit_gdb_pretty_printer_section,
-            "the `#[omit_gdb_pretty_printer_section]` \
-                attribute is just used for the Rust test \
-                suite",
-            cfg_fn!(omit_gdb_pretty_printer_section)
+            Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None),
+            sym::no_debug,
+            "the `#[no_debug]` attribute was an experimental feature that has been \
+            deprecated due to lack of demand",
+            cfg_fn!(no_debug)
         )
     ),
-    (sym::may_dangle,
-    Normal,
-    template!(Word),
-    Gated(Stability::Unstable,
-        sym::dropck_eyepatch,
+    gated!(
+        omit_gdb_pretty_printer_section, Whitelisted, template!(Word),
+        "the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite",
+    ),
+    gated!(
+        may_dangle, Normal, template!(Word), dropck_eyepatch,
         "`may_dangle` has unstable semantics and may be removed in the future",
-        cfg_fn!(dropck_eyepatch))),
-    (sym::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable,
-                                sym::unwind_attributes,
-                                "`#[unwind]` is experimental",
-                                cfg_fn!(unwind_attributes))),
-    (sym::used, Whitelisted, template!(Word), Ungated),
-
-    // used in resolve
-    (sym::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable,
-                                        sym::prelude_import,
-                                        "`#[prelude_import]` is for use by rustc only",
-                                        cfg_fn!(prelude_import))),
+    ),
+    gated!(
+        unwind, Whitelisted, template!(List: "allowed|aborts"), unwind_attributes,
+        "`#[unwind]` is experimental",
+    ),
+    ungated!(used, Whitelisted, template!(Word)),
+
+    // Used in resolve:
+    gated!(
+        prelude_import, Whitelisted, template!(Word),
+        "`#[prelude_import]` is for use by rustc only",
+    ),
 
     // FIXME: #14407 these are only looked at on-demand so we can't
     // guarantee they'll have already been checked
-    (
-        sym::rustc_deprecated,
-        Whitelisted,
-        template!(List: r#"since = "version", reason = "...""#),
-        Ungated
-    ),
-    (sym::must_use, Whitelisted, template!(Word, NameValueStr: "reason"), Ungated),
-    (
-        sym::stable,
-        Whitelisted,
-        template!(List: r#"feature = "name", since = "version""#),
-        Ungated
+    ungated!(
+        rustc_deprecated, Whitelisted,
+        template!(List: r#"since = "version", reason = "...""#)
     ),
-    (
-        sym::unstable,
-        Whitelisted,
+    ungated!(must_use, Whitelisted, template!(Word, NameValueStr: "reason")),
+    ungated!(stable, Whitelisted, template!(List: r#"feature = "name", since = "version""#)),
+    ungated!(
+        unstable, Whitelisted,
         template!(List: r#"feature = "name", reason = "...", issue = "N""#),
-        Ungated
     ),
-    (sym::deprecated,
-        Normal,
+    ungated!(
+        deprecated, Normal,
         template!(
             Word,
             List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#,
             NameValueStr: "reason"
         ),
-        Ungated
     ),
 
-    (sym::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable,
-                                        sym::unboxed_closures,
-                                        "unboxed_closures are still evolving",
-                                        cfg_fn!(unboxed_closures))),
+    gated!(
+        rustc_paren_sugar, Normal, template!(Word), unboxed_closures,
+        "unboxed_closures are still evolving",
+    ),
 
-    (sym::windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console"), Ungated),
+    ungated!(windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console")),
 
-    (sym::proc_macro_attribute, Normal, template!(Word), Ungated),
-    (sym::proc_macro, Normal, template!(Word), Ungated),
+    ungated!(proc_macro_attribute, Normal, template!(Word)),
+    ungated!(proc_macro, Normal, template!(Word)),
 
     rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), "used internally by rustc"),
 
-    (sym::allow_fail, Normal, template!(Word), Gated(Stability::Unstable,
-                                sym::allow_fail,
-                                "allow_fail attribute is currently unstable",
-                                cfg_fn!(allow_fail))),
+    gated!(allow_fail, Normal, template!(Word), "allow_fail attribute is currently unstable"),
 
     rustc_attr!(
         rustc_std_internal_symbol, Whitelisted, template!(Word),
@@ -545,33 +486,33 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         rustc_args_required_const, Whitelisted, template!(List: "N"),
         "this is an internal attribute that will never be stable",
     ),
-    // RFC 2070
-    (sym::panic_handler, Normal, template!(Word), Ungated),
 
-    (sym::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable,
-                        sym::alloc_error_handler,
-                        "`#[alloc_error_handler]` is an unstable feature",
-                        cfg_fn!(alloc_error_handler))),
+    // RFC 2070
+    ungated!(panic_handler, Normal, template!(Word)),
+    gated!(
+        alloc_error_handler, Normal, template!(Word),
+        "`#[alloc_error_handler]` is an unstable feature",
+    ),
 
     // RFC 2412
-    (sym::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable,
-                            sym::optimize_attribute,
-                            "`#[optimize]` attribute is an unstable feature",
-                            cfg_fn!(optimize_attribute))),
+    gated!(
+        optimize, Whitelisted, template!(List: "size|speed"), optimize_attribute,
+        "`#[optimize]` attribute is an unstable feature",
+    ),
 
     // Crate level attributes
-    (sym::crate_name, CrateLevel, template!(NameValueStr: "name"), Ungated),
-    (sym::crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated),
-    (sym::crate_id, CrateLevel, template!(NameValueStr: "ignored"), Ungated),
-    (sym::feature, CrateLevel, template!(List: "name1, name1, ..."), Ungated),
-    (sym::no_start, CrateLevel, template!(Word), Ungated),
-    (sym::no_main, CrateLevel, template!(Word), Ungated),
-    (sym::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
-    (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated),
-    (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable,
-                    sym::custom_test_frameworks,
-                    "custom test frameworks are an unstable feature",
-                    cfg_fn!(custom_test_frameworks))),
+    ungated!(crate_name, CrateLevel, template!(NameValueStr: "name")),
+    ungated!(crate_type, CrateLevel, template!(NameValueStr: "bin|lib|...")),
+    ungated!(crate_id, CrateLevel, template!(NameValueStr: "ignored")),
+    ungated!(feature, CrateLevel, template!(List: "name1, name1, ...")),
+    ungated!(no_start, CrateLevel, template!(Word)),
+    ungated!(no_main, CrateLevel, template!(Word)),
+    ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N")),
+    ungated!(type_length_limit, CrateLevel, template!(NameValueStr: "N")),
+    gated!(
+        test_runner, CrateLevel, template!(List: "path"), custom_test_frameworks,
+        "custom test frameworks are an unstable feature",
+    ),
 ];
 
 pub fn deprecated_attributes() -> Vec<&'static BuiltinAttribute> {

From d286fe0b8d33175cf89c1bc92717bc3bff857420 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 22 Aug 2019 23:30:59 +0200
Subject: [PATCH 153/943] builtin_attrs.rs: organize!

---
 src/libsyntax/feature_gate/builtin_attrs.rs | 500 ++++++++++----------
 1 file changed, 259 insertions(+), 241 deletions(-)

diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index 3188e92ed78d5..293e63c4c16db 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -158,184 +158,215 @@ macro_rules! rustc_attr {
     };
 }
 
+macro_rules! experimental {
+    ($attr:ident) => {
+        concat!("the `#[", stringify!($attr), "]` attribute is an experimental feature")
+    }
+}
+
+const IMPL_DETAIL: &str = "internal implementation detail";
+const INTERAL_UNSTABLE: &str = "this is an internal attribute that will never be stable";
+
 pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
 
 /// Attributes that have a special meaning to rustc or rustdoc
 pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
-    // Normal attributes
+    // ==========================================================================
+    // Stable attributes:
+    // ==========================================================================
+
+    // Condtional compilation:
+    ungated!(cfg, Normal, template!(List: "predicate")),
+    ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ...")),
 
+    // Testing:
+    ungated!(ignore, Normal, template!(Word, NameValueStr: "reason")),
+    ungated!(
+        should_panic, Normal,
+        template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"),
+    ),
+    // FIXME(Centril): This can be used on stable but shouldn't.
+    ungated!(reexport_test_harness_main, Normal, template!(NameValueStr: "name")),
+
+    // Macros:
+    ungated!(derive, Normal, template!(List: "Trait1, Trait2, ...")),
+    ungated!(automatically_derived, Normal, template!(Word)),
+    ungated!(macro_use, Normal, template!(Word, List: "name1, name2, ...")),
+    ungated!(macro_escape, Normal, template!(Word)), // Deprecated synonym for `macro_use`.
+    ungated!(macro_export, Normal, template!(Word, List: "local_inner_macros")),
+    ungated!(proc_macro, Normal, template!(Word)),
+    ungated!(
+        proc_macro_derive, Normal,
+        template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"),
+    ),
+    ungated!(proc_macro_attribute, Normal, template!(Word)),
+
+    // Lints:
     ungated!(warn, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
     ungated!(allow, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
     ungated!(forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
     ungated!(deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
+    ungated!(must_use, Whitelisted, template!(Word, NameValueStr: "reason")),
+    ungated!(
+        deprecated, Normal,
+        template!(
+            Word,
+            List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#,
+            NameValueStr: "reason"
+        ),
+    ),
 
-    ungated!(macro_use, Normal, template!(Word, List: "name1, name2, ...")),
-    ungated!(macro_export, Normal, template!(Word, List: "local_inner_macros")),
-    ungated!(plugin_registrar, Normal, template!(Word)),
+    // Crate properties:
+    ungated!(crate_name, CrateLevel, template!(NameValueStr: "name")),
+    ungated!(crate_type, CrateLevel, template!(NameValueStr: "bin|lib|...")),
+    ungated!(crate_id, CrateLevel, template!(NameValueStr: "ignored")),
 
-    ungated!(cfg, Normal, template!(List: "predicate")),
-    ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ...")),
+    // ABI, linking, symbols, and FFI
+    ungated!(
+        link, Whitelisted,
+        template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...""#),
+    ),
+    ungated!(link_name, Whitelisted, template!(NameValueStr: "name")),
+    ungated!(no_link, Normal, template!(Word)),
+    ungated!(repr, Normal, template!(List: "C, packed, ...")),
+    ungated!(export_name, Whitelisted, template!(NameValueStr: "name")),
+    ungated!(link_section, Whitelisted, template!(NameValueStr: "name")),
+    ungated!(no_mangle, Whitelisted, template!(Word)),
+    ungated!(used, Whitelisted, template!(Word)),
+
+    // Limits:
+    ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N")),
+    ungated!(type_length_limit, CrateLevel, template!(NameValueStr: "N")),
+
+    // Entry point:
     ungated!(main, Normal, template!(Word)),
     ungated!(start, Normal, template!(Word)),
-    ungated!(repr, Normal, template!(List: "C, packed, ...")),
+    ungated!(no_start, CrateLevel, template!(Word)),
+    ungated!(no_main, CrateLevel, template!(Word)),
+
+    // Modules, prelude, and resolution:
     ungated!(path, Normal, template!(NameValueStr: "file")),
-    ungated!(automatically_derived, Normal, template!(Word)),
-    ungated!(no_mangle, Whitelisted, template!(Word)),
-    ungated!(no_link, Normal, template!(Word)),
-    ungated!(derive, Normal, template!(List: "Trait1, Trait2, ...")),
-    ungated!(
-        should_panic, Normal,
-        template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"),
-    ),
-    ungated!(ignore, Normal, template!(Word, NameValueStr: "reason")),
+    ungated!(no_std, CrateLevel, template!(Word)),
     ungated!(no_implicit_prelude, Normal, template!(Word)),
-    ungated!(reexport_test_harness_main, Normal, template!(NameValueStr: "name")),
+
+    // Runtime
+    ungated!(windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console")),
+    ungated!(panic_handler, Normal, template!(Word)), // RFC 2070
+
+    // Code generation:
+    ungated!(inline, Whitelisted, template!(Word, List: "always|never")),
+    ungated!(cold, Whitelisted, template!(Word)),
+    ungated!(no_builtins, Whitelisted, template!(Word)),
+    ungated!(target_feature, Whitelisted, template!(List: r#"enable = "name""#)),
+
+    // FIXME: #14408 whitelist docs since rustdoc looks at them
+    ungated!(doc, Whitelisted, template!(List: "hidden|inline|...", NameValueStr: "string")),
+
+    // ==========================================================================
+    // Unstable attributes:
+    // ==========================================================================
+
+    // Linking:
+    gated!(naked, Whitelisted, template!(Word), naked_functions, experimental!(naked)),
     gated!(
         link_args, Normal, template!(NameValueStr: "args"),
         "the `link_args` attribute is experimental and not portable across platforms, \
         it is recommended to use `#[link(name = \"foo\")] instead",
     ),
-    ungated!(macro_escape, Normal, template!(Word)),
 
-    // RFC #1445.
+    // Plugins:
+    ungated!(plugin_registrar, Normal, template!(Word)),
     gated!(
-        structural_match, Whitelisted, template!(Word),
-        "the semantics of constant patterns is not yet settled",
+        plugin, CrateLevel, template!(List: "name|name(args)"),
+        "compiler plugins are experimental and possibly buggy",
     ),
 
-    // RFC #2008
+    // Testing:
+    gated!(allow_fail, Normal, template!(Word), experimental!(allow_fail)),
     gated!(
-        non_exhaustive, Whitelisted, template!(Word),
-        "non exhaustive is an experimental feature",
+        test_runner, CrateLevel, template!(List: "path"), custom_test_frameworks,
+        "custom test frameworks are an unstable feature",
     ),
 
+    // RFC #2008
+    gated!(non_exhaustive, Whitelisted, template!(Word), experimental!(non_exhaustive)),
     // RFC #1268
+    gated!(marker, Normal, template!(Word), marker_trait_attr, experimental!(marker)),
     gated!(
-        marker, Normal, template!(Word), marker_trait_attr,
-        "marker traits is an experimental feature",
+        thread_local, Whitelisted, template!(Word),
+        "`#[thread_local]` is an experimental feature, and does not currently handle destructors",
     ),
-
+    gated!(no_core, CrateLevel, template!(Word), experimental!(no_core)),
+    // RFC 2412
     gated!(
-        plugin, CrateLevel, template!(List: "name|name(args)"),
-        "compiler plugins are experimental and possibly buggy",
+        optimize, Whitelisted, template!(List: "size|speed"), optimize_attribute,
+        experimental!(optimize),
     ),
 
-    ungated!(no_std, CrateLevel, template!(Word)),
-    gated!(no_core, CrateLevel, template!(Word), "no_core is experimental"),
-    gated!(
-        lang, Normal, template!(NameValueStr: "name"), lang_items,
-        "language items are subject to change",
+    gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)),
+
+    // ==========================================================================
+    // Internal attributes: Stability, deprecation, and unsafe:
+    // ==========================================================================
+
+    ungated!(feature, CrateLevel, template!(List: "name1, name1, ...")),
+    // FIXME: #14407 these are only looked at on-demand so we can't
+    // guarantee they'll have already been checked
+    ungated!(
+        rustc_deprecated, Whitelisted,
+        template!(List: r#"since = "version", reason = "...""#)
+    ),
+    ungated!(stable, Whitelisted, template!(List: r#"feature = "name", since = "version""#)),
+    ungated!(
+        unstable, Whitelisted,
+        template!(List: r#"feature = "name", reason = "...", issue = "N""#),
     ),
     gated!(
-        linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
-        "the `linkage` attribute is experimental and not portable across platforms",
+        rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
+        "the `#[rustc_const_unstable]` attribute is an internal feature",
     ),
     gated!(
-        thread_local, Whitelisted, template!(Word),
-        "`#[thread_local]` is an experimental feature, and does not currently handle destructors",
+        allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
+        EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
     ),
+    gated!(allow_internal_unsafe, Normal, template!(Word), EXPLAIN_ALLOW_INTERNAL_UNSAFE),
+
+    // ==========================================================================
+    // Internal attributes: Type system related:
+    // ==========================================================================
 
+    gated!(fundamental, Whitelisted, template!(Word), experimental!(fundamental)),
     gated!(
-        rustc_on_unimplemented, Whitelisted,
-        template!(
-            List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
-            NameValueStr: "message"
-        ),
-        on_unimplemented,
-        "the `#[rustc_on_unimplemented]` attribute is an experimental feature",
+        // RFC #1445.
+        structural_match, Whitelisted, template!(Word),
+        "the semantics of constant patterns is not yet settled",
     ),
     gated!(
-        rustc_const_unstable, Normal, template!(List: r#"feature = "name""#),
-        "the `#[rustc_const_unstable]` attribute is an internal feature",
+        may_dangle, Normal, template!(Word), dropck_eyepatch,
+        "`may_dangle` has unstable semantics and may be removed in the future",
     ),
+
+    // ==========================================================================
+    // Internal attributes: Runtime related:
+    // ==========================================================================
+
+    rustc_attr!(rustc_allocator, Whitelisted, template!(Word), IMPL_DETAIL),
+    rustc_attr!(rustc_allocator_nounwind, Whitelisted, template!(Word), IMPL_DETAIL),
+    gated!(alloc_error_handler, Normal, template!(Word), experimental!(alloc_error_handler)),
     gated!(
         default_lib_allocator, Whitelisted, template!(Word), allocator_internals,
-        "the `#[default_lib_allocator]` attribute is an experimental feature",
+        experimental!(default_lib_allocator),
     ),
     gated!(
         needs_allocator, Normal, template!(Word), allocator_internals,
-        "the `#[needs_allocator]` attribute is an experimental feature",
+        experimental!(needs_allocator),
     ),
+    gated!(panic_runtime, Whitelisted, template!(Word), experimental!(panic_runtime)),
+    gated!(needs_panic_runtime, Whitelisted, template!(Word), experimental!(needs_panic_runtime)),
     gated!(
-        panic_runtime, Whitelisted, template!(Word),
-        "the `#[panic_runtime]` attribute is an experimental feature",
-    ),
-    gated!(
-        needs_panic_runtime, Whitelisted, template!(Word),
-        "the `#[needs_panic_runtime]` attribute is an experimental feature",
-    ),
-    rustc_attr!(TEST, rustc_outlives, Normal, template!(Word)),
-    rustc_attr!(TEST, rustc_variance, Normal, template!(Word)),
-    rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")),
-    rustc_attr!(
-        rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
-        "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \
-        niche optimizations in libcore and will never be stable",
-    ),
-    rustc_attr!(
-        rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
-        "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
-        niche optimizations in libcore and will never be stable",
-    ),
-    rustc_attr!(
-        rustc_nonnull_optimization_guaranteed, Whitelisted, template!(Word),
-        "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \
-        niche optimizations in libcore and will never be stable",
-    ),
-    rustc_attr!(TEST, rustc_regions, Normal, template!(Word)),
-    rustc_attr!(TEST, rustc_error, Whitelisted, template!(Word)),
-    rustc_attr!(TEST, rustc_dump_user_substs, Whitelisted, template!(Word)),
-    rustc_attr!(TEST, rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode")),
-    rustc_attr!(TEST, rustc_then_this_would_need, Whitelisted, template!(List: "DepNode")),
-    rustc_attr!(
-        TEST, rustc_dirty, Whitelisted,
-        template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
-    ),
-    rustc_attr!(
-        TEST, rustc_clean, Whitelisted,
-        template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
-    ),
-    rustc_attr!(
-        TEST, rustc_partition_reused, Whitelisted,
-        template!(List: r#"cfg = "...", module = "...""#),
-    ),
-    rustc_attr!(
-        TEST, rustc_partition_codegened, Whitelisted,
-        template!(List: r#"cfg = "...", module = "...""#),
-    ),
-    rustc_attr!(
-        TEST, rustc_expected_cgu_reuse, Whitelisted,
-        template!(List: r#"cfg = "...", module = "...", kind = "...""#),
-    ),
-    rustc_attr!(TEST, rustc_synthetic, Whitelisted, template!(Word)),
-    rustc_attr!(
-        rustc_symbol_name, Whitelisted, template!(Word),
-        "internal rustc attributes will never be stable",
-    ),
-    rustc_attr!(
-        rustc_def_path, Whitelisted, template!(Word),
-        "internal rustc attributes will never be stable",
-    ),
-    rustc_attr!(TEST, rustc_mir, Whitelisted, template!(List: "arg1, arg2, ...")),
-    rustc_attr!(
-        rustc_inherit_overflow_checks, Whitelisted, template!(Word),
-        "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \
-        overflow checking behavior of several libcore functions that are inlined \
-        across crates and will never be stable",
-    ),
-    rustc_attr!(TEST, rustc_dump_program_clauses, Whitelisted, template!(Word)),
-    rustc_attr!(TEST, rustc_dump_env_program_clauses, Whitelisted, template!(Word)),
-    rustc_attr!(TEST, rustc_object_lifetime_default, Whitelisted, template!(Word)),
-    rustc_attr!(
-        rustc_test_marker, Normal, template!(Word),
-        "the `#[rustc_test_marker]` attribute is used internally to track tests",
-    ),
-    rustc_attr!(
-        rustc_macro_transparency, Whitelisted,
-        template!(NameValueStr: "transparent|semitransparent|opaque"),
-        "used internally for testing macro hygiene",
+        unwind, Whitelisted, template!(List: "allowed|aborts"), unwind_attributes,
+        experimental!(unwind),
     ),
-
     gated!(
         compiler_builtins, Whitelisted, template!(Word),
         "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \
@@ -352,62 +383,80 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         which contains the profiler runtime and will never be stable",
     ),
 
+    // ==========================================================================
+    // Internal attributes, Linkage:
+    // ==========================================================================
+
     gated!(
-        allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."),
-        EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
+        linkage, Whitelisted, template!(NameValueStr: "external|internal|..."),
+        "the `linkage` attribute is experimental and not portable across platforms",
     ),
-    gated!(allow_internal_unsafe, Normal, template!(Word), EXPLAIN_ALLOW_INTERNAL_UNSAFE),
+    rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERAL_UNSTABLE),
 
-    gated!(
-        fundamental, Whitelisted, template!(Word),
-        "the `#[fundamental]` attribute is an experimental feature",
+    // ==========================================================================
+    // Internal attributes, Macro related:
+    // ==========================================================================
+
+    rustc_attr!(rustc_builtin_macro, Whitelisted, template!(Word), IMPL_DETAIL),
+    rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERAL_UNSTABLE),
+    rustc_attr!(
+        rustc_macro_transparency, Whitelisted,
+        template!(NameValueStr: "transparent|semitransparent|opaque"),
+        "used internally for testing macro hygiene",
     ),
 
-    ungated!(
-        proc_macro_derive, Normal,
-        template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"),
+    // ==========================================================================
+    // Internal attributes, Diagnostics related:
+    // ==========================================================================
+
+    gated!(
+        rustc_on_unimplemented, Whitelisted,
+        template!(
+            List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#,
+            NameValueStr: "message"
+        ),
+        on_unimplemented,
+        experimental!(rustc_on_unimplemented),
     ),
+    // Whitelists "identity-like" conversion methods to suggest on type mismatch.
+    rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERAL_UNSTABLE),
+
+    // ==========================================================================
+    // Internal attributes, Const related:
+    // ==========================================================================
+
+    rustc_attr!(rustc_promotable, Whitelisted, template!(Word), IMPL_DETAIL),
+    rustc_attr!(rustc_allow_const_fn_ptr, Whitelisted, template!(Word), IMPL_DETAIL),
+    rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERAL_UNSTABLE),
+
+    // ==========================================================================
+    // Internal attributes, Layout related:
+    // ==========================================================================
 
-    rustc_attr!(rustc_allocator, Whitelisted, template!(Word), "internal implementation detail"),
     rustc_attr!(
-        rustc_allocator_nounwind, Whitelisted, template!(Word),
-        "internal implementation detail",
+        rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"),
+        "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \
+        niche optimizations in libcore and will never be stable",
     ),
     rustc_attr!(
-        rustc_builtin_macro, Whitelisted, template!(Word),
-        "internal implementation detail"
+        rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"),
+        "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \
+        niche optimizations in libcore and will never be stable",
     ),
-    rustc_attr!(rustc_promotable, Whitelisted, template!(Word), "internal implementation detail"),
     rustc_attr!(
-        rustc_allow_const_fn_ptr, Whitelisted, template!(Word),
-        "internal implementation detail",
+        rustc_nonnull_optimization_guaranteed, Whitelisted, template!(Word),
+        "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \
+        niche optimizations in libcore and will never be stable",
     ),
-    rustc_attr!(rustc_dummy, Normal, template!(Word /* doesn't matter*/), "used by the test suite"),
 
-    // FIXME: #14408 whitelist docs since rustdoc looks at them
-    ungated!(doc, Whitelisted, template!(List: "hidden|inline|...", NameValueStr: "string")),
-
-    // FIXME: #14406 these are processed in codegen, which happens after the lint pass
+    // ==========================================================================
+    // Internal attributes, Misc:
+    // ==========================================================================
 
-    ungated!(cold, Whitelisted, template!(Word)),
     gated!(
-        naked, Whitelisted, template!(Word), naked_functions,
-        "the `#[naked]` attribute is an experimental feature",
-    ),
-    gated!(
-        ffi_returns_twice, Whitelisted, template!(Word),
-        "the `#[ffi_returns_twice]` attribute is an experimental feature",
-    ),
-    ungated!(target_feature, Whitelisted, template!(List: r#"enable = "name""#)),
-    ungated!(export_name, Whitelisted, template!(NameValueStr: "name")),
-    ungated!(inline, Whitelisted, template!(Word, List: "always|never")),
-    ungated!(
-        link, Whitelisted,
-        template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...""#),
+        lang, Normal, template!(NameValueStr: "name"), lang_items,
+        "language items are subject to change",
     ),
-    ungated!(link_name, Whitelisted, template!(NameValueStr: "name")),
-    ungated!(link_section, Whitelisted, template!(NameValueStr: "name")),
-    ungated!(no_builtins, Whitelisted, template!(Word)),
     (
         sym::no_debug, Whitelisted, template!(Word),
         Gated(
@@ -419,99 +468,68 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         )
     ),
     gated!(
-        omit_gdb_pretty_printer_section, Whitelisted, template!(Word),
-        "the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite",
-    ),
-    gated!(
-        may_dangle, Normal, template!(Word), dropck_eyepatch,
-        "`may_dangle` has unstable semantics and may be removed in the future",
-    ),
-    gated!(
-        unwind, Whitelisted, template!(List: "allowed|aborts"), unwind_attributes,
-        "`#[unwind]` is experimental",
-    ),
-    ungated!(used, Whitelisted, template!(Word)),
-
-    // Used in resolve:
-    gated!(
+        // Used in resolve:
         prelude_import, Whitelisted, template!(Word),
         "`#[prelude_import]` is for use by rustc only",
     ),
-
-    // FIXME: #14407 these are only looked at on-demand so we can't
-    // guarantee they'll have already been checked
-    ungated!(
-        rustc_deprecated, Whitelisted,
-        template!(List: r#"since = "version", reason = "...""#)
-    ),
-    ungated!(must_use, Whitelisted, template!(Word, NameValueStr: "reason")),
-    ungated!(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"
-        ),
-    ),
-
     gated!(
         rustc_paren_sugar, Normal, template!(Word), unboxed_closures,
         "unboxed_closures are still evolving",
     ),
+    rustc_attr!(
+        rustc_inherit_overflow_checks, Whitelisted, template!(Word),
+        "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \
+        overflow checking behavior of several libcore functions that are inlined \
+        across crates and will never be stable",
+    ),
+    rustc_attr!(
+        rustc_test_marker, Normal, template!(Word),
+        "the `#[rustc_test_marker]` attribute is used internally to track tests",
+    ),
 
-    ungated!(windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console")),
-
-    ungated!(proc_macro_attribute, Normal, template!(Word)),
-    ungated!(proc_macro, Normal, template!(Word)),
-
-    rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), "used internally by rustc"),
-
-    gated!(allow_fail, Normal, template!(Word), "allow_fail attribute is currently unstable"),
+    // ==========================================================================
+    // Internal attributes, Testing:
+    // ==========================================================================
 
+    rustc_attr!(TEST, rustc_outlives, Normal, template!(Word)),
+    rustc_attr!(TEST, rustc_variance, Normal, template!(Word)),
+    rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")),
+    rustc_attr!(TEST, rustc_regions, Normal, template!(Word)),
+    rustc_attr!(TEST, rustc_error, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_dump_user_substs, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode")),
+    rustc_attr!(TEST, rustc_then_this_would_need, Whitelisted, template!(List: "DepNode")),
     rustc_attr!(
-        rustc_std_internal_symbol, Whitelisted, template!(Word),
-        "this is an internal attribute that will never be stable",
+        TEST, rustc_dirty, Whitelisted,
+        template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
     ),
-    // whitelists "identity-like" conversion methods to suggest on type mismatch
     rustc_attr!(
-        rustc_conversion_suggestion, Whitelisted, template!(Word),
-        "this is an internal attribute that will never be stable",
+        TEST, rustc_clean, Whitelisted,
+        template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#),
     ),
     rustc_attr!(
-        rustc_args_required_const, Whitelisted, template!(List: "N"),
-        "this is an internal attribute that will never be stable",
+        TEST, rustc_partition_reused, Whitelisted,
+        template!(List: r#"cfg = "...", module = "...""#),
     ),
-
-    // RFC 2070
-    ungated!(panic_handler, Normal, template!(Word)),
-    gated!(
-        alloc_error_handler, Normal, template!(Word),
-        "`#[alloc_error_handler]` is an unstable feature",
+    rustc_attr!(
+        TEST, rustc_partition_codegened, Whitelisted,
+        template!(List: r#"cfg = "...", module = "...""#),
     ),
-
-    // RFC 2412
-    gated!(
-        optimize, Whitelisted, template!(List: "size|speed"), optimize_attribute,
-        "`#[optimize]` attribute is an unstable feature",
+    rustc_attr!(
+        TEST, rustc_expected_cgu_reuse, Whitelisted,
+        template!(List: r#"cfg = "...", module = "...", kind = "...""#),
     ),
-
-    // Crate level attributes
-    ungated!(crate_name, CrateLevel, template!(NameValueStr: "name")),
-    ungated!(crate_type, CrateLevel, template!(NameValueStr: "bin|lib|...")),
-    ungated!(crate_id, CrateLevel, template!(NameValueStr: "ignored")),
-    ungated!(feature, CrateLevel, template!(List: "name1, name1, ...")),
-    ungated!(no_start, CrateLevel, template!(Word)),
-    ungated!(no_main, CrateLevel, template!(Word)),
-    ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N")),
-    ungated!(type_length_limit, CrateLevel, template!(NameValueStr: "N")),
+    rustc_attr!(TEST, rustc_synthetic, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_symbol_name, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_def_path, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_mir, Whitelisted, template!(List: "arg1, arg2, ...")),
+    rustc_attr!(TEST, rustc_dump_program_clauses, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_dump_env_program_clauses, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_object_lifetime_default, Whitelisted, template!(Word)),
+    rustc_attr!(TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/)),
     gated!(
-        test_runner, CrateLevel, template!(List: "path"), custom_test_frameworks,
-        "custom test frameworks are an unstable feature",
+        omit_gdb_pretty_printer_section, Whitelisted, template!(Word),
+        "the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite",
     ),
 ];
 

From e5aa2dd1ff73e3fc0a17a68938ffafe2d4ed0e8c Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 22 Aug 2019 23:35:03 +0200
Subject: [PATCH 154/943] builtin_attrs.rs: retain FIXMEs.

---
 src/libsyntax/feature_gate/builtin_attrs.rs | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index 293e63c4c16db..9b347711fddc5 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -191,6 +191,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // Macros:
     ungated!(derive, Normal, template!(List: "Trait1, Trait2, ...")),
     ungated!(automatically_derived, Normal, template!(Word)),
+    // FIXME(#14407)
     ungated!(macro_use, Normal, template!(Word, List: "name1, name2, ...")),
     ungated!(macro_escape, Normal, template!(Word)), // Deprecated synonym for `macro_use`.
     ungated!(macro_export, Normal, template!(Word, List: "local_inner_macros")),
@@ -207,6 +208,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ungated!(forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
     ungated!(deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)),
     ungated!(must_use, Whitelisted, template!(Word, NameValueStr: "reason")),
+    // FIXME(#14407)
     ungated!(
         deprecated, Normal,
         template!(
@@ -310,13 +312,15 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // ==========================================================================
 
     ungated!(feature, CrateLevel, template!(List: "name1, name1, ...")),
-    // FIXME: #14407 these are only looked at on-demand so we can't
-    // guarantee they'll have already been checked
+    // FIXME(#14407) -- only looked at on-demand so we can't
+    // guarantee they'll have already been checked.
     ungated!(
         rustc_deprecated, Whitelisted,
         template!(List: r#"since = "version", reason = "...""#)
     ),
+    // FIXME(#14407)
     ungated!(stable, Whitelisted, template!(List: r#"feature = "name", since = "version""#)),
+    // FIXME(#14407)
     ungated!(
         unstable, Whitelisted,
         template!(List: r#"feature = "name", reason = "...", issue = "N""#),

From 87eafd6c1b844f4258a2bbd7563c16609c4606e6 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 22 Aug 2019 23:48:08 +0200
Subject: [PATCH 155/943] syntax: extract `check.rs`.

---
 src/libsyntax/feature_gate.rs               | 958 +-------------------
 src/libsyntax/feature_gate/builtin_attrs.rs |   4 +-
 src/libsyntax/feature_gate/check.rs         | 951 +++++++++++++++++++
 3 files changed, 960 insertions(+), 953 deletions(-)
 create mode 100644 src/libsyntax/feature_gate/check.rs

diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 0e04d4c6c2309..97793bca1f589 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -13,963 +13,19 @@
 //! becomes stable.
 
 mod accepted;
-use accepted::ACCEPTED_FEATURES;
 mod removed;
-use removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
 mod active;
-use active::{ACTIVE_FEATURES};
-pub use active::{Features, INCOMPLETE_FEATURES};
 mod builtin_attrs;
+mod check;
+
+pub use active::{Features, INCOMPLETE_FEATURES};
 pub use builtin_attrs::{
     AttributeGate, AttributeType, GatedCfg,
     BuiltinAttribute, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP,
     deprecated_attributes, is_builtin_attr,  is_builtin_attr_name,
 };
-
-use crate::ast::{
-    self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind,
-    PatKind, RangeEnd,
+pub use check::{
+    check_attribute, check_crate, get_features, feature_err, emit_feature_err,
+    Stability, GateIssue, UnstableFeatures,
+    EXPLAIN_STMT_ATTR_SYNTAX, EXPLAIN_UNSIZED_TUPLE_COERCION,
 };
-use crate::attr::{self, check_builtin_attribute};
-use crate::source_map::Spanned;
-use crate::edition::{ALL_EDITIONS, Edition};
-use crate::visit::{self, FnKind, Visitor};
-use crate::parse::{token, ParseSess};
-use crate::parse::parser::Parser;
-use crate::symbol::{Symbol, sym};
-use crate::tokenstream::TokenTree;
-
-use errors::{Applicability, DiagnosticBuilder, Handler};
-use rustc_data_structures::fx::FxHashMap;
-use rustc_target::spec::abi::Abi;
-use syntax_pos::{Span, DUMMY_SP, MultiSpan};
-use log::debug;
-
-use std::env;
-
-#[derive(Copy, Clone, Debug)]
-pub enum Stability {
-    Unstable,
-    // First argument is tracking issue link; second argument is an optional
-    // help message, which defaults to "remove this attribute"
-    Deprecated(&'static str, Option<&'static str>),
-}
-
-struct Context<'a> {
-    features: &'a Features,
-    parse_sess: &'a ParseSess,
-    plugin_attributes: &'a [(Symbol, AttributeType)],
-}
-
-macro_rules! gate_feature_fn {
-    ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => {{
-        let (cx, has_feature, span,
-             name, explain, level) = ($cx, $has_feature, $span, $name, $explain, $level);
-        let has_feature: bool = has_feature(&$cx.features);
-        debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
-        if !has_feature && !span.allows_unstable($name) {
-            leveled_feature_err(cx.parse_sess, name, span, GateIssue::Language, explain, level)
-                .emit();
-        }
-    }}
-}
-
-macro_rules! gate_feature {
-    ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {
-        gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
-                         sym::$feature, $explain, GateStrength::Hard)
-    };
-    ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {
-        gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
-                         sym::$feature, $explain, $level)
-    };
-}
-
-impl<'a> Context<'a> {
-    fn check_attribute(
-        &self,
-        attr: &ast::Attribute,
-        attr_info: Option<&BuiltinAttribute>,
-        is_macro: bool
-    ) {
-        debug!("check_attribute(attr = {:?})", attr);
-        if let Some(&(name, ty, _template, ref gateage)) = attr_info {
-            if let AttributeGate::Gated(_, name, desc, ref has_feature) = *gateage {
-                if !attr.span.allows_unstable(name) {
-                    gate_feature_fn!(
-                        self, has_feature, attr.span, name, desc, GateStrength::Hard
-                    );
-                }
-            } else if name == sym::doc {
-                if let Some(content) = attr.meta_item_list() {
-                    if content.iter().any(|c| c.check_name(sym::include)) {
-                        gate_feature!(self, external_doc, attr.span,
-                            "`#[doc(include = \"...\")]` is experimental"
-                        );
-                    }
-                }
-            }
-            debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
-            return;
-        } else {
-            for segment in &attr.path.segments {
-                if segment.ident.as_str().starts_with("rustc") {
-                    let msg = "attributes starting with `rustc` are \
-                               reserved for use by the `rustc` compiler";
-                    gate_feature!(self, rustc_attrs, segment.ident.span, msg);
-                }
-            }
-        }
-        for &(n, ty) in self.plugin_attributes {
-            if attr.path == n {
-                // Plugins can't gate attributes, so we don't check for it
-                // unlike the code above; we only use this loop to
-                // short-circuit to avoid the checks below.
-                debug!("check_attribute: {:?} is registered by a plugin, {:?}", attr.path, ty);
-                return;
-            }
-        }
-        if !is_macro && !attr::is_known(attr) {
-            // Only run the custom attribute lint during regular feature gate
-            // checking. Macro gating runs before the plugin attributes are
-            // registered, so we skip this in that case.
-            let msg = format!("the attribute `{}` is currently unknown to the compiler and \
-                               may have meaning added to it in the future", attr.path);
-            gate_feature!(self, custom_attribute, attr.span, &msg);
-        }
-    }
-}
-
-pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) {
-    let cx = Context { features, parse_sess, plugin_attributes: &[] };
-    cx.check_attribute(
-        attr,
-        attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name).map(|a| *a)),
-        true
-    );
-}
-
-fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
-    if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) {
-        let issue = info.2;
-        // FIXME (#28244): enforce that active features have issue numbers
-        // assert!(issue.is_some())
-        issue
-    } else {
-        // search in Accepted, Removed, or Stable Removed features
-        let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES)
-            .find(|t| t.0 == feature);
-        match found {
-            Some(&(_, _, issue, _)) => issue,
-            None => panic!("Feature `{}` is not declared anywhere", feature),
-        }
-    }
-}
-
-pub enum GateIssue {
-    Language,
-    Library(Option<u32>)
-}
-
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub enum GateStrength {
-    /// A hard error. (Most feature gates should use this.)
-    Hard,
-    /// Only a warning. (Use this only as backwards-compatibility demands.)
-    Soft,
-}
-
-pub fn emit_feature_err(
-    sess: &ParseSess,
-    feature: Symbol,
-    span: Span,
-    issue: GateIssue,
-    explain: &str,
-) {
-    feature_err(sess, feature, span, issue, explain).emit();
-}
-
-pub fn feature_err<'a, S: Into<MultiSpan>>(
-    sess: &'a ParseSess,
-    feature: Symbol,
-    span: S,
-    issue: GateIssue,
-    explain: &str,
-) -> DiagnosticBuilder<'a> {
-    leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard)
-}
-
-fn leveled_feature_err<'a, S: Into<MultiSpan>>(
-    sess: &'a ParseSess,
-    feature: Symbol,
-    span: S,
-    issue: GateIssue,
-    explain: &str,
-    level: GateStrength,
-) -> DiagnosticBuilder<'a> {
-    let diag = &sess.span_diagnostic;
-
-    let issue = match issue {
-        GateIssue::Language => find_lang_feature_issue(feature),
-        GateIssue::Library(lib) => lib,
-    };
-
-    let mut err = match level {
-        GateStrength::Hard => {
-            diag.struct_span_err_with_code(span, explain, stringify_error_code!(E0658))
-        }
-        GateStrength::Soft => diag.struct_span_warn(span, explain),
-    };
-
-    match issue {
-        None | Some(0) => {}  // We still accept `0` as a stand-in for backwards compatibility
-        Some(n) => {
-            err.note(&format!(
-                "for more information, see https://github.com/rust-lang/rust/issues/{}",
-                n,
-            ));
-        }
-    }
-
-    // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
-    if sess.unstable_features.is_nightly_build() {
-        err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature));
-    }
-
-    // If we're on stable and only emitting a "soft" warning, add a note to
-    // clarify that the feature isn't "on" (rather than being on but
-    // warning-worthy).
-    if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft {
-        err.help("a nightly build of the compiler is required to enable this feature");
-    }
-
-    err
-
-}
-
-const EXPLAIN_BOX_SYNTAX: &str =
-    "box expression syntax is experimental; you can call `Box::new` instead";
-
-pub const EXPLAIN_STMT_ATTR_SYNTAX: &str =
-    "attributes on expressions are experimental";
-
-pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &str =
-    "allow_internal_unstable side-steps feature gating and stability checks";
-pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str =
-    "allow_internal_unsafe side-steps the unsafe_code lint";
-
-pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str =
-    "unsized tuple coercion is not stable enough for use and is subject to change";
-
-struct PostExpansionVisitor<'a> {
-    context: &'a Context<'a>,
-    builtin_attributes: &'static FxHashMap<Symbol, &'static BuiltinAttribute>,
-}
-
-macro_rules! gate_feature_post {
-    ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{
-        let (cx, span) = ($cx, $span);
-        if !span.allows_unstable(sym::$feature) {
-            gate_feature!(cx.context, $feature, span, $explain)
-        }
-    }};
-    ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{
-        let (cx, span) = ($cx, $span);
-        if !span.allows_unstable(sym::$feature) {
-            gate_feature!(cx.context, $feature, span, $explain, $level)
-        }
-    }}
-}
-
-impl<'a> PostExpansionVisitor<'a> {
-    fn check_abi(&self, abi: Abi, span: Span) {
-        match abi {
-            Abi::RustIntrinsic => {
-                gate_feature_post!(&self, intrinsics, span,
-                                   "intrinsics are subject to change");
-            },
-            Abi::PlatformIntrinsic => {
-                gate_feature_post!(&self, platform_intrinsics, span,
-                                   "platform intrinsics are experimental and possibly buggy");
-            },
-            Abi::Vectorcall => {
-                gate_feature_post!(&self, abi_vectorcall, span,
-                                   "vectorcall is experimental and subject to change");
-            },
-            Abi::Thiscall => {
-                gate_feature_post!(&self, abi_thiscall, span,
-                                   "thiscall is experimental and subject to change");
-            },
-            Abi::RustCall => {
-                gate_feature_post!(&self, unboxed_closures, span,
-                                   "rust-call ABI is subject to change");
-            },
-            Abi::PtxKernel => {
-                gate_feature_post!(&self, abi_ptx, span,
-                                   "PTX ABIs are experimental and subject to change");
-            },
-            Abi::Unadjusted => {
-                gate_feature_post!(&self, abi_unadjusted, span,
-                                   "unadjusted ABI is an implementation detail and perma-unstable");
-            },
-            Abi::Msp430Interrupt => {
-                gate_feature_post!(&self, abi_msp430_interrupt, span,
-                                   "msp430-interrupt ABI is experimental and subject to change");
-            },
-            Abi::X86Interrupt => {
-                gate_feature_post!(&self, abi_x86_interrupt, span,
-                                   "x86-interrupt ABI is experimental and subject to change");
-            },
-            Abi::AmdGpuKernel => {
-                gate_feature_post!(&self, abi_amdgpu_kernel, span,
-                                   "amdgpu-kernel ABI is experimental and subject to change");
-            },
-            // Stable
-            Abi::Cdecl |
-            Abi::Stdcall |
-            Abi::Fastcall |
-            Abi::Aapcs |
-            Abi::Win64 |
-            Abi::SysV64 |
-            Abi::Rust |
-            Abi::C |
-            Abi::System => {}
-        }
-    }
-}
-
-impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
-    fn visit_attribute(&mut self, attr: &ast::Attribute) {
-        let attr_info = attr.ident().and_then(|ident| {
-            self.builtin_attributes.get(&ident.name).map(|a| *a)
-        });
-
-        // Check for gated attributes.
-        self.context.check_attribute(attr, attr_info, false);
-
-        if attr.check_name(sym::doc) {
-            if let Some(content) = attr.meta_item_list() {
-                if content.len() == 1 && content[0].check_name(sym::cfg) {
-                    gate_feature_post!(&self, doc_cfg, attr.span,
-                        "`#[doc(cfg(...))]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::masked)) {
-                    gate_feature_post!(&self, doc_masked, attr.span,
-                        "`#[doc(masked)]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::spotlight)) {
-                    gate_feature_post!(&self, doc_spotlight, attr.span,
-                        "`#[doc(spotlight)]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::alias)) {
-                    gate_feature_post!(&self, doc_alias, attr.span,
-                        "`#[doc(alias = \"...\")]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::keyword)) {
-                    gate_feature_post!(&self, doc_keyword, attr.span,
-                        "`#[doc(keyword = \"...\")]` is experimental"
-                    );
-                }
-            }
-        }
-
-        match attr_info {
-            // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
-            Some(&(name, _, template, _)) if name != sym::rustc_dummy =>
-                check_builtin_attribute(self.context.parse_sess, attr, name, template),
-            _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
-                if token == token::Eq {
-                    // All key-value attributes are restricted to meta-item syntax.
-                    attr.parse_meta(self.context.parse_sess).map_err(|mut err| err.emit()).ok();
-                }
-            }
-        }
-    }
-
-    fn visit_name(&mut self, sp: Span, name: ast::Name) {
-        if !name.as_str().is_ascii() {
-            gate_feature_post!(
-                &self,
-                non_ascii_idents,
-                self.context.parse_sess.source_map().def_span(sp),
-                "non-ascii idents are not fully supported"
-            );
-        }
-    }
-
-    fn visit_item(&mut self, i: &'a ast::Item) {
-        match i.node {
-            ast::ItemKind::ForeignMod(ref foreign_module) => {
-                self.check_abi(foreign_module.abi, i.span);
-            }
-
-            ast::ItemKind::Fn(..) => {
-                if attr::contains_name(&i.attrs[..], sym::plugin_registrar) {
-                    gate_feature_post!(&self, plugin_registrar, i.span,
-                                       "compiler plugins are experimental and possibly buggy");
-                }
-                if attr::contains_name(&i.attrs[..], sym::start) {
-                    gate_feature_post!(&self, start, i.span,
-                                      "a `#[start]` function is an experimental \
-                                       feature whose signature may change \
-                                       over time");
-                }
-                if attr::contains_name(&i.attrs[..], sym::main) {
-                    gate_feature_post!(&self, main, i.span,
-                                       "declaration of a non-standard `#[main]` \
-                                        function may change over time, for now \
-                                        a top-level `fn main()` is required");
-                }
-            }
-
-            ast::ItemKind::Struct(..) => {
-                for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
-                    for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
-                        if item.check_name(sym::simd) {
-                            gate_feature_post!(&self, repr_simd, attr.span,
-                                               "SIMD types are experimental and possibly buggy");
-                        }
-                    }
-                }
-            }
-
-            ast::ItemKind::Enum(ast::EnumDef{ref variants, ..}, ..) => {
-                for variant in variants {
-                    match (&variant.data, &variant.disr_expr) {
-                        (ast::VariantData::Unit(..), _) => {},
-                        (_, Some(disr_expr)) =>
-                            gate_feature_post!(
-                                &self,
-                                arbitrary_enum_discriminant,
-                                disr_expr.value.span,
-                                "discriminants on non-unit variants are experimental"),
-                        _ => {},
-                    }
-                }
-
-                let has_feature = self.context.features.arbitrary_enum_discriminant;
-                if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) {
-                    Parser::maybe_report_invalid_custom_discriminants(
-                        self.context.parse_sess,
-                        &variants,
-                    );
-                }
-            }
-
-            ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => {
-                if polarity == ast::ImplPolarity::Negative {
-                    gate_feature_post!(&self, optin_builtin_traits,
-                                       i.span,
-                                       "negative trait bounds are not yet fully implemented; \
-                                        use marker types for now");
-                }
-
-                if let ast::Defaultness::Default = defaultness {
-                    gate_feature_post!(&self, specialization,
-                                       i.span,
-                                       "specialization is unstable");
-                }
-            }
-
-            ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => {
-                gate_feature_post!(&self, optin_builtin_traits,
-                                   i.span,
-                                   "auto traits are experimental and possibly buggy");
-            }
-
-            ast::ItemKind::TraitAlias(..) => {
-                gate_feature_post!(
-                    &self,
-                    trait_alias,
-                    i.span,
-                    "trait aliases are experimental"
-                );
-            }
-
-            ast::ItemKind::MacroDef(ast::MacroDef { legacy: false, .. }) => {
-                let msg = "`macro` is experimental";
-                gate_feature_post!(&self, decl_macro, i.span, msg);
-            }
-
-            ast::ItemKind::OpaqueTy(..) => {
-                gate_feature_post!(
-                    &self,
-                    type_alias_impl_trait,
-                    i.span,
-                    "`impl Trait` in type aliases is unstable"
-                );
-            }
-
-            _ => {}
-        }
-
-        visit::walk_item(self, i);
-    }
-
-    fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
-        match i.node {
-            ast::ForeignItemKind::Fn(..) |
-            ast::ForeignItemKind::Static(..) => {
-                let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name);
-                let links_to_llvm = match link_name {
-                    Some(val) => val.as_str().starts_with("llvm."),
-                    _ => false
-                };
-                if links_to_llvm {
-                    gate_feature_post!(&self, link_llvm_intrinsics, i.span,
-                                       "linking to LLVM intrinsics is experimental");
-                }
-            }
-            ast::ForeignItemKind::Ty => {
-                    gate_feature_post!(&self, extern_types, i.span,
-                                       "extern types are experimental");
-            }
-            ast::ForeignItemKind::Macro(..) => {}
-        }
-
-        visit::walk_foreign_item(self, i)
-    }
-
-    fn visit_ty(&mut self, ty: &'a ast::Ty) {
-        match ty.node {
-            ast::TyKind::BareFn(ref bare_fn_ty) => {
-                self.check_abi(bare_fn_ty.abi, ty.span);
-            }
-            ast::TyKind::Never => {
-                gate_feature_post!(&self, never_type, ty.span,
-                                   "The `!` type is experimental");
-            }
-            _ => {}
-        }
-        visit::walk_ty(self, ty)
-    }
-
-    fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) {
-        if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty {
-            if let ast::TyKind::Never = output_ty.node {
-                // Do nothing.
-            } else {
-                self.visit_ty(output_ty)
-            }
-        }
-    }
-
-    fn visit_expr(&mut self, e: &'a ast::Expr) {
-        match e.node {
-            ast::ExprKind::Box(_) => {
-                gate_feature_post!(&self, box_syntax, e.span, EXPLAIN_BOX_SYNTAX);
-            }
-            ast::ExprKind::Type(..) => {
-                // To avoid noise about type ascription in common syntax errors, only emit if it
-                // is the *only* error.
-                if self.context.parse_sess.span_diagnostic.err_count() == 0 {
-                    gate_feature_post!(&self, type_ascription, e.span,
-                                       "type ascription is experimental");
-                }
-            }
-            ast::ExprKind::TryBlock(_) => {
-                gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
-            }
-            ast::ExprKind::Block(_, opt_label) => {
-                if let Some(label) = opt_label {
-                    gate_feature_post!(&self, label_break_value, label.ident.span,
-                                    "labels on blocks are unstable");
-                }
-            }
-            _ => {}
-        }
-        visit::walk_expr(self, e)
-    }
-
-    fn visit_arm(&mut self, arm: &'a ast::Arm) {
-        visit::walk_arm(self, arm)
-    }
-
-    fn visit_pat(&mut self, pattern: &'a ast::Pat) {
-        match &pattern.node {
-            PatKind::Slice(pats) => {
-                for pat in &*pats {
-                    let span = pat.span;
-                    let inner_pat = match &pat.node {
-                        PatKind::Ident(.., Some(pat)) => pat,
-                        _ => pat,
-                    };
-                    if inner_pat.is_rest() {
-                        gate_feature_post!(
-                            &self,
-                            slice_patterns,
-                            span,
-                            "subslice patterns are unstable"
-                        );
-                    }
-                }
-            }
-            PatKind::Box(..) => {
-                gate_feature_post!(&self, box_patterns,
-                                  pattern.span,
-                                  "box pattern syntax is experimental");
-            }
-            PatKind::Range(_, _, Spanned { node: RangeEnd::Excluded, .. }) => {
-                gate_feature_post!(&self, exclusive_range_pattern, pattern.span,
-                                   "exclusive range pattern syntax is experimental");
-            }
-            _ => {}
-        }
-        visit::walk_pat(self, pattern)
-    }
-
-    fn visit_fn(&mut self,
-                fn_kind: FnKind<'a>,
-                fn_decl: &'a ast::FnDecl,
-                span: Span,
-                _node_id: NodeId) {
-        if let Some(header) = fn_kind.header() {
-            // Stability of const fn methods are covered in
-            // `visit_trait_item` and `visit_impl_item` below; this is
-            // because default methods don't pass through this point.
-            self.check_abi(header.abi, span);
-        }
-
-        if fn_decl.c_variadic {
-            gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable");
-        }
-
-        visit::walk_fn(self, fn_kind, fn_decl, span)
-    }
-
-    fn visit_generic_param(&mut self, param: &'a GenericParam) {
-        match param.kind {
-            GenericParamKind::Const { .. } =>
-                gate_feature_post!(&self, const_generics, param.ident.span,
-                    "const generics are unstable"),
-            _ => {}
-        }
-        visit::walk_generic_param(self, param)
-    }
-
-    fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) {
-        match constraint.kind {
-            AssocTyConstraintKind::Bound { .. } =>
-                gate_feature_post!(&self, associated_type_bounds, constraint.span,
-                    "associated type bounds are unstable"),
-            _ => {}
-        }
-        visit::walk_assoc_ty_constraint(self, constraint)
-    }
-
-    fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
-        match ti.node {
-            ast::TraitItemKind::Method(ref sig, ref block) => {
-                if block.is_none() {
-                    self.check_abi(sig.header.abi, ti.span);
-                }
-                if sig.decl.c_variadic {
-                    gate_feature_post!(&self, c_variadic, ti.span,
-                                       "C-variadic functions are unstable");
-                }
-                if sig.header.constness.node == ast::Constness::Const {
-                    gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable");
-                }
-            }
-            ast::TraitItemKind::Type(_, ref default) => {
-                // We use three if statements instead of something like match guards so that all
-                // of these errors can be emitted if all cases apply.
-                if default.is_some() {
-                    gate_feature_post!(&self, associated_type_defaults, ti.span,
-                                       "associated type defaults are unstable");
-                }
-                if !ti.generics.params.is_empty() {
-                    gate_feature_post!(&self, generic_associated_types, ti.span,
-                                       "generic associated types are unstable");
-                }
-                if !ti.generics.where_clause.predicates.is_empty() {
-                    gate_feature_post!(&self, generic_associated_types, ti.span,
-                                       "where clauses on associated types are unstable");
-                }
-            }
-            _ => {}
-        }
-        visit::walk_trait_item(self, ti)
-    }
-
-    fn visit_impl_item(&mut self, ii: &'a ast::ImplItem) {
-        if ii.defaultness == ast::Defaultness::Default {
-            gate_feature_post!(&self, specialization,
-                              ii.span,
-                              "specialization is unstable");
-        }
-
-        match ii.node {
-            ast::ImplItemKind::Method(..) => {}
-            ast::ImplItemKind::OpaqueTy(..) => {
-                gate_feature_post!(
-                    &self,
-                    type_alias_impl_trait,
-                    ii.span,
-                    "`impl Trait` in type aliases is unstable"
-                );
-            }
-            ast::ImplItemKind::TyAlias(_) => {
-                if !ii.generics.params.is_empty() {
-                    gate_feature_post!(&self, generic_associated_types, ii.span,
-                                       "generic associated types are unstable");
-                }
-                if !ii.generics.where_clause.predicates.is_empty() {
-                    gate_feature_post!(&self, generic_associated_types, ii.span,
-                                       "where clauses on associated types are unstable");
-                }
-            }
-            _ => {}
-        }
-        visit::walk_impl_item(self, ii)
-    }
-
-    fn visit_vis(&mut self, vis: &'a ast::Visibility) {
-        if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.node {
-            gate_feature_post!(&self, crate_visibility_modifier, vis.span,
-                               "`crate` visibility modifier is experimental");
-        }
-        visit::walk_vis(self, vis)
-    }
-}
-
-pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
-                    crate_edition: Edition, allow_features: &Option<Vec<String>>) -> Features {
-    fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
-        let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
-        if let Some(reason) = reason {
-            err.span_note(span, reason);
-        } else {
-            err.span_label(span, "feature has been removed");
-        }
-        err.emit();
-    }
-
-    let mut features = Features::new();
-    let mut edition_enabled_features = FxHashMap::default();
-
-    for &edition in ALL_EDITIONS {
-        if edition <= crate_edition {
-            // The `crate_edition` implies its respective umbrella feature-gate
-            // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
-            edition_enabled_features.insert(edition.feature_name(), edition);
-        }
-    }
-
-    for &(name, .., f_edition, set) in ACTIVE_FEATURES {
-        if let Some(f_edition) = f_edition {
-            if f_edition <= crate_edition {
-                set(&mut features, DUMMY_SP);
-                edition_enabled_features.insert(name, crate_edition);
-            }
-        }
-    }
-
-    // Process the edition umbrella feature-gates first, to ensure
-    // `edition_enabled_features` is completed before it's queried.
-    for attr in krate_attrs {
-        if !attr.check_name(sym::feature) {
-            continue
-        }
-
-        let list = match attr.meta_item_list() {
-            Some(list) => list,
-            None => continue,
-        };
-
-        for mi in list {
-            if !mi.is_word() {
-                continue;
-            }
-
-            let name = mi.name_or_empty();
-
-            if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
-                if *edition <= crate_edition {
-                    continue;
-                }
-
-                for &(name, .., f_edition, set) in ACTIVE_FEATURES {
-                    if let Some(f_edition) = f_edition {
-                        if f_edition <= *edition {
-                            // FIXME(Manishearth) there is currently no way to set
-                            // lib features by edition
-                            set(&mut features, DUMMY_SP);
-                            edition_enabled_features.insert(name, *edition);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    for attr in krate_attrs {
-        if !attr.check_name(sym::feature) {
-            continue
-        }
-
-        let list = match attr.meta_item_list() {
-            Some(list) => list,
-            None => continue,
-        };
-
-        let bad_input = |span| {
-            struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input")
-        };
-
-        for mi in list {
-            let name = match mi.ident() {
-                Some(ident) if mi.is_word() => ident.name,
-                Some(ident) => {
-                    bad_input(mi.span()).span_suggestion(
-                        mi.span(),
-                        "expected just one word",
-                        format!("{}", ident.name),
-                        Applicability::MaybeIncorrect,
-                    ).emit();
-                    continue
-                }
-                None => {
-                    bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit();
-                    continue
-                }
-            };
-
-            if let Some(edition) = edition_enabled_features.get(&name) {
-                struct_span_warn!(
-                    span_handler,
-                    mi.span(),
-                    E0705,
-                    "the feature `{}` is included in the Rust {} edition",
-                    name,
-                    edition,
-                ).emit();
-                continue;
-            }
-
-            if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) {
-                // Handled in the separate loop above.
-                continue;
-            }
-
-            let removed = REMOVED_FEATURES.iter().find(|f| name == f.0);
-            let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.0);
-            if let Some((.., reason)) = removed.or(stable_removed) {
-                feature_removed(span_handler, mi.span(), *reason);
-                continue;
-            }
-
-            if let Some((_, since, ..)) = ACCEPTED_FEATURES.iter().find(|f| name == f.0) {
-                let since = Some(Symbol::intern(since));
-                features.declared_lang_features.push((name, mi.span(), since));
-                continue;
-            }
-
-            if let Some(allowed) = allow_features.as_ref() {
-                if allowed.iter().find(|f| *f == name.as_str()).is_none() {
-                    span_err!(span_handler, mi.span(), E0725,
-                              "the feature `{}` is not in the list of allowed features",
-                              name);
-                    continue;
-                }
-            }
-
-            if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
-                set(&mut features, mi.span());
-                features.declared_lang_features.push((name, mi.span(), None));
-                continue;
-            }
-
-            features.declared_lib_features.push((name, mi.span()));
-        }
-    }
-
-    features
-}
-
-pub fn check_crate(krate: &ast::Crate,
-                   sess: &ParseSess,
-                   features: &Features,
-                   plugin_attributes: &[(Symbol, AttributeType)],
-                   unstable: UnstableFeatures) {
-    maybe_stage_features(&sess.span_diagnostic, krate, unstable);
-    let ctx = Context {
-        features,
-        parse_sess: sess,
-        plugin_attributes,
-    };
-
-    macro_rules! gate_all {
-        ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); };
-        ($spans:ident, $gate:ident, $msg:literal) => {
-            for span in &*sess.gated_spans.$spans.borrow() {
-                gate_feature!(&ctx, $gate, *span, $msg);
-            }
-        }
-    }
-
-    gate_all!(param_attrs, "attributes on function parameters are unstable");
-    gate_all!(let_chains, "`let` expressions in this position are experimental");
-    gate_all!(async_closure, "async closures are unstable");
-    gate_all!(yields, generators, "yield syntax is experimental");
-    gate_all!(or_patterns, "or-patterns syntax is experimental");
-
-    let visitor = &mut PostExpansionVisitor {
-        context: &ctx,
-        builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP,
-    };
-    visit::walk_crate(visitor, krate);
-}
-
-#[derive(Clone, Copy, Hash)]
-pub enum UnstableFeatures {
-    /// Hard errors for unstable features are active, as on beta/stable channels.
-    Disallow,
-    /// Allow features to be activated, as on nightly.
-    Allow,
-    /// Errors are bypassed for bootstrapping. This is required any time
-    /// during the build that feature-related lints are set to warn or above
-    /// because the build turns on warnings-as-errors and uses lots of unstable
-    /// features. As a result, this is always required for building Rust itself.
-    Cheat
-}
-
-impl UnstableFeatures {
-    pub fn from_environment() -> UnstableFeatures {
-        // Whether this is a feature-staged build, i.e., on the beta or stable channel
-        let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
-        // Whether we should enable unstable features for bootstrapping
-        let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok();
-        match (disable_unstable_features, bootstrap) {
-            (_, true) => UnstableFeatures::Cheat,
-            (true, _) => UnstableFeatures::Disallow,
-            (false, _) => UnstableFeatures::Allow
-        }
-    }
-
-    pub fn is_nightly_build(&self) -> bool {
-        match *self {
-            UnstableFeatures::Allow | UnstableFeatures::Cheat => true,
-            _ => false,
-        }
-    }
-}
-
-fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate,
-                        unstable: UnstableFeatures) {
-    let allow_features = match unstable {
-        UnstableFeatures::Allow => true,
-        UnstableFeatures::Disallow => false,
-        UnstableFeatures::Cheat => true
-    };
-    if !allow_features {
-        for attr in &krate.attrs {
-            if attr.check_name(sym::feature) {
-                let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)");
-                span_err!(span_handler, attr.span, E0554,
-                          "`#![feature]` may not be used on the {} release channel",
-                          release_channel);
-            }
-        }
-    }
-}
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index 9b347711fddc5..b934f2e7f64ef 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -3,8 +3,8 @@
 use AttributeType::*;
 use AttributeGate::*;
 
-use super::{emit_feature_err, GateIssue};
-use super::{Stability, EXPLAIN_ALLOW_INTERNAL_UNSAFE, EXPLAIN_ALLOW_INTERNAL_UNSTABLE};
+use super::check::{emit_feature_err, GateIssue};
+use super::check::{Stability, EXPLAIN_ALLOW_INTERNAL_UNSAFE, EXPLAIN_ALLOW_INTERNAL_UNSTABLE};
 use super::active::Features;
 
 use crate::ast;
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
new file mode 100644
index 0000000000000..d82b287b6fb05
--- /dev/null
+++ b/src/libsyntax/feature_gate/check.rs
@@ -0,0 +1,951 @@
+use super::active::{ACTIVE_FEATURES, Features};
+use super::accepted::ACCEPTED_FEATURES;
+use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
+use super::builtin_attrs::{AttributeGate, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
+
+use crate::ast::{
+    self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind,
+    PatKind, RangeEnd,
+};
+use crate::attr::{self, check_builtin_attribute};
+use crate::source_map::Spanned;
+use crate::edition::{ALL_EDITIONS, Edition};
+use crate::visit::{self, FnKind, Visitor};
+use crate::parse::{token, ParseSess};
+use crate::parse::parser::Parser;
+use crate::symbol::{Symbol, sym};
+use crate::tokenstream::TokenTree;
+
+use errors::{Applicability, DiagnosticBuilder, Handler};
+use rustc_data_structures::fx::FxHashMap;
+use rustc_target::spec::abi::Abi;
+use syntax_pos::{Span, DUMMY_SP, MultiSpan};
+use log::debug;
+
+use std::env;
+
+#[derive(Copy, Clone, Debug)]
+pub enum Stability {
+    Unstable,
+    // First argument is tracking issue link; second argument is an optional
+    // help message, which defaults to "remove this attribute"
+    Deprecated(&'static str, Option<&'static str>),
+}
+
+struct Context<'a> {
+    features: &'a Features,
+    parse_sess: &'a ParseSess,
+    plugin_attributes: &'a [(Symbol, AttributeType)],
+}
+
+macro_rules! gate_feature_fn {
+    ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => {{
+        let (cx, has_feature, span,
+             name, explain, level) = ($cx, $has_feature, $span, $name, $explain, $level);
+        let has_feature: bool = has_feature(&$cx.features);
+        debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
+        if !has_feature && !span.allows_unstable($name) {
+            leveled_feature_err(cx.parse_sess, name, span, GateIssue::Language, explain, level)
+                .emit();
+        }
+    }}
+}
+
+macro_rules! gate_feature {
+    ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {
+        gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
+                         sym::$feature, $explain, GateStrength::Hard)
+    };
+    ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {
+        gate_feature_fn!($cx, |x:&Features| x.$feature, $span,
+                         sym::$feature, $explain, $level)
+    };
+}
+
+impl<'a> Context<'a> {
+    fn check_attribute(
+        &self,
+        attr: &ast::Attribute,
+        attr_info: Option<&BuiltinAttribute>,
+        is_macro: bool
+    ) {
+        debug!("check_attribute(attr = {:?})", attr);
+        if let Some(&(name, ty, _template, ref gateage)) = attr_info {
+            if let AttributeGate::Gated(_, name, desc, ref has_feature) = *gateage {
+                if !attr.span.allows_unstable(name) {
+                    gate_feature_fn!(
+                        self, has_feature, attr.span, name, desc, GateStrength::Hard
+                    );
+                }
+            } else if name == sym::doc {
+                if let Some(content) = attr.meta_item_list() {
+                    if content.iter().any(|c| c.check_name(sym::include)) {
+                        gate_feature!(self, external_doc, attr.span,
+                            "`#[doc(include = \"...\")]` is experimental"
+                        );
+                    }
+                }
+            }
+            debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
+            return;
+        } else {
+            for segment in &attr.path.segments {
+                if segment.ident.as_str().starts_with("rustc") {
+                    let msg = "attributes starting with `rustc` are \
+                               reserved for use by the `rustc` compiler";
+                    gate_feature!(self, rustc_attrs, segment.ident.span, msg);
+                }
+            }
+        }
+        for &(n, ty) in self.plugin_attributes {
+            if attr.path == n {
+                // Plugins can't gate attributes, so we don't check for it
+                // unlike the code above; we only use this loop to
+                // short-circuit to avoid the checks below.
+                debug!("check_attribute: {:?} is registered by a plugin, {:?}", attr.path, ty);
+                return;
+            }
+        }
+        if !is_macro && !attr::is_known(attr) {
+            // Only run the custom attribute lint during regular feature gate
+            // checking. Macro gating runs before the plugin attributes are
+            // registered, so we skip this in that case.
+            let msg = format!("the attribute `{}` is currently unknown to the compiler and \
+                               may have meaning added to it in the future", attr.path);
+            gate_feature!(self, custom_attribute, attr.span, &msg);
+        }
+    }
+}
+
+pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) {
+    let cx = Context { features, parse_sess, plugin_attributes: &[] };
+    cx.check_attribute(
+        attr,
+        attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name).map(|a| *a)),
+        true
+    );
+}
+
+fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
+    if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) {
+        let issue = info.2;
+        // FIXME (#28244): enforce that active features have issue numbers
+        // assert!(issue.is_some())
+        issue
+    } else {
+        // search in Accepted, Removed, or Stable Removed features
+        let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES)
+            .find(|t| t.0 == feature);
+        match found {
+            Some(&(_, _, issue, _)) => issue,
+            None => panic!("Feature `{}` is not declared anywhere", feature),
+        }
+    }
+}
+
+pub enum GateIssue {
+    Language,
+    Library(Option<u32>)
+}
+
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub enum GateStrength {
+    /// A hard error. (Most feature gates should use this.)
+    Hard,
+    /// Only a warning. (Use this only as backwards-compatibility demands.)
+    Soft,
+}
+
+pub fn emit_feature_err(
+    sess: &ParseSess,
+    feature: Symbol,
+    span: Span,
+    issue: GateIssue,
+    explain: &str,
+) {
+    feature_err(sess, feature, span, issue, explain).emit();
+}
+
+pub fn feature_err<'a, S: Into<MultiSpan>>(
+    sess: &'a ParseSess,
+    feature: Symbol,
+    span: S,
+    issue: GateIssue,
+    explain: &str,
+) -> DiagnosticBuilder<'a> {
+    leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard)
+}
+
+fn leveled_feature_err<'a, S: Into<MultiSpan>>(
+    sess: &'a ParseSess,
+    feature: Symbol,
+    span: S,
+    issue: GateIssue,
+    explain: &str,
+    level: GateStrength,
+) -> DiagnosticBuilder<'a> {
+    let diag = &sess.span_diagnostic;
+
+    let issue = match issue {
+        GateIssue::Language => find_lang_feature_issue(feature),
+        GateIssue::Library(lib) => lib,
+    };
+
+    let mut err = match level {
+        GateStrength::Hard => {
+            diag.struct_span_err_with_code(span, explain, stringify_error_code!(E0658))
+        }
+        GateStrength::Soft => diag.struct_span_warn(span, explain),
+    };
+
+    match issue {
+        None | Some(0) => {}  // We still accept `0` as a stand-in for backwards compatibility
+        Some(n) => {
+            err.note(&format!(
+                "for more information, see https://github.com/rust-lang/rust/issues/{}",
+                n,
+            ));
+        }
+    }
+
+    // #23973: do not suggest `#![feature(...)]` if we are in beta/stable
+    if sess.unstable_features.is_nightly_build() {
+        err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature));
+    }
+
+    // If we're on stable and only emitting a "soft" warning, add a note to
+    // clarify that the feature isn't "on" (rather than being on but
+    // warning-worthy).
+    if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft {
+        err.help("a nightly build of the compiler is required to enable this feature");
+    }
+
+    err
+
+}
+
+const EXPLAIN_BOX_SYNTAX: &str =
+    "box expression syntax is experimental; you can call `Box::new` instead";
+
+pub const EXPLAIN_STMT_ATTR_SYNTAX: &str =
+    "attributes on expressions are experimental";
+
+pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &str =
+    "allow_internal_unstable side-steps feature gating and stability checks";
+pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str =
+    "allow_internal_unsafe side-steps the unsafe_code lint";
+
+pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str =
+    "unsized tuple coercion is not stable enough for use and is subject to change";
+
+struct PostExpansionVisitor<'a> {
+    context: &'a Context<'a>,
+    builtin_attributes: &'static FxHashMap<Symbol, &'static BuiltinAttribute>,
+}
+
+macro_rules! gate_feature_post {
+    ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{
+        let (cx, span) = ($cx, $span);
+        if !span.allows_unstable(sym::$feature) {
+            gate_feature!(cx.context, $feature, span, $explain)
+        }
+    }};
+    ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{
+        let (cx, span) = ($cx, $span);
+        if !span.allows_unstable(sym::$feature) {
+            gate_feature!(cx.context, $feature, span, $explain, $level)
+        }
+    }}
+}
+
+impl<'a> PostExpansionVisitor<'a> {
+    fn check_abi(&self, abi: Abi, span: Span) {
+        match abi {
+            Abi::RustIntrinsic => {
+                gate_feature_post!(&self, intrinsics, span,
+                                   "intrinsics are subject to change");
+            },
+            Abi::PlatformIntrinsic => {
+                gate_feature_post!(&self, platform_intrinsics, span,
+                                   "platform intrinsics are experimental and possibly buggy");
+            },
+            Abi::Vectorcall => {
+                gate_feature_post!(&self, abi_vectorcall, span,
+                                   "vectorcall is experimental and subject to change");
+            },
+            Abi::Thiscall => {
+                gate_feature_post!(&self, abi_thiscall, span,
+                                   "thiscall is experimental and subject to change");
+            },
+            Abi::RustCall => {
+                gate_feature_post!(&self, unboxed_closures, span,
+                                   "rust-call ABI is subject to change");
+            },
+            Abi::PtxKernel => {
+                gate_feature_post!(&self, abi_ptx, span,
+                                   "PTX ABIs are experimental and subject to change");
+            },
+            Abi::Unadjusted => {
+                gate_feature_post!(&self, abi_unadjusted, span,
+                                   "unadjusted ABI is an implementation detail and perma-unstable");
+            },
+            Abi::Msp430Interrupt => {
+                gate_feature_post!(&self, abi_msp430_interrupt, span,
+                                   "msp430-interrupt ABI is experimental and subject to change");
+            },
+            Abi::X86Interrupt => {
+                gate_feature_post!(&self, abi_x86_interrupt, span,
+                                   "x86-interrupt ABI is experimental and subject to change");
+            },
+            Abi::AmdGpuKernel => {
+                gate_feature_post!(&self, abi_amdgpu_kernel, span,
+                                   "amdgpu-kernel ABI is experimental and subject to change");
+            },
+            // Stable
+            Abi::Cdecl |
+            Abi::Stdcall |
+            Abi::Fastcall |
+            Abi::Aapcs |
+            Abi::Win64 |
+            Abi::SysV64 |
+            Abi::Rust |
+            Abi::C |
+            Abi::System => {}
+        }
+    }
+}
+
+impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
+    fn visit_attribute(&mut self, attr: &ast::Attribute) {
+        let attr_info = attr.ident().and_then(|ident| {
+            self.builtin_attributes.get(&ident.name).map(|a| *a)
+        });
+
+        // Check for gated attributes.
+        self.context.check_attribute(attr, attr_info, false);
+
+        if attr.check_name(sym::doc) {
+            if let Some(content) = attr.meta_item_list() {
+                if content.len() == 1 && content[0].check_name(sym::cfg) {
+                    gate_feature_post!(&self, doc_cfg, attr.span,
+                        "`#[doc(cfg(...))]` is experimental"
+                    );
+                } else if content.iter().any(|c| c.check_name(sym::masked)) {
+                    gate_feature_post!(&self, doc_masked, attr.span,
+                        "`#[doc(masked)]` is experimental"
+                    );
+                } else if content.iter().any(|c| c.check_name(sym::spotlight)) {
+                    gate_feature_post!(&self, doc_spotlight, attr.span,
+                        "`#[doc(spotlight)]` is experimental"
+                    );
+                } else if content.iter().any(|c| c.check_name(sym::alias)) {
+                    gate_feature_post!(&self, doc_alias, attr.span,
+                        "`#[doc(alias = \"...\")]` is experimental"
+                    );
+                } else if content.iter().any(|c| c.check_name(sym::keyword)) {
+                    gate_feature_post!(&self, doc_keyword, attr.span,
+                        "`#[doc(keyword = \"...\")]` is experimental"
+                    );
+                }
+            }
+        }
+
+        match attr_info {
+            // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
+            Some(&(name, _, template, _)) if name != sym::rustc_dummy =>
+                check_builtin_attribute(self.context.parse_sess, attr, name, template),
+            _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
+                if token == token::Eq {
+                    // All key-value attributes are restricted to meta-item syntax.
+                    attr.parse_meta(self.context.parse_sess).map_err(|mut err| err.emit()).ok();
+                }
+            }
+        }
+    }
+
+    fn visit_name(&mut self, sp: Span, name: ast::Name) {
+        if !name.as_str().is_ascii() {
+            gate_feature_post!(
+                &self,
+                non_ascii_idents,
+                self.context.parse_sess.source_map().def_span(sp),
+                "non-ascii idents are not fully supported"
+            );
+        }
+    }
+
+    fn visit_item(&mut self, i: &'a ast::Item) {
+        match i.node {
+            ast::ItemKind::ForeignMod(ref foreign_module) => {
+                self.check_abi(foreign_module.abi, i.span);
+            }
+
+            ast::ItemKind::Fn(..) => {
+                if attr::contains_name(&i.attrs[..], sym::plugin_registrar) {
+                    gate_feature_post!(&self, plugin_registrar, i.span,
+                                       "compiler plugins are experimental and possibly buggy");
+                }
+                if attr::contains_name(&i.attrs[..], sym::start) {
+                    gate_feature_post!(&self, start, i.span,
+                                      "a `#[start]` function is an experimental \
+                                       feature whose signature may change \
+                                       over time");
+                }
+                if attr::contains_name(&i.attrs[..], sym::main) {
+                    gate_feature_post!(&self, main, i.span,
+                                       "declaration of a non-standard `#[main]` \
+                                        function may change over time, for now \
+                                        a top-level `fn main()` is required");
+                }
+            }
+
+            ast::ItemKind::Struct(..) => {
+                for attr in attr::filter_by_name(&i.attrs[..], sym::repr) {
+                    for item in attr.meta_item_list().unwrap_or_else(Vec::new) {
+                        if item.check_name(sym::simd) {
+                            gate_feature_post!(&self, repr_simd, attr.span,
+                                               "SIMD types are experimental and possibly buggy");
+                        }
+                    }
+                }
+            }
+
+            ast::ItemKind::Enum(ast::EnumDef{ref variants, ..}, ..) => {
+                for variant in variants {
+                    match (&variant.data, &variant.disr_expr) {
+                        (ast::VariantData::Unit(..), _) => {},
+                        (_, Some(disr_expr)) =>
+                            gate_feature_post!(
+                                &self,
+                                arbitrary_enum_discriminant,
+                                disr_expr.value.span,
+                                "discriminants on non-unit variants are experimental"),
+                        _ => {},
+                    }
+                }
+
+                let has_feature = self.context.features.arbitrary_enum_discriminant;
+                if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) {
+                    Parser::maybe_report_invalid_custom_discriminants(
+                        self.context.parse_sess,
+                        &variants,
+                    );
+                }
+            }
+
+            ast::ItemKind::Impl(_, polarity, defaultness, ..) => {
+                if polarity == ast::ImplPolarity::Negative {
+                    gate_feature_post!(&self, optin_builtin_traits,
+                                       i.span,
+                                       "negative trait bounds are not yet fully implemented; \
+                                        use marker types for now");
+                }
+
+                if let ast::Defaultness::Default = defaultness {
+                    gate_feature_post!(&self, specialization,
+                                       i.span,
+                                       "specialization is unstable");
+                }
+            }
+
+            ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => {
+                gate_feature_post!(&self, optin_builtin_traits,
+                                   i.span,
+                                   "auto traits are experimental and possibly buggy");
+            }
+
+            ast::ItemKind::TraitAlias(..) => {
+                gate_feature_post!(
+                    &self,
+                    trait_alias,
+                    i.span,
+                    "trait aliases are experimental"
+                );
+            }
+
+            ast::ItemKind::MacroDef(ast::MacroDef { legacy: false, .. }) => {
+                let msg = "`macro` is experimental";
+                gate_feature_post!(&self, decl_macro, i.span, msg);
+            }
+
+            ast::ItemKind::OpaqueTy(..) => {
+                gate_feature_post!(
+                    &self,
+                    type_alias_impl_trait,
+                    i.span,
+                    "`impl Trait` in type aliases is unstable"
+                );
+            }
+
+            _ => {}
+        }
+
+        visit::walk_item(self, i);
+    }
+
+    fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) {
+        match i.node {
+            ast::ForeignItemKind::Fn(..) |
+            ast::ForeignItemKind::Static(..) => {
+                let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name);
+                let links_to_llvm = match link_name {
+                    Some(val) => val.as_str().starts_with("llvm."),
+                    _ => false
+                };
+                if links_to_llvm {
+                    gate_feature_post!(&self, link_llvm_intrinsics, i.span,
+                                       "linking to LLVM intrinsics is experimental");
+                }
+            }
+            ast::ForeignItemKind::Ty => {
+                    gate_feature_post!(&self, extern_types, i.span,
+                                       "extern types are experimental");
+            }
+            ast::ForeignItemKind::Macro(..) => {}
+        }
+
+        visit::walk_foreign_item(self, i)
+    }
+
+    fn visit_ty(&mut self, ty: &'a ast::Ty) {
+        match ty.node {
+            ast::TyKind::BareFn(ref bare_fn_ty) => {
+                self.check_abi(bare_fn_ty.abi, ty.span);
+            }
+            ast::TyKind::Never => {
+                gate_feature_post!(&self, never_type, ty.span,
+                                   "The `!` type is experimental");
+            }
+            _ => {}
+        }
+        visit::walk_ty(self, ty)
+    }
+
+    fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) {
+        if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty {
+            if let ast::TyKind::Never = output_ty.node {
+                // Do nothing.
+            } else {
+                self.visit_ty(output_ty)
+            }
+        }
+    }
+
+    fn visit_expr(&mut self, e: &'a ast::Expr) {
+        match e.node {
+            ast::ExprKind::Box(_) => {
+                gate_feature_post!(&self, box_syntax, e.span, EXPLAIN_BOX_SYNTAX);
+            }
+            ast::ExprKind::Type(..) => {
+                // To avoid noise about type ascription in common syntax errors, only emit if it
+                // is the *only* error.
+                if self.context.parse_sess.span_diagnostic.err_count() == 0 {
+                    gate_feature_post!(&self, type_ascription, e.span,
+                                       "type ascription is experimental");
+                }
+            }
+            ast::ExprKind::TryBlock(_) => {
+                gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
+            }
+            ast::ExprKind::Block(_, opt_label) => {
+                if let Some(label) = opt_label {
+                    gate_feature_post!(&self, label_break_value, label.ident.span,
+                                    "labels on blocks are unstable");
+                }
+            }
+            _ => {}
+        }
+        visit::walk_expr(self, e)
+    }
+
+    fn visit_arm(&mut self, arm: &'a ast::Arm) {
+        visit::walk_arm(self, arm)
+    }
+
+    fn visit_pat(&mut self, pattern: &'a ast::Pat) {
+        match &pattern.node {
+            PatKind::Slice(pats) => {
+                for pat in &*pats {
+                    let span = pat.span;
+                    let inner_pat = match &pat.node {
+                        PatKind::Ident(.., Some(pat)) => pat,
+                        _ => pat,
+                    };
+                    if inner_pat.is_rest() {
+                        gate_feature_post!(
+                            &self,
+                            slice_patterns,
+                            span,
+                            "subslice patterns are unstable"
+                        );
+                    }
+                }
+            }
+            PatKind::Box(..) => {
+                gate_feature_post!(&self, box_patterns,
+                                  pattern.span,
+                                  "box pattern syntax is experimental");
+            }
+            PatKind::Range(_, _, Spanned { node: RangeEnd::Excluded, .. }) => {
+                gate_feature_post!(&self, exclusive_range_pattern, pattern.span,
+                                   "exclusive range pattern syntax is experimental");
+            }
+            _ => {}
+        }
+        visit::walk_pat(self, pattern)
+    }
+
+    fn visit_fn(&mut self,
+                fn_kind: FnKind<'a>,
+                fn_decl: &'a ast::FnDecl,
+                span: Span,
+                _node_id: NodeId) {
+        if let Some(header) = fn_kind.header() {
+            // Stability of const fn methods are covered in
+            // `visit_trait_item` and `visit_impl_item` below; this is
+            // because default methods don't pass through this point.
+            self.check_abi(header.abi, span);
+        }
+
+        if fn_decl.c_variadic {
+            gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable");
+        }
+
+        visit::walk_fn(self, fn_kind, fn_decl, span)
+    }
+
+    fn visit_generic_param(&mut self, param: &'a GenericParam) {
+        match param.kind {
+            GenericParamKind::Const { .. } =>
+                gate_feature_post!(&self, const_generics, param.ident.span,
+                    "const generics are unstable"),
+            _ => {}
+        }
+        visit::walk_generic_param(self, param)
+    }
+
+    fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) {
+        match constraint.kind {
+            AssocTyConstraintKind::Bound { .. } =>
+                gate_feature_post!(&self, associated_type_bounds, constraint.span,
+                    "associated type bounds are unstable"),
+            _ => {}
+        }
+        visit::walk_assoc_ty_constraint(self, constraint)
+    }
+
+    fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) {
+        match ti.node {
+            ast::TraitItemKind::Method(ref sig, ref block) => {
+                if block.is_none() {
+                    self.check_abi(sig.header.abi, ti.span);
+                }
+                if sig.decl.c_variadic {
+                    gate_feature_post!(&self, c_variadic, ti.span,
+                                       "C-variadic functions are unstable");
+                }
+                if sig.header.constness.node == ast::Constness::Const {
+                    gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable");
+                }
+            }
+            ast::TraitItemKind::Type(_, ref default) => {
+                // We use three if statements instead of something like match guards so that all
+                // of these errors can be emitted if all cases apply.
+                if default.is_some() {
+                    gate_feature_post!(&self, associated_type_defaults, ti.span,
+                                       "associated type defaults are unstable");
+                }
+                if !ti.generics.params.is_empty() {
+                    gate_feature_post!(&self, generic_associated_types, ti.span,
+                                       "generic associated types are unstable");
+                }
+                if !ti.generics.where_clause.predicates.is_empty() {
+                    gate_feature_post!(&self, generic_associated_types, ti.span,
+                                       "where clauses on associated types are unstable");
+                }
+            }
+            _ => {}
+        }
+        visit::walk_trait_item(self, ti)
+    }
+
+    fn visit_impl_item(&mut self, ii: &'a ast::ImplItem) {
+        if ii.defaultness == ast::Defaultness::Default {
+            gate_feature_post!(&self, specialization,
+                              ii.span,
+                              "specialization is unstable");
+        }
+
+        match ii.node {
+            ast::ImplItemKind::Method(..) => {}
+            ast::ImplItemKind::OpaqueTy(..) => {
+                gate_feature_post!(
+                    &self,
+                    type_alias_impl_trait,
+                    ii.span,
+                    "`impl Trait` in type aliases is unstable"
+                );
+            }
+            ast::ImplItemKind::TyAlias(_) => {
+                if !ii.generics.params.is_empty() {
+                    gate_feature_post!(&self, generic_associated_types, ii.span,
+                                       "generic associated types are unstable");
+                }
+                if !ii.generics.where_clause.predicates.is_empty() {
+                    gate_feature_post!(&self, generic_associated_types, ii.span,
+                                       "where clauses on associated types are unstable");
+                }
+            }
+            _ => {}
+        }
+        visit::walk_impl_item(self, ii)
+    }
+
+    fn visit_vis(&mut self, vis: &'a ast::Visibility) {
+        if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.node {
+            gate_feature_post!(&self, crate_visibility_modifier, vis.span,
+                               "`crate` visibility modifier is experimental");
+        }
+        visit::walk_vis(self, vis)
+    }
+}
+
+pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
+                    crate_edition: Edition, allow_features: &Option<Vec<String>>) -> Features {
+    fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) {
+        let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed");
+        if let Some(reason) = reason {
+            err.span_note(span, reason);
+        } else {
+            err.span_label(span, "feature has been removed");
+        }
+        err.emit();
+    }
+
+    let mut features = Features::new();
+    let mut edition_enabled_features = FxHashMap::default();
+
+    for &edition in ALL_EDITIONS {
+        if edition <= crate_edition {
+            // The `crate_edition` implies its respective umbrella feature-gate
+            // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX).
+            edition_enabled_features.insert(edition.feature_name(), edition);
+        }
+    }
+
+    for &(name, .., f_edition, set) in ACTIVE_FEATURES {
+        if let Some(f_edition) = f_edition {
+            if f_edition <= crate_edition {
+                set(&mut features, DUMMY_SP);
+                edition_enabled_features.insert(name, crate_edition);
+            }
+        }
+    }
+
+    // Process the edition umbrella feature-gates first, to ensure
+    // `edition_enabled_features` is completed before it's queried.
+    for attr in krate_attrs {
+        if !attr.check_name(sym::feature) {
+            continue
+        }
+
+        let list = match attr.meta_item_list() {
+            Some(list) => list,
+            None => continue,
+        };
+
+        for mi in list {
+            if !mi.is_word() {
+                continue;
+            }
+
+            let name = mi.name_or_empty();
+
+            if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
+                if *edition <= crate_edition {
+                    continue;
+                }
+
+                for &(name, .., f_edition, set) in ACTIVE_FEATURES {
+                    if let Some(f_edition) = f_edition {
+                        if f_edition <= *edition {
+                            // FIXME(Manishearth) there is currently no way to set
+                            // lib features by edition
+                            set(&mut features, DUMMY_SP);
+                            edition_enabled_features.insert(name, *edition);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    for attr in krate_attrs {
+        if !attr.check_name(sym::feature) {
+            continue
+        }
+
+        let list = match attr.meta_item_list() {
+            Some(list) => list,
+            None => continue,
+        };
+
+        let bad_input = |span| {
+            struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input")
+        };
+
+        for mi in list {
+            let name = match mi.ident() {
+                Some(ident) if mi.is_word() => ident.name,
+                Some(ident) => {
+                    bad_input(mi.span()).span_suggestion(
+                        mi.span(),
+                        "expected just one word",
+                        format!("{}", ident.name),
+                        Applicability::MaybeIncorrect,
+                    ).emit();
+                    continue
+                }
+                None => {
+                    bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit();
+                    continue
+                }
+            };
+
+            if let Some(edition) = edition_enabled_features.get(&name) {
+                struct_span_warn!(
+                    span_handler,
+                    mi.span(),
+                    E0705,
+                    "the feature `{}` is included in the Rust {} edition",
+                    name,
+                    edition,
+                ).emit();
+                continue;
+            }
+
+            if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) {
+                // Handled in the separate loop above.
+                continue;
+            }
+
+            let removed = REMOVED_FEATURES.iter().find(|f| name == f.0);
+            let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.0);
+            if let Some((.., reason)) = removed.or(stable_removed) {
+                feature_removed(span_handler, mi.span(), *reason);
+                continue;
+            }
+
+            if let Some((_, since, ..)) = ACCEPTED_FEATURES.iter().find(|f| name == f.0) {
+                let since = Some(Symbol::intern(since));
+                features.declared_lang_features.push((name, mi.span(), since));
+                continue;
+            }
+
+            if let Some(allowed) = allow_features.as_ref() {
+                if allowed.iter().find(|f| *f == name.as_str()).is_none() {
+                    span_err!(span_handler, mi.span(), E0725,
+                              "the feature `{}` is not in the list of allowed features",
+                              name);
+                    continue;
+                }
+            }
+
+            if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
+                set(&mut features, mi.span());
+                features.declared_lang_features.push((name, mi.span(), None));
+                continue;
+            }
+
+            features.declared_lib_features.push((name, mi.span()));
+        }
+    }
+
+    features
+}
+
+pub fn check_crate(krate: &ast::Crate,
+                   sess: &ParseSess,
+                   features: &Features,
+                   plugin_attributes: &[(Symbol, AttributeType)],
+                   unstable: UnstableFeatures) {
+    maybe_stage_features(&sess.span_diagnostic, krate, unstable);
+    let ctx = Context {
+        features,
+        parse_sess: sess,
+        plugin_attributes,
+    };
+
+    macro_rules! gate_all {
+        ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); };
+        ($spans:ident, $gate:ident, $msg:literal) => {
+            for span in &*sess.gated_spans.$spans.borrow() {
+                gate_feature!(&ctx, $gate, *span, $msg);
+            }
+        }
+    }
+
+    gate_all!(param_attrs, "attributes on function parameters are unstable");
+    gate_all!(let_chains, "`let` expressions in this position are experimental");
+    gate_all!(async_closure, "async closures are unstable");
+    gate_all!(yields, generators, "yield syntax is experimental");
+    gate_all!(or_patterns, "or-patterns syntax is experimental");
+
+    let visitor = &mut PostExpansionVisitor {
+        context: &ctx,
+        builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP,
+    };
+    visit::walk_crate(visitor, krate);
+}
+
+#[derive(Clone, Copy, Hash)]
+pub enum UnstableFeatures {
+    /// Hard errors for unstable features are active, as on beta/stable channels.
+    Disallow,
+    /// Allow features to be activated, as on nightly.
+    Allow,
+    /// Errors are bypassed for bootstrapping. This is required any time
+    /// during the build that feature-related lints are set to warn or above
+    /// because the build turns on warnings-as-errors and uses lots of unstable
+    /// features. As a result, this is always required for building Rust itself.
+    Cheat
+}
+
+impl UnstableFeatures {
+    pub fn from_environment() -> UnstableFeatures {
+        // Whether this is a feature-staged build, i.e., on the beta or stable channel
+        let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
+        // Whether we should enable unstable features for bootstrapping
+        let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok();
+        match (disable_unstable_features, bootstrap) {
+            (_, true) => UnstableFeatures::Cheat,
+            (true, _) => UnstableFeatures::Disallow,
+            (false, _) => UnstableFeatures::Allow
+        }
+    }
+
+    pub fn is_nightly_build(&self) -> bool {
+        match *self {
+            UnstableFeatures::Allow | UnstableFeatures::Cheat => true,
+            _ => false,
+        }
+    }
+}
+
+fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate, unstable: UnstableFeatures) {
+    let allow_features = match unstable {
+        UnstableFeatures::Allow => true,
+        UnstableFeatures::Disallow => false,
+        UnstableFeatures::Cheat => true
+    };
+    if !allow_features {
+        for attr in &krate.attrs {
+            if attr.check_name(sym::feature) {
+                let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)");
+                span_err!(span_handler, attr.span, E0554,
+                          "`#![feature]` may not be used on the {} release channel",
+                          release_channel);
+            }
+        }
+    }
+}

From 6febb75ec8e0aeade9be97a1224bd6327b531524 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 22 Aug 2019 23:49:55 +0200
Subject: [PATCH 156/943] syntax: move `feature_gate.rs`.

---
 src/libsyntax/{feature_gate.rs => feature_gate/mod.rs} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename src/libsyntax/{feature_gate.rs => feature_gate/mod.rs} (100%)

diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate/mod.rs
similarity index 100%
rename from src/libsyntax/feature_gate.rs
rename to src/libsyntax/feature_gate/mod.rs

From 3cfb6bc73a429a67f87c6542de2b8f9395cf4b94 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Fri, 23 Aug 2019 00:06:32 +0200
Subject: [PATCH 157/943] Fix `tidy` fallout due to `feature_gate.rs`
 refactoring.

---
 src/tools/tidy/src/features.rs | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 88a469ef9550c..468e56001012f 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -221,7 +221,14 @@ fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool {
 }
 
 pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features {
-    let contents = t!(fs::read_to_string(base_src_path.join("libsyntax/feature_gate.rs")));
+    let mut all = collect_lang_features_in(base_src_path, "active.rs", bad);
+    all.extend(collect_lang_features_in(base_src_path, "accepted.rs", bad));
+    all.extend(collect_lang_features_in(base_src_path, "removed.rs", bad));
+    all
+}
+
+fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features {
+    let contents = t!(fs::read_to_string(base.join("libsyntax/feature_gate").join(file)));
 
     // We allow rustc-internal features to omit a tracking issue.
     // To make tidy accept omitting a tracking issue, group the list of features

From 3e061f7c495138767a0f21ac6a56d81a9faf573d Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Fri, 23 Aug 2019 01:09:51 +0200
Subject: [PATCH 158/943] `--bless` some tests due to message format change.

---
 .../ui/conditional-compilation/cfg-attr-crate-2.rs     |  2 +-
 .../ui/conditional-compilation/cfg-attr-crate-2.stderr |  2 +-
 .../cfg-attr-multi-invalid-1.rs                        |  3 ++-
 .../cfg-attr-multi-invalid-1.stderr                    |  2 +-
 .../cfg-attr-multi-invalid-2.rs                        |  3 ++-
 .../cfg-attr-multi-invalid-2.stderr                    |  2 +-
 src/test/ui/feature-gate-optimize_attribute.rs         | 10 +++++-----
 src/test/ui/feature-gate-optimize_attribute.stderr     | 10 +++++-----
 .../feature-gates/feature-gate-alloc-error-handler.rs  |  2 +-
 .../feature-gate-alloc-error-handler.stderr            |  2 +-
 src/test/ui/feature-gates/feature-gate-allow_fail.rs   |  2 +-
 .../ui/feature-gates/feature-gate-allow_fail.stderr    |  2 +-
 .../ui/feature-gates/feature-gate-marker_trait_attr.rs |  2 +-
 .../feature-gate-marker_trait_attr.stderr              |  2 +-
 src/test/ui/feature-gates/feature-gate-no_core.rs      |  2 +-
 src/test/ui/feature-gates/feature-gate-no_core.stderr  |  2 +-
 .../ui/feature-gates/feature-gate-non_exhaustive.rs    |  2 +-
 .../feature-gates/feature-gate-non_exhaustive.stderr   |  2 +-
 src/test/ui/feature-gates/feature-gate-rustc-attrs.rs  |  2 +-
 .../ui/feature-gates/feature-gate-rustc-attrs.stderr   |  2 +-
 .../ui/feature-gates/feature-gate-unwind-attributes.rs |  2 +-
 .../feature-gate-unwind-attributes.stderr              |  2 +-
 src/test/ui/malformed/malformed-regressions.stderr     |  6 ++----
 23 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs b/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs
index 0dceba28b6ec3..7dbeba53afcfe 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs
+++ b/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs
@@ -3,6 +3,6 @@
 // compile-flags: --cfg broken
 
 #![crate_type = "lib"]
-#![cfg_attr(broken, no_core)] //~ ERROR no_core is experimental
+#![cfg_attr(broken, no_core)] //~ ERROR the `#[no_core]` attribute is an experimental feature
 
 pub struct S {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr
index 5a70a5efc7f2a..7b77701ee190f 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr
@@ -1,4 +1,4 @@
-error[E0658]: no_core is experimental
+error[E0658]: the `#[no_core]` attribute is an experimental feature
   --> $DIR/cfg-attr-crate-2.rs:6:21
    |
 LL | #![cfg_attr(broken, no_core)]
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs
index be762c56048d4..42ffb71e3d7b9 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs
@@ -1,6 +1,7 @@
 // compile-flags: --cfg broken
 
 #![crate_type = "lib"]
-#![cfg_attr(broken, no_core, no_std)] //~ ERROR no_core is experimental
+#![cfg_attr(broken, no_core, no_std)]
+//~^ ERROR the `#[no_core]` attribute is an experimental feature
 
 pub struct S {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr
index 5e9adf1780737..ab7e1eb96032d 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr
@@ -1,4 +1,4 @@
-error[E0658]: no_core is experimental
+error[E0658]: the `#[no_core]` attribute is an experimental feature
   --> $DIR/cfg-attr-multi-invalid-1.rs:4:21
    |
 LL | #![cfg_attr(broken, no_core, no_std)]
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs
index 8a9e99d703c70..29690e2848f2d 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs
@@ -1,6 +1,7 @@
 // compile-flags: --cfg broken
 
 #![crate_type = "lib"]
-#![cfg_attr(broken, no_std, no_core)] //~ ERROR no_core is experimental
+#![cfg_attr(broken, no_std, no_core)]
+//~^ ERROR the `#[no_core]` attribute is an experimental feature
 
 pub struct S {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr
index 06b67156651cc..8126affbd36cd 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr
@@ -1,4 +1,4 @@
-error[E0658]: no_core is experimental
+error[E0658]: the `#[no_core]` attribute is an experimental feature
   --> $DIR/cfg-attr-multi-invalid-2.rs:4:29
    |
 LL | #![cfg_attr(broken, no_std, no_core)]
diff --git a/src/test/ui/feature-gate-optimize_attribute.rs b/src/test/ui/feature-gate-optimize_attribute.rs
index 7fc0fdde6fba8..15aa3a6af4ca9 100644
--- a/src/test/ui/feature-gate-optimize_attribute.rs
+++ b/src/test/ui/feature-gate-optimize_attribute.rs
@@ -1,17 +1,17 @@
 #![crate_type="rlib"]
-#![optimize(speed)] //~ ERROR `#[optimize]` attribute is an unstable feature
+#![optimize(speed)] //~ ERROR the `#[optimize]` attribute is an experimental feature
 
-#[optimize(size)] //~ ERROR `#[optimize]` attribute is an unstable feature
+#[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature
 mod module {
 
-#[optimize(size)] //~ ERROR `#[optimize]` attribute is an unstable feature
+#[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature
 fn size() {}
 
-#[optimize(speed)] //~ ERROR `#[optimize]` attribute is an unstable feature
+#[optimize(speed)] //~ ERROR the `#[optimize]` attribute is an experimental feature
 fn speed() {}
 
 #[optimize(banana)]
-//~^ ERROR `#[optimize]` attribute is an unstable feature
+//~^ ERROR the `#[optimize]` attribute is an experimental feature
 //~| ERROR E0722
 fn not_known() {}
 
diff --git a/src/test/ui/feature-gate-optimize_attribute.stderr b/src/test/ui/feature-gate-optimize_attribute.stderr
index 4ec512eaf39a4..3e3ad71c344ee 100644
--- a/src/test/ui/feature-gate-optimize_attribute.stderr
+++ b/src/test/ui/feature-gate-optimize_attribute.stderr
@@ -1,4 +1,4 @@
-error[E0658]: `#[optimize]` attribute is an unstable feature
+error[E0658]: the `#[optimize]` attribute is an experimental feature
   --> $DIR/feature-gate-optimize_attribute.rs:7:1
    |
 LL | #[optimize(size)]
@@ -7,7 +7,7 @@ LL | #[optimize(size)]
    = note: for more information, see https://github.com/rust-lang/rust/issues/54882
    = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
 
-error[E0658]: `#[optimize]` attribute is an unstable feature
+error[E0658]: the `#[optimize]` attribute is an experimental feature
   --> $DIR/feature-gate-optimize_attribute.rs:10:1
    |
 LL | #[optimize(speed)]
@@ -16,7 +16,7 @@ LL | #[optimize(speed)]
    = note: for more information, see https://github.com/rust-lang/rust/issues/54882
    = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
 
-error[E0658]: `#[optimize]` attribute is an unstable feature
+error[E0658]: the `#[optimize]` attribute is an experimental feature
   --> $DIR/feature-gate-optimize_attribute.rs:13:1
    |
 LL | #[optimize(banana)]
@@ -25,7 +25,7 @@ LL | #[optimize(banana)]
    = note: for more information, see https://github.com/rust-lang/rust/issues/54882
    = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
 
-error[E0658]: `#[optimize]` attribute is an unstable feature
+error[E0658]: the `#[optimize]` attribute is an experimental feature
   --> $DIR/feature-gate-optimize_attribute.rs:4:1
    |
 LL | #[optimize(size)]
@@ -34,7 +34,7 @@ LL | #[optimize(size)]
    = note: for more information, see https://github.com/rust-lang/rust/issues/54882
    = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable
 
-error[E0658]: `#[optimize]` attribute is an unstable feature
+error[E0658]: the `#[optimize]` attribute is an experimental feature
   --> $DIR/feature-gate-optimize_attribute.rs:2:1
    |
 LL | #![optimize(speed)]
diff --git a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs
index 17b4f775ad4de..ad89096183080 100644
--- a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs
+++ b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs
@@ -5,7 +5,7 @@
 
 use core::alloc::Layout;
 
-#[alloc_error_handler] //~ ERROR `#[alloc_error_handler]` is an unstable feature
+#[alloc_error_handler] //~ ERROR the `#[alloc_error_handler]` attribute is an experimental feature
 fn oom(info: Layout) -> ! {
     loop {}
 }
diff --git a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr
index d18cc09ffe777..79e44bf0d8ec1 100644
--- a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr
+++ b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr
@@ -1,4 +1,4 @@
-error[E0658]: `#[alloc_error_handler]` is an unstable feature
+error[E0658]: the `#[alloc_error_handler]` attribute is an experimental feature
   --> $DIR/feature-gate-alloc-error-handler.rs:8:1
    |
 LL | #[alloc_error_handler]
diff --git a/src/test/ui/feature-gates/feature-gate-allow_fail.rs b/src/test/ui/feature-gates/feature-gate-allow_fail.rs
index f9ad48551410c..287d4ccf18010 100644
--- a/src/test/ui/feature-gates/feature-gate-allow_fail.rs
+++ b/src/test/ui/feature-gates/feature-gate-allow_fail.rs
@@ -1,6 +1,6 @@
 // check that #[allow_fail] is feature-gated
 
-#[allow_fail] //~ ERROR allow_fail attribute is currently unstable
+#[allow_fail] //~ ERROR the `#[allow_fail]` attribute is an experimental feature
 fn ok_to_fail() {
     assert!(false);
 }
diff --git a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr b/src/test/ui/feature-gates/feature-gate-allow_fail.stderr
index 37bf3a262aaa0..0f60a2de3a4e5 100644
--- a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr
+++ b/src/test/ui/feature-gates/feature-gate-allow_fail.stderr
@@ -1,4 +1,4 @@
-error[E0658]: allow_fail attribute is currently unstable
+error[E0658]: the `#[allow_fail]` attribute is an experimental feature
   --> $DIR/feature-gate-allow_fail.rs:3:1
    |
 LL | #[allow_fail]
diff --git a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs
index ea06c775b1a60..5050c4792b064 100644
--- a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs
+++ b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs
@@ -1,7 +1,7 @@
 use std::fmt::{Debug, Display};
 
 #[marker] trait ExplicitMarker {}
-//~^ ERROR marker traits is an experimental feature
+//~^ ERROR the `#[marker]` attribute is an experimental feature
 
 impl<T: Display> ExplicitMarker for T {}
 impl<T: Debug> ExplicitMarker for T {}
diff --git a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr
index 94dfaf9206d14..304c081c5aace 100644
--- a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr
+++ b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr
@@ -1,4 +1,4 @@
-error[E0658]: marker traits is an experimental feature
+error[E0658]: the `#[marker]` attribute is an experimental feature
   --> $DIR/feature-gate-marker_trait_attr.rs:3:1
    |
 LL | #[marker] trait ExplicitMarker {}
diff --git a/src/test/ui/feature-gates/feature-gate-no_core.rs b/src/test/ui/feature-gates/feature-gate-no_core.rs
index 40178edd74b8d..706efd7867211 100644
--- a/src/test/ui/feature-gates/feature-gate-no_core.rs
+++ b/src/test/ui/feature-gates/feature-gate-no_core.rs
@@ -1,5 +1,5 @@
 #![crate_type = "rlib"]
 
-#![no_core] //~ ERROR no_core is experimental
+#![no_core] //~ ERROR the `#[no_core]` attribute is an experimental feature
 
 pub struct S {}
diff --git a/src/test/ui/feature-gates/feature-gate-no_core.stderr b/src/test/ui/feature-gates/feature-gate-no_core.stderr
index 4d4ca96544e56..a80b3cbba25b1 100644
--- a/src/test/ui/feature-gates/feature-gate-no_core.stderr
+++ b/src/test/ui/feature-gates/feature-gate-no_core.stderr
@@ -1,4 +1,4 @@
-error[E0658]: no_core is experimental
+error[E0658]: the `#[no_core]` attribute is an experimental feature
   --> $DIR/feature-gate-no_core.rs:3:1
    |
 LL | #![no_core]
diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs b/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs
index aca214d1935e2..950f170f4fd41 100644
--- a/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs
+++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs
@@ -1,6 +1,6 @@
 //#![feature(non_exhaustive)]
 
-#[non_exhaustive] //~ERROR non exhaustive is an experimental feature
+#[non_exhaustive] //~ERROR the `#[non_exhaustive]` attribute is an experimental feature
 pub enum NonExhaustiveEnum {
     Unit,
     Tuple(u32),
diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr b/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr
index 8a01aa9eb6a9a..482332b8d706c 100644
--- a/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr
+++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr
@@ -1,4 +1,4 @@
-error[E0658]: non exhaustive is an experimental feature
+error[E0658]: the `#[non_exhaustive]` attribute is an experimental feature
   --> $DIR/feature-gate-non_exhaustive.rs:3:1
    |
 LL | #[non_exhaustive]
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs
index 13983726c78de..4044fd2b895e4 100644
--- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs
+++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs
@@ -16,7 +16,7 @@ fn f() {}
 fn g() {}
 
 #[rustc_dummy]
-//~^ ERROR used by the test suite
+//~^ ERROR the `#[rustc_dummy]` attribute is just used for rustc unit tests
 #[rustc_unknown]
 //~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
 //~| ERROR cannot find attribute macro `rustc_unknown` in this scope
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
index 23cf936ee8350..c1063027fa444 100644
--- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
+++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
@@ -43,7 +43,7 @@ error: cannot find attribute macro `rustc_unknown` in this scope
 LL | #[rustc_unknown]
    |   ^^^^^^^^^^^^^
 
-error[E0658]: used by the test suite
+error[E0658]: the `#[rustc_dummy]` attribute is just used for rustc unit tests and will never be stable
   --> $DIR/feature-gate-rustc-attrs.rs:18:1
    |
 LL | #[rustc_dummy]
diff --git a/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs b/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs
index 08e8ec9a56e51..6d8ac7e8f2911 100644
--- a/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs
+++ b/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs
@@ -8,7 +8,7 @@ extern {
     fn extern_fn();
 // CHECK-NOT: Function Attrs: nounwind
 // CHECK: declare void @unwinding_extern_fn
-    #[unwind(allowed)] //~ ERROR `#[unwind]` is experimental
+    #[unwind(allowed)] //~ ERROR the `#[unwind]` attribute is an experimental feature
     fn unwinding_extern_fn();
 }
 
diff --git a/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr b/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr
index 639b87e016214..10cc494213507 100644
--- a/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr
+++ b/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr
@@ -1,4 +1,4 @@
-error[E0658]: `#[unwind]` is experimental
+error[E0658]: the `#[unwind]` attribute is an experimental feature
   --> $DIR/feature-gate-unwind-attributes.rs:11:5
    |
 LL |     #[unwind(allowed)]
diff --git a/src/test/ui/malformed/malformed-regressions.stderr b/src/test/ui/malformed/malformed-regressions.stderr
index eebb6f0623fbf..164668f562ce0 100644
--- a/src/test/ui/malformed/malformed-regressions.stderr
+++ b/src/test/ui/malformed/malformed-regressions.stderr
@@ -26,8 +26,7 @@ LL | #[inline = ""]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
-warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...",
-                                               /*opt*/ cfg = "...")]`
+warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]`
   --> $DIR/malformed-regressions.rs:6:1
    |
 LL | #[link]
@@ -36,8 +35,7 @@ LL | #[link]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
 
-warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...",
-                                               /*opt*/ cfg = "...")]`
+warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]`
   --> $DIR/malformed-regressions.rs:7:1
    |
 LL | #[link = ""]

From c8838efe355df9a9834e96a0d853743d21f06ce2 Mon Sep 17 00:00:00 2001
From: Marco A L Barbosa <malbarbo@gmail.com>
Date: Thu, 22 Aug 2019 14:40:21 -0300
Subject: [PATCH 159/943] Implement decode_error_kind for wasi

Based on the implementation for unix targets
---
 src/libstd/sys/wasi/mod.rs | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs
index f842869e08ee6..57da81b41e7ca 100644
--- a/src/libstd/sys/wasi/mod.rs
+++ b/src/libstd/sys/wasi/mod.rs
@@ -64,8 +64,24 @@ pub fn unsupported_err() -> Error {
     Error::new(ErrorKind::Other, "operation not supported on wasm yet")
 }
 
-pub fn decode_error_kind(_code: i32) -> ErrorKind {
-    ErrorKind::Other
+pub fn decode_error_kind(errno: i32) -> ErrorKind {
+    match errno as libc::c_int {
+        libc::ECONNREFUSED => ErrorKind::ConnectionRefused,
+        libc::ECONNRESET => ErrorKind::ConnectionReset,
+        libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied,
+        libc::EPIPE => ErrorKind::BrokenPipe,
+        libc::ENOTCONN => ErrorKind::NotConnected,
+        libc::ECONNABORTED => ErrorKind::ConnectionAborted,
+        libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
+        libc::EADDRINUSE => ErrorKind::AddrInUse,
+        libc::ENOENT => ErrorKind::NotFound,
+        libc::EINTR => ErrorKind::Interrupted,
+        libc::EINVAL => ErrorKind::InvalidInput,
+        libc::ETIMEDOUT => ErrorKind::TimedOut,
+        libc::EEXIST => ErrorKind::AlreadyExists,
+        libc::EAGAIN => ErrorKind::WouldBlock,
+        _ => ErrorKind::Other,
+    }
 }
 
 // This enum is used as the storage for a bunch of types which can't actually

From 73e3508bb84bec2911f56e5c2463eee3688cf8ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 23 Aug 2019 11:14:11 -0700
Subject: [PATCH 160/943] Suggest calling closure with resolved return type
 when appropriate

---
 src/librustc/ty/sty.rs                        |   3 +-
 src/librustc_typeck/check/coercion.rs         |  13 +-
 src/librustc_typeck/check/mod.rs              | 130 +++++++++++-------
 .../fn-or-tuple-struct-without-args.rs        |   2 +
 .../fn-or-tuple-struct-without-args.stderr    |  16 ++-
 5 files changed, 103 insertions(+), 61 deletions(-)

diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index da66fdf5b1b1b..7b7e2b8bfbdc8 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -385,7 +385,8 @@ impl<'tcx> ClosureSubsts<'tcx> {
         let ty = self.closure_sig_ty(def_id, tcx);
         match ty.sty {
             ty::FnPtr(sig) => sig,
-            _ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty),
+            ty::Infer(_) | ty::Error => ty::Binder::dummy(FnSig::fake()),  // ignore errors
+            _ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty.sty),
         }
     }
 }
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 4edb6ad893113..61b9c2a15ba16 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -799,12 +799,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// adjusted type of the expression, if successful.
     /// Adjustments are only recorded if the coercion succeeded.
     /// The expressions *must not* have any pre-existing adjustments.
-    pub fn try_coerce(&self,
-                      expr: &hir::Expr,
-                      expr_ty: Ty<'tcx>,
-                      target: Ty<'tcx>,
-                      allow_two_phase: AllowTwoPhase)
-                      -> RelateResult<'tcx, Ty<'tcx>> {
+    pub fn try_coerce(
+        &self,
+        expr: &hir::Expr,
+        expr_ty: Ty<'tcx>,
+        target: Ty<'tcx>,
+        allow_two_phase: AllowTwoPhase,
+    ) -> RelateResult<'tcx, Ty<'tcx>> {
         let source = self.resolve_type_vars_with_obligations(expr_ty);
         debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target);
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 9c7ac83e82e97..d92ce29f28459 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3917,75 +3917,99 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
     ) -> bool {
-        match found.sty {
-            ty::FnDef(..) | ty::FnPtr(_) => {}
-            _ => return false,
-        }
         let hir = self.tcx.hir();
+        let (def_id, sig) = match found.sty {
+            ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
+            ty::Closure(def_id, substs) => {
+                // We don't use `closure_sig` to account for malformed closures like
+                // `|_: [_; continue]| {}` and instead we don't suggest anything.
+                let closure_sig_ty = substs.closure_sig_ty(def_id, self.tcx);
+                (def_id, match closure_sig_ty.sty {
+                    ty::FnPtr(sig) => sig,
+                    _ => return false,
+                })
+            }
+            _ => return false,
+        };
 
-        let sig = found.fn_sig(self.tcx);
         let sig = self
             .replace_bound_vars_with_fresh_vars(expr.span, infer::FnCall, &sig)
             .0;
         let sig = self.normalize_associated_types_in(expr.span, &sig);
-        if let Ok(_) = self.try_coerce(expr, sig.output(), expected, AllowTwoPhase::No) {
+        if self.can_coerce(sig.output(), expected) {
             let (mut sugg_call, applicability) = if sig.inputs().is_empty() {
                 (String::new(), Applicability::MachineApplicable)
             } else {
                 ("...".to_string(), Applicability::HasPlaceholders)
             };
             let mut msg = "call this function";
-            if let ty::FnDef(def_id, ..) = found.sty {
-                match hir.get_if_local(def_id) {
-                    Some(Node::Item(hir::Item {
-                        node: ItemKind::Fn(.., body_id),
-                        ..
-                    })) |
-                    Some(Node::ImplItem(hir::ImplItem {
-                        node: hir::ImplItemKind::Method(_, body_id),
-                        ..
-                    })) |
-                    Some(Node::TraitItem(hir::TraitItem {
-                        node: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)),
-                        ..
-                    })) => {
-                        let body = hir.body(*body_id);
-                        sugg_call = body.arguments.iter()
-                            .map(|arg| match &arg.pat.node {
-                                hir::PatKind::Binding(_, _, ident, None)
-                                if ident.name != kw::SelfLower => ident.to_string(),
-                                _ => "_".to_string(),
-                            }).collect::<Vec<_>>().join(", ");
+            match hir.get_if_local(def_id) {
+                Some(Node::Item(hir::Item {
+                    node: ItemKind::Fn(.., body_id),
+                    ..
+                })) |
+                Some(Node::ImplItem(hir::ImplItem {
+                    node: hir::ImplItemKind::Method(_, body_id),
+                    ..
+                })) |
+                Some(Node::TraitItem(hir::TraitItem {
+                    node: hir::TraitItemKind::Method(.., hir::TraitMethod::Provided(body_id)),
+                    ..
+                })) => {
+                    let body = hir.body(*body_id);
+                    sugg_call = body.arguments.iter()
+                        .map(|arg| match &arg.pat.node {
+                            hir::PatKind::Binding(_, _, ident, None)
+                            if ident.name != kw::SelfLower => ident.to_string(),
+                            _ => "_".to_string(),
+                        }).collect::<Vec<_>>().join(", ");
+                }
+                Some(Node::Expr(hir::Expr {
+                    node: ExprKind::Closure(_, _, body_id, closure_span, _),
+                    span: full_closure_span,
+                    ..
+                })) => {
+                    if *full_closure_span == expr.span {
+                        return false;
                     }
-                    Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
-                        sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
-                        match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
-                            Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
-                                msg = "instantiate this tuple variant";
-                            }
-                            Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
-                                msg = "instantiate this tuple struct";
-                            }
-                            _ => {}
+                    err.span_label(*closure_span, "closure defined here");
+                    msg = "call this closure";
+                    let body = hir.body(*body_id);
+                    sugg_call = body.arguments.iter()
+                        .map(|arg| match &arg.pat.node {
+                            hir::PatKind::Binding(_, _, ident, None)
+                            if ident.name != kw::SelfLower => ident.to_string(),
+                            _ => "_".to_string(),
+                        }).collect::<Vec<_>>().join(", ");
+                }
+                Some(Node::Ctor(hir::VariantData::Tuple(fields, _))) => {
+                    sugg_call = fields.iter().map(|_| "_").collect::<Vec<_>>().join(", ");
+                    match hir.as_local_hir_id(def_id).and_then(|hir_id| hir.def_kind(hir_id)) {
+                        Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Variant, _)) => {
+                            msg = "instantiate this tuple variant";
                         }
+                        Some(hir::def::DefKind::Ctor(hir::def::CtorOf::Struct, _)) => {
+                            msg = "instantiate this tuple struct";
+                        }
+                        _ => {}
                     }
-                    Some(Node::ForeignItem(hir::ForeignItem {
-                        node: hir::ForeignItemKind::Fn(_, idents, _),
-                        ..
-                    })) |
-                    Some(Node::TraitItem(hir::TraitItem {
-                        node: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)),
-                        ..
-                    })) => sugg_call = idents.iter()
-                            .map(|ident| if ident.name != kw::SelfLower {
-                                ident.to_string()
-                            } else {
-                                "_".to_string()
-                            }).collect::<Vec<_>>()
-                            .join(", "),
-                    _ => {}
                 }
-            };
+                Some(Node::ForeignItem(hir::ForeignItem {
+                    node: hir::ForeignItemKind::Fn(_, idents, _),
+                    ..
+                })) |
+                Some(Node::TraitItem(hir::TraitItem {
+                    node: hir::TraitItemKind::Method(.., hir::TraitMethod::Required(idents)),
+                    ..
+                })) => sugg_call = idents.iter()
+                        .map(|ident| if ident.name != kw::SelfLower {
+                            ident.to_string()
+                        } else {
+                            "_".to_string()
+                        }).collect::<Vec<_>>()
+                        .join(", "),
+                _ => {}
+            }
             if let Ok(code) = self.sess().source_map().span_to_snippet(expr.span) {
                 err.span_suggestion(
                     expr.span,
diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs
index 9b6b10748172b..dd5af3e344cab 100644
--- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs
+++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.rs
@@ -42,4 +42,6 @@ fn main() {
     let _: usize = X::bal; //~ ERROR mismatched types
     let _: usize = X.ban; //~ ERROR attempted to take value of method
     let _: usize = X.bal; //~ ERROR attempted to take value of method
+    let closure = || 42;
+    let _: usize = closure; //~ ERROR mismatched types
 }
diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
index 0686b56f97ded..28b331bdbdcbc 100644
--- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
+++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
@@ -214,7 +214,21 @@ error[E0615]: attempted to take value of method `bal` on type `X`
 LL |     let _: usize = X.bal;
    |                      ^^^ help: use parentheses to call the method: `bal()`
 
-error: aborting due to 16 previous errors
+error[E0308]: mismatched types
+  --> $DIR/fn-or-tuple-struct-without-args.rs:46:20
+   |
+LL |     let closure = || 42;
+   |                   -- closure defined here
+LL |     let _: usize = closure;
+   |                    ^^^^^^^
+   |                    |
+   |                    expected usize, found closure
+   |                    help: use parentheses to call this closure: `closure()`
+   |
+   = note: expected type `usize`
+              found type `[closure@$DIR/fn-or-tuple-struct-without-args.rs:45:19: 45:24]`
+
+error: aborting due to 17 previous errors
 
 Some errors have detailed explanations: E0308, E0423, E0615.
 For more information about an error, try `rustc --explain E0308`.

From 055f7e2ec23f36e522e318a64eab414caba55e7e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 23 Aug 2019 13:45:18 -0700
Subject: [PATCH 161/943] Extend comment

---
 src/librustc_typeck/check/method/suggest.rs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 9f4fed23697ab..440e7e5d0e314 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -747,7 +747,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if let Node::GenericParam(ref param) = hir.get(id) {
                             match param.kind {
                                 hir::GenericParamKind::Type { synthetic: Some(_), .. } => {
-                                    impl_trait = true;  // #63706
+                                    // We've found `fn foo(x: impl Trait)` instead of
+                                    // `fn foo<T>(x: T)`. We want to suggest the correct
+                                    // `fn foo(x: impl Trait + TraitBound)` instead of
+                                    // `fn foo<T: TraitBound>(x: T)`. (#63706)
+                                    impl_trait = true;
                                     has_bounds = param.bounds.len() > 1;
                                 }
                                 _ => {

From 912feabfc282d0040f5e56bfbba752069d4f5a1f Mon Sep 17 00:00:00 2001
From: Baoshan Pang <baoshan.pang@windriver.com>
Date: Fri, 23 Aug 2019 13:25:01 -0700
Subject: [PATCH 162/943] VxWorks does not provide a way to set the task name
 except at creation time

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

diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs
index 58af8cbe48e36..ef896f6a6e8cf 100644
--- a/src/libstd/sys/vxworks/thread.rs
+++ b/src/libstd/sys/vxworks/thread.rs
@@ -77,7 +77,7 @@ impl Thread {
     }
 
     pub fn set_name(_name: &CStr) {
-        assert!(false, "FIXME: set_name");
+        // VxWorks does not provide a way to set the task name except at creation time
     }
 
     pub fn sleep(dur: Duration) {

From b47c9690d2974ec0318f1e87bf38f8f7ee6cf202 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Fri, 16 Aug 2019 08:29:08 -0700
Subject: [PATCH 163/943] bootstrap: Merge the libtest build step with libstd

Since its inception rustbuild has always worked in three stages: one for
libstd, one for libtest, and one for rustc. These three stages were
architected around crates.io dependencies, where rustc wants to depend
on crates.io crates but said crates don't explicitly depend on libstd,
requiring a sysroot assembly step in the middle. This same logic was
applied for libtest where libtest wants to depend on crates.io crates
(`getopts`) but `getopts` didn't say that it depended on std, so it
needed `std` built ahead of time.

Lots of time has passed since the inception of rustbuild, however,
and we've since gotten to the point where even `std` itself is depending
on crates.io crates (albeit with some wonky configuration). This
commit applies the same logic to the two dependencies that the `test`
crate pulls in from crates.io, `getopts` and `unicode-width`. Over the
many years since rustbuild's inception `unicode-width` was the only
dependency picked up by the `test` crate, so the extra configuration
necessary to get crates building in this crate graph is unlikely to be
too much of a burden on developers.

After this patch it means that there are now only two build phasese of
rustbuild, one for libstd and one for rustc. The libtest/libproc_macro
build phase is all lumped into one now with `std`.

This was originally motivated by rust-lang/cargo#7216 where Cargo was
having to deal with synthesizing dependency edges but this commit makes
them explicit in this repository.
---
 Cargo.lock                                   |  34 ++++-
 Cargo.toml                                   |   1 +
 src/bootstrap/builder.rs                     |  12 +-
 src/bootstrap/builder/tests.rs               | 153 ++++++++-----------
 src/bootstrap/check.rs                       |  55 +------
 src/bootstrap/compile.rs                     | 139 +----------------
 src/bootstrap/dist.rs                        |   8 +-
 src/bootstrap/doc.rs                         | 128 +---------------
 src/bootstrap/lib.rs                         |   7 +-
 src/bootstrap/test.rs                        |  36 +----
 src/bootstrap/tool.rs                        |  39 +----
 src/libproc_macro/Cargo.toml                 |   3 +
 src/libterm/Cargo.toml                       |   6 +-
 src/libtest/Cargo.toml                       |  16 +-
 src/tools/rustc-std-workspace-std/Cargo.toml |  15 ++
 src/tools/rustc-std-workspace-std/README.md  |   3 +
 src/tools/rustc-std-workspace-std/lib.rs     |   1 +
 src/tools/tidy/src/deps.rs                   |   3 +
 18 files changed, 162 insertions(+), 497 deletions(-)
 create mode 100644 src/tools/rustc-std-workspace-std/Cargo.toml
 create mode 100644 src/tools/rustc-std-workspace-std/README.md
 create mode 100644 src/tools/rustc-std-workspace-std/lib.rs

diff --git a/Cargo.lock b/Cargo.lock
index d96f92505adec..8ae21c8663706 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1139,10 +1139,12 @@ dependencies = [
 
 [[package]]
 name = "getopts"
-version = "0.2.19"
+version = "0.2.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72327b15c228bfe31f1390f93dd5e9279587f0463836393c9df719ce62a3e450"
+checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
 dependencies = [
+ "rustc-std-workspace-core",
+ "rustc-std-workspace-std",
  "unicode-width",
 ]
 
@@ -2375,6 +2377,9 @@ dependencies = [
 [[package]]
 name = "proc_macro"
 version = "0.0.0"
+dependencies = [
+ "std",
+]
 
 [[package]]
 name = "profiler_builtins"
@@ -3063,6 +3068,13 @@ dependencies = [
  "core",
 ]
 
+[[package]]
+name = "rustc-std-workspace-std"
+version = "1.0.0"
+dependencies = [
+ "std",
+]
+
 [[package]]
 name = "rustc-workspace-hack"
 version = "1.0.0"
@@ -4068,6 +4080,10 @@ dependencies = [
 [[package]]
 name = "term"
 version = "0.0.0"
+dependencies = [
+ "core",
+ "std",
+]
 
 [[package]]
 name = "term"
@@ -4114,8 +4130,13 @@ dependencies = [
 name = "test"
 version = "0.0.0"
 dependencies = [
+ "core",
  "getopts",
+ "libc",
+ "panic_abort",
+ "panic_unwind",
  "proc_macro",
+ "std",
  "term 0.0.0",
 ]
 
@@ -4483,9 +4504,14 @@ checksum = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
 
 [[package]]
 name = "unicode-width"
-version = "0.1.5"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
+checksum = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20"
+dependencies = [
+ "compiler_builtins",
+ "rustc-std-workspace-core",
+ "rustc-std-workspace-std",
+]
 
 [[package]]
 name = "unicode-xid"
diff --git a/Cargo.toml b/Cargo.toml
index ccd7e8b7654a6..a242f090fbc07 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -68,6 +68,7 @@ rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' }
 # here
 rustc-std-workspace-core = { path = 'src/tools/rustc-std-workspace-core' }
 rustc-std-workspace-alloc = { path = 'src/tools/rustc-std-workspace-alloc' }
+rustc-std-workspace-std = { path = 'src/tools/rustc-std-workspace-std' }
 
 [patch."https://github.com/rust-lang/rust-clippy"]
 clippy_lints = { path = "src/tools/clippy/clippy_lints" }
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 4e49aaa16eae1..4f5de1ecd2b44 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -337,7 +337,6 @@ impl<'a> Builder<'a> {
         match kind {
             Kind::Build => describe!(
                 compile::Std,
-                compile::Test,
                 compile::Rustc,
                 compile::CodegenBackend,
                 compile::StartupObjects,
@@ -363,7 +362,6 @@ impl<'a> Builder<'a> {
             ),
             Kind::Check | Kind::Clippy | Kind::Fix => describe!(
                 check::Std,
-                check::Test,
                 check::Rustc,
                 check::CodegenBackend,
                 check::Rustdoc
@@ -425,8 +423,6 @@ impl<'a> Builder<'a> {
                 doc::TheBook,
                 doc::Standalone,
                 doc::Std,
-                doc::Test,
-                doc::WhitelistedRustc,
                 doc::Rustc,
                 doc::Rustdoc,
                 doc::ErrorIndex,
@@ -801,7 +797,7 @@ impl<'a> Builder<'a> {
         }
 
         match mode {
-            Mode::Std | Mode::Test | Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolTest=> {},
+            Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {},
             Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
                 // Build proc macros both for the host and the target
                 if target != compiler.host && cmd != "check" {
@@ -852,7 +848,6 @@ impl<'a> Builder<'a> {
         // things still build right, please do!
         match mode {
             Mode::Std => metadata.push_str("std"),
-            Mode::Test => metadata.push_str("test"),
             _ => {},
         }
         cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata);
@@ -948,9 +943,9 @@ impl<'a> Builder<'a> {
 
         let debuginfo_level = match mode {
             Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc,
-            Mode::Std | Mode::Test => self.config.rust_debuginfo_level_std,
+            Mode::Std => self.config.rust_debuginfo_level_std,
             Mode::ToolBootstrap | Mode::ToolStd |
-            Mode::ToolTest | Mode::ToolRustc => self.config.rust_debuginfo_level_tools,
+            Mode::ToolRustc => self.config.rust_debuginfo_level_tools,
         };
         cargo.env("RUSTC_DEBUGINFO_LEVEL", debuginfo_level.to_string());
 
@@ -1150,7 +1145,6 @@ impl<'a> Builder<'a> {
 
         match (mode, self.config.rust_codegen_units_std, self.config.rust_codegen_units) {
             (Mode::Std, Some(n), _) |
-            (Mode::Test, Some(n), _) |
             (_, _, Some(n)) => {
                 cargo.env("RUSTC_CODEGEN_UNITS", n.to_string());
             }
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index d1542b1fca6b7..2bb90fdb04edc 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -365,27 +365,6 @@ fn dist_with_same_targets_and_hosts() {
             },
         ]
     );
-    assert_eq!(
-        first(builder.cache.all::<compile::Test>()),
-        &[
-            compile::Test {
-                compiler: Compiler { host: a, stage: 0 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 1 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 2 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 1 },
-                target: b,
-            },
-        ]
-    );
     assert_eq!(
         first(builder.cache.all::<compile::Assemble>()),
         &[
@@ -415,7 +394,47 @@ fn build_default() {
     let b = INTERNER.intern_str("B");
     let c = INTERNER.intern_str("C");
 
-    assert!(!builder.cache.all::<compile::Std>().is_empty());
+    assert_eq!(
+        first(builder.cache.all::<compile::Std>()),
+        &[
+            compile::Std {
+                compiler: Compiler { host: a, stage: 0 },
+                target: a,
+            },
+            compile::Std {
+                compiler: Compiler { host: a, stage: 1 },
+                target: a,
+            },
+            compile::Std {
+                compiler: Compiler { host: a, stage: 2 },
+                target: a,
+            },
+            compile::Std {
+                compiler: Compiler { host: b, stage: 2 },
+                target: a,
+            },
+            compile::Std {
+                compiler: Compiler { host: a, stage: 1 },
+                target: b,
+            },
+            compile::Std {
+                compiler: Compiler { host: a, stage: 2 },
+                target: b,
+            },
+            compile::Std {
+                compiler: Compiler { host: b, stage: 2 },
+                target: b,
+            },
+            compile::Std {
+                compiler: Compiler { host: a, stage: 2 },
+                target: c,
+            },
+            compile::Std {
+                compiler: Compiler { host: b, stage: 2 },
+                target: c,
+            },
+        ]
+    );
     assert!(!builder.cache.all::<compile::Assemble>().is_empty());
     assert_eq!(
         first(builder.cache.all::<compile::Rustc>()),
@@ -450,63 +469,61 @@ fn build_default() {
             },
         ]
     );
+}
+
+#[test]
+fn build_with_target_flag() {
+    let mut config = configure(&["B"], &["C"]);
+    config.skip_only_host_steps = true;
+    let build = Build::new(config);
+    let mut builder = Builder::new(&build);
+    builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
+
+    let a = INTERNER.intern_str("A");
+    let b = INTERNER.intern_str("B");
+    let c = INTERNER.intern_str("C");
 
     assert_eq!(
-        first(builder.cache.all::<compile::Test>()),
+        first(builder.cache.all::<compile::Std>()),
         &[
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 0 },
                 target: a,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 1 },
                 target: a,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 2 },
                 target: a,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: b, stage: 2 },
                 target: a,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 1 },
                 target: b,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 2 },
                 target: b,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: b, stage: 2 },
                 target: b,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: a, stage: 2 },
                 target: c,
             },
-            compile::Test {
+            compile::Std {
                 compiler: Compiler { host: b, stage: 2 },
                 target: c,
             },
         ]
     );
-}
-
-#[test]
-fn build_with_target_flag() {
-    let mut config = configure(&["B"], &["C"]);
-    config.skip_only_host_steps = true;
-    let build = Build::new(config);
-    let mut builder = Builder::new(&build);
-    builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
-
-    let a = INTERNER.intern_str("A");
-    let b = INTERNER.intern_str("B");
-    let c = INTERNER.intern_str("C");
-
-    assert!(!builder.cache.all::<compile::Std>().is_empty());
     assert_eq!(
         first(builder.cache.all::<compile::Assemble>()),
         &[
@@ -541,48 +558,6 @@ fn build_with_target_flag() {
             },
         ]
     );
-
-    assert_eq!(
-        first(builder.cache.all::<compile::Test>()),
-        &[
-            compile::Test {
-                compiler: Compiler { host: a, stage: 0 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 1 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 2 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: b, stage: 2 },
-                target: a,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 1 },
-                target: b,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 2 },
-                target: b,
-            },
-            compile::Test {
-                compiler: Compiler { host: b, stage: 2 },
-                target: b,
-            },
-            compile::Test {
-                compiler: Compiler { host: a, stage: 2 },
-                target: c,
-            },
-            compile::Test {
-                compiler: Compiler { host: b, stage: 2 },
-                target: c,
-            },
-        ]
-    );
 }
 
 #[test]
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 6e6fea6b831a7..e9a9b7881a068 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -1,6 +1,6 @@
 //! Implementation of compiling the compiler and standard library, in "check"-based modes.
 
-use crate::compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env,
+use crate::compile::{run_cargo, std_cargo, rustc_cargo, rustc_cargo_env,
                      add_to_sysroot};
 use crate::builder::{RunConfig, Builder, Kind, ShouldRun, Step};
 use crate::tool::{prepare_tool_cargo, SourceType};
@@ -92,7 +92,7 @@ impl Step for Rustc {
         let compiler = builder.compiler(0, builder.config.build);
         let target = self.target;
 
-        builder.ensure(Test { target });
+        builder.ensure(Std { target });
 
         let mut cargo = builder.cargo(compiler, Mode::Rustc, target,
             cargo_subcommand(builder.kind));
@@ -159,47 +159,6 @@ impl Step for CodegenBackend {
     }
 }
 
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub struct Test {
-    pub target: Interned<String>,
-}
-
-impl Step for Test {
-    type Output = ();
-    const DEFAULT: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.all_krates("test")
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Test {
-            target: run.target,
-        });
-    }
-
-    fn run(self, builder: &Builder<'_>) {
-        let compiler = builder.compiler(0, builder.config.build);
-        let target = self.target;
-
-        builder.ensure(Std { target });
-
-        let mut cargo = builder.cargo(compiler, Mode::Test, target, cargo_subcommand(builder.kind));
-        test_cargo(builder, &compiler, target, &mut cargo);
-
-        builder.info(&format!("Checking test artifacts ({} -> {})", &compiler.host, target));
-        run_cargo(builder,
-                  &mut cargo,
-                  args(builder.kind),
-                  &libtest_stamp(builder, compiler, target),
-                  true);
-
-        let libdir = builder.sysroot_libdir(compiler, target);
-        let hostdir = builder.sysroot_libdir(compiler, compiler.host);
-        add_to_sysroot(builder, &libdir, &hostdir, &libtest_stamp(builder, compiler, target));
-    }
-}
-
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Rustdoc {
     pub target: Interned<String>,
@@ -258,16 +217,6 @@ pub fn libstd_stamp(
     builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp")
 }
 
-/// Cargo's output path for libtest in a given stage, compiled by a particular
-/// compiler for the specified target.
-pub fn libtest_stamp(
-    builder: &Builder<'_>,
-    compiler: Compiler,
-    target: Interned<String>,
-) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Test, target).join(".libtest-check.stamp")
-}
-
 /// Cargo's output path for librustc in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn librustc_stamp(
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 96987d081594f..7dad146b48d83 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -216,7 +216,7 @@ pub fn std_cargo(builder: &Builder<'_>,
 
         cargo.arg("--features").arg(features)
             .arg("--manifest-path")
-            .arg(builder.src.join("src/libstd/Cargo.toml"));
+            .arg(builder.src.join("src/libtest/Cargo.toml"));
 
         if target.contains("musl") {
             if let Some(p) = builder.musl_root(target) {
@@ -358,129 +358,6 @@ impl Step for StartupObjects {
     }
 }
 
-#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
-pub struct Test {
-    pub target: Interned<String>,
-    pub compiler: Compiler,
-}
-
-impl Step for Test {
-    type Output = ();
-    const DEFAULT: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.all_krates("test")
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Test {
-            compiler: run.builder.compiler(run.builder.top_stage, run.host),
-            target: run.target,
-        });
-    }
-
-    /// Builds libtest.
-    ///
-    /// This will build libtest and supporting libraries for a particular stage of
-    /// the build using the `compiler` targeting the `target` architecture. The
-    /// artifacts created will also be linked into the sysroot directory.
-    fn run(self, builder: &Builder<'_>) {
-        let target = self.target;
-        let compiler = self.compiler;
-
-        builder.ensure(Std { compiler, target });
-
-        if builder.config.keep_stage.contains(&compiler.stage) {
-            builder.info("Warning: Using a potentially old libtest. This may not behave well.");
-            builder.ensure(TestLink {
-                compiler,
-                target_compiler: compiler,
-                target,
-            });
-            return;
-        }
-
-        let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
-        if compiler_to_use != compiler {
-            builder.ensure(Test {
-                compiler: compiler_to_use,
-                target,
-            });
-            builder.info(
-                &format!("Uplifting stage1 test ({} -> {})", builder.config.build, target));
-            builder.ensure(TestLink {
-                compiler: compiler_to_use,
-                target_compiler: compiler,
-                target,
-            });
-            return;
-        }
-
-        let mut cargo = builder.cargo(compiler, Mode::Test, target, "build");
-        test_cargo(builder, &compiler, target, &mut cargo);
-
-        builder.info(&format!("Building stage{} test artifacts ({} -> {})", compiler.stage,
-                &compiler.host, target));
-        run_cargo(builder,
-                  &mut cargo,
-                  vec![],
-                  &libtest_stamp(builder, compiler, target),
-                  false);
-
-        builder.ensure(TestLink {
-            compiler: builder.compiler(compiler.stage, builder.config.build),
-            target_compiler: compiler,
-            target,
-        });
-    }
-}
-
-/// Same as `std_cargo`, but for libtest
-pub fn test_cargo(builder: &Builder<'_>,
-                  _compiler: &Compiler,
-                  _target: Interned<String>,
-                  cargo: &mut Command) {
-    if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
-        cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
-    }
-    cargo.arg("--manifest-path")
-        .arg(builder.src.join("src/libtest/Cargo.toml"));
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub struct TestLink {
-    pub compiler: Compiler,
-    pub target_compiler: Compiler,
-    pub target: Interned<String>,
-}
-
-impl Step for TestLink {
-    type Output = ();
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.never()
-    }
-
-    /// Same as `std_link`, only for libtest
-    fn run(self, builder: &Builder<'_>) {
-        let compiler = self.compiler;
-        let target_compiler = self.target_compiler;
-        let target = self.target;
-        builder.info(&format!("Copying stage{} test from stage{} ({} -> {} / {})",
-                target_compiler.stage,
-                compiler.stage,
-                &compiler.host,
-                target_compiler.host,
-                target));
-        add_to_sysroot(
-            builder,
-            &builder.sysroot_libdir(target_compiler, target),
-            &builder.sysroot_libdir(target_compiler, compiler.host),
-            &libtest_stamp(builder, compiler, target)
-        );
-    }
-}
-
 #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Rustc {
     pub target: Interned<String>,
@@ -512,7 +389,7 @@ impl Step for Rustc {
         let compiler = self.compiler;
         let target = self.target;
 
-        builder.ensure(Test { compiler, target });
+        builder.ensure(Std { compiler, target });
 
         if builder.config.keep_stage.contains(&compiler.stage) {
             builder.info("Warning: Using a potentially old librustc. This may not behave well.");
@@ -541,7 +418,7 @@ impl Step for Rustc {
         }
 
         // Ensure that build scripts and proc macros have a std / libproc_macro to link against.
-        builder.ensure(Test {
+        builder.ensure(Std {
             compiler: builder.compiler(self.compiler.stage, builder.config.build),
             target: builder.config.build,
         });
@@ -872,16 +749,6 @@ pub fn libstd_stamp(
     builder.cargo_out(compiler, Mode::Std, target).join(".libstd.stamp")
 }
 
-/// Cargo's output path for libtest in a given stage, compiled by a particular
-/// compiler for the specified target.
-pub fn libtest_stamp(
-    builder: &Builder<'_>,
-    compiler: Compiler,
-    target: Interned<String>,
-) -> PathBuf {
-    builder.cargo_out(compiler, Mode::Test, target).join(".libtest.stamp")
-}
-
 /// Cargo's output path for librustc in a given stage, compiled by a particular
 /// compiler for the specified target.
 pub fn librustc_stamp(
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 213ceb194a814..0f4ac63651ca9 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -678,12 +678,7 @@ impl Step for Std {
         if builder.hosts.iter().any(|t| t == target) {
             builder.ensure(compile::Rustc { compiler, target });
         } else {
-            if builder.no_std(target) == Some(true) {
-                // the `test` doesn't compile for no-std targets
-                builder.ensure(compile::Std { compiler, target });
-            } else {
-                builder.ensure(compile::Test { compiler, target });
-            }
+            builder.ensure(compile::Std { compiler, target });
         }
 
         let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
@@ -912,6 +907,7 @@ impl Step for Src {
             "src/libproc_macro",
             "src/tools/rustc-std-workspace-core",
             "src/tools/rustc-std-workspace-alloc",
+            "src/tools/rustc-std-workspace-std",
             "src/librustc",
             "src/libsyntax",
         ];
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 4f96c12fc1ddd..6805474aa049f 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -478,138 +478,12 @@ impl Step for Std {
             builder.run(&mut cargo);
             builder.cp_r(&my_out, &out);
         };
-        for krate in &["alloc", "core", "std"] {
+        for krate in &["alloc", "core", "std", "proc_macro", "test"] {
             run_cargo_rustdoc_for(krate);
         }
     }
 }
 
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
-pub struct Test {
-    stage: u32,
-    target: Interned<String>,
-}
-
-impl Step for Test {
-    type Output = ();
-    const DEFAULT: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        let builder = run.builder;
-        run.krate("test").default_condition(builder.config.docs)
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(Test {
-            stage: run.builder.top_stage,
-            target: run.target,
-        });
-    }
-
-    /// Compile all libtest documentation.
-    ///
-    /// This will generate all documentation for libtest and its dependencies. This
-    /// is largely just a wrapper around `cargo doc`.
-    fn run(self, builder: &Builder<'_>) {
-        let stage = self.stage;
-        let target = self.target;
-        builder.info(&format!("Documenting stage{} test ({})", stage, target));
-        let out = builder.doc_out(target);
-        t!(fs::create_dir_all(&out));
-        let compiler = builder.compiler_for(stage, builder.config.build, target);
-
-        // Build libstd docs so that we generate relative links
-        builder.ensure(Std { stage, target });
-
-        builder.ensure(compile::Test { compiler, target });
-        let out_dir = builder.stage_out(compiler, Mode::Test)
-                           .join(target).join("doc");
-
-        // See docs in std above for why we symlink
-        let my_out = builder.crate_doc_out(target);
-        t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
-
-        let mut cargo = builder.cargo(compiler, Mode::Test, target, "doc");
-        compile::test_cargo(builder, &compiler, target, &mut cargo);
-
-        cargo.arg("--no-deps")
-             .arg("-p").arg("test")
-             .env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM)
-             .env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1");
-
-        builder.run(&mut cargo);
-        builder.cp_r(&my_out, &out);
-    }
-}
-
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
-pub struct WhitelistedRustc {
-    stage: u32,
-    target: Interned<String>,
-}
-
-impl Step for WhitelistedRustc {
-    type Output = ();
-    const DEFAULT: bool = true;
-    const ONLY_HOSTS: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        let builder = run.builder;
-        run.krate("rustc-main").default_condition(builder.config.docs)
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(WhitelistedRustc {
-            stage: run.builder.top_stage,
-            target: run.target,
-        });
-    }
-
-    /// Generates whitelisted compiler crate documentation.
-    ///
-    /// This will generate all documentation for crates that are whitelisted
-    /// to be included in the standard documentation. This documentation is
-    /// included in the standard Rust documentation, so we should always
-    /// document it and symlink to merge with the rest of the std and test
-    /// documentation. We don't build other compiler documentation
-    /// here as we want to be able to keep it separate from the standard
-    /// documentation. This is largely just a wrapper around `cargo doc`.
-    fn run(self, builder: &Builder<'_>) {
-        let stage = self.stage;
-        let target = self.target;
-        builder.info(&format!("Documenting stage{} whitelisted compiler ({})", stage, target));
-        let out = builder.doc_out(target);
-        t!(fs::create_dir_all(&out));
-        let compiler = builder.compiler_for(stage, builder.config.build, target);
-
-        // Build libstd docs so that we generate relative links
-        builder.ensure(Std { stage, target });
-
-        builder.ensure(compile::Rustc { compiler, target });
-        let out_dir = builder.stage_out(compiler, Mode::Rustc)
-                           .join(target).join("doc");
-
-        // See docs in std above for why we symlink
-        let my_out = builder.crate_doc_out(target);
-        t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
-
-        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc");
-        compile::rustc_cargo(builder, &mut cargo);
-
-        // We don't want to build docs for internal compiler dependencies in this
-        // step (there is another step for that). Therefore, we whitelist the crates
-        // for which docs must be built.
-        for krate in &["proc_macro"] {
-            cargo.arg("-p").arg(krate)
-                 .env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM)
-                 .env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1");
-        }
-
-        builder.run(&mut cargo);
-        builder.cp_r(&my_out, &out);
-    }
-}
-
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct Rustc {
     stage: u32,
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index b72aa78f3de19..c0e0ad1a857b9 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -297,9 +297,6 @@ pub enum Mode {
     /// Build the standard library, placing output in the "stageN-std" directory.
     Std,
 
-    /// Build libtest, placing output in the "stageN-test" directory.
-    Test,
-
     /// Build librustc, and compiler libraries, placing output in the "stageN-rustc" directory.
     Rustc,
 
@@ -315,7 +312,6 @@ pub enum Mode {
     /// Compile a tool which uses all libraries we compile (up to rustc).
     /// Doesn't use the stage0 compiler libraries like "other", and includes
     /// tools like rustdoc, cargo, rls, etc.
-    ToolTest,
     ToolStd,
     ToolRustc,
 }
@@ -536,11 +532,10 @@ impl Build {
     fn stage_out(&self, compiler: Compiler, mode: Mode) -> PathBuf {
         let suffix = match mode {
             Mode::Std => "-std",
-            Mode::Test => "-test",
             Mode::Rustc => "-rustc",
             Mode::Codegen => "-codegen",
             Mode::ToolBootstrap => "-bootstrap-tools",
-            Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => "-tools",
+            Mode::ToolStd | Mode::ToolRustc => "-tools",
         };
         self.out.join(&*compiler.host)
                 .join(format!("stage{}{}", compiler.stage, suffix))
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 87bd5cbacfffa..2bb053cc2b002 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1040,21 +1040,10 @@ impl Step for Compiletest {
             builder.ensure(compile::Rustc { compiler, target });
         }
 
-        if builder.no_std(target) == Some(true) {
-            // the `test` doesn't compile for no-std targets
-            builder.ensure(compile::Std { compiler, target });
-        } else {
-            builder.ensure(compile::Test { compiler, target });
-        }
-
-        if builder.no_std(target) == Some(true) {
-            // for no_std run-make (e.g., thumb*),
-            // we need a host compiler which is called by cargo.
-            builder.ensure(compile::Std { compiler, target: compiler.host });
-        }
+        builder.ensure(compile::Std { compiler, target });
+        // ensure that `libproc_macro` is available on the host.
+        builder.ensure(compile::Std { compiler, target: compiler.host });
 
-        // HACK(eddyb) ensure that `libproc_macro` is available on the host.
-        builder.ensure(compile::Test { compiler, target: compiler.host });
         // Also provide `rust_test_helpers` for the host.
         builder.ensure(native::TestHelpers { target: compiler.host });
 
@@ -1399,7 +1388,7 @@ impl Step for DocTest {
     fn run(self, builder: &Builder<'_>) {
         let compiler = self.compiler;
 
-        builder.ensure(compile::Test {
+        builder.ensure(compile::Std {
             compiler,
             target: compiler.host,
         });
@@ -1709,8 +1698,7 @@ impl Step for Crate {
 
     fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> {
         let builder = run.builder;
-        run = run.krate("test");
-        for krate in run.builder.in_tree_crates("std") {
+        for krate in run.builder.in_tree_crates("test") {
             if !(krate.name.starts_with("rustc_") && krate.name.ends_with("san")) {
                 run = run.path(krate.local_path(&builder).to_str().unwrap());
             }
@@ -1734,14 +1722,9 @@ impl Step for Crate {
             });
         };
 
-        for krate in builder.in_tree_crates("std") {
-            if run.path.ends_with(&krate.local_path(&builder)) {
-                make(Mode::Std, krate);
-            }
-        }
         for krate in builder.in_tree_crates("test") {
             if run.path.ends_with(&krate.local_path(&builder)) {
-                make(Mode::Test, krate);
+                make(Mode::Std, krate);
             }
         }
     }
@@ -1761,7 +1744,7 @@ impl Step for Crate {
         let test_kind = self.test_kind;
         let krate = self.krate;
 
-        builder.ensure(compile::Test { compiler, target });
+        builder.ensure(compile::Std { compiler, target });
         builder.ensure(RemoteCopyLibs { compiler, target });
 
         // If we're not doing a full bootstrap but we're testing a stage2
@@ -1775,9 +1758,6 @@ impl Step for Crate {
             Mode::Std => {
                 compile::std_cargo(builder, &compiler, target, &mut cargo);
             }
-            Mode::Test => {
-                compile::test_cargo(builder, &compiler, target, &mut cargo);
-            }
             Mode::Rustc => {
                 builder.ensure(compile::Rustc { compiler, target });
                 compile::rustc_cargo(builder, &mut cargo);
@@ -1979,7 +1959,7 @@ impl Step for RemoteCopyLibs {
             return;
         }
 
-        builder.ensure(compile::Test { compiler, target });
+        builder.ensure(compile::Std { compiler, target });
 
         builder.info(&format!("REMOTE copy libs to emulator ({})", target));
         t!(fs::create_dir_all(builder.out.join("tmp")));
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index df7eb7c455d02..54fe26f18e741 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -577,12 +577,6 @@ impl Step for Cargo {
     }
 
     fn run(self, builder: &Builder<'_>) -> PathBuf {
-        // Cargo depends on procedural macros, so make sure the host
-        // libstd/libproc_macro is available.
-        builder.ensure(compile::Test {
-            compiler: self.compiler,
-            target: builder.config.build,
-        });
         builder.ensure(ToolBuild {
             compiler: self.compiler,
             target: self.target,
@@ -650,31 +644,10 @@ macro_rules! tool_extended {
 
 tool_extended!((self, builder),
     Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", {};
-    CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", {
-        // Clippy depends on procedural macros, so make sure that's built for
-        // the compiler itself.
-        builder.ensure(compile::Test {
-            compiler: self.compiler,
-            target: builder.config.build,
-        });
-    };
-    Clippy, clippy, "src/tools/clippy", "clippy-driver", {
-        // Clippy depends on procedural macros, so make sure that's built for
-        // the compiler itself.
-        builder.ensure(compile::Test {
-            compiler: self.compiler,
-            target: builder.config.build,
-        });
-    };
+    CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", {};
+    Clippy, clippy, "src/tools/clippy", "clippy-driver", {};
     Miri, miri, "src/tools/miri", "miri", {};
-    CargoMiri, miri, "src/tools/miri", "cargo-miri", {
-        // Miri depends on procedural macros, so make sure that's built for
-        // the compiler itself.
-        builder.ensure(compile::Test {
-            compiler: self.compiler,
-            target: builder.config.build,
-        });
-    };
+    CargoMiri, miri, "src/tools/miri", "cargo-miri", {};
     Rls, rls, "src/tools/rls", "rls", {
         let clippy = builder.ensure(Clippy {
             compiler: self.compiler,
@@ -684,12 +657,6 @@ tool_extended!((self, builder),
         if clippy.is_some() {
             self.extra_features.push("clippy".to_owned());
         }
-        // RLS depends on procedural macros, so make sure that's built for
-        // the compiler itself.
-        builder.ensure(compile::Test {
-            compiler: self.compiler,
-            target: builder.config.build,
-        });
     };
     Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", {};
 );
diff --git a/src/libproc_macro/Cargo.toml b/src/libproc_macro/Cargo.toml
index b3d0ee94f0e12..187bdac80019d 100644
--- a/src/libproc_macro/Cargo.toml
+++ b/src/libproc_macro/Cargo.toml
@@ -6,3 +6,6 @@ edition = "2018"
 
 [lib]
 path = "lib.rs"
+
+[dependencies]
+std = { path = "../libstd" }
diff --git a/src/libterm/Cargo.toml b/src/libterm/Cargo.toml
index 4eba9a9d79cc4..2931e0bda9518 100644
--- a/src/libterm/Cargo.toml
+++ b/src/libterm/Cargo.toml
@@ -5,6 +5,8 @@ version = "0.0.0"
 edition = "2018"
 
 [lib]
-name = "term"
 path = "lib.rs"
-crate-type = ["dylib", "rlib"]
+
+[dependencies]
+core = { path = "../libcore" }
+std = { path = "../libstd" }
diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml
index a72e4c7050289..170fbb984cf9b 100644
--- a/src/libtest/Cargo.toml
+++ b/src/libtest/Cargo.toml
@@ -10,8 +10,22 @@ path = "lib.rs"
 crate-type = ["dylib", "rlib"]
 
 [dependencies]
-getopts = "0.2.19"
+getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
 term = { path = "../libterm" }
+std = { path = "../libstd" }
+core = { path = "../libcore" }
+libc = { version = "0.2", default-features = false }
+panic_unwind = { path = "../libpanic_unwind" }
+panic_abort = { path = "../libpanic_abort" }
 
 # not actually used but needed to always have proc_macro in the sysroot
 proc_macro = { path = "../libproc_macro" }
+
+# Forward features to the `std` crate as necessary
+[features]
+backtrace = ["std/backtrace"]
+compiler-builtins-c = ["std/compiler-builtins-c"]
+llvm-libunwind = ["std/llvm-libunwind"]
+panic-unwind = ["std/panic_unwind"]
+panic_immediate_abort = ["std/panic_immediate_abort"]
+profiler = ["std/profiler"]
diff --git a/src/tools/rustc-std-workspace-std/Cargo.toml b/src/tools/rustc-std-workspace-std/Cargo.toml
new file mode 100644
index 0000000000000..ce1644809dbe6
--- /dev/null
+++ b/src/tools/rustc-std-workspace-std/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "rustc-std-workspace-std"
+version = "1.0.0"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+license = 'MIT OR Apache-2.0'
+description = """
+Hack for the compiler's own build system
+"""
+edition = "2018"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+std = { path = "../../libstd" }
diff --git a/src/tools/rustc-std-workspace-std/README.md b/src/tools/rustc-std-workspace-std/README.md
new file mode 100644
index 0000000000000..2228907f304c4
--- /dev/null
+++ b/src/tools/rustc-std-workspace-std/README.md
@@ -0,0 +1,3 @@
+# The `rustc-std-workspace-std` crate
+
+See documentation for the `rustc-std-workspace-core` crate.
diff --git a/src/tools/rustc-std-workspace-std/lib.rs b/src/tools/rustc-std-workspace-std/lib.rs
new file mode 100644
index 0000000000000..f40d09cafbb47
--- /dev/null
+++ b/src/tools/rustc-std-workspace-std/lib.rs
@@ -0,0 +1 @@
+pub use std::*;
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index de54eb8f57312..e07a07234c71e 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -90,15 +90,18 @@ const WHITELIST: &[Crate<'_>] = &[
     Crate("crossbeam-epoch"),
     Crate("crossbeam-utils"),
     Crate("datafrog"),
+    Crate("dlmalloc"),
     Crate("either"),
     Crate("ena"),
     Crate("env_logger"),
     Crate("filetime"),
     Crate("flate2"),
+    Crate("fortanix-sgx-abi"),
     Crate("fuchsia-zircon"),
     Crate("fuchsia-zircon-sys"),
     Crate("getopts"),
     Crate("getrandom"),
+    Crate("hashbrown"),
     Crate("humantime"),
     Crate("indexmap"),
     Crate("itertools"),

From 7dff647d23103f1de29df89c0714eddec6c0a57b Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Sat, 24 Aug 2019 02:23:56 +0200
Subject: [PATCH 164/943] Ensure miri can do bit ops on pointer values

---
 src/librustc_mir/interpret/intrinsics.rs | 13 ++++++++-----
 src/librustc_mir/interpret/operand.rs    |  9 ++++-----
 src/librustc_mir/interpret/traits.rs     |  6 ++++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 4c86c53256e9b..334f1ea1a6901 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -95,7 +95,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             | "bitreverse" => {
                 let ty = substs.type_at(0);
                 let layout_of = self.layout_of(ty)?;
-                let bits = self.read_scalar(args[0])?.to_bits(layout_of.size)?;
+                let val = self.read_scalar(args[0])?.not_undef()?;
+                let bits = self.force_bits(val, layout_of.size)?;
                 let kind = match layout_of.abi {
                     ty::layout::Abi::Scalar(ref scalar) => scalar.value,
                     _ => throw_unsup!(TypeNotPrimitive(ty)),
@@ -149,7 +150,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         // term since the sign of the second term can be inferred from this and
                         // the fact that the operation has overflowed (if either is 0 no
                         // overflow can occur)
-                        let first_term: u128 = l.to_scalar()?.to_bits(l.layout.size)?;
+                        let first_term: u128 = self.force_bits(l.to_scalar()?, l.layout.size)?;
                         let first_term_positive = first_term & (1 << (num_bits-1)) == 0;
                         if first_term_positive {
                             // Negative overflow not possible since the positive first term
@@ -187,7 +188,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, l, r)?;
                 if overflowed {
                     let layout = self.layout_of(substs.type_at(0))?;
-                    let r_val = r.to_scalar()?.to_bits(layout.size)?;
+                    let r_val = self.force_bits(r.to_scalar()?, layout.size)?;
                     throw_ub_format!("Overflowing shift by {} in `{}`", r_val, intrinsic_name);
                 }
                 self.write_scalar(val, dest)?;
@@ -196,8 +197,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 // rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
                 // rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
                 let layout = self.layout_of(substs.type_at(0))?;
-                let val_bits = self.read_scalar(args[0])?.to_bits(layout.size)?;
-                let raw_shift_bits = self.read_scalar(args[1])?.to_bits(layout.size)?;
+                let val = self.read_scalar(args[0])?.not_undef()?;
+                let val_bits = self.force_bits(val, layout.size)?;
+                let raw_shift = self.read_scalar(args[1])?.not_undef()?;
+                let raw_shift_bits = self.force_bits(raw_shift, layout.size)?;
                 let width_bits = layout.size.bits() as u128;
                 let shift_bits = raw_shift_bits % width_bits;
                 let inv_shift_bits = (width_bits - shift_bits) % width_bits;
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 7a545e8ad6f79..b5aab992e3adb 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -629,11 +629,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // post-process
         Ok(match *discr_kind {
             layout::DiscriminantKind::Tag => {
-                let bits_discr = match raw_discr.to_bits(discr_val.layout.size) {
-                    Ok(raw_discr) => raw_discr,
-                    Err(_) =>
-                        throw_unsup!(InvalidDiscriminant(raw_discr.erase_tag())),
-                };
+                let bits_discr = raw_discr
+                    .not_undef()
+                    .and_then(|raw_discr| self.force_bits(raw_discr, discr_val.layout.size))
+                    .map_err(|_| err_unsup!(InvalidDiscriminant(raw_discr.erase_tag())))?;
                 let real_discr = if discr_val.layout.ty.is_signed() {
                     // going from layout tag type to typeck discriminant type
                     // requires first sign extending with the layout discriminant
diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs
index a2fc75739ffa0..34a10de7de7fc 100644
--- a/src/librustc_mir/interpret/traits.rs
+++ b/src/librustc_mir/interpret/traits.rs
@@ -144,11 +144,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         let size = alloc.read_ptr_sized(
             self,
             vtable.offset(pointer_size, self)?
-        )?.to_bits(pointer_size)? as u64;
+        )?.not_undef()?;
+        let size = self.force_bits(size, pointer_size)? as u64;
         let align = alloc.read_ptr_sized(
             self,
             vtable.offset(pointer_size * 2, self)?,
-        )?.to_bits(pointer_size)? as u64;
+        )?.not_undef()?;
+        let align = self.force_bits(align, pointer_size)? as u64;
         Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap()))
     }
 }

From d6bf776bc69c766aa70c39f28f6c70ab7faf32b7 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Wed, 21 Aug 2019 21:38:23 -0400
Subject: [PATCH 165/943] Fix incremental tests

---
 .../persist/dirty_clean.rs                    | 27 ++++++++++++++-----
 src/test/incremental/hashes/for_loops.rs      |  2 +-
 src/test/incremental/hashes/inherent_impls.rs | 12 ++++++---
 3 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index e569a9bc7df40..837aa9360c895 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -24,6 +24,7 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir::intravisit;
 use rustc::ich::{ATTR_DIRTY, ATTR_CLEAN};
 use rustc::ty::TyCtxt;
+use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashSet;
 use syntax::ast::{self, Attribute, NestedMetaItem};
 use syntax::symbol::{Symbol, sym};
@@ -71,6 +72,7 @@ const BASE_IMPL: &[&str] = &[
 /// code, i.e., functions+methods
 const BASE_MIR: &[&str] = &[
     label_strs::optimized_mir,
+    label_strs::promoted_mir,
     label_strs::mir_built,
 ];
 
@@ -472,11 +474,10 @@ impl DirtyCleanVisitor<'tcx> {
     fn assert_dirty(&self, item_span: Span, dep_node: DepNode) {
         debug!("assert_dirty({:?})", dep_node);
 
-        let dep_node_index = self.tcx.dep_graph.dep_node_index_of(&dep_node);
-        let current_fingerprint = self.tcx.dep_graph.fingerprint_of(dep_node_index);
+        let current_fingerprint = self.get_fingerprint(&dep_node);
         let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);
 
-        if Some(current_fingerprint) == prev_fingerprint {
+        if current_fingerprint == prev_fingerprint {
             let dep_node_str = self.dep_node_str(&dep_node);
             self.tcx.sess.span_err(
                 item_span,
@@ -484,14 +485,28 @@ impl DirtyCleanVisitor<'tcx> {
         }
     }
 
+    fn get_fingerprint(&self, dep_node: &DepNode) -> Option<Fingerprint> {
+        if self.tcx.dep_graph.dep_node_exists(dep_node) {
+            let dep_node_index = self.tcx.dep_graph.dep_node_index_of(dep_node);
+            Some(self.tcx.dep_graph.fingerprint_of(dep_node_index))
+        } else {
+            None
+        }
+    }
+
     fn assert_clean(&self, item_span: Span, dep_node: DepNode) {
         debug!("assert_clean({:?})", dep_node);
 
-        let dep_node_index = self.tcx.dep_graph.dep_node_index_of(&dep_node);
-        let current_fingerprint = self.tcx.dep_graph.fingerprint_of(dep_node_index);
+        let current_fingerprint = self.get_fingerprint(&dep_node);
         let prev_fingerprint = self.tcx.dep_graph.prev_fingerprint_of(&dep_node);
 
-        if Some(current_fingerprint) != prev_fingerprint {
+        // if the node wasn't previously evaluated and now is (or vice versa),
+        // then the node isn't actually clean or dirty.
+        if (current_fingerprint == None) ^ (prev_fingerprint == None) {
+            return;
+        }
+
+        if current_fingerprint != prev_fingerprint {
             let dep_node_str = self.dep_node_str(&dep_node);
             self.tcx.sess.span_err(
                 item_span,
diff --git a/src/test/incremental/hashes/for_loops.rs b/src/test/incremental/hashes/for_loops.rs
index 5d0b8b867b22f..70820dfaea4a0 100644
--- a/src/test/incremental/hashes/for_loops.rs
+++ b/src/test/incremental/hashes/for_loops.rs
@@ -94,7 +94,7 @@ pub fn change_iterable() {
 }
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg="cfail2", except="HirBody, mir_built")]
+#[rustc_clean(cfg="cfail2", except="HirBody, mir_built, promoted_mir")]
 #[rustc_clean(cfg="cfail3")]
 pub fn change_iterable() {
     let mut _x = 0;
diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs
index 882383e841957..e98f9b67ca421 100644
--- a/src/test/incremental/hashes/inherent_impls.rs
+++ b/src/test/incremental/hashes/inherent_impls.rs
@@ -42,7 +42,10 @@ impl Foo {
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 impl Foo {
-    #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,typeck_tables_of")]
+    #[rustc_clean(
+        cfg="cfail2",
+        except="HirBody,optimized_mir,promoted_mir,mir_built,typeck_tables_of"
+    )]
     #[rustc_clean(cfg="cfail3")]
     pub fn method_body() {
         println!("Hello, world!");
@@ -63,7 +66,10 @@ impl Foo {
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 impl Foo {
-    #[rustc_clean(cfg="cfail2", except="HirBody,optimized_mir,mir_built,typeck_tables_of")]
+    #[rustc_clean(
+        cfg="cfail2",
+        except="HirBody,optimized_mir,promoted_mir,mir_built,typeck_tables_of"
+    )]
     #[rustc_clean(cfg="cfail3")]
     #[inline]
     pub fn method_body_inlined() {
@@ -97,7 +103,7 @@ impl Foo {
 #[rustc_clean(cfg="cfail2", except="Hir,HirBody")]
 #[rustc_clean(cfg="cfail3")]
 impl Foo {
-    #[rustc_dirty(cfg="cfail2", except="type_of,predicates_of")]
+    #[rustc_dirty(cfg="cfail2", except="type_of,predicates_of,promoted_mir")]
     #[rustc_clean(cfg="cfail3")]
     pub fn method_selfness(&self) { }
 }

From a577316b0a136b5ca980032cf1dbe683103ba15f Mon Sep 17 00:00:00 2001
From: Christian <chris_veenman@hotmail.com>
Date: Sat, 24 Aug 2019 13:36:57 +0200
Subject: [PATCH 166/943] Removed the confusing FnOnce example. closes #47091

---
 src/libcore/ops/function.rs | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/src/libcore/ops/function.rs b/src/libcore/ops/function.rs
index b9552eaa1a0e5..9bb1ae8572b71 100644
--- a/src/libcore/ops/function.rs
+++ b/src/libcore/ops/function.rs
@@ -184,15 +184,6 @@ pub trait FnMut<Args> : FnOnce<Args> {
 /// [nomicon]: ../../nomicon/hrtb.html
 ///
 /// # Examples
-///
-/// ## Calling a by-value closure
-///
-/// ```
-/// let x = 5;
-/// let square_x = move || x * x;
-/// assert_eq!(square_x(), 25);
-/// ```
-///
 /// ## Using a `FnOnce` parameter
 ///
 /// ```

From 55f8dde6c89e3af68d4c59232f3d06e6130e9f0a Mon Sep 17 00:00:00 2001
From: Christian <chris_veenman@hotmail.com>
Date: Sat, 24 Aug 2019 13:38:09 +0200
Subject: [PATCH 167/943] Added an extra line to make the formatting conform to
 the rest of the document.

---
 src/libcore/ops/function.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/libcore/ops/function.rs b/src/libcore/ops/function.rs
index 9bb1ae8572b71..4a0a2720fe441 100644
--- a/src/libcore/ops/function.rs
+++ b/src/libcore/ops/function.rs
@@ -184,6 +184,7 @@ pub trait FnMut<Args> : FnOnce<Args> {
 /// [nomicon]: ../../nomicon/hrtb.html
 ///
 /// # Examples
+///
 /// ## Using a `FnOnce` parameter
 ///
 /// ```

From 33788c252c83aeea913482b283e33ccc41bd2860 Mon Sep 17 00:00:00 2001
From: Christian <chris_veenman@hotmail.com>
Date: Sat, 24 Aug 2019 14:49:17 +0200
Subject: [PATCH 168/943] Added table containing the system calls used by
 Instant and SystemTime.

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

diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 98371b9ba3d7e..f03020bb4954e 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -59,6 +59,21 @@ pub use core::time::Duration;
 ///    println!("{}", now.elapsed().as_secs());
 /// }
 /// ```
+///
+/// # Underlying System calls
+/// Currently, the following system calls are being used to get the current time using `now()`:
+///
+/// |  Platform |               System call                        |
+/// |:---------:|:------------------------------------------------:|
+/// | Cloud ABI | [clock_time_get (Monotonic Clock)](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt) |
+/// |    SGX    | Not implemented                                  |
+/// |    UNIX   | [mach_absolute_time](https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html)                           |
+/// |  VXWorks  | [clock_gettime (Monotonic Clock)](https://linux.die.net/man/3/clock_gettime)                                |
+/// |    WASI   | [__wasi_clock_time_get (Monotonic Clock)](https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get)      |
+/// |  Windows  | [QueryPerformanceCounter](https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter)                      |
+///
+/// **Disclaimer:** These system calls might change over time.
+///
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[stable(feature = "time2", since = "1.8.0")]
 pub struct Instant(time::Instant);
@@ -114,6 +129,21 @@ pub struct Instant(time::Instant);
 ///    }
 /// }
 /// ```
+///
+/// # Underlying System calls
+/// Currently, the following system calls are being used to get the current time using `now()`:
+///
+/// |  Platform |               System call                        |
+/// |:---------:|:------------------------------------------------:|
+/// | Cloud ABI | [clock_time_get (Realtime Clock)](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt) |
+/// |    SGX    | Not implemented                                  |
+/// |    UNIX   | [gettimeofday](http://man7.org/linux/man-pages/man2/gettimeofday.2.html)                           |
+/// |  VXWorks  | [clock_gettime (Realtime Clock)](https://linux.die.net/man/3/clock_gettime)                                |
+/// |    WASI   | [__wasi_clock_time_get (Realtime Clock)](https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get)      |
+/// |  Windows  | [GetSystemTimeAsFileTime](https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime)                      |
+///
+/// **Disclaimer:** These system calls might change over time.
+///
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[stable(feature = "time2", since = "1.8.0")]
 pub struct SystemTime(time::SystemTime);

From 8ca9c7bbe5f2be252881e1edbd2a2ce97e75244f Mon Sep 17 00:00:00 2001
From: Pascal Hertleif <pascal@technocreatives.com>
Date: Sat, 24 Aug 2019 17:45:03 +0200
Subject: [PATCH 169/943] Fix tidy feature gate error reporting

Feature gate definitions were split into multiple files in #63824 but
tidy kept reporting the hard-coded path. Now, it shows the full path
to the correct file.
---
 src/tools/tidy/src/features.rs | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 468e56001012f..50e9116c778ea 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -176,7 +176,10 @@ pub fn check(path: &Path, bad: &mut bool, verbose: bool) -> CollectedFeatures {
     CollectedFeatures { lib: lib_features, lang: features }
 }
 
-fn format_features<'a>(features: &'a Features, family: &'a str) -> impl Iterator<Item = String> + 'a {
+fn format_features<'a>(
+    features: &'a Features,
+    family: &'a str,
+) -> impl Iterator<Item = String> + 'a {
     features.iter().map(move |(name, feature)| {
         format!("{:<32} {:<8} {:<12} {:<8}",
                 name,
@@ -228,7 +231,8 @@ pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features {
 }
 
 fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features {
-    let contents = t!(fs::read_to_string(base.join("libsyntax/feature_gate").join(file)));
+    let path = base.join("libsyntax/feature_gate").join(file);
+    let contents = t!(fs::read_to_string(&path));
 
     // We allow rustc-internal features to omit a tracking issue.
     // To make tidy accept omitting a tracking issue, group the list of features
@@ -259,8 +263,9 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features
                 if in_feature_group {
                     tidy_error!(
                         bad,
-                        // ignore-tidy-linelength
-                        "libsyntax/feature_gate.rs:{}: new feature group is started without ending the previous one",
+                        "{}:{}: \
+                        new feature group is started without ending the previous one",
+                        path.display(),
                         line_number,
                     );
                 }
@@ -289,7 +294,8 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features
                 Err(err) => {
                     tidy_error!(
                         bad,
-                        "libsyntax/feature_gate.rs:{}: failed to parse since: {} ({:?})",
+                        "{}:{}: failed to parse since: {} ({:?})",
+                        path.display(),
                         line_number,
                         since_str,
                         err,
@@ -301,7 +307,8 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features
                 if prev_since > since {
                     tidy_error!(
                         bad,
-                        "libsyntax/feature_gate.rs:{}: feature {} is not sorted by since",
+                        "{}:{}: feature {} is not sorted by since",
+                        path.display(),
                         line_number,
                         name,
                     );
@@ -315,7 +322,8 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features
                     *bad = true;
                     tidy_error!(
                         bad,
-                        "libsyntax/feature_gate.rs:{}: no tracking issue for feature {}",
+                        "{}:{}: no tracking issue for feature {}",
+                        path.display(),
                         line_number,
                         name,
                     );

From c9619a4202bd013f1be2776c328937ddd643e7b7 Mon Sep 17 00:00:00 2001
From: Pascal Hertleif <pascal@technocreatives.com>
Date: Sat, 24 Aug 2019 17:47:26 +0200
Subject: [PATCH 170/943] Use doc comments for feature gate descriptions

This is just in preparation for future usage of these texts.
---
 src/libsyntax/feature_gate/accepted.rs | 218 +++++++++---------
 src/libsyntax/feature_gate/active.rs   | 305 +++++++++++++------------
 src/libsyntax/feature_gate/removed.rs  |  22 +-
 3 files changed, 284 insertions(+), 261 deletions(-)

diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs
index 32a0b76d5f0d8..28e4d2c073c7c 100644
--- a/src/libsyntax/feature_gate/accepted.rs
+++ b/src/libsyntax/feature_gate/accepted.rs
@@ -3,7 +3,9 @@
 use crate::symbol::{Symbol, sym};
 
 macro_rules! declare_features {
-    ($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
+    ($(
+        $(#[doc = $doc:tt])* (accepted, $feature:ident, $ver:expr, $issue:expr, None),
+    )+) => {
         /// Those language feature has since been Accepted (it was once Active)
         pub const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
             $((sym::$feature, $ver, $issue, None)),+
@@ -16,11 +18,11 @@ declare_features! (
     // feature-group-start: for testing purposes
     // -------------------------------------------------------------------------
 
-    // A temporary feature gate used to enable parser extensions needed
-    // to bootstrap fix for #5723.
+    /// A temporary feature gate used to enable parser extensions needed
+    /// to bootstrap fix for #5723.
     (accepted, issue_5723_bootstrap, "1.0.0", None, None),
-    // These are used to test this portion of the compiler,
-    // they don't actually mean anything.
+    /// These are used to test this portion of the compiler,
+    /// they don't actually mean anything.
     (accepted, test_accepted_feature, "1.0.0", None, None),
 
     // -------------------------------------------------------------------------
@@ -31,203 +33,203 @@ declare_features! (
     // feature-group-start: accepted features
     // -------------------------------------------------------------------------
 
-    // Allows using associated `type`s in `trait`s.
+    /// Allows using associated `type`s in `trait`s.
     (accepted, associated_types, "1.0.0", None, None),
-    // Allows using assigning a default type to type parameters in algebraic data type definitions.
+    /// Allows using assigning a default type to type parameters in algebraic data type definitions.
     (accepted, default_type_params, "1.0.0", None, None),
     // FIXME: explain `globs`.
     (accepted, globs, "1.0.0", None, None),
-    // Allows `macro_rules!` items.
+    /// Allows `macro_rules!` items.
     (accepted, macro_rules, "1.0.0", None, None),
-    // Allows use of `&foo[a..b]` as a slicing syntax.
+    /// Allows use of `&foo[a..b]` as a slicing syntax.
     (accepted, slicing_syntax, "1.0.0", None, None),
-    // Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418).
+    /// Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418).
     (accepted, struct_variant, "1.0.0", None, None),
-    // Allows indexing tuples.
+    /// Allows indexing tuples.
     (accepted, tuple_indexing, "1.0.0", None, None),
-    // Allows the use of `if let` expressions.
+    /// Allows the use of `if let` expressions.
     (accepted, if_let, "1.0.0", None, None),
-    // Allows the use of `while let` expressions.
+    /// Allows the use of `while let` expressions.
     (accepted, while_let, "1.0.0", None, None),
-    // Allows using `#![no_std]`.
+    /// Allows using `#![no_std]`.
     (accepted, no_std, "1.6.0", None, None),
-    // Allows overloading augmented assignment operations like `a += b`.
+    /// Allows overloading augmented assignment operations like `a += b`.
     (accepted, augmented_assignments, "1.8.0", Some(28235), None),
-    // Allows empty structs and enum variants with braces.
+    /// Allows empty structs and enum variants with braces.
     (accepted, braced_empty_structs, "1.8.0", Some(29720), None),
-    // Allows `#[deprecated]` attribute.
+    /// Allows `#[deprecated]` attribute.
     (accepted, deprecated, "1.9.0", Some(29935), None),
-    // Allows macros to appear in the type position.
+    /// Allows macros to appear in the type position.
     (accepted, type_macros, "1.13.0", Some(27245), None),
-    // Allows use of the postfix `?` operator in expressions.
+    /// Allows use of the postfix `?` operator in expressions.
     (accepted, question_mark, "1.13.0", Some(31436), None),
-    // Allows `..` in tuple (struct) patterns.
+    /// Allows `..` in tuple (struct) patterns.
     (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None),
-    // Allows some increased flexibility in the name resolution rules,
-    // especially around globs and shadowing (RFC 1560).
+    /// Allows some increased flexibility in the name resolution rules,
+    /// especially around globs and shadowing (RFC 1560).
     (accepted, item_like_imports, "1.15.0", Some(35120), None),
-    // Allows using `Self` and associated types in struct expressions and patterns.
+    /// Allows using `Self` and associated types in struct expressions and patterns.
     (accepted, more_struct_aliases, "1.16.0", Some(37544), None),
-    // Allows elision of `'static` lifetimes in `static`s and `const`s.
+    /// Allows elision of `'static` lifetimes in `static`s and `const`s.
     (accepted, static_in_const, "1.17.0", Some(35897), None),
-    // Allows field shorthands (`x` meaning `x: x`) in struct literal expressions.
+    /// Allows field shorthands (`x` meaning `x: x`) in struct literal expressions.
     (accepted, field_init_shorthand, "1.17.0", Some(37340), None),
-    // Allows the definition recursive static items.
+    /// Allows the definition recursive static items.
     (accepted, static_recursion, "1.17.0", Some(29719), None),
-    // Allows `pub(restricted)` visibilities (RFC 1422).
+    /// Allows `pub(restricted)` visibilities (RFC 1422).
     (accepted, pub_restricted, "1.18.0", Some(32409), None),
-    // Allows `#![windows_subsystem]`.
+    /// Allows `#![windows_subsystem]`.
     (accepted, windows_subsystem, "1.18.0", Some(37499), None),
-    // Allows `break {expr}` with a value inside `loop`s.
+    /// Allows `break {expr}` with a value inside `loop`s.
     (accepted, loop_break_value, "1.19.0", Some(37339), None),
-    // Allows numeric fields in struct expressions and patterns.
+    /// Allows numeric fields in struct expressions and patterns.
     (accepted, relaxed_adts, "1.19.0", Some(35626), None),
-    // Allows coercing non capturing closures to function pointers.
+    /// Allows coercing non capturing closures to function pointers.
     (accepted, closure_to_fn_coercion, "1.19.0", Some(39817), None),
-    // Allows attributes on struct literal fields.
+    /// Allows attributes on struct literal fields.
     (accepted, struct_field_attributes, "1.20.0", Some(38814), None),
-    // Allows the definition of associated constants in `trait` or `impl` blocks.
+    /// Allows the definition of associated constants in `trait` or `impl` blocks.
     (accepted, associated_consts, "1.20.0", Some(29646), None),
-    // Allows usage of the `compile_error!` macro.
+    /// Allows usage of the `compile_error!` macro.
     (accepted, compile_error, "1.20.0", Some(40872), None),
-    // Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
+    /// Allows code like `let x: &'static u32 = &42` to work (RFC 1414).
     (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None),
-    // Allows `Drop` types in constants (RFC 1440).
+    /// Allows `Drop` types in constants (RFC 1440).
     (accepted, drop_types_in_const, "1.22.0", Some(33156), None),
-    // Allows the sysV64 ABI to be specified on all platforms
-    // instead of just the platforms on which it is the C ABI.
+    /// Allows the sysV64 ABI to be specified on all platforms
+    /// instead of just the platforms on which it is the C ABI.
     (accepted, abi_sysv64, "1.24.0", Some(36167), None),
-    // Allows `repr(align(16))` struct attribute (RFC 1358).
+    /// Allows `repr(align(16))` struct attribute (RFC 1358).
     (accepted, repr_align, "1.25.0", Some(33626), None),
-    // Allows '|' at beginning of match arms (RFC 1925).
+    /// Allows '|' at beginning of match arms (RFC 1925).
     (accepted, match_beginning_vert, "1.25.0", Some(44101), None),
-    // Allows nested groups in `use` items (RFC 2128).
+    /// Allows nested groups in `use` items (RFC 2128).
     (accepted, use_nested_groups, "1.25.0", Some(44494), None),
-    // Allows indexing into constant arrays.
+    /// Allows indexing into constant arrays.
     (accepted, const_indexing, "1.26.0", Some(29947), None),
-    // Allows using `a..=b` and `..=b` as inclusive range syntaxes.
+    /// Allows using `a..=b` and `..=b` as inclusive range syntaxes.
     (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None),
-    // Allows `..=` in patterns (RFC 1192).
+    /// Allows `..=` in patterns (RFC 1192).
     (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None),
-    // Allows `fn main()` with return types which implements `Termination` (RFC 1937).
+    /// Allows `fn main()` with return types which implements `Termination` (RFC 1937).
     (accepted, termination_trait, "1.26.0", Some(43301), None),
-    // Allows implementing `Clone` for closures where possible (RFC 2132).
+    /// Allows implementing `Clone` for closures where possible (RFC 2132).
     (accepted, clone_closures, "1.26.0", Some(44490), None),
-    // Allows implementing `Copy` for closures where possible (RFC 2132).
+    /// Allows implementing `Copy` for closures where possible (RFC 2132).
     (accepted, copy_closures, "1.26.0", Some(44490), None),
-    // Allows `impl Trait` in function arguments.
+    /// Allows `impl Trait` in function arguments.
     (accepted, universal_impl_trait, "1.26.0", Some(34511), None),
-    // Allows `impl Trait` in function return types.
+    /// Allows `impl Trait` in function return types.
     (accepted, conservative_impl_trait, "1.26.0", Some(34511), None),
-    // Allows using the `u128` and `i128` types.
+    /// Allows using the `u128` and `i128` types.
     (accepted, i128_type, "1.26.0", Some(35118), None),
-    // Allows default match binding modes (RFC 2005).
+    /// Allows default match binding modes (RFC 2005).
     (accepted, match_default_bindings, "1.26.0", Some(42640), None),
-    // Allows `'_` placeholder lifetimes.
+    /// Allows `'_` placeholder lifetimes.
     (accepted, underscore_lifetimes, "1.26.0", Some(44524), None),
-    // Allows attributes on lifetime/type formal parameters in generics (RFC 1327).
+    /// Allows attributes on lifetime/type formal parameters in generics (RFC 1327).
     (accepted, generic_param_attrs, "1.27.0", Some(48848), None),
-    // Allows `cfg(target_feature = "...")`.
+    /// Allows `cfg(target_feature = "...")`.
     (accepted, cfg_target_feature, "1.27.0", Some(29717), None),
-    // Allows `#[target_feature(...)]`.
+    /// Allows `#[target_feature(...)]`.
     (accepted, target_feature, "1.27.0", None, None),
-    // Allows using `dyn Trait` as a syntax for trait objects.
+    /// Allows using `dyn Trait` as a syntax for trait objects.
     (accepted, dyn_trait, "1.27.0", Some(44662), None),
-    // Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940).
+    /// Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940).
     (accepted, fn_must_use, "1.27.0", Some(43302), None),
-    // Allows use of the `:lifetime` macro fragment specifier.
+    /// Allows use of the `:lifetime` macro fragment specifier.
     (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None),
-    // Allows `#[test]` functions where the return type implements `Termination` (RFC 1937).
+    /// Allows `#[test]` functions where the return type implements `Termination` (RFC 1937).
     (accepted, termination_trait_test, "1.27.0", Some(48854), None),
-    // Allows the `#[global_allocator]` attribute.
+    /// Allows the `#[global_allocator]` attribute.
     (accepted, global_allocator, "1.28.0", Some(27389), None),
-    // Allows `#[repr(transparent)]` attribute on newtype structs.
+    /// Allows `#[repr(transparent)]` attribute on newtype structs.
     (accepted, repr_transparent, "1.28.0", Some(43036), None),
-    // Allows procedural macros in `proc-macro` crates.
+    /// Allows procedural macros in `proc-macro` crates.
     (accepted, proc_macro, "1.29.0", Some(38356), None),
-    // Allows `foo.rs` as an alternative to `foo/mod.rs`.
+    /// Allows `foo.rs` as an alternative to `foo/mod.rs`.
     (accepted, non_modrs_mods, "1.30.0", Some(44660), None),
-    // Allows use of the `:vis` macro fragment specifier
+    /// Allows use of the `:vis` macro fragment specifier
     (accepted, macro_vis_matcher, "1.30.0", Some(41022), None),
-    // Allows importing and reexporting macros with `use`,
-    // enables macro modularization in general.
+    /// Allows importing and reexporting macros with `use`,
+    /// enables macro modularization in general.
     (accepted, use_extern_macros, "1.30.0", Some(35896), None),
-    // Allows keywords to be escaped for use as identifiers.
+    /// Allows keywords to be escaped for use as identifiers.
     (accepted, raw_identifiers, "1.30.0", Some(48589), None),
-    // Allows attributes scoped to tools.
+    /// Allows attributes scoped to tools.
     (accepted, tool_attributes, "1.30.0", Some(44690), None),
-    // Allows multi-segment paths in attributes and derives.
+    /// Allows multi-segment paths in attributes and derives.
     (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None),
-    // Allows all literals in attribute lists and values of key-value pairs.
+    /// Allows all literals in attribute lists and values of key-value pairs.
     (accepted, attr_literals, "1.30.0", Some(34981), None),
-    // Allows inferring outlives requirements (RFC 2093).
+    /// Allows inferring outlives requirements (RFC 2093).
     (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None),
-    // Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`.
-    // This defines the behavior of panics.
+    /// Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`.
+    /// This defines the behavior of panics.
     (accepted, panic_handler, "1.30.0", Some(44489), None),
-    // Allows `#[used]` to preserve symbols (see llvm.used).
+    /// Allows `#[used]` to preserve symbols (see llvm.used).
     (accepted, used, "1.30.0", Some(40289), None),
-    // Allows `crate` in paths.
+    /// Allows `crate` in paths.
     (accepted, crate_in_paths, "1.30.0", Some(45477), None),
-    // Allows resolving absolute paths as paths from other crates.
+    /// Allows resolving absolute paths as paths from other crates.
     (accepted, extern_absolute_paths, "1.30.0", Some(44660), None),
-    // Allows access to crate names passed via `--extern` through prelude.
+    /// Allows access to crate names passed via `--extern` through prelude.
     (accepted, extern_prelude, "1.30.0", Some(44660), None),
-    // Allows parentheses in patterns.
+    /// Allows parentheses in patterns.
     (accepted, pattern_parentheses, "1.31.0", Some(51087), None),
-    // Allows the definition of `const fn` functions.
+    /// Allows the definition of `const fn` functions.
     (accepted, min_const_fn, "1.31.0", Some(53555), None),
-    // Allows scoped lints.
+    /// Allows scoped lints.
     (accepted, tool_lints, "1.31.0", Some(44690), None),
-    // Allows lifetime elision in `impl` headers. For example:
-    // + `impl<I:Iterator> Iterator for &mut Iterator`
-    // + `impl Debug for Foo<'_>`
+    /// Allows lifetime elision in `impl` headers. For example:
+    /// + `impl<I:Iterator> Iterator for &mut Iterator`
+    /// + `impl Debug for Foo<'_>`
     (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None),
-    // Allows `extern crate foo as bar;`. This puts `bar` into extern prelude.
+    /// Allows `extern crate foo as bar;`. This puts `bar` into extern prelude.
     (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
-    // Allows use of the `:literal` macro fragment specifier (RFC 1576).
+    /// Allows use of the `:literal` macro fragment specifier (RFC 1576).
     (accepted, macro_literal_matcher, "1.32.0", Some(35625), None),
-    // Allows use of `?` as the Kleene "at most one" operator in macros.
+    /// Allows use of `?` as the Kleene "at most one" operator in macros.
     (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None),
-    // Allows `Self` struct constructor (RFC 2302).
+    /// Allows `Self` struct constructor (RFC 2302).
     (accepted, self_struct_ctor, "1.32.0", Some(51994), None),
-    // Allows `Self` in type definitions (RFC 2300).
+    /// Allows `Self` in type definitions (RFC 2300).
     (accepted, self_in_typedefs, "1.32.0", Some(49303), None),
-    // Allows `use x::y;` to search `x` in the current scope.
+    /// Allows `use x::y;` to search `x` in the current scope.
     (accepted, uniform_paths, "1.32.0", Some(53130), None),
-    // Allows integer match exhaustiveness checking (RFC 2591).
+    /// Allows integer match exhaustiveness checking (RFC 2591).
     (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None),
-    // Allows `use path as _;` and `extern crate c as _;`.
+    /// Allows `use path as _;` and `extern crate c as _;`.
     (accepted, underscore_imports, "1.33.0", Some(48216), None),
-    // Allows `#[repr(packed(N))]` attribute on structs.
+    /// Allows `#[repr(packed(N))]` attribute on structs.
     (accepted, repr_packed, "1.33.0", Some(33158), None),
-    // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
+    /// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
     (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None),
-    // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
+    /// Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
     (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
-    // Allows let bindings, assignments and destructuring in `const` functions and constants.
-    // As long as control flow is not implemented in const eval, `&&` and `||` may not be used
-    // at the same time as let bindings.
+    /// Allows let bindings, assignments and destructuring in `const` functions and constants.
+    /// As long as control flow is not implemented in const eval, `&&` and `||` may not be used
+    /// at the same time as let bindings.
     (accepted, const_let, "1.33.0", Some(48821), None),
-    // Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
+    /// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
     (accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
-    // Allows top level or-patterns (`p | q`) in `if let` and `while let`.
+    /// Allows top level or-patterns (`p | q`) in `if let` and `while let`.
     (accepted, if_while_or_patterns, "1.33.0", Some(48215), None),
-    // Allows `cfg(target_vendor = "...")`.
+    /// Allows `cfg(target_vendor = "...")`.
     (accepted, cfg_target_vendor, "1.33.0", Some(29718), None),
-    // Allows `extern crate self as foo;`.
-    // This puts local crate root into extern prelude under name `foo`.
+    /// Allows `extern crate self as foo;`.
+    /// This puts local crate root into extern prelude under name `foo`.
     (accepted, extern_crate_self, "1.34.0", Some(56409), None),
-    // Allows arbitrary delimited token streams in non-macro attributes.
+    /// Allows arbitrary delimited token streams in non-macro attributes.
     (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None),
-    // Allows paths to enum variants on type aliases including `Self`.
+    /// Allows paths to enum variants on type aliases including `Self`.
     (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None),
-    // Allows using `#[repr(align(X))]` on enums with equivalent semantics
-    // to wrapping an enum in a wrapper struct with `#[repr(align(X))]`.
+    /// Allows using `#[repr(align(X))]` on enums with equivalent semantics
+    /// to wrapping an enum in a wrapper struct with `#[repr(align(X))]`.
     (accepted, repr_align_enum, "1.37.0", Some(57996), None),
-    // Allows `const _: TYPE = VALUE`.
+    /// Allows `const _: TYPE = VALUE`.
     (accepted, underscore_const_names, "1.37.0", Some(54912), None),
-    // Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
+    /// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
     (accepted, async_await, "1.39.0", Some(50547), None),
 
     // -------------------------------------------------------------------------
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index 0bff4ed24a4ce..4008b79b141eb 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -3,6 +3,7 @@
 use crate::edition::Edition;
 use crate::symbol::{Symbol, sym};
 use syntax_pos::Span;
+use super::{State, Feature};
 
 macro_rules! set {
     ($field: ident) => {{
@@ -14,12 +15,24 @@ macro_rules! set {
 }
 
 macro_rules! declare_features {
-    ($((active, $feature: ident, $ver: expr, $issue: expr, $edition: expr),)+) => {
+    ($(
+        $(#[doc = $doc:tt])* (active, $feature:ident, $ver:expr, $issue:expr, $edition:expr),
+    )+) => {
         /// Represents active features that are currently being implemented or
         /// currently being considered for addition/removal.
         pub const ACTIVE_FEATURES:
-            &[(Symbol, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] =
-            &[$((sym::$feature, $ver, $issue, $edition, set!($feature))),+];
+            &[Feature] =
+            &[$(
+                // (sym::$feature, $ver, $issue, $edition, set!($feature))
+                Feature {
+                    state: State::Active { set: set!($feature) },
+                    name: sym::$feature,
+                    since: $ver,
+                    issue: $issue,
+                    edition: $edition,
+                    description: concat!($($doc,)*),
+                }
+            ),+];
 
         /// A set of features to be used by later passes.
         #[derive(Clone)]
@@ -28,7 +41,10 @@ macro_rules! declare_features {
             pub declared_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
             /// `#![feature]` attrs for non-language (library) features
             pub declared_lib_features: Vec<(Symbol, Span)>,
-            $(pub $feature: bool),+
+            $(
+                $(#[doc = $doc])*
+                pub $feature: bool
+            ),+
         }
 
         impl Features {
@@ -58,7 +74,7 @@ macro_rules! declare_features {
 // stable (active).
 //
 // Note that the features are grouped into internal/user-facing and then
-// sorted by version inside those groups. This is inforced with tidy.
+// sorted by version inside those groups. This is enforced with tidy.
 //
 // N.B., `tools/tidy/src/features.rs` parses this information directly out of the
 // source, so take care when modifying it.
@@ -70,127 +86,127 @@ declare_features! (
 
     // no-tracking-issue-start
 
-    // Allows using compiler's own crates.
+    /// Allows using compiler's own crates.
     (active, rustc_private, "1.0.0", Some(27812), None),
 
-    // Allows using the `rust-intrinsic`'s "ABI".
+    /// Allows using the `rust-intrinsic`'s "ABI".
     (active, intrinsics, "1.0.0", None, None),
 
-    // Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
+    /// Allows using `#[lang = ".."]` attribute for linking items to special compiler logic.
     (active, lang_items, "1.0.0", None, None),
 
-    // Allows using the `#[stable]` and `#[unstable]` attributes.
+    /// Allows using the `#[stable]` and `#[unstable]` attributes.
     (active, staged_api, "1.0.0", None, None),
 
-    // Allows using `#[allow_internal_unstable]`. This is an
-    // attribute on `macro_rules!` and can't use the attribute handling
-    // below (it has to be checked before expansion possibly makes
-    // macros disappear).
+    /// Allows using `#[allow_internal_unstable]`. This is an
+    /// attribute on `macro_rules!` and can't use the attribute handling
+    /// below (it has to be checked before expansion possibly makes
+    /// macros disappear).
     (active, allow_internal_unstable, "1.0.0", None, None),
 
-    // Allows using `#[allow_internal_unsafe]`. This is an
-    // attribute on `macro_rules!` and can't use the attribute handling
-    // below (it has to be checked before expansion possibly makes
-    // macros disappear).
+    /// Allows using `#[allow_internal_unsafe]`. This is an
+    /// attribute on `macro_rules!` and can't use the attribute handling
+    /// below (it has to be checked before expansion possibly makes
+    /// macros disappear).
     (active, allow_internal_unsafe, "1.0.0", None, None),
 
-    // Allows using the macros:
-    // + `__diagnostic_used`
-    // + `__register_diagnostic`
-    // +`__build_diagnostic_array`
+    /// Allows using the macros:
+    /// + `__diagnostic_used`
+    /// + `__register_diagnostic`
+    /// +`__build_diagnostic_array`
     (active, rustc_diagnostic_macros, "1.0.0", None, None),
 
-    // Allows using `#[rustc_const_unstable(feature = "foo", ..)]` which
-    // lets a function to be `const` when opted into with `#![feature(foo)]`.
+    /// Allows using `#[rustc_const_unstable(feature = "foo", ..)]` which
+    /// lets a function to be `const` when opted into with `#![feature(foo)]`.
     (active, rustc_const_unstable, "1.0.0", None, None),
 
-    // no-tracking-issue-end
+    /// no-tracking-issue-end
 
-    // Allows using `#[link_name="llvm.*"]`.
+    /// Allows using `#[link_name="llvm.*"]`.
     (active, link_llvm_intrinsics, "1.0.0", Some(29602), None),
 
-    // Allows using `rustc_*` attributes (RFC 572).
+    /// Allows using `rustc_*` attributes (RFC 572).
     (active, rustc_attrs, "1.0.0", Some(29642), None),
 
-    // Allows using `#[on_unimplemented(..)]` on traits.
+    /// Allows using `#[on_unimplemented(..)]` on traits.
     (active, on_unimplemented, "1.0.0", Some(29628), None),
 
-    // Allows using the `box $expr` syntax.
+    /// Allows using the `box $expr` syntax.
     (active, box_syntax, "1.0.0", Some(49733), None),
 
-    // Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls.
+    /// Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls.
     (active, main, "1.0.0", Some(29634), None),
 
-    // Allows using `#[start]` on a function indicating that it is the program entrypoint.
+    /// Allows using `#[start]` on a function indicating that it is the program entrypoint.
     (active, start, "1.0.0", Some(29633), None),
 
-    // Allows using the `#[fundamental]` attribute.
+    /// Allows using the `#[fundamental]` attribute.
     (active, fundamental, "1.0.0", Some(29635), None),
 
-    // Allows using the `rust-call` ABI.
+    /// Allows using the `rust-call` ABI.
     (active, unboxed_closures, "1.0.0", Some(29625), None),
 
-    // Allows using the `#[linkage = ".."]` attribute.
+    /// Allows using the `#[linkage = ".."]` attribute.
     (active, linkage, "1.0.0", Some(29603), None),
 
-    // Allows features specific to OIBIT (auto traits).
+    /// Allows features specific to OIBIT (auto traits).
     (active, optin_builtin_traits, "1.0.0", Some(13231), None),
 
-    // Allows using `box` in patterns (RFC 469).
+    /// Allows using `box` in patterns (RFC 469).
     (active, box_patterns, "1.0.0", Some(29641), None),
 
     // no-tracking-issue-start
 
-    // Allows using `#[prelude_import]` on glob `use` items.
+    /// Allows using `#[prelude_import]` on glob `use` items.
     (active, prelude_import, "1.2.0", None, None),
 
     // no-tracking-issue-end
 
     // no-tracking-issue-start
 
-    // Allows using `#[omit_gdb_pretty_printer_section]`.
+    /// Allows using `#[omit_gdb_pretty_printer_section]`.
     (active, omit_gdb_pretty_printer_section, "1.5.0", None, None),
 
-    // Allows using the `vectorcall` ABI.
+    /// Allows using the `vectorcall` ABI.
     (active, abi_vectorcall, "1.7.0", None, None),
 
     // no-tracking-issue-end
 
-    // Allows using `#[structural_match]` which indicates that a type is structurally matchable.
+    /// Allows using `#[structural_match]` which indicates that a type is structurally matchable.
     (active, structural_match, "1.8.0", Some(31434), None),
 
-    // Allows using the `may_dangle` attribute (RFC 1327).
+    /// Allows using the `may_dangle` attribute (RFC 1327).
     (active, dropck_eyepatch, "1.10.0", Some(34761), None),
 
-    // Allows using the `#![panic_runtime]` attribute.
+    /// Allows using the `#![panic_runtime]` attribute.
     (active, panic_runtime, "1.10.0", Some(32837), None),
 
-    // Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
+    /// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
     (active, needs_panic_runtime, "1.10.0", Some(32837), None),
 
     // no-tracking-issue-start
 
-    // Allows identifying the `compiler_builtins` crate.
+    /// Allows identifying the `compiler_builtins` crate.
     (active, compiler_builtins, "1.13.0", None, None),
 
-    // Allows using the `unadjusted` ABI; perma-unstable.
+    /// Allows using the `unadjusted` ABI; perma-unstable.
     (active, abi_unadjusted, "1.16.0", None, None),
 
-    // Allows identifying crates that contain sanitizer runtimes.
+    /// Allows identifying crates that contain sanitizer runtimes.
     (active, sanitizer_runtime, "1.17.0", None, None),
 
-    // Used to identify crates that contain the profiler runtime.
+    /// Used to identify crates that contain the profiler runtime.
     (active, profiler_runtime, "1.18.0", None, None),
 
-    // Allows using the `thiscall` ABI.
+    /// Allows using the `thiscall` ABI.
     (active, abi_thiscall, "1.19.0", None, None),
 
-    // Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`.
+    /// Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`.
     (active, allocator_internals, "1.20.0", None, None),
 
     // no-tracking-issue-end
 
-    // Added for testing E0705; perma-unstable.
+    /// Added for testing E0705; perma-unstable.
     (active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)),
 
     // -------------------------------------------------------------------------
@@ -228,281 +244,282 @@ declare_features! (
     // feature-group-start: actual feature gates
     // -------------------------------------------------------------------------
 
-    // Allows using the `#[link_args]` attribute.
+    /// Allows using the `#[link_args]` attribute.
     (active, link_args, "1.0.0", Some(29596), None),
 
-    // Allows defining identifiers beyond ASCII.
+    /// Allows defining identifiers beyond ASCII.
     (active, non_ascii_idents, "1.0.0", Some(55467), None),
 
-    // Allows using `#[plugin_registrar]` on functions.
+    /// Allows using `#[plugin_registrar]` on functions.
     (active, plugin_registrar, "1.0.0", Some(29597), None),
 
-    // Allows using `#![plugin(myplugin)]`.
+    /// Allows using `#![plugin(myplugin)]`.
     (active, plugin, "1.0.0", Some(29597), None),
 
-    // Allows using `#[thread_local]` on `static` items.
+    /// Allows using `#[thread_local]` on `static` items.
     (active, thread_local, "1.0.0", Some(29594), None),
 
-    // Allows the use of SIMD types in functions declared in `extern` blocks.
+    /// Allows the use of SIMD types in functions declared in `extern` blocks.
     (active, simd_ffi, "1.0.0", Some(27731), None),
 
-    // Allows using custom attributes (RFC 572).
+    /// Allows using custom attributes (RFC 572).
     (active, custom_attribute, "1.0.0", Some(29642), None),
 
-    // Allows using non lexical lifetimes (RFC 2094).
+    /// Allows using non lexical lifetimes (RFC 2094).
     (active, nll, "1.0.0", Some(43234), None),
 
-    // Allows using slice patterns.
+    /// Allows using slice patterns.
     (active, slice_patterns, "1.0.0", Some(62254), None),
 
-    // Allows the definition of `const` functions with some advanced features.
+    /// Allows the definition of `const` functions with some advanced features.
     (active, const_fn, "1.2.0", Some(57563), None),
 
-    // Allows associated type defaults.
+    /// Allows associated type defaults.
     (active, associated_type_defaults, "1.2.0", Some(29661), None),
 
-    // Allows `#![no_core]`.
+    /// Allows `#![no_core]`.
     (active, no_core, "1.3.0", Some(29639), None),
 
-    // Allows default type parameters to influence type inference.
+    /// Allows default type parameters to influence type inference.
     (active, default_type_parameter_fallback, "1.3.0", Some(27336), None),
 
-    // Allows `repr(simd)` and importing the various simd intrinsics.
+    /// Allows `repr(simd)` and importing the various simd intrinsics.
     (active, repr_simd, "1.4.0", Some(27731), None),
 
-    // Allows `extern "platform-intrinsic" { ... }`.
+    /// Allows `extern "platform-intrinsic" { ... }`.
     (active, platform_intrinsics, "1.4.0", Some(27731), None),
 
-    // Allows `#[unwind(..)]`.
-    //
-    // Permits specifying whether a function should permit unwinding or abort on unwind.
+    /// Allows `#[unwind(..)]`.
+    ///
+    /// Permits specifying whether a function should permit unwinding or abort on unwind.
     (active, unwind_attributes, "1.4.0", Some(58760), None),
 
-    // Allows `#[no_debug]`.
+    /// Allows `#[no_debug]`.
     (active, no_debug, "1.5.0", Some(29721), None),
 
-    // Allows attributes on expressions and non-item statements.
+    /// Allows attributes on expressions and non-item statements.
     (active, stmt_expr_attributes, "1.6.0", Some(15701), None),
 
-    // Allows the use of type ascription in expressions.
+    /// Allows the use of type ascription in expressions.
     (active, type_ascription, "1.6.0", Some(23416), None),
 
-    // Allows `cfg(target_thread_local)`.
+    /// Allows `cfg(target_thread_local)`.
     (active, cfg_target_thread_local, "1.7.0", Some(29594), None),
 
-    // Allows specialization of implementations (RFC 1210).
+    /// Allows specialization of implementations (RFC 1210).
     (active, specialization, "1.7.0", Some(31844), None),
 
-    // Allows using `#[naked]` on functions.
+    /// Allows using `#[naked]` on functions.
     (active, naked_functions, "1.9.0", Some(32408), None),
 
-    // Allows `cfg(target_has_atomic = "...")`.
+    /// Allows `cfg(target_has_atomic = "...")`.
     (active, cfg_target_has_atomic, "1.9.0", Some(32976), None),
 
-    // Allows `X..Y` patterns.
+    /// Allows `X..Y` patterns.
     (active, exclusive_range_pattern, "1.11.0", Some(37854), None),
 
-    // Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
+    /// Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more.
     (active, never_type, "1.13.0", Some(35121), None),
 
-    // Allows exhaustive pattern matching on types that contain uninhabited types.
+    /// Allows exhaustive pattern matching on types that contain uninhabited types.
     (active, exhaustive_patterns, "1.13.0", Some(51085), None),
 
-    // Allows untagged unions `union U { ... }`.
+    /// Allows untagged unions `union U { ... }`.
     (active, untagged_unions, "1.13.0", Some(32836), None),
 
-    // Allows `#[link(..., cfg(..))]`.
+    /// Allows `#[link(..., cfg(..))]`.
     (active, link_cfg, "1.14.0", Some(37406), None),
 
-    // Allows `extern "ptx-*" fn()`.
+    /// Allows `extern "ptx-*" fn()`.
     (active, abi_ptx, "1.15.0", Some(38788), None),
 
-    // Allows the `#[repr(i128)]` attribute for enums.
+    /// Allows the `#[repr(i128)]` attribute for enums.
     (active, repr128, "1.16.0", Some(35118), None),
 
-    // Allows `#[link(kind="static-nobundle"...)]`.
+    /// Allows `#[link(kind="static-nobundle"...)]`.
     (active, static_nobundle, "1.16.0", Some(37403), None),
 
-    // Allows `extern "msp430-interrupt" fn()`.
+    /// Allows `extern "msp430-interrupt" fn()`.
     (active, abi_msp430_interrupt, "1.16.0", Some(38487), None),
 
-    // Allows declarative macros 2.0 (`macro`).
+    /// Allows declarative macros 2.0 (`macro`).
     (active, decl_macro, "1.17.0", Some(39412), None),
 
-    // Allows `extern "x86-interrupt" fn()`.
+    /// Allows `extern "x86-interrupt" fn()`.
     (active, abi_x86_interrupt, "1.17.0", Some(40180), None),
 
-    // Allows overlapping impls of marker traits.
+    /// Allows overlapping impls of marker traits.
     (active, overlapping_marker_traits, "1.18.0", Some(29864), None),
 
-    // Allows a test to fail without failing the whole suite.
+    /// Allows a test to fail without failing the whole suite.
     (active, allow_fail, "1.19.0", Some(46488), None),
 
-    // Allows unsized tuple coercion.
+    /// Allows unsized tuple coercion.
     (active, unsized_tuple_coercion, "1.20.0", Some(42877), None),
 
-    // Allows defining generators.
+    /// Allows defining generators.
     (active, generators, "1.21.0", Some(43122), None),
 
-    // Allows `#[doc(cfg(...))]`.
+    /// Allows `#[doc(cfg(...))]`.
     (active, doc_cfg, "1.21.0", Some(43781), None),
 
-    // Allows `#[doc(masked)]`.
+    /// Allows `#[doc(masked)]`.
     (active, doc_masked, "1.21.0", Some(44027), None),
 
-    // Allows `#[doc(spotlight)]`.
+    /// Allows `#[doc(spotlight)]`.
     (active, doc_spotlight, "1.22.0", Some(45040), None),
 
-    // Allows `#[doc(include = "some-file")]`.
+    /// Allows `#[doc(include = "some-file")]`.
     (active, external_doc, "1.22.0", Some(44732), None),
 
-    // Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008).
+    /// Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008).
     (active, non_exhaustive, "1.22.0", Some(44109), None),
 
-    // Allows using `crate` as visibility modifier, synonymous with `pub(crate)`.
+    /// Allows using `crate` as visibility modifier, synonymous with `pub(crate)`.
     (active, crate_visibility_modifier, "1.23.0", Some(53120), None),
 
-    // Allows defining `extern type`s.
+    /// Allows defining `extern type`s.
     (active, extern_types, "1.23.0", Some(43467), None),
 
-    // Allows trait methods with arbitrary self types.
+    /// Allows trait methods with arbitrary self types.
     (active, arbitrary_self_types, "1.23.0", Some(44874), None),
 
-    // Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
+    /// Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`).
     (active, in_band_lifetimes, "1.23.0", Some(44524), None),
 
-    // Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
+    /// Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
     (active, generic_associated_types, "1.23.0", Some(44265), None),
 
-    // Allows defining `trait X = A + B;` alias items.
+    /// Allows defining `trait X = A + B;` alias items.
     (active, trait_alias, "1.24.0", Some(41517), None),
 
-    // Allows infering `'static` outlives requirements (RFC 2093).
+    /// Allows infering `'static` outlives requirements (RFC 2093).
     (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None),
 
-    // Allows macro invocations in `extern {}` blocks.
+    /// Allows macro invocations in `extern {}` blocks.
     (active, macros_in_extern, "1.27.0", Some(49476), None),
 
-    // Allows accessing fields of unions inside `const` functions.
+    /// Allows accessing fields of unions inside `const` functions.
     (active, const_fn_union, "1.27.0", Some(51909), None),
 
-    // Allows casting raw pointers to `usize` during const eval.
+    /// Allows casting raw pointers to `usize` during const eval.
     (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None),
 
-    // Allows dereferencing raw pointers during const eval.
+    /// Allows dereferencing raw pointers during const eval.
     (active, const_raw_ptr_deref, "1.27.0", Some(51911), None),
 
-    // Allows comparing raw pointers during const eval.
+    /// Allows comparing raw pointers during const eval.
     (active, const_compare_raw_pointers, "1.27.0", Some(53020), None),
 
-    // Allows `#[doc(alias = "...")]`.
+    /// Allows `#[doc(alias = "...")]`.
     (active, doc_alias, "1.27.0", Some(50146), None),
 
-    // Allows inconsistent bounds in where clauses.
+    /// Allows inconsistent bounds in where clauses.
     (active, trivial_bounds, "1.28.0", Some(48214), None),
 
-    // Allows `'a: { break 'a; }`.
+    /// Allows `'a: { break 'a; }`.
     (active, label_break_value, "1.28.0", Some(48594), None),
 
-    // Allows using `#[doc(keyword = "...")]`.
+    /// Allows using `#[doc(keyword = "...")]`.
     (active, doc_keyword, "1.28.0", Some(51315), None),
 
-    // Allows reinterpretation of the bits of a value of one type as another type during const eval.
+    /// Allows reinterpretation of the bits of a value of one type as another
+    /// type during const eval.
     (active, const_transmute, "1.29.0", Some(53605), None),
 
-    // Allows using `try {...}` expressions.
+    /// Allows using `try {...}` expressions.
     (active, try_blocks, "1.29.0", Some(31436), None),
 
-    // Allows defining an `#[alloc_error_handler]`.
+    /// Allows defining an `#[alloc_error_handler]`.
     (active, alloc_error_handler, "1.29.0", Some(51540), None),
 
-    // Allows using the `amdgpu-kernel` ABI.
+    /// Allows using the `amdgpu-kernel` ABI.
     (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None),
 
-    // Allows panicking during const eval (producing compile-time errors).
+    /// Allows panicking during const eval (producing compile-time errors).
     (active, const_panic, "1.30.0", Some(51999), None),
 
-    // Allows `#[marker]` on certain traits allowing overlapping implementations.
+    /// Allows `#[marker]` on certain traits allowing overlapping implementations.
     (active, marker_trait_attr, "1.30.0", Some(29864), None),
 
-    // Allows macro invocations on modules expressions and statements and
-    // procedural macros to expand to non-items.
+    /// Allows macro invocations on modules expressions and statements and
+    /// procedural macros to expand to non-items.
     (active, proc_macro_hygiene, "1.30.0", Some(54727), None),
 
-    // Allows unsized rvalues at arguments and parameters.
+    /// Allows unsized rvalues at arguments and parameters.
     (active, unsized_locals, "1.30.0", Some(48055), None),
 
-    // Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.
+    /// Allows custom test frameworks with `#![test_runner]` and `#[test_case]`.
     (active, custom_test_frameworks, "1.30.0", Some(50297), None),
 
-    // Allows non-builtin attributes in inner attribute position.
+    /// Allows non-builtin attributes in inner attribute position.
     (active, custom_inner_attributes, "1.30.0", Some(54726), None),
 
-    // Allows mixing bind-by-move in patterns and references to those identifiers in guards.
+    /// Allows mixing bind-by-move in patterns and references to those identifiers in guards.
     (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None),
 
-    // Allows `impl Trait` in bindings (`let`, `const`, `static`).
+    /// Allows `impl Trait` in bindings (`let`, `const`, `static`).
     (active, impl_trait_in_bindings, "1.30.0", Some(63065), None),
 
-    // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
+    /// Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check.
     (active, lint_reasons, "1.31.0", Some(54503), None),
 
-    // Allows exhaustive integer pattern matching on `usize` and `isize`.
+    /// Allows exhaustive integer pattern matching on `usize` and `isize`.
     (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
 
-    // Allows relaxing the coherence rules such that
-    // `impl<T> ForeignTrait<LocalType> for ForeignType<T> is permitted.
+    /// Allows relaxing the coherence rules such that
+    /// `impl<T> ForeignTrait<LocalType> for ForeignType<T> is permitted.
     (active, re_rebalance_coherence, "1.32.0", Some(55437), None),
 
-    // Allows using `#[ffi_returns_twice]` on foreign functions.
+    /// Allows using `#[ffi_returns_twice]` on foreign functions.
     (active, ffi_returns_twice, "1.34.0", Some(58314), None),
 
-    // Allows const generic types (e.g. `struct Foo<const N: usize>(...);`).
+    /// Allows const generic types (e.g. `struct Foo<const N: usize>(...);`).
     (active, const_generics, "1.34.0", Some(44580), None),
 
-    // Allows using `#[optimize(X)]`.
+    /// Allows using `#[optimize(X)]`.
     (active, optimize_attribute, "1.34.0", Some(54882), None),
 
-    // Allows using C-variadics.
+    /// Allows using C-variadics.
     (active, c_variadic, "1.34.0", Some(44930), None),
 
-    // Allows the user of associated type bounds.
+    /// Allows the user of associated type bounds.
     (active, associated_type_bounds, "1.34.0", Some(52662), None),
 
-    // Attributes on formal function params.
+    /// Attributes on formal function params.
     (active, param_attrs, "1.36.0", Some(60406), None),
 
-    // Allows calling constructor functions in `const fn`.
+    /// Allows calling constructor functions in `const fn`.
     (active, const_constructor, "1.37.0", Some(61456), None),
 
-    // Allows `if/while p && let q = r && ...` chains.
+    /// Allows `if/while p && let q = r && ...` chains.
     (active, let_chains, "1.37.0", Some(53667), None),
 
-    // Allows #[repr(transparent)] on enums (RFC 2645).
+    /// Allows #[repr(transparent)] on enums (RFC 2645).
     (active, transparent_enums, "1.37.0", Some(60405), None),
 
-    // Allows #[repr(transparent)] on unions (RFC 2645).
+    /// Allows #[repr(transparent)] on unions (RFC 2645).
     (active, transparent_unions, "1.37.0", Some(60405), None),
 
-    // Allows explicit discriminants on non-unit enum variants.
+    /// Allows explicit discriminants on non-unit enum variants.
     (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
 
-    // Allows `impl Trait` with multiple unrelated lifetimes.
+    /// Allows `impl Trait` with multiple unrelated lifetimes.
     (active, member_constraints, "1.37.0", Some(61977), None),
 
-    // Allows `async || body` closures.
+    /// Allows `async || body` closures.
     (active, async_closure, "1.37.0", Some(62290), None),
 
-    // Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests
+    /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests
     (active, cfg_doctest, "1.37.0", Some(62210), None),
 
-    // Allows `[x; N]` where `x` is a constant (RFC 2203).
+    /// Allows `[x; N]` where `x` is a constant (RFC 2203).
     (active, const_in_array_repeat_expressions, "1.37.0", Some(49147), None),
 
-    // Allows `impl Trait` to be used inside type aliases (RFC 2515).
+    /// Allows `impl Trait` to be used inside type aliases (RFC 2515).
     (active, type_alias_impl_trait, "1.38.0", Some(63063), None),
 
-    // Allows the use of or-patterns, e.g. `0 | 1`.
+    /// Allows the use of or-patterns, e.g. `0 | 1`.
     (active, or_patterns, "1.38.0", Some(54883), None),
 
     // -------------------------------------------------------------------------
diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs
index 6ebfeb29f677b..6494c82e1228b 100644
--- a/src/libsyntax/feature_gate/removed.rs
+++ b/src/libsyntax/feature_gate/removed.rs
@@ -3,14 +3,18 @@
 use crate::symbol::{Symbol, sym};
 
 macro_rules! declare_features {
-    ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => {
+    ($(
+        $(#[doc = $doc:tt])* (removed, $feature:ident, $ver:expr, $issue:expr, None, $reason:expr),
+    )+) => {
         /// Represents unstable features which have since been removed (it was once Active)
         pub const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
             $((sym::$feature, $ver, $issue, $reason)),+
         ];
     };
 
-    ($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => {
+    ($(
+        $(#[doc = $doc:tt])* (stable_removed, $feature:ident, $ver:expr, $issue:expr, None),
+    )+) => {
         /// Represents stable features which have since been removed (it was once Accepted)
         pub const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
             $((sym::$feature, $ver, $issue, None)),+
@@ -25,17 +29,17 @@ declare_features! (
 
     (removed, import_shadowing, "1.0.0", None, None, None),
     (removed, managed_boxes, "1.0.0", None, None, None),
-    // Allows use of unary negate on unsigned integers, e.g., -e for e: u8
+    /// Allows use of unary negate on unsigned integers, e.g., -e for e: u8
     (removed, negate_unsigned, "1.0.0", Some(29645), None, None),
     (removed, reflect, "1.0.0", Some(27749), None, None),
-    // A way to temporarily opt out of opt in copy. This will *never* be accepted.
+    /// A way to temporarily opt out of opt in copy. This will *never* be accepted.
     (removed, opt_out_copy, "1.0.0", None, None, None),
     (removed, quad_precision_float, "1.0.0", None, None, None),
     (removed, struct_inherit, "1.0.0", None, None, None),
     (removed, test_removed_feature, "1.0.0", None, None, None),
     (removed, visible_private_types, "1.0.0", None, None, None),
     (removed, unsafe_no_drop_flag, "1.0.0", None, None, None),
-    // Allows using items which are missing stability attributes
+    /// Allows using items which are missing stability attributes
     (removed, unmarked_api, "1.0.0", None, None, None),
     (removed, allocator, "1.0.0", None, None, None),
     (removed, simd, "1.0.0", Some(27731), None,
@@ -57,18 +61,18 @@ declare_features! (
      Some("subsumed by `#![feature(proc_macro_hygiene)]`")),
     (removed, panic_implementation, "1.28.0", Some(44489), None,
      Some("subsumed by `#[panic_handler]`")),
-    // Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
+    /// Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`.
     (removed, custom_derive, "1.32.0", Some(29644), None,
      Some("subsumed by `#[proc_macro_derive]`")),
-    // Paths of the form: `extern::foo::bar`
+    /// Paths of the form: `extern::foo::bar`
     (removed, extern_in_paths, "1.33.0", Some(55600), None,
      Some("subsumed by `::foo::bar` paths")),
     (removed, quote, "1.33.0", Some(29601), None, None),
-    // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
+    /// Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238).
     (removed, dropck_parametricity, "1.38.0", Some(28498), None, None),
     (removed, await_macro, "1.38.0", Some(50547), None,
      Some("subsumed by `.await` syntax")),
-    // Allows defining `existential type`s.
+    /// Allows defining `existential type`s.
     (removed, existential_type, "1.38.0", Some(63063), None,
      Some("removed in favor of `#![feature(type_alias_impl_trait)]`")),
 

From 9bbe8aed4b524c0922e2414b4916e57730f20407 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de>
Date: Sat, 24 Aug 2019 18:47:43 +0200
Subject: [PATCH 171/943] submodules: update clippy from cd3df6be to 2bcb6155

Changes:
````
Refactor some minor things
Use more if-chains
Refactor 'lint_or_fun_call'
Refactor 'check_unwrap_or_default'
Refactor 'check_impl_item'
Add missing field to LitKind::Str
Run update_lints for Unicode lint
Re-add false positive check
Add raw string regression test for useless_format lint
Re-factor useless_format lint
Update Unicode lint tests
Add two more tests, allow 2 other lints.
Fix `temporary_cstring_as_ptr` false negative
Add more testcases for redundant_pattern_matching
Fix suggestions for redundant_pattern_matching
Add note on how to find the latest beta commit
Remove feature gate for async_await
Update if_chain doc link
Requested test cleanup
Requested changes
Ignore lines starting with '#'
run-rustfix for unseparated-prefix-literals
Add autofixable suggestion for unseparated integer literal suffices
Further text improvements
Add image
docs: Explain how to update the changelog
````
---
 src/tools/clippy | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/clippy b/src/tools/clippy
index cd3df6bee0ee0..2bcb6155948e2 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit cd3df6bee0ee07c7dbb562b29576a0b513a4331b
+Subproject commit 2bcb6155948e2f8b86db08152a5f54bd5af625e5

From 6a3d51731408708cbc6a6e4e2683da8df7326007 Mon Sep 17 00:00:00 2001
From: Caio <c410.f3r@gmail.com>
Date: Sat, 24 Aug 2019 13:54:40 -0300
Subject: [PATCH 172/943] Modifies how Arg, Arm, Field, FieldPattern and
 Variant are visited

Part of the necessary work to accomplish #63468.
---
 src/librustc/hir/map/def_collector.rs  |   7 +-
 src/librustc/lint/context.rs           |  35 +++----
 src/librustc/lint/mod.rs               |  36 ++-----
 src/librustc_lint/builtin.rs           |   2 +-
 src/librustc_lint/nonstandard_style.rs |   5 +-
 src/librustc_passes/ast_validation.rs  |   3 +-
 src/librustc_passes/hir_stats.rs       |   7 +-
 src/libsyntax/ext/expand.rs            |  10 +-
 src/libsyntax/mut_visit.rs             | 126 +++++++++++++++----------
 src/libsyntax/util/node_count.rs       |   7 +-
 src/libsyntax/visit.rs                 |  54 ++++++-----
 11 files changed, 147 insertions(+), 145 deletions(-)

diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index d725afa405212..17bcb1d085968 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -154,7 +154,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
         });
     }
 
-    fn visit_variant(&mut self, v: &'a Variant, g: &'a Generics, item_id: NodeId) {
+    fn visit_variant(&mut self, v: &'a Variant) {
         let def = self.create_def(v.id,
                                   DefPathData::TypeNs(v.ident.as_interned_str()),
                                   v.span);
@@ -162,12 +162,11 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
             if let Some(ctor_hir_id) = v.data.ctor_id() {
                 this.create_def(ctor_hir_id, DefPathData::Ctor, v.span);
             }
-            visit::walk_variant(this, v, g, item_id)
+            visit::walk_variant(this, v)
         });
     }
 
-    fn visit_variant_data(&mut self, data: &'a VariantData, _: Ident,
-                          _: &'a Generics, _: NodeId, _: Span) {
+    fn visit_variant_data(&mut self, data: &'a VariantData) {
         for (index, field) in data.fields().iter().enumerate() {
             let name = field.ident.map(|ident| ident.name)
                 .unwrap_or_else(|| sym::integer(index));
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 6801fa8d8dbe5..8126db1429247 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -1040,13 +1040,13 @@ for LateContextAndPass<'a, 'tcx, T> {
 
     fn visit_variant_data(&mut self,
                         s: &'tcx hir::VariantData,
-                        name: ast::Name,
-                        g: &'tcx hir::Generics,
-                        item_id: hir::HirId,
+                        _: ast::Name,
+                        _: &'tcx hir::Generics,
+                        _: hir::HirId,
                         _: Span) {
-        lint_callback!(self, check_struct_def, s, name, g, item_id);
+        lint_callback!(self, check_struct_def, s);
         hir_visit::walk_struct_def(self, s);
-        lint_callback!(self, check_struct_def_post, s, name, g, item_id);
+        lint_callback!(self, check_struct_def_post, s);
     }
 
     fn visit_struct_field(&mut self, s: &'tcx hir::StructField) {
@@ -1061,9 +1061,9 @@ for LateContextAndPass<'a, 'tcx, T> {
                      g: &'tcx hir::Generics,
                      item_id: hir::HirId) {
         self.with_lint_attrs(v.id, &v.attrs, |cx| {
-            lint_callback!(cx, check_variant, v, g);
+            lint_callback!(cx, check_variant, v);
             hir_visit::walk_variant(cx, v, g, item_id);
-            lint_callback!(cx, check_variant_post, v, g);
+            lint_callback!(cx, check_variant_post, v);
         })
     }
 
@@ -1214,18 +1214,13 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
         run_early_pass!(self, check_fn_post, fk, decl, span, id);
     }
 
-    fn visit_variant_data(&mut self,
-                        s: &'a ast::VariantData,
-                        ident: ast::Ident,
-                        g: &'a ast::Generics,
-                        item_id: ast::NodeId,
-                        _: Span) {
-        run_early_pass!(self, check_struct_def, s, ident, g, item_id);
+    fn visit_variant_data(&mut self, s: &'a ast::VariantData) {
+        run_early_pass!(self, check_struct_def, s);
         if let Some(ctor_hir_id) = s.ctor_id() {
             self.check_id(ctor_hir_id);
         }
         ast_visit::walk_struct_def(self, s);
-        run_early_pass!(self, check_struct_def_post, s, ident, g, item_id);
+        run_early_pass!(self, check_struct_def_post, s);
     }
 
     fn visit_struct_field(&mut self, s: &'a ast::StructField) {
@@ -1235,11 +1230,11 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
         })
     }
 
-    fn visit_variant(&mut self, v: &'a ast::Variant, g: &'a ast::Generics, item_id: ast::NodeId) {
-        self.with_lint_attrs(item_id, &v.attrs, |cx| {
-            run_early_pass!(cx, check_variant, v, g);
-            ast_visit::walk_variant(cx, v, g, item_id);
-            run_early_pass!(cx, check_variant_post, v, g);
+    fn visit_variant(&mut self, v: &'a ast::Variant) {
+        self.with_lint_attrs(v.id, &v.attrs, |cx| {
+            run_early_pass!(cx, check_variant, v);
+            ast_visit::walk_variant(cx, v);
+            run_early_pass!(cx, check_variant_post, v);
         })
     }
 
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 2b58627cdea56..7e2707b98d50a 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -248,21 +248,11 @@ macro_rules! late_lint_methods {
             fn check_trait_item_post(a: &$hir hir::TraitItem);
             fn check_impl_item(a: &$hir hir::ImplItem);
             fn check_impl_item_post(a: &$hir hir::ImplItem);
-            fn check_struct_def(
-                a: &$hir hir::VariantData,
-                b: ast::Name,
-                c: &$hir hir::Generics,
-                d: hir::HirId
-            );
-            fn check_struct_def_post(
-                a: &$hir hir::VariantData,
-                b: ast::Name,
-                c: &$hir hir::Generics,
-                d: hir::HirId
-            );
+            fn check_struct_def(a: &$hir hir::VariantData);
+            fn check_struct_def_post(a: &$hir hir::VariantData);
             fn check_struct_field(a: &$hir hir::StructField);
-            fn check_variant(a: &$hir hir::Variant, b: &$hir hir::Generics);
-            fn check_variant_post(a: &$hir hir::Variant, b: &$hir hir::Generics);
+            fn check_variant(a: &$hir hir::Variant);
+            fn check_variant_post(a: &$hir hir::Variant);
             fn check_lifetime(a: &$hir hir::Lifetime);
             fn check_path(a: &$hir hir::Path, b: hir::HirId);
             fn check_attribute(a: &$hir ast::Attribute);
@@ -395,21 +385,11 @@ macro_rules! early_lint_methods {
             fn check_trait_item_post(a: &ast::TraitItem);
             fn check_impl_item(a: &ast::ImplItem);
             fn check_impl_item_post(a: &ast::ImplItem);
-            fn check_struct_def(
-                a: &ast::VariantData,
-                b: ast::Ident,
-                c: &ast::Generics,
-                d: ast::NodeId
-            );
-            fn check_struct_def_post(
-                a: &ast::VariantData,
-                b: ast::Ident,
-                c: &ast::Generics,
-                d: ast::NodeId
-            );
+            fn check_struct_def(a: &ast::VariantData);
+            fn check_struct_def_post(a: &ast::VariantData);
             fn check_struct_field(a: &ast::StructField);
-            fn check_variant(a: &ast::Variant, b: &ast::Generics);
-            fn check_variant_post(a: &ast::Variant, b: &ast::Generics);
+            fn check_variant(a: &ast::Variant);
+            fn check_variant_post(a: &ast::Variant);
             fn check_lifetime(a: &ast::Lifetime);
             fn check_path(a: &ast::Path, b: ast::NodeId);
             fn check_attribute(a: &ast::Attribute);
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index ce7681c974a5d..d3c94060e274a 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -482,7 +482,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc {
         }
     }
 
-    fn check_variant(&mut self, cx: &LateContext<'_, '_>, v: &hir::Variant, _: &hir::Generics) {
+    fn check_variant(&mut self, cx: &LateContext<'_, '_>, v: &hir::Variant) {
         self.check_missing_docs_attrs(cx,
                                       Some(v.id),
                                       &v.attrs,
diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs
index acd17f7663234..bb6119d0ff2aa 100644
--- a/src/librustc_lint/nonstandard_style.rs
+++ b/src/librustc_lint/nonstandard_style.rs
@@ -146,7 +146,7 @@ impl EarlyLintPass for NonCamelCaseTypes {
         }
     }
 
-    fn check_variant(&mut self, cx: &EarlyContext<'_>, v: &ast::Variant, _: &ast::Generics) {
+    fn check_variant(&mut self, cx: &EarlyContext<'_>, v: &ast::Variant) {
         self.check_case(cx, "variant", &v.ident);
     }
 
@@ -350,9 +350,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase {
         &mut self,
         cx: &LateContext<'_, '_>,
         s: &hir::VariantData,
-        _: ast::Name,
-        _: &hir::Generics,
-        _: hir::HirId,
     ) {
         for sf in s.fields() {
             self.check_snake_case(cx, "structure field", &sf.ident);
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index bd46ca4779a43..5b78727fdd5ad 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -813,8 +813,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         visit::walk_poly_trait_ref(self, t, m);
     }
 
-    fn visit_variant_data(&mut self, s: &'a VariantData, _: Ident,
-                          _: &'a Generics, _: NodeId, _: Span) {
+    fn visit_variant_data(&mut self, s: &'a VariantData) {
         self.with_banned_assoc_ty_bound(|this| visit::walk_struct_def(this, s))
     }
 
diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs
index 8fba3256ec429..7e03df5b75bdc 100644
--- a/src/librustc_passes/hir_stats.rs
+++ b/src/librustc_passes/hir_stats.rs
@@ -334,12 +334,9 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
         ast_visit::walk_struct_field(self, s)
     }
 
-    fn visit_variant(&mut self,
-                     v: &'v ast::Variant,
-                     g: &'v ast::Generics,
-                     item_id: NodeId) {
+    fn visit_variant(&mut self, v: &'v ast::Variant) {
         self.record("Variant", Id::None, v);
-        ast_visit::walk_variant(self, v, g, item_id)
+        ast_visit::walk_variant(self, v)
     }
 
     fn visit_lifetime(&mut self, lifetime: &'v ast::Lifetime) {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 72f2c1375e7a2..92b48ed62cdce 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1210,9 +1210,13 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         }
     }
 
-    fn visit_generic_params(&mut self, params: &mut Vec<ast::GenericParam>) {
-        self.cfg.configure_generic_params(params);
-        noop_visit_generic_params(params, self);
+   fn flat_map_generic_param(
+       &mut self,
+       param: ast::GenericParam
+    ) -> SmallVec<[ast::GenericParam; 1]>
+    {
+        let param = configure!(self, param);
+        noop_flat_map_generic_param(param, self)
     }
 
     fn visit_attribute(&mut self, at: &mut ast::Attribute) {
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 9785f8e2de098..414d234e43419 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -98,8 +98,8 @@ pub trait MutVisitor: Sized {
         noop_visit_fn_header(header, self);
     }
 
-    fn visit_struct_field(&mut self, sf: &mut StructField) {
-        noop_visit_struct_field(sf, self);
+    fn flat_map_struct_field(&mut self, sf: StructField) -> SmallVec<[StructField; 1]> {
+        noop_flat_map_struct_field(sf, self)
     }
 
     fn visit_item_kind(&mut self, i: &mut ItemKind) {
@@ -130,8 +130,8 @@ pub trait MutVisitor: Sized {
         noop_flat_map_stmt(s, self)
     }
 
-    fn visit_arm(&mut self, a: &mut Arm) {
-        noop_visit_arm(a, self);
+    fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> {
+        noop_flat_map_arm(arm, self)
     }
 
     fn visit_pat(&mut self, p: &mut P<Pat>) {
@@ -174,8 +174,8 @@ pub trait MutVisitor: Sized {
         noop_visit_foreign_mod(nm, self);
     }
 
-    fn visit_variant(&mut self, v: &mut Variant) {
-        noop_visit_variant(v, self);
+    fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]>  {
+        noop_flat_map_variant(v, self)
     }
 
     fn visit_ident(&mut self, i: &mut Ident) {
@@ -225,8 +225,8 @@ pub trait MutVisitor: Sized {
         noop_visit_attribute(at, self);
     }
 
-    fn visit_arg(&mut self, a: &mut Arg) {
-        noop_visit_arg(a, self);
+    fn flat_map_arg(&mut self, arg: Arg) -> SmallVec<[Arg; 1]> {
+        noop_flat_map_arg(arg, self)
     }
 
     fn visit_generics(&mut self, generics: &mut Generics) {
@@ -245,12 +245,8 @@ pub trait MutVisitor: Sized {
         noop_visit_variant_data(vdata, self);
     }
 
-    fn visit_generic_param(&mut self, param: &mut GenericParam) {
-        noop_visit_generic_param(param, self);
-    }
-
-    fn visit_generic_params(&mut self, params: &mut Vec<GenericParam>) {
-        noop_visit_generic_params(params, self);
+    fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> {
+        noop_flat_map_generic_param(param, self)
     }
 
     fn visit_tt(&mut self, tt: &mut TokenTree) {
@@ -277,8 +273,8 @@ pub trait MutVisitor: Sized {
         noop_visit_mt(mt, self);
     }
 
-    fn visit_field(&mut self, field: &mut Field) {
-        noop_visit_field(field, self);
+    fn flat_map_field(&mut self, f: Field) -> SmallVec<[Field; 1]> {
+        noop_flat_map_field(f, self)
     }
 
     fn visit_where_clause(&mut self, where_clause: &mut WhereClause) {
@@ -300,6 +296,10 @@ pub trait MutVisitor: Sized {
     fn visit_span(&mut self, _sp: &mut Span) {
         // Do nothing.
     }
+
+    fn flat_map_field_pattern(&mut self, fp: FieldPat) -> SmallVec<[FieldPat; 1]> {
+        noop_flat_map_field_pattern(fp, self)
+    }
 }
 
 /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
@@ -362,6 +362,26 @@ pub fn visit_method_sig<T: MutVisitor>(MethodSig { header, decl }: &mut MethodSi
     vis.visit_fn_decl(decl);
 }
 
+pub fn noop_flat_map_field_pattern<T: MutVisitor>(
+    mut fp: FieldPat,
+    vis: &mut T,
+) -> SmallVec<[FieldPat; 1]> {
+    let FieldPat {
+        attrs,
+        id,
+        ident,
+        is_shorthand: _,
+        pat,
+        span,
+    } = &mut fp;
+    vis.visit_id(id);
+    vis.visit_ident(ident);
+    vis.visit_pat(pat);
+    vis.visit_span(span);
+    visit_thin_attrs(attrs, vis);
+    smallvec![fp]
+}
+
 pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
     let UseTree { prefix, kind, span } = use_tree;
     vis.visit_path(prefix);
@@ -382,16 +402,18 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
     vis.visit_span(span);
 }
 
-pub fn noop_visit_arm<T: MutVisitor>(
-    Arm { attrs, pats, guard, body, span, id }: &mut Arm,
+pub fn noop_flat_map_arm<T: MutVisitor>(
+    mut arm: Arm,
     vis: &mut T,
-) {
+) -> SmallVec<[Arm; 1]> {
+    let Arm { attrs, pats, guard, body, span, id } = &mut arm;
     visit_attrs(attrs, vis);
     vis.visit_id(id);
     visit_vec(pats, |pat| vis.visit_pat(pat));
     visit_opt(guard, |guard| vis.visit_expr(guard));
     vis.visit_expr(body);
     vis.visit_span(span);
+    smallvec![arm]
 }
 
 pub fn noop_visit_ty_constraint<T: MutVisitor>(
@@ -425,7 +447,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
         }
         TyKind::BareFn(bft) => {
             let BareFnTy { unsafety: _, abi: _, generic_params, decl } = bft.deref_mut();
-            vis.visit_generic_params(generic_params);
+            generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
             vis.visit_fn_decl(decl);
         }
         TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)),
@@ -455,14 +477,17 @@ pub fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis:
     items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
 }
 
-pub fn noop_visit_variant<T: MutVisitor>(variant: &mut Variant, vis: &mut T) {
-    let Variant { ident, attrs, id, data, disr_expr, span } = variant;
+pub fn noop_flat_map_variant<T: MutVisitor>(mut variant: Variant, vis: &mut T)
+    -> SmallVec<[Variant; 1]>
+{
+    let Variant { ident, attrs, id, data, disr_expr, span } = &mut variant;
     vis.visit_ident(ident);
     visit_attrs(attrs, vis);
     vis.visit_id(id);
     vis.visit_variant_data(data);
     visit_opt(disr_expr, |disr_expr| vis.visit_anon_const(disr_expr));
     vis.visit_span(span);
+    smallvec![variant]
 }
 
 pub fn noop_visit_ident<T: MutVisitor>(Ident { name: _, span }: &mut Ident, vis: &mut T) {
@@ -562,12 +587,14 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
     vis.visit_span(span);
 }
 
-pub fn noop_visit_arg<T: MutVisitor>(Arg { attrs, id, pat, span, ty }: &mut Arg, vis: &mut T) {
+pub fn noop_flat_map_arg<T: MutVisitor>(mut arg: Arg, vis: &mut T) -> SmallVec<[Arg; 1]> {
+    let Arg { attrs, id, pat, span, ty } = &mut arg;
     vis.visit_id(id);
     visit_thin_attrs(attrs, vis);
     vis.visit_pat(pat);
     vis.visit_span(span);
     vis.visit_ty(ty);
+    smallvec![arg]
 }
 
 pub fn noop_visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) {
@@ -693,7 +720,7 @@ pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut IsAsync, vis: &mut T)
 
 pub fn noop_visit_fn_decl<T: MutVisitor>(decl: &mut P<FnDecl>, vis: &mut T) {
     let FnDecl { inputs, output, c_variadic: _ } = decl.deref_mut();
-    visit_vec(inputs, |input| vis.visit_arg(input));
+    inputs.flat_map_in_place(|arg| vis.flat_map_arg(arg));
     match output {
         FunctionRetTy::Default(span) => vis.visit_span(span),
         FunctionRetTy::Ty(ty) => vis.visit_ty(ty),
@@ -707,8 +734,12 @@ pub fn noop_visit_param_bound<T: MutVisitor>(pb: &mut GenericBound, vis: &mut T)
     }
 }
 
-pub fn noop_visit_generic_param<T: MutVisitor>(param: &mut GenericParam, vis: &mut T) {
-    let GenericParam { id, ident, attrs, bounds, kind } = param;
+pub fn noop_flat_map_generic_param<T: MutVisitor>(
+    mut param: GenericParam,
+    vis: &mut T
+) -> SmallVec<[GenericParam; 1]>
+{
+    let GenericParam { id, ident, attrs, bounds, kind } = &mut param;
     vis.visit_id(id);
     vis.visit_ident(ident);
     visit_thin_attrs(attrs, vis);
@@ -722,10 +753,7 @@ pub fn noop_visit_generic_param<T: MutVisitor>(param: &mut GenericParam, vis: &m
             vis.visit_ty(ty);
         }
     }
-}
-
-pub fn noop_visit_generic_params<T: MutVisitor>(params: &mut Vec<GenericParam>, vis: &mut T){
-    visit_vec(params, |param| vis.visit_generic_param(param));
+    smallvec![param]
 }
 
 pub fn noop_visit_label<T: MutVisitor>(Label { ident }: &mut Label, vis: &mut T) {
@@ -739,7 +767,7 @@ fn noop_visit_lifetime<T: MutVisitor>(Lifetime { id, ident }: &mut Lifetime, vis
 
 pub fn noop_visit_generics<T: MutVisitor>(generics: &mut Generics, vis: &mut T) {
     let Generics { params, where_clause, span } = generics;
-    vis.visit_generic_params(params);
+    params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
     vis.visit_where_clause(where_clause);
     vis.visit_span(span);
 }
@@ -755,7 +783,7 @@ pub fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis:
         WherePredicate::BoundPredicate(bp) => {
             let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp;
             vis.visit_span(span);
-            vis.visit_generic_params(bound_generic_params);
+            bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
             vis.visit_ty(bounded_ty);
             visit_vec(bounds, |bound| vis.visit_param_bound(bound));
         }
@@ -777,9 +805,11 @@ pub fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis:
 
 pub fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut T) {
     match vdata {
-        VariantData::Struct(fields, ..) => visit_vec(fields, |field| vis.visit_struct_field(field)),
+        VariantData::Struct(fields, ..) => {
+            fields.flat_map_in_place(|field| vis.flat_map_struct_field(field));
+        },
         VariantData::Tuple(fields, id) => {
-            visit_vec(fields, |field| vis.visit_struct_field(field));
+            fields.flat_map_in_place(|field| vis.flat_map_struct_field(field));
             vis.visit_id(id);
         },
         VariantData::Unit(id) => vis.visit_id(id),
@@ -793,28 +823,32 @@ pub fn noop_visit_trait_ref<T: MutVisitor>(TraitRef { path, ref_id }: &mut Trait
 
 pub fn noop_visit_poly_trait_ref<T: MutVisitor>(p: &mut PolyTraitRef, vis: &mut T) {
     let PolyTraitRef { bound_generic_params, trait_ref, span } = p;
-    vis.visit_generic_params(bound_generic_params);
+    bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param));
     vis.visit_trait_ref(trait_ref);
     vis.visit_span(span);
 }
 
-pub fn noop_visit_struct_field<T: MutVisitor>(f: &mut StructField, visitor: &mut T) {
-    let StructField { span, ident, vis, id, ty, attrs } = f;
+pub fn noop_flat_map_struct_field<T: MutVisitor>(mut sf: StructField, visitor: &mut T)
+    -> SmallVec<[StructField; 1]>
+{
+    let StructField { span, ident, vis, id, ty, attrs } = &mut sf;
     visitor.visit_span(span);
     visit_opt(ident, |ident| visitor.visit_ident(ident));
     visitor.visit_vis(vis);
     visitor.visit_id(id);
     visitor.visit_ty(ty);
     visit_attrs(attrs, visitor);
+    smallvec![sf]
 }
 
-pub fn noop_visit_field<T: MutVisitor>(f: &mut Field, vis: &mut T) {
-    let Field { ident, expr, span, is_shorthand: _, attrs, id } = f;
+pub fn noop_flat_map_field<T: MutVisitor>(mut f: Field, vis: &mut T) -> SmallVec<[Field; 1]> {
+    let Field { ident, expr, span, is_shorthand: _, attrs, id } = &mut f;
     vis.visit_ident(ident);
     vis.visit_expr(expr);
     vis.visit_id(id);
     vis.visit_span(span);
     visit_thin_attrs(attrs, vis);
+    smallvec![f]
 }
 
 pub fn noop_visit_mt<T: MutVisitor>(MutTy { ty, mutbl: _ }: &mut MutTy, vis: &mut T) {
@@ -858,7 +892,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
             vis.visit_generics(generics);
         }
         ItemKind::Enum(EnumDef { variants }, generics) => {
-            visit_vec(variants, |variant| vis.visit_variant(variant));
+            variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
             vis.visit_generics(generics);
         }
         ItemKind::Struct(variant_data, generics) |
@@ -1042,13 +1076,7 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
         }
         PatKind::Struct(path, fields, _etc) => {
             vis.visit_path(path);
-            for FieldPat { ident, pat, is_shorthand: _, attrs, id, span } in fields {
-                vis.visit_ident(ident);
-                vis.visit_id(id);
-                vis.visit_pat(pat);
-                visit_thin_attrs(attrs, vis);
-                vis.visit_span(span);
-            };
+            fields.flat_map_in_place(|field| vis.flat_map_field_pattern(field));
         }
         PatKind::Box(inner) => vis.visit_pat(inner),
         PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner),
@@ -1130,7 +1158,7 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
         }
         ExprKind::Match(expr, arms) => {
             vis.visit_expr(expr);
-            visit_vec(arms, |arm| vis.visit_arm(arm));
+            arms.flat_map_in_place(|arm| vis.flat_map_arm(arm));
         }
         ExprKind::Closure(_capture_by, asyncness, _movability, decl, body, span) => {
             vis.visit_asyncness(asyncness);
@@ -1193,7 +1221,7 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
         ExprKind::Mac(mac) => vis.visit_mac(mac),
         ExprKind::Struct(path, fields, expr) => {
             vis.visit_path(path);
-            visit_vec(fields, |field| vis.visit_field(field));
+            fields.flat_map_in_place(|field| vis.flat_map_field(field));
             visit_opt(expr, |expr| vis.visit_expr(expr));
         },
         ExprKind::Paren(expr) => {
diff --git a/src/libsyntax/util/node_count.rs b/src/libsyntax/util/node_count.rs
index f17eb3b39432e..a64fec7096132 100644
--- a/src/libsyntax/util/node_count.rs
+++ b/src/libsyntax/util/node_count.rs
@@ -93,8 +93,7 @@ impl<'ast> Visitor<'ast> for NodeCounter {
         self.count += 1;
         walk_poly_trait_ref(self, t, m)
     }
-    fn visit_variant_data(&mut self, s: &VariantData, _: Ident,
-                          _: &Generics, _: NodeId, _: Span) {
+    fn visit_variant_data(&mut self, s: &VariantData) {
         self.count += 1;
         walk_struct_def(self, s)
     }
@@ -107,9 +106,9 @@ impl<'ast> Visitor<'ast> for NodeCounter {
         self.count += 1;
         walk_enum_def(self, enum_definition, generics, item_id)
     }
-    fn visit_variant(&mut self, v: &Variant, g: &Generics, item_id: NodeId) {
+    fn visit_variant(&mut self, v: &Variant) {
         self.count += 1;
-        walk_variant(self, v, g, item_id)
+        walk_variant(self, v)
     }
     fn visit_lifetime(&mut self, lifetime: &Lifetime) {
         self.count += 1;
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 91b92d84a811f..86f6d36c3c6ba 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -92,8 +92,7 @@ pub trait Visitor<'ast>: Sized {
     fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) {
         walk_poly_trait_ref(self, t, m)
     }
-    fn visit_variant_data(&mut self, s: &'ast VariantData, _: Ident,
-                          _: &'ast Generics, _: NodeId, _: Span) {
+    fn visit_variant_data(&mut self, s: &'ast VariantData) {
         walk_struct_def(self, s)
     }
     fn visit_struct_field(&mut self, s: &'ast StructField) { walk_struct_field(self, s) }
@@ -101,8 +100,8 @@ pub trait Visitor<'ast>: Sized {
                       generics: &'ast Generics, item_id: NodeId, _: Span) {
         walk_enum_def(self, enum_definition, generics, item_id)
     }
-    fn visit_variant(&mut self, v: &'ast Variant, g: &'ast Generics, item_id: NodeId) {
-        walk_variant(self, v, g, item_id)
+    fn visit_variant(&mut self, v: &'ast Variant) {
+        walk_variant(self, v)
     }
     fn visit_label(&mut self, label: &'ast Label) {
         walk_label(self, label)
@@ -163,6 +162,12 @@ pub trait Visitor<'ast>: Sized {
     fn visit_fn_header(&mut self, _header: &'ast FnHeader) {
         // Nothing to do
     }
+    fn visit_field(&mut self, f: &'ast Field) {
+        walk_field(self, f)
+    }
+    fn visit_field_pattern(&mut self, fp: &'ast FieldPat) {
+        walk_field_pattern(self, fp)
+    }
 }
 
 #[macro_export]
@@ -280,8 +285,7 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
         ItemKind::Struct(ref struct_definition, ref generics) |
         ItemKind::Union(ref struct_definition, ref generics) => {
             visitor.visit_generics(generics);
-            visitor.visit_variant_data(struct_definition, item.ident,
-                                     generics, item.id, item.span);
+            visitor.visit_variant_data(struct_definition);
         }
         ItemKind::Trait(.., ref generics, ref bounds, ref methods) => {
             visitor.visit_generics(generics);
@@ -300,24 +304,32 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
 
 pub fn walk_enum_def<'a, V: Visitor<'a>>(visitor: &mut V,
                                  enum_definition: &'a EnumDef,
-                                 generics: &'a Generics,
-                                 item_id: NodeId) {
-    walk_list!(visitor, visit_variant, &enum_definition.variants, generics, item_id);
+                                 _: &'a Generics,
+                                 _: NodeId) {
+    walk_list!(visitor, visit_variant, &enum_definition.variants);
 }
 
-pub fn walk_variant<'a, V>(visitor: &mut V,
-                           variant: &'a Variant,
-                           generics: &'a Generics,
-                           item_id: NodeId)
+pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant)
     where V: Visitor<'a>,
 {
     visitor.visit_ident(variant.ident);
-    visitor.visit_variant_data(&variant.data, variant.ident,
-                             generics, item_id, variant.span);
+    visitor.visit_variant_data(&variant.data);
     walk_list!(visitor, visit_anon_const, &variant.disr_expr);
     walk_list!(visitor, visit_attribute, &variant.attrs);
 }
 
+pub fn walk_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a Field) {
+    visitor.visit_expr(&f.expr);
+    visitor.visit_ident(f.ident);
+    walk_list!(visitor, visit_attribute, f.attrs.iter());
+}
+
+pub fn walk_field_pattern<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a FieldPat) {
+    visitor.visit_ident(fp.ident);
+    visitor.visit_pat(&fp.pat);
+    walk_list!(visitor, visit_attribute, fp.attrs.iter());
+}
+
 pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
     match typ.node {
         TyKind::Slice(ref ty) | TyKind::Paren(ref ty) => {
@@ -441,11 +453,7 @@ pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) {
         }
         PatKind::Struct(ref path, ref fields, _) => {
             visitor.visit_path(path, pattern.id);
-            for field in fields {
-                walk_list!(visitor, visit_attribute, field.attrs.iter());
-                visitor.visit_ident(field.ident);
-                visitor.visit_pat(&field.pat)
-            }
+            walk_list!(visitor, visit_field_pattern, fields);
         }
         PatKind::Box(ref subpattern) |
         PatKind::Ref(ref subpattern, _) |
@@ -686,11 +694,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
         }
         ExprKind::Struct(ref path, ref fields, ref optional_base) => {
             visitor.visit_path(path, expression.id);
-            for field in fields {
-                walk_list!(visitor, visit_attribute, field.attrs.iter());
-                visitor.visit_ident(field.ident);
-                visitor.visit_expr(&field.expr)
-            }
+            walk_list!(visitor, visit_field, fields);
             walk_list!(visitor, visit_expr, optional_base);
         }
         ExprKind::Tup(ref subexpressions) => {

From 14986081355db0a2ae67df6a43dd9e6e360d718c Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Sat, 20 Jul 2019 16:34:41 -0400
Subject: [PATCH 173/943] Improve Rustdoc's handling of procedural macros

Fixes #58700
Fixes #58696
Fixes #49553
Fixes #52210

This commit removes the special rustdoc handling for proc macros, as we
can now
retrieve their span and attributes just like any other item.

A new command-line option is added to rustdoc: `--crate-type`. This
takes the same options as rustc's `--crate-type` option. However, all
values other than `proc-macro` are treated the same. This allows Rustdoc
to enable 'proc macro mode' when handling a proc macro crate.

In compiletest, a new 'rustdoc-flags' option is added. This allows us to
pass in the '--proc-macro-crate' flag in the absence of Cargo.

I've opened [an additional PR to
Cargo](https://github.com/rust-lang/cargo/pull/7159) to support passing
in this flag.
These two PRS can be merged in any order - the Cargo changes will not
take effect until the 'cargo' submodule is updated in this repository.
---
 src/librustc/session/config.rs                | 18 +++++----
 src/librustc_interface/passes.rs              | 37 ++++++++-----------
 src/librustdoc/clean/inline.rs                | 18 +++++----
 src/librustdoc/config.rs                      | 14 +++++++
 src/librustdoc/core.rs                        |  8 +++-
 src/librustdoc/lib.rs                         |  3 +-
 src/librustdoc/test.rs                        |  8 +++-
 src/test/rustdoc-ui/failed-doctest-output.rs  |  1 +
 .../rustdoc-ui/failed-doctest-output.stdout   | 14 +++----
 .../inline_cross/auxiliary/proc_macro.rs      |  7 ++++
 src/test/rustdoc/inline_cross/proc_macro.rs   | 19 +++++-----
 src/test/rustdoc/proc-macro.rs                |  3 +-
 src/test/rustdoc/rustc-macro-crate.rs         |  1 +
 13 files changed, 95 insertions(+), 56 deletions(-)

diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 8e3b910e0da3a..9ecdff25d2649 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1719,13 +1719,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
                              static, framework, or dylib (the default).",
             "[KIND=]NAME",
         ),
-        opt::multi_s(
-            "",
-            "crate-type",
-            "Comma separated list of types of crates
-                                    for the compiler to emit",
-            "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]",
-        ),
+        make_crate_type_option(),
         opt::opt_s(
             "",
             "crate-name",
@@ -2506,6 +2500,16 @@ pub fn build_session_options_and_crate_config(
     )
 }
 
+pub fn make_crate_type_option() -> RustcOptGroup {
+    opt::multi_s(
+        "",
+        "crate-type",
+        "Comma separated list of types of crates
+                                for the compiler to emit",
+        "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]",
+    )
+}
+
 pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
     let mut crate_types: Vec<CrateType> = Vec::new();
     for unparsed_crate_type in &list_list {
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 8b0b5a5b7a2bd..856690903c659 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -473,27 +473,22 @@ fn configure_and_expand_inner<'a>(
         ast_validation::check_crate(sess, &krate)
     });
 
-    // If we're in rustdoc we're always compiling as an rlib, but that'll trip a
-    // bunch of checks in the `modify` function below. For now just skip this
-    // step entirely if we're rustdoc as it's not too useful anyway.
-    if !sess.opts.actually_rustdoc {
-        krate = time(sess, "maybe creating a macro crate", || {
-            let crate_types = sess.crate_types.borrow();
-            let num_crate_types = crate_types.len();
-            let is_proc_macro_crate = crate_types.contains(&config::CrateType::ProcMacro);
-            let is_test_crate = sess.opts.test;
-            syntax_ext::proc_macro_harness::inject(
-                &sess.parse_sess,
-                &mut resolver,
-                krate,
-                is_proc_macro_crate,
-                has_proc_macro_decls,
-                is_test_crate,
-                num_crate_types,
-                sess.diagnostic(),
-            )
-        });
-    }
+    krate = time(sess, "maybe creating a macro crate", || {
+        let crate_types = sess.crate_types.borrow();
+        let num_crate_types = crate_types.len();
+        let is_proc_macro_crate = crate_types.contains(&config::CrateType::ProcMacro);
+        let is_test_crate = sess.opts.test;
+        syntax_ext::proc_macro_harness::inject(
+            &sess.parse_sess,
+            &mut resolver,
+            krate,
+            is_proc_macro_crate,
+            has_proc_macro_decls,
+            is_test_crate,
+            num_crate_types,
+            sess.diagnostic(),
+        )
+    });
 
     // Done with macro expansion!
 
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 6f93c95edef08..9d93e5f93c13e 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -20,6 +20,7 @@ use crate::clean::{
     self,
     GetDefId,
     ToSource,
+    TypeKind
 };
 
 use super::Clean;
@@ -107,15 +108,16 @@ pub fn try_inline(
             record_extern_fqn(cx, did, clean::TypeKind::Const);
             clean::ConstantItem(build_const(cx, did))
         }
-        // FIXME: proc-macros don't propagate attributes or spans across crates, so they look empty
-        Res::Def(DefKind::Macro(MacroKind::Bang), did) => {
+        Res::Def(DefKind::Macro(kind), did) => {
             let mac = build_macro(cx, did, name);
-            if let clean::MacroItem(..) = mac {
-                record_extern_fqn(cx, did, clean::TypeKind::Macro);
-                mac
-            } else {
-                return None;
-            }
+
+            let type_kind = match kind {
+                MacroKind::Bang => TypeKind::Macro,
+                MacroKind::Attr => TypeKind::Attr,
+                MacroKind::Derive => TypeKind::Derive
+            };
+            record_extern_fqn(cx, did, type_kind);
+            mac
         }
         _ => return None,
     };
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 98ab957ecbb38..cefae2e105eda 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -6,6 +6,7 @@ use errors;
 use getopts;
 use rustc::lint::Level;
 use rustc::session;
+use rustc::session::config::{CrateType, parse_crate_types_from_list};
 use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
 use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options,
                              get_cmd_lint_options, ExternEntry};
@@ -32,6 +33,8 @@ pub struct Options {
     pub input: PathBuf,
     /// The name of the crate being documented.
     pub crate_name: Option<String>,
+    /// Whether or not this is a proc-macro crate
+    pub proc_macro_crate: bool,
     /// How to format errors and warnings.
     pub error_format: ErrorOutputType,
     /// Library search paths to hand to the compiler.
@@ -111,6 +114,7 @@ impl fmt::Debug for Options {
         f.debug_struct("Options")
             .field("input", &self.input)
             .field("crate_name", &self.crate_name)
+            .field("proc_macro_crate", &self.proc_macro_crate)
             .field("error_format", &self.error_format)
             .field("libs", &self.libs)
             .field("externs", &FmtExterns(&self.externs))
@@ -431,7 +435,16 @@ impl Options {
         };
         let manual_passes = matches.opt_strs("passes");
 
+        let crate_types = match parse_crate_types_from_list(matches.opt_strs("crate-type")) {
+            Ok(types) => types,
+            Err(e) =>{
+                diag.struct_err(&format!("unknown crate type: {}", e)).emit();
+                return Err(1);
+            }
+        };
+
         let crate_name = matches.opt_str("crate-name");
+        let proc_macro_crate = crate_types.contains(&CrateType::ProcMacro);
         let playground_url = matches.opt_str("playground-url");
         let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
         let display_warnings = matches.opt_present("display-warnings");
@@ -454,6 +467,7 @@ impl Options {
         Ok(Options {
             input,
             crate_name,
+            proc_macro_crate,
             error_format,
             libs,
             externs,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 87381f224d0bb..003276a5e4868 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -228,6 +228,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
     let RustdocOptions {
         input,
         crate_name,
+        proc_macro_crate,
         error_format,
         libs,
         externs,
@@ -293,11 +294,16 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
     }).collect();
 
     let host_triple = TargetTriple::from_triple(config::host_triple());
+    let crate_types = if proc_macro_crate {
+        vec![config::CrateType::ProcMacro]
+    } else {
+        vec![config::CrateType::Rlib]
+    };
     // plays with error output here!
     let sessopts = config::Options {
         maybe_sysroot,
         search_paths: libs,
-        crate_types: vec![config::CrateType::Rlib],
+        crate_types,
         lint_opts: if !display_warnings {
             lint_opts
         } else {
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index e30b35937db9f..bb83ff64b2f18 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -46,7 +46,7 @@ use std::panic;
 use std::process;
 
 use rustc::session::{early_warn, early_error};
-use rustc::session::config::{ErrorOutputType, RustcOptGroup};
+use rustc::session::config::{ErrorOutputType, RustcOptGroup, make_crate_type_option};
 
 #[macro_use]
 mod externalfiles;
@@ -132,6 +132,7 @@ fn opts() -> Vec<RustcOptGroup> {
         stable("crate-name", |o| {
             o.optopt("", "crate-name", "specify the name of this crate", "NAME")
         }),
+        make_crate_type_option(),
         stable("L", |o| {
             o.optmulti("L", "library-path", "directory to add to crate search path",
                        "DIR")
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 83a8d3fc10999..87bc6f09e74f5 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -43,10 +43,16 @@ pub struct TestOptions {
 pub fn run(options: Options) -> i32 {
     let input = config::Input::File(options.input.clone());
 
+    let crate_types = if options.proc_macro_crate {
+        vec![config::CrateType::ProcMacro]
+    } else {
+        vec![config::CrateType::Dylib]
+    };
+
     let sessopts = config::Options {
         maybe_sysroot: options.maybe_sysroot.clone(),
         search_paths: options.libs.clone(),
-        crate_types: vec![config::CrateType::Dylib],
+        crate_types,
         cg: options.codegen_options.clone(),
         externs: options.externs.clone(),
         unstable_features: UnstableFeatures::from_environment(),
diff --git a/src/test/rustdoc-ui/failed-doctest-output.rs b/src/test/rustdoc-ui/failed-doctest-output.rs
index d2cdeb8f8f50e..fcbd7cabc6900 100644
--- a/src/test/rustdoc-ui/failed-doctest-output.rs
+++ b/src/test/rustdoc-ui/failed-doctest-output.rs
@@ -3,6 +3,7 @@
 // adapted to use that, and that normalize line can go away
 
 // compile-flags:--test
+// rustc-env:RUST_BACKTRACE=0
 // normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR"
 // failure-status: 101
 
diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout
index e362ecf349e45..ef1b419f52895 100644
--- a/src/test/rustdoc-ui/failed-doctest-output.stdout
+++ b/src/test/rustdoc-ui/failed-doctest-output.stdout
@@ -1,13 +1,13 @@
 
 running 2 tests
-test $DIR/failed-doctest-output.rs - OtherStruct (line 20) ... FAILED
-test $DIR/failed-doctest-output.rs - SomeStruct (line 10) ... FAILED
+test $DIR/failed-doctest-output.rs - OtherStruct (line 21) ... FAILED
+test $DIR/failed-doctest-output.rs - SomeStruct (line 11) ... FAILED
 
 failures:
 
----- $DIR/failed-doctest-output.rs - OtherStruct (line 20) stdout ----
+---- $DIR/failed-doctest-output.rs - OtherStruct (line 21) stdout ----
 error[E0425]: cannot find value `no` in this scope
- --> $DIR/failed-doctest-output.rs:21:1
+ --> $DIR/failed-doctest-output.rs:22:1
   |
 3 | no
   | ^^ not found in this scope
@@ -16,7 +16,7 @@ error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0425`.
 Couldn't compile the test.
----- $DIR/failed-doctest-output.rs - SomeStruct (line 10) stdout ----
+---- $DIR/failed-doctest-output.rs - SomeStruct (line 11) stdout ----
 Test executable failed (exit code 101).
 
 stdout:
@@ -32,8 +32,8 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
 
 
 failures:
-    $DIR/failed-doctest-output.rs - OtherStruct (line 20)
-    $DIR/failed-doctest-output.rs - SomeStruct (line 10)
+    $DIR/failed-doctest-output.rs - OtherStruct (line 21)
+    $DIR/failed-doctest-output.rs - SomeStruct (line 11)
 
 test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out
 
diff --git a/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs b/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs
index c99ef74433358..37465ccf1c27e 100644
--- a/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs
+++ b/src/test/rustdoc/inline_cross/auxiliary/proc_macro.rs
@@ -1,5 +1,6 @@
 // force-host
 // no-prefer-dynamic
+// compile-flags: --crate-type proc-macro
 
 #![crate_type="proc-macro"]
 #![crate_name="some_macros"]
@@ -25,3 +26,9 @@ pub fn some_proc_attr(_attr: TokenStream, item: TokenStream) -> TokenStream {
 pub fn some_derive(_item: TokenStream) -> TokenStream {
     TokenStream::new()
 }
+
+/// Doc comment from the original crate
+#[proc_macro]
+pub fn reexported_macro(_input: TokenStream) -> TokenStream {
+    TokenStream::new()
+}
diff --git a/src/test/rustdoc/inline_cross/proc_macro.rs b/src/test/rustdoc/inline_cross/proc_macro.rs
index e1cdcf4940244..6880e303df90b 100644
--- a/src/test/rustdoc/inline_cross/proc_macro.rs
+++ b/src/test/rustdoc/inline_cross/proc_macro.rs
@@ -1,16 +1,17 @@
 // aux-build:proc_macro.rs
 // build-aux-docs
 
-// FIXME: if/when proc-macros start exporting their doc attributes across crates, we can turn on
-// cross-crate inlining for them
-
 extern crate some_macros;
 
 // @has proc_macro/index.html
-// @has - '//a/@href' '../some_macros/macro.some_proc_macro.html'
-// @has - '//a/@href' '../some_macros/attr.some_proc_attr.html'
-// @has - '//a/@href' '../some_macros/derive.SomeDerive.html'
-// @!has proc_macro/macro.some_proc_macro.html
-// @!has proc_macro/attr.some_proc_attr.html
-// @!has proc_macro/derive.SomeDerive.html
+// @has - '//a/@href' 'macro.some_proc_macro.html'
+// @has - '//a/@href' 'attr.some_proc_attr.html'
+// @has - '//a/@href' 'derive.SomeDerive.html'
+// @has proc_macro/macro.some_proc_macro.html
+// @has proc_macro/attr.some_proc_attr.html
+// @has proc_macro/derive.SomeDerive.html
 pub use some_macros::{some_proc_macro, some_proc_attr, SomeDerive};
+
+// @has proc_macro/macro.reexported_macro.html
+// @has - 'Doc comment from the original crate'
+pub use some_macros::reexported_macro;
diff --git a/src/test/rustdoc/proc-macro.rs b/src/test/rustdoc/proc-macro.rs
index 4bd0b092b55a7..82196e413e94b 100644
--- a/src/test/rustdoc/proc-macro.rs
+++ b/src/test/rustdoc/proc-macro.rs
@@ -1,5 +1,6 @@
 // force-host
 // no-prefer-dynamic
+// compile-flags: --crate-type proc-macro --document-private-items
 
 #![crate_type="proc-macro"]
 #![crate_name="some_macros"]
@@ -58,7 +59,7 @@ pub fn some_derive(_item: TokenStream) -> TokenStream {
 }
 
 // @has some_macros/foo/index.html
-pub mod foo {
+mod foo {
     // @has - '//code' 'pub use some_proc_macro;'
     // @has - '//a/@href' '../../some_macros/macro.some_proc_macro.html'
     pub use some_proc_macro;
diff --git a/src/test/rustdoc/rustc-macro-crate.rs b/src/test/rustdoc/rustc-macro-crate.rs
index 2f6308b20c2ee..dd5edc984dafa 100644
--- a/src/test/rustdoc/rustc-macro-crate.rs
+++ b/src/test/rustdoc/rustc-macro-crate.rs
@@ -1,5 +1,6 @@
 // force-host
 // no-prefer-dynamic
+// compile-flags: --crate-type proc-macro
 
 #![crate_type = "proc-macro"]
 

From 11d40910cdc501b22e503cfe1054a7f21478785e Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Fri, 23 Aug 2019 15:03:21 +0200
Subject: [PATCH 174/943] typeck: move `check_pat_walk` and children to
 `pat.rs`.

---
 src/librustc_typeck/check/_match.rs | 965 +--------------------------
 src/librustc_typeck/check/mod.rs    |   1 +
 src/librustc_typeck/check/pat.rs    | 968 ++++++++++++++++++++++++++++
 3 files changed, 971 insertions(+), 963 deletions(-)
 create mode 100644 src/librustc_typeck/check/pat.rs

diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index fc25eb44cbd88..8cb365d91fa79 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -1,631 +1,12 @@
 use crate::check::{FnCtxt, Expectation, Diverges, Needs};
 use crate::check::coercion::CoerceMany;
-use crate::util::nodemap::FxHashMap;
-use errors::{Applicability, DiagnosticBuilder};
-use rustc::hir::{self, PatKind, Pat, ExprKind};
-use rustc::hir::def::{Res, DefKind, CtorKind};
-use rustc::hir::pat_util::EnumerateAndAdjustIterator;
-use rustc::hir::ptr::P;
-use rustc::infer;
+use rustc::hir::{self, ExprKind};
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::traits::{ObligationCause, ObligationCauseCode};
-use rustc::ty::{self, Ty, TypeFoldable};
-use rustc::ty::subst::Kind;
-use syntax::ast;
-use syntax::util::lev_distance::find_best_match_for_name;
+use rustc::ty::{self, Ty};
 use syntax_pos::Span;
-use syntax_pos::hygiene::DesugaringKind;
-
-use std::collections::hash_map::Entry::{Occupied, Vacant};
-use std::cmp;
-
-use super::report_unexpected_variant_res;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    /// `discrim_span` argument having a `Span` indicates that this pattern is part of a match
-    /// expression arm guard, and it points to the match discriminant to add context in type errors.
-    /// In the following example, `discrim_span` corresponds to the `a + b` expression:
-    ///
-    /// ```text
-    /// error[E0308]: mismatched types
-    ///  --> src/main.rs:5:9
-    ///   |
-    /// 4 |    let temp: usize = match a + b {
-    ///   |                            ----- this expression has type `usize`
-    /// 5 |         Ok(num) => num,
-    ///   |         ^^^^^^^ expected usize, found enum `std::result::Result`
-    ///   |
-    ///   = note: expected type `usize`
-    ///              found type `std::result::Result<_, _>`
-    /// ```
-    pub fn check_pat_walk(
-        &self,
-        pat: &'tcx hir::Pat,
-        mut expected: Ty<'tcx>,
-        mut def_bm: ty::BindingMode,
-        discrim_span: Option<Span>,
-    ) {
-        let tcx = self.tcx;
-
-        debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
-
-        let mut path_resolution = None;
-        let is_non_ref_pat = match pat.node {
-            PatKind::Struct(..) |
-            PatKind::TupleStruct(..) |
-            PatKind::Or(_) |
-            PatKind::Tuple(..) |
-            PatKind::Box(_) |
-            PatKind::Range(..) |
-            PatKind::Slice(..) => true,
-            PatKind::Lit(ref lt) => {
-                let ty = self.check_expr(lt);
-                match ty.sty {
-                    ty::Ref(..) => false,
-                    _ => true,
-                }
-            }
-            PatKind::Path(ref qpath) => {
-                let resolution = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
-                path_resolution = Some(resolution);
-                match resolution.0 {
-                    Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => false,
-                    _ => true,
-                }
-            }
-            PatKind::Wild |
-            PatKind::Binding(..) |
-            PatKind::Ref(..) => false,
-        };
-        if is_non_ref_pat {
-            debug!("pattern is non reference pattern");
-            let mut exp_ty = self.resolve_type_vars_with_obligations(&expected);
-
-            // Peel off as many `&` or `&mut` from the discriminant as possible. For example,
-            // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
-            // the `Some(5)` which is not of type Ref.
-            //
-            // For each ampersand peeled off, update the binding mode and push the original
-            // type into the adjustments vector.
-            //
-            // See the examples in `ui/match-defbm*.rs`.
-            let mut pat_adjustments = vec![];
-            while let ty::Ref(_, inner_ty, inner_mutability) = exp_ty.sty {
-                debug!("inspecting {:?}", exp_ty);
-
-                debug!("current discriminant is Ref, inserting implicit deref");
-                // Preserve the reference type. We'll need it later during HAIR lowering.
-                pat_adjustments.push(exp_ty);
-
-                exp_ty = inner_ty;
-                def_bm = match def_bm {
-                    // If default binding mode is by value, make it `ref` or `ref mut`
-                    // (depending on whether we observe `&` or `&mut`).
-                    ty::BindByValue(_) =>
-                        ty::BindByReference(inner_mutability),
-
-                    // Once a `ref`, always a `ref`. This is because a `& &mut` can't mutate
-                    // the underlying value.
-                    ty::BindByReference(hir::Mutability::MutImmutable) =>
-                        ty::BindByReference(hir::Mutability::MutImmutable),
-
-                    // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref`
-                    // (on `&`).
-                    ty::BindByReference(hir::Mutability::MutMutable) =>
-                        ty::BindByReference(inner_mutability),
-                };
-            }
-            expected = exp_ty;
-
-            if pat_adjustments.len() > 0 {
-                debug!("default binding mode is now {:?}", def_bm);
-                self.inh.tables.borrow_mut()
-                    .pat_adjustments_mut()
-                    .insert(pat.hir_id, pat_adjustments);
-            }
-        } else if let PatKind::Ref(..) = pat.node {
-            // When you encounter a `&pat` pattern, reset to "by
-            // value". This is so that `x` and `y` here are by value,
-            // as they appear to be:
-            //
-            // ```
-            // match &(&22, &44) {
-            //   (&x, &y) => ...
-            // }
-            // ```
-            //
-            // See issue #46688.
-            def_bm = ty::BindByValue(hir::MutImmutable);
-        }
-
-        // Lose mutability now that we know binding mode and discriminant type.
-        let def_bm = def_bm;
-        let expected = expected;
-
-        let ty = match pat.node {
-            PatKind::Wild => {
-                expected
-            }
-            PatKind::Lit(ref lt) => {
-                // We've already computed the type above (when checking for a non-ref pat), so
-                // avoid computing it again.
-                let ty = self.node_ty(lt.hir_id);
-
-                // Byte string patterns behave the same way as array patterns
-                // They can denote both statically and dynamically-sized byte arrays.
-                let mut pat_ty = ty;
-                if let hir::ExprKind::Lit(ref lt) = lt.node {
-                    if let ast::LitKind::ByteStr(_) = lt.node {
-                        let expected_ty = self.structurally_resolved_type(pat.span, expected);
-                        if let ty::Ref(_, r_ty, _) = expected_ty.sty {
-                            if let ty::Slice(_) = r_ty.sty {
-                                pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static,
-                                                        tcx.mk_slice(tcx.types.u8))
-                            }
-                        }
-                    }
-                }
-
-                // Somewhat surprising: in this case, the subtyping
-                // relation goes the opposite way as the other
-                // cases. Actually what we really want is not a subtyping
-                // relation at all but rather that there exists a LUB (so
-                // that they can be compared). However, in practice,
-                // constants are always scalars or strings.  For scalars
-                // subtyping is irrelevant, and for strings `ty` is
-                // type is `&'static str`, so if we say that
-                //
-                //     &'static str <: expected
-                //
-                // then that's equivalent to there existing a LUB.
-                if let Some(mut err) = self.demand_suptype_diag(pat.span, expected, pat_ty) {
-                    err.emit_unless(discrim_span
-                        .filter(|&s| {
-                            // In the case of `if`- and `while`-expressions we've already checked
-                            // that `scrutinee: bool`. We know that the pattern is `true`,
-                            // so an error here would be a duplicate and from the wrong POV.
-                            s.is_desugaring(DesugaringKind::CondTemporary)
-                        })
-                        .is_some());
-                }
-
-                pat_ty
-            }
-            PatKind::Range(ref begin, ref end, _) => {
-                let lhs_ty = self.check_expr(begin);
-                let rhs_ty = self.check_expr(end);
-
-                // Check that both end-points are of numeric or char type.
-                let numeric_or_char = |ty: Ty<'_>| {
-                    ty.is_numeric()
-                    || ty.is_char()
-                    || ty.references_error()
-                };
-                let lhs_compat = numeric_or_char(lhs_ty);
-                let rhs_compat = numeric_or_char(rhs_ty);
-
-                if !lhs_compat || !rhs_compat {
-                    let span = if !lhs_compat && !rhs_compat {
-                        pat.span
-                    } else if !lhs_compat {
-                        begin.span
-                    } else {
-                        end.span
-                    };
-
-                    let mut err = struct_span_err!(
-                        tcx.sess,
-                        span,
-                        E0029,
-                        "only char and numeric types are allowed in range patterns"
-                    );
-                    err.span_label(span, "ranges require char or numeric types");
-                    err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
-                    err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
-                    if tcx.sess.teach(&err.get_code().unwrap()) {
-                        err.note(
-                            "In a match expression, only numbers and characters can be matched \
-                             against a range. This is because the compiler checks that the range \
-                             is non-empty at compile-time, and is unable to evaluate arbitrary \
-                             comparison functions. If you want to capture values of an orderable \
-                             type between two end-points, you can use a guard."
-                         );
-                    }
-                    err.emit();
-                    return;
-                }
-
-                // Now that we know the types can be unified we find the unified type and use
-                // it to type the entire expression.
-                let common_type = self.resolve_vars_if_possible(&lhs_ty);
-
-                // Subtyping doesn't matter here, as the value is some kind of scalar.
-                self.demand_eqtype_pat(pat.span, expected, lhs_ty, discrim_span);
-                self.demand_eqtype_pat(pat.span, expected, rhs_ty, discrim_span);
-                common_type
-            }
-            PatKind::Binding(ba, var_id, _, ref sub) => {
-                let bm = if ba == hir::BindingAnnotation::Unannotated {
-                    def_bm
-                } else {
-                    ty::BindingMode::convert(ba)
-                };
-                self.inh
-                    .tables
-                    .borrow_mut()
-                    .pat_binding_modes_mut()
-                    .insert(pat.hir_id, bm);
-                debug!("check_pat_walk: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
-                let local_ty = self.local_ty(pat.span, pat.hir_id).decl_ty;
-                match bm {
-                    ty::BindByReference(mutbl) => {
-                        // If the binding is like
-                        //     ref x | ref const x | ref mut x
-                        // then `x` is assigned a value of type `&M T` where M is the mutability
-                        // and T is the expected type.
-                        let region_var = self.next_region_var(infer::PatternRegion(pat.span));
-                        let mt = ty::TypeAndMut { ty: expected, mutbl: mutbl };
-                        let region_ty = tcx.mk_ref(region_var, mt);
-
-                        // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
-                        // required. However, we use equality, which is stronger. See (*) for
-                        // an explanation.
-                        self.demand_eqtype_pat(pat.span, region_ty, local_ty, discrim_span);
-                    }
-                    // Otherwise, the type of x is the expected type `T`.
-                    ty::BindByValue(_) => {
-                        // As above, `T <: typeof(x)` is required, but we
-                        // use equality, see (*) below.
-                        self.demand_eqtype_pat(pat.span, expected, local_ty, discrim_span);
-                    }
-                }
-
-                // If there are multiple arms, make sure they all agree on
-                // what the type of the binding `x` ought to be.
-                if var_id != pat.hir_id {
-                    let vt = self.local_ty(pat.span, var_id).decl_ty;
-                    self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span);
-                }
-
-                if let Some(ref p) = *sub {
-                    self.check_pat_walk(&p, expected, def_bm, discrim_span);
-                }
-
-                local_ty
-            }
-            PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
-                self.check_pat_tuple_struct(
-                    pat,
-                    qpath,
-                    &subpats,
-                    ddpos,
-                    expected,
-                    def_bm,
-                    discrim_span,
-                )
-            }
-            PatKind::Path(ref qpath) => {
-                self.check_pat_path(pat, path_resolution.unwrap(), qpath, expected)
-            }
-            PatKind::Struct(ref qpath, ref fields, etc) => {
-                self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, discrim_span)
-            }
-            PatKind::Or(ref pats) => {
-                let expected_ty = self.structurally_resolved_type(pat.span, expected);
-                for pat in pats {
-                    self.check_pat_walk(pat, expected, def_bm, discrim_span);
-                }
-                expected_ty
-            }
-            PatKind::Tuple(ref elements, ddpos) => {
-                let mut expected_len = elements.len();
-                if ddpos.is_some() {
-                    // Require known type only when `..` is present.
-                    if let ty::Tuple(ref tys) =
-                            self.structurally_resolved_type(pat.span, expected).sty {
-                        expected_len = tys.len();
-                    }
-                }
-                let max_len = cmp::max(expected_len, elements.len());
-
-                let element_tys_iter = (0..max_len).map(|_| {
-                    Kind::from(self.next_ty_var(
-                        // FIXME: `MiscVariable` for now -- obtaining the span and name information
-                        // from all tuple elements isn't trivial.
-                        TypeVariableOrigin {
-                            kind: TypeVariableOriginKind::TypeInference,
-                            span: pat.span,
-                        },
-                    ))
-                });
-                let element_tys = tcx.mk_substs(element_tys_iter);
-                let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
-                if let Some(mut err) = self.demand_eqtype_diag(pat.span, expected, pat_ty) {
-                    err.emit();
-                    // Walk subpatterns with an expected type of `err` in this case to silence
-                    // further errors being emitted when using the bindings. #50333
-                    let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
-                    for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
-                        self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
-                    }
-                    tcx.mk_tup(element_tys_iter)
-                } else {
-                    for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
-                        self.check_pat_walk(
-                            elem,
-                            &element_tys[i].expect_ty(),
-                            def_bm,
-                            discrim_span,
-                        );
-                    }
-                    pat_ty
-                }
-            }
-            PatKind::Box(ref inner) => {
-                let inner_ty = self.next_ty_var(TypeVariableOrigin {
-                    kind: TypeVariableOriginKind::TypeInference,
-                    span: inner.span,
-                });
-                let uniq_ty = tcx.mk_box(inner_ty);
-
-                if self.check_dereferencable(pat.span, expected, &inner) {
-                    // Here, `demand::subtype` is good enough, but I don't
-                    // think any errors can be introduced by using
-                    // `demand::eqtype`.
-                    self.demand_eqtype_pat(pat.span, expected, uniq_ty, discrim_span);
-                    self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
-                    uniq_ty
-                } else {
-                    self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
-                    tcx.types.err
-                }
-            }
-            PatKind::Ref(ref inner, mutbl) => {
-                let expected = self.shallow_resolve(expected);
-                if self.check_dereferencable(pat.span, expected, &inner) {
-                    // `demand::subtype` would be good enough, but using
-                    // `eqtype` turns out to be equally general. See (*)
-                    // below for details.
-
-                    // Take region, inner-type from expected type if we
-                    // can, to avoid creating needless variables.  This
-                    // also helps with the bad interactions of the given
-                    // hack detailed in (*) below.
-                    debug!("check_pat_walk: expected={:?}", expected);
-                    let (rptr_ty, inner_ty) = match expected.sty {
-                        ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
-                            (expected, r_ty)
-                        }
-                        _ => {
-                            let inner_ty = self.next_ty_var(
-                                TypeVariableOrigin {
-                                    kind: TypeVariableOriginKind::TypeInference,
-                                    span: inner.span,
-                                }
-                            );
-                            let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
-                            let region = self.next_region_var(infer::PatternRegion(pat.span));
-                            let rptr_ty = tcx.mk_ref(region, mt);
-                            debug!("check_pat_walk: demanding {:?} = {:?}", expected, rptr_ty);
-                            let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
-
-                            // Look for a case like `fn foo(&foo: u32)` and suggest
-                            // `fn foo(foo: &u32)`
-                            if let Some(mut err) = err {
-                                self.borrow_pat_suggestion(&mut err, &pat, &inner, &expected);
-                                err.emit();
-                            }
-                            (rptr_ty, inner_ty)
-                        }
-                    };
-
-                    self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
-                    rptr_ty
-                } else {
-                    self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
-                    tcx.types.err
-                }
-            }
-            PatKind::Slice(ref before, ref slice, ref after) => {
-                let expected_ty = self.structurally_resolved_type(pat.span, expected);
-                let (inner_ty, slice_ty) = match expected_ty.sty {
-                    ty::Array(inner_ty, size) => {
-                        if let Some(size) = size.try_eval_usize(tcx, self.param_env) {
-                            let min_len = before.len() as u64 + after.len() as u64;
-                            if slice.is_none() {
-                                if min_len != size {
-                                    struct_span_err!(
-                                        tcx.sess, pat.span, E0527,
-                                        "pattern requires {} elements but array has {}",
-                                        min_len, size)
-                                        .span_label(pat.span, format!("expected {} elements", size))
-                                        .emit();
-                                }
-                                (inner_ty, tcx.types.err)
-                            } else if let Some(rest) = size.checked_sub(min_len) {
-                                (inner_ty, tcx.mk_array(inner_ty, rest))
-                            } else {
-                                struct_span_err!(tcx.sess, pat.span, E0528,
-                                        "pattern requires at least {} elements but array has {}",
-                                        min_len, size)
-                                    .span_label(pat.span,
-                                        format!("pattern cannot match array of {} elements", size))
-                                    .emit();
-                                (inner_ty, tcx.types.err)
-                            }
-                        } else {
-                            struct_span_err!(
-                                tcx.sess,
-                                pat.span,
-                                E0730,
-                                "cannot pattern-match on an array without a fixed length",
-                            ).emit();
-                            (inner_ty, tcx.types.err)
-                        }
-                    }
-                    ty::Slice(inner_ty) => (inner_ty, expected_ty),
-                    _ => {
-                        if !expected_ty.references_error() {
-                            let mut err = struct_span_err!(
-                                tcx.sess, pat.span, E0529,
-                                "expected an array or slice, found `{}`",
-                                expected_ty);
-                            if let ty::Ref(_, ty, _) = expected_ty.sty {
-                                match ty.sty {
-                                    ty::Array(..) | ty::Slice(..) => {
-                                        err.help("the semantics of slice patterns changed \
-                                                  recently; see issue #62254");
-                                    }
-                                    _ => {}
-                                }
-                            }
-
-                            err.span_label( pat.span,
-                                format!("pattern cannot match with input type `{}`", expected_ty)
-                            ).emit();
-                        }
-                        (tcx.types.err, tcx.types.err)
-                    }
-                };
-
-                for elt in before {
-                    self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
-                }
-                if let Some(ref slice) = *slice {
-                    self.check_pat_walk(&slice, slice_ty, def_bm, discrim_span);
-                }
-                for elt in after {
-                    self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
-                }
-                expected_ty
-            }
-        };
-
-        self.write_ty(pat.hir_id, ty);
-
-        // (*) In most of the cases above (literals and constants being
-        // the exception), we relate types using strict equality, even
-        // though subtyping would be sufficient. There are a few reasons
-        // for this, some of which are fairly subtle and which cost me
-        // (nmatsakis) an hour or two debugging to remember, so I thought
-        // I'd write them down this time.
-        //
-        // 1. There is no loss of expressiveness here, though it does
-        // cause some inconvenience. What we are saying is that the type
-        // of `x` becomes *exactly* what is expected. This can cause unnecessary
-        // errors in some cases, such as this one:
-        //
-        // ```
-        // fn foo<'x>(x: &'x int) {
-        //    let a = 1;
-        //    let mut z = x;
-        //    z = &a;
-        // }
-        // ```
-        //
-        // The reason we might get an error is that `z` might be
-        // assigned a type like `&'x int`, and then we would have
-        // a problem when we try to assign `&a` to `z`, because
-        // the lifetime of `&a` (i.e., the enclosing block) is
-        // shorter than `'x`.
-        //
-        // HOWEVER, this code works fine. The reason is that the
-        // expected type here is whatever type the user wrote, not
-        // the initializer's type. In this case the user wrote
-        // nothing, so we are going to create a type variable `Z`.
-        // Then we will assign the type of the initializer (`&'x
-        // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we
-        // will instantiate `Z` as a type `&'0 int` where `'0` is
-        // a fresh region variable, with the constraint that `'x :
-        // '0`.  So basically we're all set.
-        //
-        // Note that there are two tests to check that this remains true
-        // (`regions-reassign-{match,let}-bound-pointer.rs`).
-        //
-        // 2. Things go horribly wrong if we use subtype. The reason for
-        // THIS is a fairly subtle case involving bound regions. See the
-        // `givens` field in `region_constraints`, as well as the test
-        // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
-        // for details. Short version is that we must sometimes detect
-        // relationships between specific region variables and regions
-        // bound in a closure signature, and that detection gets thrown
-        // off when we substitute fresh region variables here to enable
-        // subtyping.
-    }
-
-    fn borrow_pat_suggestion(
-        &self,
-        err: &mut DiagnosticBuilder<'_>,
-        pat: &Pat,
-        inner: &Pat,
-        expected: Ty<'tcx>,
-    ) {
-        let tcx = self.tcx;
-        if let PatKind::Binding(..) = inner.node {
-            let binding_parent_id = tcx.hir().get_parent_node(pat.hir_id);
-            let binding_parent = tcx.hir().get(binding_parent_id);
-            debug!("inner {:?} pat {:?} parent {:?}", inner, pat, binding_parent);
-            match binding_parent {
-                hir::Node::Arg(hir::Arg { span, .. }) => {
-                    if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
-                        err.span_suggestion(
-                            *span,
-                            &format!("did you mean `{}`", snippet),
-                            format!(" &{}", expected),
-                            Applicability::MachineApplicable,
-                        );
-                    }
-                }
-                hir::Node::Arm(_) |
-                hir::Node::Pat(_) => {
-                    // rely on match ergonomics or it might be nested `&&pat`
-                    if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
-                        err.span_suggestion(
-                            pat.span,
-                            "you can probably remove the explicit borrow",
-                            snippet,
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
-                }
-                _ => {} // don't provide suggestions in other cases #55175
-            }
-        }
-    }
-
-    pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
-        if let PatKind::Binding(..) = inner.node {
-            if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
-                if let ty::Dynamic(..) = mt.ty.sty {
-                    // This is "x = SomeTrait" being reduced from
-                    // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
-                    let type_str = self.ty_to_string(expected);
-                    let mut err = struct_span_err!(
-                        self.tcx.sess,
-                        span,
-                        E0033,
-                        "type `{}` cannot be dereferenced",
-                        type_str
-                    );
-                    err.span_label(span, format!("type `{}` cannot be dereferenced", type_str));
-                    if self.tcx.sess.teach(&err.get_code().unwrap()) {
-                        err.note("\
-This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a \
-pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, \
-this type has no compile-time size. Therefore, all accesses to trait types must be through \
-pointers. If you encounter this error you should try to avoid dereferencing the pointer.
-
-You can read more about trait objects in the Trait Objects section of the Reference: \
-https://doc.rust-lang.org/reference/types.html#trait-objects");
-                    }
-                    err.emit();
-                    return false
-                }
-            }
-        }
-        true
-    }
-
     pub fn check_match(
         &self,
         expr: &'tcx hir::Expr,
@@ -1038,346 +419,4 @@ https://doc.rust-lang.org/reference/types.html#trait-objects");
             discrim_ty
         }
     }
-
-    fn check_pat_struct(
-        &self,
-        pat: &'tcx hir::Pat,
-        qpath: &hir::QPath,
-        fields: &'tcx [hir::FieldPat],
-        etc: bool,
-        expected: Ty<'tcx>,
-        def_bm: ty::BindingMode,
-        discrim_span: Option<Span>,
-    ) -> Ty<'tcx> {
-        // Resolve the path and check the definition for errors.
-        let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.hir_id)
-        {
-            variant_ty
-        } else {
-            for field in fields {
-                self.check_pat_walk(&field.pat, self.tcx.types.err, def_bm, discrim_span);
-            }
-            return self.tcx.types.err;
-        };
-
-        // Type-check the path.
-        self.demand_eqtype_pat(pat.span, expected, pat_ty, discrim_span);
-
-        // Type-check subpatterns.
-        if self.check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm)
-        {
-            pat_ty
-        } else {
-            self.tcx.types.err
-        }
-    }
-
-    fn check_pat_path(
-        &self,
-        pat: &hir::Pat,
-        path_resolution: (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment]),
-        qpath: &hir::QPath,
-        expected: Ty<'tcx>,
-    ) -> Ty<'tcx> {
-        let tcx = self.tcx;
-
-        // We have already resolved the path.
-        let (res, opt_ty, segments) = path_resolution;
-        match res {
-            Res::Err => {
-                self.set_tainted_by_errors();
-                return tcx.types.err;
-            }
-            Res::Def(DefKind::Method, _) |
-            Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) |
-            Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
-                report_unexpected_variant_res(tcx, res, pat.span, qpath);
-                return tcx.types.err;
-            }
-            Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..) |
-            Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => {} // OK
-            _ => bug!("unexpected pattern resolution: {:?}", res)
-        }
-
-        // Type-check the path.
-        let pat_ty = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id).0;
-        self.demand_suptype(pat.span, expected, pat_ty);
-        pat_ty
-    }
-
-    fn check_pat_tuple_struct(
-        &self,
-        pat: &hir::Pat,
-        qpath: &hir::QPath,
-        subpats: &'tcx [P<hir::Pat>],
-        ddpos: Option<usize>,
-        expected: Ty<'tcx>,
-        def_bm: ty::BindingMode,
-        match_arm_pat_span: Option<Span>,
-    ) -> Ty<'tcx> {
-        let tcx = self.tcx;
-        let on_error = || {
-            for pat in subpats {
-                self.check_pat_walk(&pat, tcx.types.err, def_bm, match_arm_pat_span);
-            }
-        };
-        let report_unexpected_res = |res: Res| {
-            let msg = format!("expected tuple struct/variant, found {} `{}`",
-                              res.descr(),
-                              hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
-            let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg);
-            match (res, &pat.node) {
-                (Res::Def(DefKind::Fn, _), _) | (Res::Def(DefKind::Method, _), _) => {
-                    err.span_label(pat.span, "`fn` calls are not allowed in patterns");
-                    err.help("for more information, visit \
-                              https://doc.rust-lang.org/book/ch18-00-patterns.html");
-                }
-                _ => {
-                    err.span_label(pat.span, "not a tuple variant or struct");
-                }
-            }
-            err.emit();
-            on_error();
-        };
-
-        // Resolve the path and check the definition for errors.
-        let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
-        if res == Res::Err {
-            self.set_tainted_by_errors();
-            on_error();
-            return self.tcx.types.err;
-        }
-
-        // Type-check the path.
-        let (pat_ty, res) = self.instantiate_value_path(segments, opt_ty, res, pat.span,
-            pat.hir_id);
-        if !pat_ty.is_fn() {
-            report_unexpected_res(res);
-            return self.tcx.types.err;
-        }
-
-        let variant = match res {
-            Res::Err => {
-                self.set_tainted_by_errors();
-                on_error();
-                return tcx.types.err;
-            }
-            Res::Def(DefKind::AssocConst, _) | Res::Def(DefKind::Method, _) => {
-                report_unexpected_res(res);
-                return tcx.types.err;
-            }
-            Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
-                tcx.expect_variant_res(res)
-            }
-            _ => bug!("unexpected pattern resolution: {:?}", res)
-        };
-
-        // Replace constructor type with constructed type for tuple struct patterns.
-        let pat_ty = pat_ty.fn_sig(tcx).output();
-        let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
-
-        self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span);
-
-        // Type-check subpatterns.
-        if subpats.len() == variant.fields.len() ||
-                subpats.len() < variant.fields.len() && ddpos.is_some() {
-            let substs = match pat_ty.sty {
-                ty::Adt(_, substs) => substs,
-                _ => bug!("unexpected pattern type {:?}", pat_ty),
-            };
-            for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
-                let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
-                self.check_pat_walk(&subpat, field_ty, def_bm, match_arm_pat_span);
-
-                self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
-            }
-        } else {
-            let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
-            let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
-            struct_span_err!(tcx.sess, pat.span, E0023,
-                             "this pattern has {} field{}, but the corresponding {} has {} field{}",
-                             subpats.len(), subpats_ending, res.descr(),
-                             variant.fields.len(),  fields_ending)
-                .span_label(pat.span, format!("expected {} field{}, found {}",
-                                              variant.fields.len(), fields_ending, subpats.len()))
-                .emit();
-            on_error();
-            return tcx.types.err;
-        }
-        pat_ty
-    }
-
-    fn check_struct_pat_fields(
-        &self,
-        adt_ty: Ty<'tcx>,
-        pat_id: hir::HirId,
-        span: Span,
-        variant: &'tcx ty::VariantDef,
-        fields: &'tcx [hir::FieldPat],
-        etc: bool,
-        def_bm: ty::BindingMode,
-    ) -> bool {
-        let tcx = self.tcx;
-
-        let (substs, adt) = match adt_ty.sty {
-            ty::Adt(adt, substs) => (substs, adt),
-            _ => span_bug!(span, "struct pattern is not an ADT")
-        };
-        let kind_name = adt.variant_descr();
-
-        // Index the struct fields' types.
-        let field_map = variant.fields
-            .iter()
-            .enumerate()
-            .map(|(i, field)| (field.ident.modern(), (i, field)))
-            .collect::<FxHashMap<_, _>>();
-
-        // Keep track of which fields have already appeared in the pattern.
-        let mut used_fields = FxHashMap::default();
-        let mut no_field_errors = true;
-
-        let mut inexistent_fields = vec![];
-        // Typecheck each field.
-        for field in fields {
-            let span = field.span;
-            let ident = tcx.adjust_ident(field.ident, variant.def_id);
-            let field_ty = match used_fields.entry(ident) {
-                Occupied(occupied) => {
-                    struct_span_err!(tcx.sess, span, E0025,
-                                     "field `{}` bound multiple times \
-                                      in the pattern",
-                                     field.ident)
-                        .span_label(span,
-                                    format!("multiple uses of `{}` in pattern", field.ident))
-                        .span_label(*occupied.get(), format!("first use of `{}`", field.ident))
-                        .emit();
-                    no_field_errors = false;
-                    tcx.types.err
-                }
-                Vacant(vacant) => {
-                    vacant.insert(span);
-                    field_map.get(&ident)
-                        .map(|(i, f)| {
-                            self.write_field_index(field.hir_id, *i);
-                            self.tcx.check_stability(f.did, Some(pat_id), span);
-                            self.field_ty(span, f, substs)
-                        })
-                        .unwrap_or_else(|| {
-                            inexistent_fields.push(field.ident);
-                            no_field_errors = false;
-                            tcx.types.err
-                        })
-                }
-            };
-
-            self.check_pat_walk(&field.pat, field_ty, def_bm, None);
-        }
-        let mut unmentioned_fields = variant.fields
-                .iter()
-                .map(|field| field.ident.modern())
-                .filter(|ident| !used_fields.contains_key(&ident))
-                .collect::<Vec<_>>();
-        if inexistent_fields.len() > 0 && !variant.recovered {
-            let (field_names, t, plural) = if inexistent_fields.len() == 1 {
-                (format!("a field named `{}`", inexistent_fields[0]), "this", "")
-            } else {
-                (format!("fields named {}",
-                         inexistent_fields.iter()
-                            .map(|ident| format!("`{}`", ident))
-                            .collect::<Vec<String>>()
-                            .join(", ")), "these", "s")
-            };
-            let spans = inexistent_fields.iter().map(|ident| ident.span).collect::<Vec<_>>();
-            let mut err = struct_span_err!(tcx.sess,
-                                           spans,
-                                           E0026,
-                                           "{} `{}` does not have {}",
-                                           kind_name,
-                                           tcx.def_path_str(variant.def_id),
-                                           field_names);
-            if let Some(ident) = inexistent_fields.last() {
-                err.span_label(ident.span,
-                               format!("{} `{}` does not have {} field{}",
-                                       kind_name,
-                                       tcx.def_path_str(variant.def_id),
-                                       t,
-                                       plural));
-                if plural == "" {
-                    let input = unmentioned_fields.iter().map(|field| &field.name);
-                    let suggested_name =
-                        find_best_match_for_name(input, &ident.as_str(), None);
-                    if let Some(suggested_name) = suggested_name {
-                        err.span_suggestion(
-                            ident.span,
-                            "a field with a similar name exists",
-                            suggested_name.to_string(),
-                            Applicability::MaybeIncorrect,
-                        );
-
-                        // we don't want to throw `E0027` in case we have thrown `E0026` for them
-                        unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
-                    }
-                }
-            }
-            if tcx.sess.teach(&err.get_code().unwrap()) {
-                err.note(
-                    "This error indicates that a struct pattern attempted to \
-                     extract a non-existent field from a struct. Struct fields \
-                     are identified by the name used before the colon : so struct \
-                     patterns should resemble the declaration of the struct type \
-                     being matched.\n\n\
-                     If you are using shorthand field patterns but want to refer \
-                     to the struct field by a different name, you should rename \
-                     it explicitly."
-                );
-            }
-            err.emit();
-        }
-
-        // Require `..` if struct has non_exhaustive attribute.
-        if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc {
-            span_err!(tcx.sess, span, E0638,
-                      "`..` required with {} marked as non-exhaustive",
-                      kind_name);
-        }
-
-        // Report an error if incorrect number of the fields were specified.
-        if kind_name == "union" {
-            if fields.len() != 1 {
-                tcx.sess.span_err(span, "union patterns should have exactly one field");
-            }
-            if etc {
-                tcx.sess.span_err(span, "`..` cannot be used in union patterns");
-            }
-        } else if !etc {
-            if unmentioned_fields.len() > 0 {
-                let field_names = if unmentioned_fields.len() == 1 {
-                    format!("field `{}`", unmentioned_fields[0])
-                } else {
-                    format!("fields {}",
-                            unmentioned_fields.iter()
-                                .map(|name| format!("`{}`", name))
-                                .collect::<Vec<String>>()
-                                .join(", "))
-                };
-                let mut diag = struct_span_err!(tcx.sess, span, E0027,
-                                                "pattern does not mention {}",
-                                                field_names);
-                diag.span_label(span, format!("missing {}", field_names));
-                if variant.ctor_kind == CtorKind::Fn {
-                    diag.note("trying to match a tuple variant with a struct variant pattern");
-                }
-                if tcx.sess.teach(&diag.get_code().unwrap()) {
-                    diag.note(
-                        "This error indicates that a pattern for a struct fails to specify a \
-                         sub-pattern for every one of the struct's fields. Ensure that each field \
-                         from the struct's definition is mentioned in the pattern, or use `..` to \
-                         ignore unwanted fields."
-                    );
-                }
-                diag.emit();
-            }
-        }
-        no_field_errors
-    }
 }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 9c7ac83e82e97..a130d11a5e645 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -70,6 +70,7 @@ type parameter).
 mod autoderef;
 pub mod dropck;
 pub mod _match;
+mod pat;
 pub mod writeback;
 mod regionck;
 pub mod coercion;
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
new file mode 100644
index 0000000000000..e2d0f485bdf01
--- /dev/null
+++ b/src/librustc_typeck/check/pat.rs
@@ -0,0 +1,968 @@
+use crate::check::FnCtxt;
+use crate::util::nodemap::FxHashMap;
+use errors::{Applicability, DiagnosticBuilder};
+use rustc::hir::{self, PatKind, Pat};
+use rustc::hir::def::{Res, DefKind, CtorKind};
+use rustc::hir::pat_util::EnumerateAndAdjustIterator;
+use rustc::hir::ptr::P;
+use rustc::infer;
+use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc::ty::{self, Ty, TypeFoldable};
+use rustc::ty::subst::Kind;
+use syntax::ast;
+use syntax::util::lev_distance::find_best_match_for_name;
+use syntax_pos::Span;
+use syntax_pos::hygiene::DesugaringKind;
+
+use std::collections::hash_map::Entry::{Occupied, Vacant};
+use std::cmp;
+
+use super::report_unexpected_variant_res;
+
+impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
+    /// `discrim_span` argument having a `Span` indicates that this pattern is part of a match
+    /// expression arm guard, and it points to the match discriminant to add context in type errors.
+    /// In the following example, `discrim_span` corresponds to the `a + b` expression:
+    ///
+    /// ```text
+    /// error[E0308]: mismatched types
+    ///  --> src/main.rs:5:9
+    ///   |
+    /// 4 |    let temp: usize = match a + b {
+    ///   |                            ----- this expression has type `usize`
+    /// 5 |         Ok(num) => num,
+    ///   |         ^^^^^^^ expected usize, found enum `std::result::Result`
+    ///   |
+    ///   = note: expected type `usize`
+    ///              found type `std::result::Result<_, _>`
+    /// ```
+    pub fn check_pat_walk(
+        &self,
+        pat: &'tcx hir::Pat,
+        mut expected: Ty<'tcx>,
+        mut def_bm: ty::BindingMode,
+        discrim_span: Option<Span>,
+    ) {
+        let tcx = self.tcx;
+
+        debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
+
+        let mut path_resolution = None;
+        let is_non_ref_pat = match pat.node {
+            PatKind::Struct(..) |
+            PatKind::TupleStruct(..) |
+            PatKind::Or(_) |
+            PatKind::Tuple(..) |
+            PatKind::Box(_) |
+            PatKind::Range(..) |
+            PatKind::Slice(..) => true,
+            PatKind::Lit(ref lt) => {
+                let ty = self.check_expr(lt);
+                match ty.sty {
+                    ty::Ref(..) => false,
+                    _ => true,
+                }
+            }
+            PatKind::Path(ref qpath) => {
+                let resolution = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
+                path_resolution = Some(resolution);
+                match resolution.0 {
+                    Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => false,
+                    _ => true,
+                }
+            }
+            PatKind::Wild |
+            PatKind::Binding(..) |
+            PatKind::Ref(..) => false,
+        };
+        if is_non_ref_pat {
+            debug!("pattern is non reference pattern");
+            let mut exp_ty = self.resolve_type_vars_with_obligations(&expected);
+
+            // Peel off as many `&` or `&mut` from the discriminant as possible. For example,
+            // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
+            // the `Some(5)` which is not of type Ref.
+            //
+            // For each ampersand peeled off, update the binding mode and push the original
+            // type into the adjustments vector.
+            //
+            // See the examples in `ui/match-defbm*.rs`.
+            let mut pat_adjustments = vec![];
+            while let ty::Ref(_, inner_ty, inner_mutability) = exp_ty.sty {
+                debug!("inspecting {:?}", exp_ty);
+
+                debug!("current discriminant is Ref, inserting implicit deref");
+                // Preserve the reference type. We'll need it later during HAIR lowering.
+                pat_adjustments.push(exp_ty);
+
+                exp_ty = inner_ty;
+                def_bm = match def_bm {
+                    // If default binding mode is by value, make it `ref` or `ref mut`
+                    // (depending on whether we observe `&` or `&mut`).
+                    ty::BindByValue(_) =>
+                        ty::BindByReference(inner_mutability),
+
+                    // Once a `ref`, always a `ref`. This is because a `& &mut` can't mutate
+                    // the underlying value.
+                    ty::BindByReference(hir::Mutability::MutImmutable) =>
+                        ty::BindByReference(hir::Mutability::MutImmutable),
+
+                    // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref`
+                    // (on `&`).
+                    ty::BindByReference(hir::Mutability::MutMutable) =>
+                        ty::BindByReference(inner_mutability),
+                };
+            }
+            expected = exp_ty;
+
+            if pat_adjustments.len() > 0 {
+                debug!("default binding mode is now {:?}", def_bm);
+                self.inh.tables.borrow_mut()
+                    .pat_adjustments_mut()
+                    .insert(pat.hir_id, pat_adjustments);
+            }
+        } else if let PatKind::Ref(..) = pat.node {
+            // When you encounter a `&pat` pattern, reset to "by
+            // value". This is so that `x` and `y` here are by value,
+            // as they appear to be:
+            //
+            // ```
+            // match &(&22, &44) {
+            //   (&x, &y) => ...
+            // }
+            // ```
+            //
+            // See issue #46688.
+            def_bm = ty::BindByValue(hir::MutImmutable);
+        }
+
+        // Lose mutability now that we know binding mode and discriminant type.
+        let def_bm = def_bm;
+        let expected = expected;
+
+        let ty = match pat.node {
+            PatKind::Wild => {
+                expected
+            }
+            PatKind::Lit(ref lt) => {
+                // We've already computed the type above (when checking for a non-ref pat), so
+                // avoid computing it again.
+                let ty = self.node_ty(lt.hir_id);
+
+                // Byte string patterns behave the same way as array patterns
+                // They can denote both statically and dynamically-sized byte arrays.
+                let mut pat_ty = ty;
+                if let hir::ExprKind::Lit(ref lt) = lt.node {
+                    if let ast::LitKind::ByteStr(_) = lt.node {
+                        let expected_ty = self.structurally_resolved_type(pat.span, expected);
+                        if let ty::Ref(_, r_ty, _) = expected_ty.sty {
+                            if let ty::Slice(_) = r_ty.sty {
+                                pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static,
+                                                        tcx.mk_slice(tcx.types.u8))
+                            }
+                        }
+                    }
+                }
+
+                // Somewhat surprising: in this case, the subtyping
+                // relation goes the opposite way as the other
+                // cases. Actually what we really want is not a subtyping
+                // relation at all but rather that there exists a LUB (so
+                // that they can be compared). However, in practice,
+                // constants are always scalars or strings.  For scalars
+                // subtyping is irrelevant, and for strings `ty` is
+                // type is `&'static str`, so if we say that
+                //
+                //     &'static str <: expected
+                //
+                // then that's equivalent to there existing a LUB.
+                if let Some(mut err) = self.demand_suptype_diag(pat.span, expected, pat_ty) {
+                    err.emit_unless(discrim_span
+                        .filter(|&s| {
+                            // In the case of `if`- and `while`-expressions we've already checked
+                            // that `scrutinee: bool`. We know that the pattern is `true`,
+                            // so an error here would be a duplicate and from the wrong POV.
+                            s.is_desugaring(DesugaringKind::CondTemporary)
+                        })
+                        .is_some());
+                }
+
+                pat_ty
+            }
+            PatKind::Range(ref begin, ref end, _) => {
+                let lhs_ty = self.check_expr(begin);
+                let rhs_ty = self.check_expr(end);
+
+                // Check that both end-points are of numeric or char type.
+                let numeric_or_char = |ty: Ty<'_>| {
+                    ty.is_numeric()
+                    || ty.is_char()
+                    || ty.references_error()
+                };
+                let lhs_compat = numeric_or_char(lhs_ty);
+                let rhs_compat = numeric_or_char(rhs_ty);
+
+                if !lhs_compat || !rhs_compat {
+                    let span = if !lhs_compat && !rhs_compat {
+                        pat.span
+                    } else if !lhs_compat {
+                        begin.span
+                    } else {
+                        end.span
+                    };
+
+                    let mut err = struct_span_err!(
+                        tcx.sess,
+                        span,
+                        E0029,
+                        "only char and numeric types are allowed in range patterns"
+                    );
+                    err.span_label(span, "ranges require char or numeric types");
+                    err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
+                    err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
+                    if tcx.sess.teach(&err.get_code().unwrap()) {
+                        err.note(
+                            "In a match expression, only numbers and characters can be matched \
+                             against a range. This is because the compiler checks that the range \
+                             is non-empty at compile-time, and is unable to evaluate arbitrary \
+                             comparison functions. If you want to capture values of an orderable \
+                             type between two end-points, you can use a guard."
+                         );
+                    }
+                    err.emit();
+                    return;
+                }
+
+                // Now that we know the types can be unified we find the unified type and use
+                // it to type the entire expression.
+                let common_type = self.resolve_vars_if_possible(&lhs_ty);
+
+                // Subtyping doesn't matter here, as the value is some kind of scalar.
+                self.demand_eqtype_pat(pat.span, expected, lhs_ty, discrim_span);
+                self.demand_eqtype_pat(pat.span, expected, rhs_ty, discrim_span);
+                common_type
+            }
+            PatKind::Binding(ba, var_id, _, ref sub) => {
+                let bm = if ba == hir::BindingAnnotation::Unannotated {
+                    def_bm
+                } else {
+                    ty::BindingMode::convert(ba)
+                };
+                self.inh
+                    .tables
+                    .borrow_mut()
+                    .pat_binding_modes_mut()
+                    .insert(pat.hir_id, bm);
+                debug!("check_pat_walk: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
+                let local_ty = self.local_ty(pat.span, pat.hir_id).decl_ty;
+                match bm {
+                    ty::BindByReference(mutbl) => {
+                        // If the binding is like
+                        //     ref x | ref const x | ref mut x
+                        // then `x` is assigned a value of type `&M T` where M is the mutability
+                        // and T is the expected type.
+                        let region_var = self.next_region_var(infer::PatternRegion(pat.span));
+                        let mt = ty::TypeAndMut { ty: expected, mutbl: mutbl };
+                        let region_ty = tcx.mk_ref(region_var, mt);
+
+                        // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
+                        // required. However, we use equality, which is stronger. See (*) for
+                        // an explanation.
+                        self.demand_eqtype_pat(pat.span, region_ty, local_ty, discrim_span);
+                    }
+                    // Otherwise, the type of x is the expected type `T`.
+                    ty::BindByValue(_) => {
+                        // As above, `T <: typeof(x)` is required, but we
+                        // use equality, see (*) below.
+                        self.demand_eqtype_pat(pat.span, expected, local_ty, discrim_span);
+                    }
+                }
+
+                // If there are multiple arms, make sure they all agree on
+                // what the type of the binding `x` ought to be.
+                if var_id != pat.hir_id {
+                    let vt = self.local_ty(pat.span, var_id).decl_ty;
+                    self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span);
+                }
+
+                if let Some(ref p) = *sub {
+                    self.check_pat_walk(&p, expected, def_bm, discrim_span);
+                }
+
+                local_ty
+            }
+            PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
+                self.check_pat_tuple_struct(
+                    pat,
+                    qpath,
+                    &subpats,
+                    ddpos,
+                    expected,
+                    def_bm,
+                    discrim_span,
+                )
+            }
+            PatKind::Path(ref qpath) => {
+                self.check_pat_path(pat, path_resolution.unwrap(), qpath, expected)
+            }
+            PatKind::Struct(ref qpath, ref fields, etc) => {
+                self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, discrim_span)
+            }
+            PatKind::Or(ref pats) => {
+                let expected_ty = self.structurally_resolved_type(pat.span, expected);
+                for pat in pats {
+                    self.check_pat_walk(pat, expected, def_bm, discrim_span);
+                }
+                expected_ty
+            }
+            PatKind::Tuple(ref elements, ddpos) => {
+                let mut expected_len = elements.len();
+                if ddpos.is_some() {
+                    // Require known type only when `..` is present.
+                    if let ty::Tuple(ref tys) =
+                            self.structurally_resolved_type(pat.span, expected).sty {
+                        expected_len = tys.len();
+                    }
+                }
+                let max_len = cmp::max(expected_len, elements.len());
+
+                let element_tys_iter = (0..max_len).map(|_| {
+                    Kind::from(self.next_ty_var(
+                        // FIXME: `MiscVariable` for now -- obtaining the span and name information
+                        // from all tuple elements isn't trivial.
+                        TypeVariableOrigin {
+                            kind: TypeVariableOriginKind::TypeInference,
+                            span: pat.span,
+                        },
+                    ))
+                });
+                let element_tys = tcx.mk_substs(element_tys_iter);
+                let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
+                if let Some(mut err) = self.demand_eqtype_diag(pat.span, expected, pat_ty) {
+                    err.emit();
+                    // Walk subpatterns with an expected type of `err` in this case to silence
+                    // further errors being emitted when using the bindings. #50333
+                    let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
+                    for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
+                        self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
+                    }
+                    tcx.mk_tup(element_tys_iter)
+                } else {
+                    for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
+                        self.check_pat_walk(
+                            elem,
+                            &element_tys[i].expect_ty(),
+                            def_bm,
+                            discrim_span,
+                        );
+                    }
+                    pat_ty
+                }
+            }
+            PatKind::Box(ref inner) => {
+                let inner_ty = self.next_ty_var(TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::TypeInference,
+                    span: inner.span,
+                });
+                let uniq_ty = tcx.mk_box(inner_ty);
+
+                if self.check_dereferencable(pat.span, expected, &inner) {
+                    // Here, `demand::subtype` is good enough, but I don't
+                    // think any errors can be introduced by using
+                    // `demand::eqtype`.
+                    self.demand_eqtype_pat(pat.span, expected, uniq_ty, discrim_span);
+                    self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
+                    uniq_ty
+                } else {
+                    self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
+                    tcx.types.err
+                }
+            }
+            PatKind::Ref(ref inner, mutbl) => {
+                let expected = self.shallow_resolve(expected);
+                if self.check_dereferencable(pat.span, expected, &inner) {
+                    // `demand::subtype` would be good enough, but using
+                    // `eqtype` turns out to be equally general. See (*)
+                    // below for details.
+
+                    // Take region, inner-type from expected type if we
+                    // can, to avoid creating needless variables.  This
+                    // also helps with the bad interactions of the given
+                    // hack detailed in (*) below.
+                    debug!("check_pat_walk: expected={:?}", expected);
+                    let (rptr_ty, inner_ty) = match expected.sty {
+                        ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
+                            (expected, r_ty)
+                        }
+                        _ => {
+                            let inner_ty = self.next_ty_var(
+                                TypeVariableOrigin {
+                                    kind: TypeVariableOriginKind::TypeInference,
+                                    span: inner.span,
+                                }
+                            );
+                            let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
+                            let region = self.next_region_var(infer::PatternRegion(pat.span));
+                            let rptr_ty = tcx.mk_ref(region, mt);
+                            debug!("check_pat_walk: demanding {:?} = {:?}", expected, rptr_ty);
+                            let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
+
+                            // Look for a case like `fn foo(&foo: u32)` and suggest
+                            // `fn foo(foo: &u32)`
+                            if let Some(mut err) = err {
+                                self.borrow_pat_suggestion(&mut err, &pat, &inner, &expected);
+                                err.emit();
+                            }
+                            (rptr_ty, inner_ty)
+                        }
+                    };
+
+                    self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
+                    rptr_ty
+                } else {
+                    self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
+                    tcx.types.err
+                }
+            }
+            PatKind::Slice(ref before, ref slice, ref after) => {
+                let expected_ty = self.structurally_resolved_type(pat.span, expected);
+                let (inner_ty, slice_ty) = match expected_ty.sty {
+                    ty::Array(inner_ty, size) => {
+                        if let Some(size) = size.try_eval_usize(tcx, self.param_env) {
+                            let min_len = before.len() as u64 + after.len() as u64;
+                            if slice.is_none() {
+                                if min_len != size {
+                                    struct_span_err!(
+                                        tcx.sess, pat.span, E0527,
+                                        "pattern requires {} elements but array has {}",
+                                        min_len, size)
+                                        .span_label(pat.span, format!("expected {} elements", size))
+                                        .emit();
+                                }
+                                (inner_ty, tcx.types.err)
+                            } else if let Some(rest) = size.checked_sub(min_len) {
+                                (inner_ty, tcx.mk_array(inner_ty, rest))
+                            } else {
+                                struct_span_err!(tcx.sess, pat.span, E0528,
+                                        "pattern requires at least {} elements but array has {}",
+                                        min_len, size)
+                                    .span_label(pat.span,
+                                        format!("pattern cannot match array of {} elements", size))
+                                    .emit();
+                                (inner_ty, tcx.types.err)
+                            }
+                        } else {
+                            struct_span_err!(
+                                tcx.sess,
+                                pat.span,
+                                E0730,
+                                "cannot pattern-match on an array without a fixed length",
+                            ).emit();
+                            (inner_ty, tcx.types.err)
+                        }
+                    }
+                    ty::Slice(inner_ty) => (inner_ty, expected_ty),
+                    _ => {
+                        if !expected_ty.references_error() {
+                            let mut err = struct_span_err!(
+                                tcx.sess, pat.span, E0529,
+                                "expected an array or slice, found `{}`",
+                                expected_ty);
+                            if let ty::Ref(_, ty, _) = expected_ty.sty {
+                                match ty.sty {
+                                    ty::Array(..) | ty::Slice(..) => {
+                                        err.help("the semantics of slice patterns changed \
+                                                  recently; see issue #62254");
+                                    }
+                                    _ => {}
+                                }
+                            }
+
+                            err.span_label( pat.span,
+                                format!("pattern cannot match with input type `{}`", expected_ty)
+                            ).emit();
+                        }
+                        (tcx.types.err, tcx.types.err)
+                    }
+                };
+
+                for elt in before {
+                    self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
+                }
+                if let Some(ref slice) = *slice {
+                    self.check_pat_walk(&slice, slice_ty, def_bm, discrim_span);
+                }
+                for elt in after {
+                    self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
+                }
+                expected_ty
+            }
+        };
+
+        self.write_ty(pat.hir_id, ty);
+
+        // (*) In most of the cases above (literals and constants being
+        // the exception), we relate types using strict equality, even
+        // though subtyping would be sufficient. There are a few reasons
+        // for this, some of which are fairly subtle and which cost me
+        // (nmatsakis) an hour or two debugging to remember, so I thought
+        // I'd write them down this time.
+        //
+        // 1. There is no loss of expressiveness here, though it does
+        // cause some inconvenience. What we are saying is that the type
+        // of `x` becomes *exactly* what is expected. This can cause unnecessary
+        // errors in some cases, such as this one:
+        //
+        // ```
+        // fn foo<'x>(x: &'x int) {
+        //    let a = 1;
+        //    let mut z = x;
+        //    z = &a;
+        // }
+        // ```
+        //
+        // The reason we might get an error is that `z` might be
+        // assigned a type like `&'x int`, and then we would have
+        // a problem when we try to assign `&a` to `z`, because
+        // the lifetime of `&a` (i.e., the enclosing block) is
+        // shorter than `'x`.
+        //
+        // HOWEVER, this code works fine. The reason is that the
+        // expected type here is whatever type the user wrote, not
+        // the initializer's type. In this case the user wrote
+        // nothing, so we are going to create a type variable `Z`.
+        // Then we will assign the type of the initializer (`&'x
+        // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we
+        // will instantiate `Z` as a type `&'0 int` where `'0` is
+        // a fresh region variable, with the constraint that `'x :
+        // '0`.  So basically we're all set.
+        //
+        // Note that there are two tests to check that this remains true
+        // (`regions-reassign-{match,let}-bound-pointer.rs`).
+        //
+        // 2. Things go horribly wrong if we use subtype. The reason for
+        // THIS is a fairly subtle case involving bound regions. See the
+        // `givens` field in `region_constraints`, as well as the test
+        // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
+        // for details. Short version is that we must sometimes detect
+        // relationships between specific region variables and regions
+        // bound in a closure signature, and that detection gets thrown
+        // off when we substitute fresh region variables here to enable
+        // subtyping.
+    }
+
+    fn borrow_pat_suggestion(
+        &self,
+        err: &mut DiagnosticBuilder<'_>,
+        pat: &Pat,
+        inner: &Pat,
+        expected: Ty<'tcx>,
+    ) {
+        let tcx = self.tcx;
+        if let PatKind::Binding(..) = inner.node {
+            let binding_parent_id = tcx.hir().get_parent_node(pat.hir_id);
+            let binding_parent = tcx.hir().get(binding_parent_id);
+            debug!("inner {:?} pat {:?} parent {:?}", inner, pat, binding_parent);
+            match binding_parent {
+                hir::Node::Arg(hir::Arg { span, .. }) => {
+                    if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
+                        err.span_suggestion(
+                            *span,
+                            &format!("did you mean `{}`", snippet),
+                            format!(" &{}", expected),
+                            Applicability::MachineApplicable,
+                        );
+                    }
+                }
+                hir::Node::Arm(_) |
+                hir::Node::Pat(_) => {
+                    // rely on match ergonomics or it might be nested `&&pat`
+                    if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
+                        err.span_suggestion(
+                            pat.span,
+                            "you can probably remove the explicit borrow",
+                            snippet,
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                }
+                _ => {} // don't provide suggestions in other cases #55175
+            }
+        }
+    }
+
+    pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
+        if let PatKind::Binding(..) = inner.node {
+            if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
+                if let ty::Dynamic(..) = mt.ty.sty {
+                    // This is "x = SomeTrait" being reduced from
+                    // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
+                    let type_str = self.ty_to_string(expected);
+                    let mut err = struct_span_err!(
+                        self.tcx.sess,
+                        span,
+                        E0033,
+                        "type `{}` cannot be dereferenced",
+                        type_str
+                    );
+                    err.span_label(span, format!("type `{}` cannot be dereferenced", type_str));
+                    if self.tcx.sess.teach(&err.get_code().unwrap()) {
+                        err.note("\
+This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a \
+pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, \
+this type has no compile-time size. Therefore, all accesses to trait types must be through \
+pointers. If you encounter this error you should try to avoid dereferencing the pointer.
+
+You can read more about trait objects in the Trait Objects section of the Reference: \
+https://doc.rust-lang.org/reference/types.html#trait-objects");
+                    }
+                    err.emit();
+                    return false
+                }
+            }
+        }
+        true
+    }
+
+    fn check_pat_struct(
+        &self,
+        pat: &'tcx hir::Pat,
+        qpath: &hir::QPath,
+        fields: &'tcx [hir::FieldPat],
+        etc: bool,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        discrim_span: Option<Span>,
+    ) -> Ty<'tcx> {
+        // Resolve the path and check the definition for errors.
+        let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(qpath, pat.hir_id)
+        {
+            variant_ty
+        } else {
+            for field in fields {
+                self.check_pat_walk(&field.pat, self.tcx.types.err, def_bm, discrim_span);
+            }
+            return self.tcx.types.err;
+        };
+
+        // Type-check the path.
+        self.demand_eqtype_pat(pat.span, expected, pat_ty, discrim_span);
+
+        // Type-check subpatterns.
+        if self.check_struct_pat_fields(pat_ty, pat.hir_id, pat.span, variant, fields, etc, def_bm)
+        {
+            pat_ty
+        } else {
+            self.tcx.types.err
+        }
+    }
+
+    fn check_pat_path(
+        &self,
+        pat: &hir::Pat,
+        path_resolution: (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment]),
+        qpath: &hir::QPath,
+        expected: Ty<'tcx>,
+    ) -> Ty<'tcx> {
+        let tcx = self.tcx;
+
+        // We have already resolved the path.
+        let (res, opt_ty, segments) = path_resolution;
+        match res {
+            Res::Err => {
+                self.set_tainted_by_errors();
+                return tcx.types.err;
+            }
+            Res::Def(DefKind::Method, _) |
+            Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) |
+            Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
+                report_unexpected_variant_res(tcx, res, pat.span, qpath);
+                return tcx.types.err;
+            }
+            Res::Def(DefKind::Ctor(_, CtorKind::Const), _) | Res::SelfCtor(..) |
+            Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => {} // OK
+            _ => bug!("unexpected pattern resolution: {:?}", res)
+        }
+
+        // Type-check the path.
+        let pat_ty = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id).0;
+        self.demand_suptype(pat.span, expected, pat_ty);
+        pat_ty
+    }
+
+    fn check_pat_tuple_struct(
+        &self,
+        pat: &hir::Pat,
+        qpath: &hir::QPath,
+        subpats: &'tcx [P<hir::Pat>],
+        ddpos: Option<usize>,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        match_arm_pat_span: Option<Span>,
+    ) -> Ty<'tcx> {
+        let tcx = self.tcx;
+        let on_error = || {
+            for pat in subpats {
+                self.check_pat_walk(&pat, tcx.types.err, def_bm, match_arm_pat_span);
+            }
+        };
+        let report_unexpected_res = |res: Res| {
+            let msg = format!("expected tuple struct/variant, found {} `{}`",
+                              res.descr(),
+                              hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false)));
+            let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg);
+            match (res, &pat.node) {
+                (Res::Def(DefKind::Fn, _), _) | (Res::Def(DefKind::Method, _), _) => {
+                    err.span_label(pat.span, "`fn` calls are not allowed in patterns");
+                    err.help("for more information, visit \
+                              https://doc.rust-lang.org/book/ch18-00-patterns.html");
+                }
+                _ => {
+                    err.span_label(pat.span, "not a tuple variant or struct");
+                }
+            }
+            err.emit();
+            on_error();
+        };
+
+        // Resolve the path and check the definition for errors.
+        let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
+        if res == Res::Err {
+            self.set_tainted_by_errors();
+            on_error();
+            return self.tcx.types.err;
+        }
+
+        // Type-check the path.
+        let (pat_ty, res) = self.instantiate_value_path(segments, opt_ty, res, pat.span,
+            pat.hir_id);
+        if !pat_ty.is_fn() {
+            report_unexpected_res(res);
+            return self.tcx.types.err;
+        }
+
+        let variant = match res {
+            Res::Err => {
+                self.set_tainted_by_errors();
+                on_error();
+                return tcx.types.err;
+            }
+            Res::Def(DefKind::AssocConst, _) | Res::Def(DefKind::Method, _) => {
+                report_unexpected_res(res);
+                return tcx.types.err;
+            }
+            Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => {
+                tcx.expect_variant_res(res)
+            }
+            _ => bug!("unexpected pattern resolution: {:?}", res)
+        };
+
+        // Replace constructor type with constructed type for tuple struct patterns.
+        let pat_ty = pat_ty.fn_sig(tcx).output();
+        let pat_ty = pat_ty.no_bound_vars().expect("expected fn type");
+
+        self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span);
+
+        // Type-check subpatterns.
+        if subpats.len() == variant.fields.len() ||
+                subpats.len() < variant.fields.len() && ddpos.is_some() {
+            let substs = match pat_ty.sty {
+                ty::Adt(_, substs) => substs,
+                _ => bug!("unexpected pattern type {:?}", pat_ty),
+            };
+            for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
+                let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
+                self.check_pat_walk(&subpat, field_ty, def_bm, match_arm_pat_span);
+
+                self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
+            }
+        } else {
+            let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
+            let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
+            struct_span_err!(tcx.sess, pat.span, E0023,
+                             "this pattern has {} field{}, but the corresponding {} has {} field{}",
+                             subpats.len(), subpats_ending, res.descr(),
+                             variant.fields.len(),  fields_ending)
+                .span_label(pat.span, format!("expected {} field{}, found {}",
+                                              variant.fields.len(), fields_ending, subpats.len()))
+                .emit();
+            on_error();
+            return tcx.types.err;
+        }
+        pat_ty
+    }
+
+    fn check_struct_pat_fields(
+        &self,
+        adt_ty: Ty<'tcx>,
+        pat_id: hir::HirId,
+        span: Span,
+        variant: &'tcx ty::VariantDef,
+        fields: &'tcx [hir::FieldPat],
+        etc: bool,
+        def_bm: ty::BindingMode,
+    ) -> bool {
+        let tcx = self.tcx;
+
+        let (substs, adt) = match adt_ty.sty {
+            ty::Adt(adt, substs) => (substs, adt),
+            _ => span_bug!(span, "struct pattern is not an ADT")
+        };
+        let kind_name = adt.variant_descr();
+
+        // Index the struct fields' types.
+        let field_map = variant.fields
+            .iter()
+            .enumerate()
+            .map(|(i, field)| (field.ident.modern(), (i, field)))
+            .collect::<FxHashMap<_, _>>();
+
+        // Keep track of which fields have already appeared in the pattern.
+        let mut used_fields = FxHashMap::default();
+        let mut no_field_errors = true;
+
+        let mut inexistent_fields = vec![];
+        // Typecheck each field.
+        for field in fields {
+            let span = field.span;
+            let ident = tcx.adjust_ident(field.ident, variant.def_id);
+            let field_ty = match used_fields.entry(ident) {
+                Occupied(occupied) => {
+                    struct_span_err!(tcx.sess, span, E0025,
+                                     "field `{}` bound multiple times \
+                                      in the pattern",
+                                     field.ident)
+                        .span_label(span,
+                                    format!("multiple uses of `{}` in pattern", field.ident))
+                        .span_label(*occupied.get(), format!("first use of `{}`", field.ident))
+                        .emit();
+                    no_field_errors = false;
+                    tcx.types.err
+                }
+                Vacant(vacant) => {
+                    vacant.insert(span);
+                    field_map.get(&ident)
+                        .map(|(i, f)| {
+                            self.write_field_index(field.hir_id, *i);
+                            self.tcx.check_stability(f.did, Some(pat_id), span);
+                            self.field_ty(span, f, substs)
+                        })
+                        .unwrap_or_else(|| {
+                            inexistent_fields.push(field.ident);
+                            no_field_errors = false;
+                            tcx.types.err
+                        })
+                }
+            };
+
+            self.check_pat_walk(&field.pat, field_ty, def_bm, None);
+        }
+        let mut unmentioned_fields = variant.fields
+                .iter()
+                .map(|field| field.ident.modern())
+                .filter(|ident| !used_fields.contains_key(&ident))
+                .collect::<Vec<_>>();
+        if inexistent_fields.len() > 0 && !variant.recovered {
+            let (field_names, t, plural) = if inexistent_fields.len() == 1 {
+                (format!("a field named `{}`", inexistent_fields[0]), "this", "")
+            } else {
+                (format!("fields named {}",
+                         inexistent_fields.iter()
+                            .map(|ident| format!("`{}`", ident))
+                            .collect::<Vec<String>>()
+                            .join(", ")), "these", "s")
+            };
+            let spans = inexistent_fields.iter().map(|ident| ident.span).collect::<Vec<_>>();
+            let mut err = struct_span_err!(tcx.sess,
+                                           spans,
+                                           E0026,
+                                           "{} `{}` does not have {}",
+                                           kind_name,
+                                           tcx.def_path_str(variant.def_id),
+                                           field_names);
+            if let Some(ident) = inexistent_fields.last() {
+                err.span_label(ident.span,
+                               format!("{} `{}` does not have {} field{}",
+                                       kind_name,
+                                       tcx.def_path_str(variant.def_id),
+                                       t,
+                                       plural));
+                if plural == "" {
+                    let input = unmentioned_fields.iter().map(|field| &field.name);
+                    let suggested_name =
+                        find_best_match_for_name(input, &ident.as_str(), None);
+                    if let Some(suggested_name) = suggested_name {
+                        err.span_suggestion(
+                            ident.span,
+                            "a field with a similar name exists",
+                            suggested_name.to_string(),
+                            Applicability::MaybeIncorrect,
+                        );
+
+                        // we don't want to throw `E0027` in case we have thrown `E0026` for them
+                        unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
+                    }
+                }
+            }
+            if tcx.sess.teach(&err.get_code().unwrap()) {
+                err.note(
+                    "This error indicates that a struct pattern attempted to \
+                     extract a non-existent field from a struct. Struct fields \
+                     are identified by the name used before the colon : so struct \
+                     patterns should resemble the declaration of the struct type \
+                     being matched.\n\n\
+                     If you are using shorthand field patterns but want to refer \
+                     to the struct field by a different name, you should rename \
+                     it explicitly."
+                );
+            }
+            err.emit();
+        }
+
+        // Require `..` if struct has non_exhaustive attribute.
+        if variant.is_field_list_non_exhaustive() && !adt.did.is_local() && !etc {
+            span_err!(tcx.sess, span, E0638,
+                      "`..` required with {} marked as non-exhaustive",
+                      kind_name);
+        }
+
+        // Report an error if incorrect number of the fields were specified.
+        if kind_name == "union" {
+            if fields.len() != 1 {
+                tcx.sess.span_err(span, "union patterns should have exactly one field");
+            }
+            if etc {
+                tcx.sess.span_err(span, "`..` cannot be used in union patterns");
+            }
+        } else if !etc {
+            if unmentioned_fields.len() > 0 {
+                let field_names = if unmentioned_fields.len() == 1 {
+                    format!("field `{}`", unmentioned_fields[0])
+                } else {
+                    format!("fields {}",
+                            unmentioned_fields.iter()
+                                .map(|name| format!("`{}`", name))
+                                .collect::<Vec<String>>()
+                                .join(", "))
+                };
+                let mut diag = struct_span_err!(tcx.sess, span, E0027,
+                                                "pattern does not mention {}",
+                                                field_names);
+                diag.span_label(span, format!("missing {}", field_names));
+                if variant.ctor_kind == CtorKind::Fn {
+                    diag.note("trying to match a tuple variant with a struct variant pattern");
+                }
+                if tcx.sess.teach(&diag.get_code().unwrap()) {
+                    diag.note(
+                        "This error indicates that a pattern for a struct fails to specify a \
+                         sub-pattern for every one of the struct's fields. Ensure that each field \
+                         from the struct's definition is mentioned in the pattern, or use `..` to \
+                         ignore unwanted fields."
+                    );
+                }
+                diag.emit();
+            }
+        }
+        no_field_errors
+    }
+}

From dbe6d59d6ef744ef17d5fb3e13a1e017baae9ce8 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Fri, 23 Aug 2019 15:05:58 +0200
Subject: [PATCH 175/943] typeck/pat.rs: move note out of
 `check_dereferenceable` as it angers VSCode.

---
 src/librustc_typeck/check/pat.rs | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index e2d0f485bdf01..d8c6438817413 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -19,6 +19,15 @@ use std::cmp;
 
 use super::report_unexpected_variant_res;
 
+const CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ: &str = "\
+This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a \
+pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, \
+this type has no compile-time size. Therefore, all accesses to trait types must be through \
+pointers. If you encounter this error you should try to avoid dereferencing the pointer.
+
+You can read more about trait objects in the Trait Objects section of the Reference: \
+https://doc.rust-lang.org/reference/types.html#trait-objects";
+
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// `discrim_span` argument having a `Span` indicates that this pattern is part of a match
     /// expression arm guard, and it points to the match discriminant to add context in type errors.
@@ -607,14 +616,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
                     err.span_label(span, format!("type `{}` cannot be dereferenced", type_str));
                     if self.tcx.sess.teach(&err.get_code().unwrap()) {
-                        err.note("\
-This error indicates that a pointer to a trait type cannot be implicitly dereferenced by a \
-pattern. Every trait defines a type, but because the size of trait implementors isn't fixed, \
-this type has no compile-time size. Therefore, all accesses to trait types must be through \
-pointers. If you encounter this error you should try to avoid dereferencing the pointer.
-
-You can read more about trait objects in the Trait Objects section of the Reference: \
-https://doc.rust-lang.org/reference/types.html#trait-objects");
+                        err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
                     }
                     err.emit();
                     return false

From d1580eef6565be5708b0668bd813e1b9abedbbb5 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Fri, 23 Aug 2019 15:31:38 +0200
Subject: [PATCH 176/943] typeck/pat.rs: extract `is_non_ref_pat`.

---
 src/librustc_typeck/check/pat.rs | 62 ++++++++++++++++++--------------
 1 file changed, 35 insertions(+), 27 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index d8c6438817413..25eefbaa24c6f 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -56,34 +56,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
 
-        let mut path_resolution = None;
-        let is_non_ref_pat = match pat.node {
-            PatKind::Struct(..) |
-            PatKind::TupleStruct(..) |
-            PatKind::Or(_) |
-            PatKind::Tuple(..) |
-            PatKind::Box(_) |
-            PatKind::Range(..) |
-            PatKind::Slice(..) => true,
-            PatKind::Lit(ref lt) => {
-                let ty = self.check_expr(lt);
-                match ty.sty {
-                    ty::Ref(..) => false,
-                    _ => true,
-                }
-            }
-            PatKind::Path(ref qpath) => {
-                let resolution = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
-                path_resolution = Some(resolution);
-                match resolution.0 {
-                    Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => false,
-                    _ => true,
-                }
-            }
-            PatKind::Wild |
-            PatKind::Binding(..) |
-            PatKind::Ref(..) => false,
+        let path_resolution = match &pat.node {
+            PatKind::Path(qpath) => Some(self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span)),
+            _ => None,
         };
+
+        let is_non_ref_pat = self.is_non_ref_pat(pat, path_resolution.map(|(res, ..)| res));
         if is_non_ref_pat {
             debug!("pattern is non reference pattern");
             let mut exp_ty = self.resolve_type_vars_with_obligations(&expected);
@@ -560,6 +538,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // subtyping.
     }
 
+    /// Is the pattern a "non reference pattern"?
+    /// When the pattern is a path pattern, `opt_path_res` must be `Some(res)`.
+    fn is_non_ref_pat(&self, pat: &'tcx hir::Pat, opt_path_res: Option<Res>) -> bool {
+        match pat.node {
+            PatKind::Struct(..) |
+            PatKind::TupleStruct(..) |
+            PatKind::Or(_) |
+            PatKind::Tuple(..) |
+            PatKind::Box(_) |
+            PatKind::Range(..) |
+            PatKind::Slice(..) => true,
+            PatKind::Lit(ref lt) => {
+                let ty = self.check_expr(lt);
+                match ty.sty {
+                    ty::Ref(..) => false,
+                    _ => true,
+                }
+            }
+            PatKind::Path(_) => {
+                match opt_path_res.unwrap() {
+                    Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => false,
+                    _ => true,
+                }
+            }
+            PatKind::Wild |
+            PatKind::Binding(..) |
+            PatKind::Ref(..) => false,
+        }
+    }
+
     fn borrow_pat_suggestion(
         &self,
         err: &mut DiagnosticBuilder<'_>,

From 8b4114b0d4975bde6df41dd9c8a41e44033da221 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Fri, 23 Aug 2019 15:51:18 +0200
Subject: [PATCH 177/943] typeck/pat.rs: extract `peel_off_references` and
 define `def_bm` algorithm more declaratively.

---
 src/librustc_typeck/check/pat.rs | 121 +++++++++++++++++--------------
 1 file changed, 67 insertions(+), 54 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 25eefbaa24c6f..625c57356af38 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -48,8 +48,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn check_pat_walk(
         &self,
         pat: &'tcx hir::Pat,
-        mut expected: Ty<'tcx>,
-        mut def_bm: ty::BindingMode,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
         discrim_span: Option<Span>,
     ) {
         let tcx = self.tcx;
@@ -62,53 +62,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         let is_non_ref_pat = self.is_non_ref_pat(pat, path_resolution.map(|(res, ..)| res));
-        if is_non_ref_pat {
+        let (expected, def_bm) = if is_non_ref_pat {
             debug!("pattern is non reference pattern");
-            let mut exp_ty = self.resolve_type_vars_with_obligations(&expected);
-
-            // Peel off as many `&` or `&mut` from the discriminant as possible. For example,
-            // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
-            // the `Some(5)` which is not of type Ref.
-            //
-            // For each ampersand peeled off, update the binding mode and push the original
-            // type into the adjustments vector.
-            //
-            // See the examples in `ui/match-defbm*.rs`.
-            let mut pat_adjustments = vec![];
-            while let ty::Ref(_, inner_ty, inner_mutability) = exp_ty.sty {
-                debug!("inspecting {:?}", exp_ty);
-
-                debug!("current discriminant is Ref, inserting implicit deref");
-                // Preserve the reference type. We'll need it later during HAIR lowering.
-                pat_adjustments.push(exp_ty);
-
-                exp_ty = inner_ty;
-                def_bm = match def_bm {
-                    // If default binding mode is by value, make it `ref` or `ref mut`
-                    // (depending on whether we observe `&` or `&mut`).
-                    ty::BindByValue(_) =>
-                        ty::BindByReference(inner_mutability),
-
-                    // Once a `ref`, always a `ref`. This is because a `& &mut` can't mutate
-                    // the underlying value.
-                    ty::BindByReference(hir::Mutability::MutImmutable) =>
-                        ty::BindByReference(hir::Mutability::MutImmutable),
-
-                    // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref`
-                    // (on `&`).
-                    ty::BindByReference(hir::Mutability::MutMutable) =>
-                        ty::BindByReference(inner_mutability),
-                };
-            }
-            expected = exp_ty;
-
-            if pat_adjustments.len() > 0 {
-                debug!("default binding mode is now {:?}", def_bm);
-                self.inh.tables.borrow_mut()
-                    .pat_adjustments_mut()
-                    .insert(pat.hir_id, pat_adjustments);
-            }
-        } else if let PatKind::Ref(..) = pat.node {
+            self.peel_off_references(pat, expected, def_bm)
+        } else {
             // When you encounter a `&pat` pattern, reset to "by
             // value". This is so that `x` and `y` here are by value,
             // as they appear to be:
@@ -120,12 +77,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // ```
             //
             // See issue #46688.
-            def_bm = ty::BindByValue(hir::MutImmutable);
-        }
-
-        // Lose mutability now that we know binding mode and discriminant type.
-        let def_bm = def_bm;
-        let expected = expected;
+            let def_bm = match pat.node {
+                PatKind::Ref(..) => ty::BindByValue(hir::MutImmutable),
+                _ => def_bm,
+            };
+            (expected, def_bm)
+        };
 
         let ty = match pat.node {
             PatKind::Wild => {
@@ -568,6 +525,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    /// Peel off as many immediately nested `& mut?` from the expected type as possible
+    /// and return the new expected type and binding default binding mode.
+    /// The adjustments vector, if non-empty is stored in a table.
+    fn peel_off_references(
+        &self,
+        pat: &'tcx hir::Pat,
+        expected: Ty<'tcx>,
+        mut def_bm: ty::BindingMode,
+    ) -> (Ty<'tcx>, ty::BindingMode) {
+        let mut expected = self.resolve_type_vars_with_obligations(&expected);
+
+        // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
+        // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches
+        // the `Some(5)` which is not of type Ref.
+        //
+        // For each ampersand peeled off, update the binding mode and push the original
+        // type into the adjustments vector.
+        //
+        // See the examples in `ui/match-defbm*.rs`.
+        let mut pat_adjustments = vec![];
+        while let ty::Ref(_, inner_ty, inner_mutability) = expected.sty {
+            debug!("inspecting {:?}", expected);
+
+            debug!("current discriminant is Ref, inserting implicit deref");
+            // Preserve the reference type. We'll need it later during HAIR lowering.
+            pat_adjustments.push(expected);
+
+            expected = inner_ty;
+            def_bm = match def_bm {
+                // If default binding mode is by value, make it `ref` or `ref mut`
+                // (depending on whether we observe `&` or `&mut`).
+                ty::BindByValue(_) =>
+                    ty::BindByReference(inner_mutability),
+
+                // Once a `ref`, always a `ref`. This is because a `& &mut` can't mutate
+                // the underlying value.
+                ty::BindByReference(hir::Mutability::MutImmutable) =>
+                    ty::BindByReference(hir::Mutability::MutImmutable),
+
+                // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref`
+                // (on `&`).
+                ty::BindByReference(hir::Mutability::MutMutable) =>
+                    ty::BindByReference(inner_mutability),
+            };
+        }
+
+        if pat_adjustments.len() > 0 {
+            debug!("default binding mode is now {:?}", def_bm);
+            self.inh.tables.borrow_mut()
+                .pat_adjustments_mut()
+                .insert(pat.hir_id, pat_adjustments);
+        }
+
+        (expected, def_bm)
+    }
+
     fn borrow_pat_suggestion(
         &self,
         err: &mut DiagnosticBuilder<'_>,

From 3ec5d07b1d30124e85cd804a74f1b03198cce1f5 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Fri, 23 Aug 2019 15:55:35 +0200
Subject: [PATCH 178/943] typeck/pat.rs: simplify `peel_off_references`.

---
 src/librustc_typeck/check/pat.rs | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 625c57356af38..ce033b85fce05 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -553,22 +553,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             pat_adjustments.push(expected);
 
             expected = inner_ty;
-            def_bm = match def_bm {
+            def_bm = ty::BindByReference(match def_bm {
                 // If default binding mode is by value, make it `ref` or `ref mut`
                 // (depending on whether we observe `&` or `&mut`).
-                ty::BindByValue(_) =>
-                    ty::BindByReference(inner_mutability),
-
-                // Once a `ref`, always a `ref`. This is because a `& &mut` can't mutate
-                // the underlying value.
-                ty::BindByReference(hir::Mutability::MutImmutable) =>
-                    ty::BindByReference(hir::Mutability::MutImmutable),
-
-                // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref`
-                // (on `&`).
-                ty::BindByReference(hir::Mutability::MutMutable) =>
-                    ty::BindByReference(inner_mutability),
-            };
+                ty::BindByValue(_) |
+                // When `ref mut`, stay a `ref mut` (on `&mut`) or downgrade to `ref` (on `&`).
+                ty::BindByReference(hir::Mutability::MutMutable) => inner_mutability,
+                // Once a `ref`, always a `ref`.
+                // This is because a `& &mut` cannot mutate the underlying value.
+                ty::BindByReference(m @ hir::Mutability::MutImmutable) => m,
+            });
         }
 
         if pat_adjustments.len() > 0 {

From 23dc37d21d392b7f796a495f8616e32ca558d578 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Fri, 23 Aug 2019 16:06:33 +0200
Subject: [PATCH 179/943] typeck/pat.rs: extract `calc_default_binding_mode`.

---
 src/librustc_typeck/check/pat.rs | 57 +++++++++++++++++++-------------
 1 file changed, 34 insertions(+), 23 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index ce033b85fce05..a9e6cfb41a469 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -60,29 +60,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             PatKind::Path(qpath) => Some(self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span)),
             _ => None,
         };
-
-        let is_non_ref_pat = self.is_non_ref_pat(pat, path_resolution.map(|(res, ..)| res));
-        let (expected, def_bm) = if is_non_ref_pat {
-            debug!("pattern is non reference pattern");
-            self.peel_off_references(pat, expected, def_bm)
-        } else {
-            // When you encounter a `&pat` pattern, reset to "by
-            // value". This is so that `x` and `y` here are by value,
-            // as they appear to be:
-            //
-            // ```
-            // match &(&22, &44) {
-            //   (&x, &y) => ...
-            // }
-            // ```
-            //
-            // See issue #46688.
-            let def_bm = match pat.node {
-                PatKind::Ref(..) => ty::BindByValue(hir::MutImmutable),
-                _ => def_bm,
-            };
-            (expected, def_bm)
-        };
+        let is_nrp = self.is_non_ref_pat(pat, path_resolution.map(|(res, ..)| res));
+        let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, is_nrp);
 
         let ty = match pat.node {
             PatKind::Wild => {
@@ -495,6 +474,38 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // subtyping.
     }
 
+    /// Compute the new expected type and default binding mode from the old ones
+    /// as well as the pattern form we are currently checking.
+    fn calc_default_binding_mode(
+        &self,
+        pat: &'tcx hir::Pat,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        is_non_ref_pat: bool,
+    ) -> (Ty<'tcx>, ty::BindingMode) {
+        if is_non_ref_pat {
+            debug!("pattern is non reference pattern");
+            self.peel_off_references(pat, expected, def_bm)
+        } else {
+            // When you encounter a `&pat` pattern, reset to "by
+            // value". This is so that `x` and `y` here are by value,
+            // as they appear to be:
+            //
+            // ```
+            // match &(&22, &44) {
+            //   (&x, &y) => ...
+            // }
+            // ```
+            //
+            // See issue #46688.
+            let def_bm = match pat.node {
+                PatKind::Ref(..) => ty::BindByValue(hir::MutImmutable),
+                _ => def_bm,
+            };
+            (expected, def_bm)
+        }
+    }
+
     /// Is the pattern a "non reference pattern"?
     /// When the pattern is a path pattern, `opt_path_res` must be `Some(res)`.
     fn is_non_ref_pat(&self, pat: &'tcx hir::Pat, opt_path_res: Option<Res>) -> bool {

From d891e70b6421e2ef48a64badf3e432059a5c4b96 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 03:52:09 +0200
Subject: [PATCH 180/943] typeck/pat.rs: extract `check_pat_lit`.

---
 src/librustc_typeck/check/pat.rs | 98 ++++++++++++++++++--------------
 1 file changed, 55 insertions(+), 43 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index a9e6cfb41a469..95013f60cd6de 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -68,49 +68,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 expected
             }
             PatKind::Lit(ref lt) => {
-                // We've already computed the type above (when checking for a non-ref pat), so
-                // avoid computing it again.
-                let ty = self.node_ty(lt.hir_id);
-
-                // Byte string patterns behave the same way as array patterns
-                // They can denote both statically and dynamically-sized byte arrays.
-                let mut pat_ty = ty;
-                if let hir::ExprKind::Lit(ref lt) = lt.node {
-                    if let ast::LitKind::ByteStr(_) = lt.node {
-                        let expected_ty = self.structurally_resolved_type(pat.span, expected);
-                        if let ty::Ref(_, r_ty, _) = expected_ty.sty {
-                            if let ty::Slice(_) = r_ty.sty {
-                                pat_ty = tcx.mk_imm_ref(tcx.lifetimes.re_static,
-                                                        tcx.mk_slice(tcx.types.u8))
-                            }
-                        }
-                    }
-                }
-
-                // Somewhat surprising: in this case, the subtyping
-                // relation goes the opposite way as the other
-                // cases. Actually what we really want is not a subtyping
-                // relation at all but rather that there exists a LUB (so
-                // that they can be compared). However, in practice,
-                // constants are always scalars or strings.  For scalars
-                // subtyping is irrelevant, and for strings `ty` is
-                // type is `&'static str`, so if we say that
-                //
-                //     &'static str <: expected
-                //
-                // then that's equivalent to there existing a LUB.
-                if let Some(mut err) = self.demand_suptype_diag(pat.span, expected, pat_ty) {
-                    err.emit_unless(discrim_span
-                        .filter(|&s| {
-                            // In the case of `if`- and `while`-expressions we've already checked
-                            // that `scrutinee: bool`. We know that the pattern is `true`,
-                            // so an error here would be a duplicate and from the wrong POV.
-                            s.is_desugaring(DesugaringKind::CondTemporary)
-                        })
-                        .is_some());
-                }
-
-                pat_ty
+                self.check_pat_lit(pat.span, lt, expected, discrim_span)
             }
             PatKind::Range(ref begin, ref end, _) => {
                 let lhs_ty = self.check_expr(begin);
@@ -586,6 +544,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         (expected, def_bm)
     }
 
+    fn check_pat_lit(
+        &self,
+        span: Span,
+        lt: &hir::Expr,
+        expected: Ty<'tcx>,
+        discrim_span: Option<Span>,
+    ) -> Ty<'tcx> {
+        // We've already computed the type above (when checking for a non-ref pat),
+        // so avoid computing it again.
+        let ty = self.node_ty(lt.hir_id);
+
+        // Byte string patterns behave the same way as array patterns
+        // They can denote both statically and dynamically-sized byte arrays.
+        let mut pat_ty = ty;
+        if let hir::ExprKind::Lit(ref lt) = lt.node {
+            if let ast::LitKind::ByteStr(_) = lt.node {
+                let expected_ty = self.structurally_resolved_type(span, expected);
+                if let ty::Ref(_, r_ty, _) = expected_ty.sty {
+                    if let ty::Slice(_) = r_ty.sty {
+                        let tcx = self.tcx;
+                        pat_ty = tcx.mk_imm_ref(
+                            tcx.lifetimes.re_static,
+                            tcx.mk_slice(tcx.types.u8),
+                        );
+                    }
+                }
+            }
+        }
+
+        // Somewhat surprising: in this case, the subtyping relation goes the
+        // opposite way as the other cases. Actually what we really want is not
+        // a subtyping relation at all but rather that there exists a LUB
+        // (so that they can be compared). However, in practice, constants are
+        // always scalars or strings. For scalars subtyping is irrelevant,
+        // and for strings `ty` is type is `&'static str`, so if we say that
+        //
+        //     &'static str <: expected
+        //
+        // then that's equivalent to there existing a LUB.
+        if let Some(mut err) = self.demand_suptype_diag(span, expected, pat_ty) {
+            err.emit_unless(discrim_span
+                .filter(|&s| {
+                    // In the case of `if`- and `while`-expressions we've already checked
+                    // that `scrutinee: bool`. We know that the pattern is `true`,
+                    // so an error here would be a duplicate and from the wrong POV.
+                    s.is_desugaring(DesugaringKind::CondTemporary)
+                })
+                .is_some());
+        }
+
+        pat_ty
+    }
+
+
     fn borrow_pat_suggestion(
         &self,
         err: &mut DiagnosticBuilder<'_>,

From d4afae943f642be2909c649997f663b384115237 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 03:59:15 +0200
Subject: [PATCH 181/943] typeck/pat.rs: extract `check_pat_range`.

---
 src/librustc_typeck/check/pat.rs | 113 +++++++++++++++++--------------
 1 file changed, 63 insertions(+), 50 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 95013f60cd6de..9693ab57bc7de 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -71,57 +71,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_pat_lit(pat.span, lt, expected, discrim_span)
             }
             PatKind::Range(ref begin, ref end, _) => {
-                let lhs_ty = self.check_expr(begin);
-                let rhs_ty = self.check_expr(end);
-
-                // Check that both end-points are of numeric or char type.
-                let numeric_or_char = |ty: Ty<'_>| {
-                    ty.is_numeric()
-                    || ty.is_char()
-                    || ty.references_error()
-                };
-                let lhs_compat = numeric_or_char(lhs_ty);
-                let rhs_compat = numeric_or_char(rhs_ty);
-
-                if !lhs_compat || !rhs_compat {
-                    let span = if !lhs_compat && !rhs_compat {
-                        pat.span
-                    } else if !lhs_compat {
-                        begin.span
-                    } else {
-                        end.span
-                    };
-
-                    let mut err = struct_span_err!(
-                        tcx.sess,
-                        span,
-                        E0029,
-                        "only char and numeric types are allowed in range patterns"
-                    );
-                    err.span_label(span, "ranges require char or numeric types");
-                    err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
-                    err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
-                    if tcx.sess.teach(&err.get_code().unwrap()) {
-                        err.note(
-                            "In a match expression, only numbers and characters can be matched \
-                             against a range. This is because the compiler checks that the range \
-                             is non-empty at compile-time, and is unable to evaluate arbitrary \
-                             comparison functions. If you want to capture values of an orderable \
-                             type between two end-points, you can use a guard."
-                         );
-                    }
-                    err.emit();
-                    return;
+                match self.check_pat_range(pat.span, begin, end, expected, discrim_span) {
+                    None => return,
+                    Some(ty) => ty,
                 }
-
-                // Now that we know the types can be unified we find the unified type and use
-                // it to type the entire expression.
-                let common_type = self.resolve_vars_if_possible(&lhs_ty);
-
-                // Subtyping doesn't matter here, as the value is some kind of scalar.
-                self.demand_eqtype_pat(pat.span, expected, lhs_ty, discrim_span);
-                self.demand_eqtype_pat(pat.span, expected, rhs_ty, discrim_span);
-                common_type
             }
             PatKind::Binding(ba, var_id, _, ref sub) => {
                 let bm = if ba == hir::BindingAnnotation::Unannotated {
@@ -597,6 +550,66 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         pat_ty
     }
 
+    fn check_pat_range(
+        &self,
+        span: Span,
+        begin: &'tcx hir::Expr,
+        end: &'tcx hir::Expr,
+        expected: Ty<'tcx>,
+        discrim_span: Option<Span>,
+    ) -> Option<Ty<'tcx>> {
+        let lhs_ty = self.check_expr(begin);
+        let rhs_ty = self.check_expr(end);
+
+        // Check that both end-points are of numeric or char type.
+        let numeric_or_char = |ty: Ty<'_>| {
+            ty.is_numeric()
+            || ty.is_char()
+            || ty.references_error()
+        };
+        let lhs_compat = numeric_or_char(lhs_ty);
+        let rhs_compat = numeric_or_char(rhs_ty);
+
+        if !lhs_compat || !rhs_compat {
+            let span = if !lhs_compat && !rhs_compat {
+                span
+            } else if !lhs_compat {
+                begin.span
+            } else {
+                end.span
+            };
+
+            let mut err = struct_span_err!(
+                self.tcx.sess,
+                span,
+                E0029,
+                "only char and numeric types are allowed in range patterns"
+            );
+            err.span_label(span, "ranges require char or numeric types");
+            err.note(&format!("start type: {}", self.ty_to_string(lhs_ty)));
+            err.note(&format!("end type: {}", self.ty_to_string(rhs_ty)));
+            if self.tcx.sess.teach(&err.get_code().unwrap()) {
+                err.note(
+                    "In a match expression, only numbers and characters can be matched \
+                        against a range. This is because the compiler checks that the range \
+                        is non-empty at compile-time, and is unable to evaluate arbitrary \
+                        comparison functions. If you want to capture values of an orderable \
+                        type between two end-points, you can use a guard."
+                    );
+            }
+            err.emit();
+            return None;
+        }
+
+        // Now that we know the types can be unified we find the unified type and use
+        // it to type the entire expression.
+        let common_type = self.resolve_vars_if_possible(&lhs_ty);
+
+        // Subtyping doesn't matter here, as the value is some kind of scalar.
+        self.demand_eqtype_pat(span, expected, lhs_ty, discrim_span);
+        self.demand_eqtype_pat(span, expected, rhs_ty, discrim_span);
+        Some(common_type)
+    }
 
     fn borrow_pat_suggestion(
         &self,

From c16248d3a1893b985d7957bfed16ed119fdbfd6f Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 04:19:16 +0200
Subject: [PATCH 182/943] typeck/pat.rs: extract `check_pat_ident`.

---
 src/librustc_typeck/check/pat.rs | 110 ++++++++++++++++++-------------
 1 file changed, 63 insertions(+), 47 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 9693ab57bc7de..fda5d3a2ecd4a 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -77,53 +77,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
             PatKind::Binding(ba, var_id, _, ref sub) => {
-                let bm = if ba == hir::BindingAnnotation::Unannotated {
-                    def_bm
-                } else {
-                    ty::BindingMode::convert(ba)
-                };
-                self.inh
-                    .tables
-                    .borrow_mut()
-                    .pat_binding_modes_mut()
-                    .insert(pat.hir_id, bm);
-                debug!("check_pat_walk: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
-                let local_ty = self.local_ty(pat.span, pat.hir_id).decl_ty;
-                match bm {
-                    ty::BindByReference(mutbl) => {
-                        // If the binding is like
-                        //     ref x | ref const x | ref mut x
-                        // then `x` is assigned a value of type `&M T` where M is the mutability
-                        // and T is the expected type.
-                        let region_var = self.next_region_var(infer::PatternRegion(pat.span));
-                        let mt = ty::TypeAndMut { ty: expected, mutbl: mutbl };
-                        let region_ty = tcx.mk_ref(region_var, mt);
-
-                        // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
-                        // required. However, we use equality, which is stronger. See (*) for
-                        // an explanation.
-                        self.demand_eqtype_pat(pat.span, region_ty, local_ty, discrim_span);
-                    }
-                    // Otherwise, the type of x is the expected type `T`.
-                    ty::BindByValue(_) => {
-                        // As above, `T <: typeof(x)` is required, but we
-                        // use equality, see (*) below.
-                        self.demand_eqtype_pat(pat.span, expected, local_ty, discrim_span);
-                    }
-                }
-
-                // If there are multiple arms, make sure they all agree on
-                // what the type of the binding `x` ought to be.
-                if var_id != pat.hir_id {
-                    let vt = self.local_ty(pat.span, var_id).decl_ty;
-                    self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span);
-                }
-
-                if let Some(ref p) = *sub {
-                    self.check_pat_walk(&p, expected, def_bm, discrim_span);
-                }
-
-                local_ty
+                let sub = sub.as_deref();
+                self.check_pat_ident(pat, ba, var_id, sub, expected, def_bm, discrim_span)
             }
             PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
                 self.check_pat_tuple_struct(
@@ -611,6 +566,67 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         Some(common_type)
     }
 
+    fn check_pat_ident(
+        &self,
+        pat: &hir::Pat,
+        ba: hir::BindingAnnotation,
+        var_id: hir::HirId,
+        sub: Option<&'tcx hir::Pat>,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        discrim_span: Option<Span>,
+    ) -> Ty<'tcx> {
+        // Determine the binding mode...
+        let bm = match ba {
+            hir::BindingAnnotation::Unannotated => def_bm,
+            _ => ty::BindingMode::convert(ba),
+        };
+        // ...and store it in a side table:
+        self.inh
+            .tables
+            .borrow_mut()
+            .pat_binding_modes_mut()
+            .insert(pat.hir_id, bm);
+
+        debug!("check_pat_ident: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
+
+        let local_ty = self.local_ty(pat.span, pat.hir_id).decl_ty;
+        let eq_ty = match bm {
+            ty::BindByReference(mutbl) => {
+                // If the binding is like `ref x | ref const x | ref mut x`
+                // then `x` is assigned a value of type `&M T` where M is the
+                // mutability and T is the expected type.
+                let region_var = self.next_region_var(infer::PatternRegion(pat.span));
+                let mt = ty::TypeAndMut { ty: expected, mutbl };
+                let region_ty = self.tcx.mk_ref(region_var, mt);
+
+                // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)`
+                // is required. However, we use equality, which is stronger.
+                // See (*) for an explanation.
+                region_ty
+            }
+            // Otherwise, the type of x is the expected type `T`.
+            ty::BindByValue(_) => {
+                // As above, `T <: typeof(x)` is required, but we use equality, see (*) below.
+                expected
+            }
+        };
+        self.demand_eqtype_pat(pat.span, eq_ty, local_ty, discrim_span);
+
+        // If there are multiple arms, make sure they all agree on
+        // what the type of the binding `x` ought to be.
+        if var_id != pat.hir_id {
+            let vt = self.local_ty(pat.span, var_id).decl_ty;
+            self.demand_eqtype_pat(pat.span, vt, local_ty, discrim_span);
+        }
+
+        if let Some(p) = sub {
+            self.check_pat_walk(&p, expected, def_bm, discrim_span);
+        }
+
+        local_ty
+    }
+
     fn borrow_pat_suggestion(
         &self,
         err: &mut DiagnosticBuilder<'_>,

From 3a51caa6485b7db6ce323cba47dfbe7c44026af5 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 04:30:03 +0200
Subject: [PATCH 183/943] typeck/pat.rs: extract `check_pat_tuple`.

---
 src/librustc_typeck/check/pat.rs | 103 +++++++++++++++++--------------
 1 file changed, 58 insertions(+), 45 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index fda5d3a2ecd4a..be128ea358e7e 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -105,48 +105,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 expected_ty
             }
             PatKind::Tuple(ref elements, ddpos) => {
-                let mut expected_len = elements.len();
-                if ddpos.is_some() {
-                    // Require known type only when `..` is present.
-                    if let ty::Tuple(ref tys) =
-                            self.structurally_resolved_type(pat.span, expected).sty {
-                        expected_len = tys.len();
-                    }
-                }
-                let max_len = cmp::max(expected_len, elements.len());
-
-                let element_tys_iter = (0..max_len).map(|_| {
-                    Kind::from(self.next_ty_var(
-                        // FIXME: `MiscVariable` for now -- obtaining the span and name information
-                        // from all tuple elements isn't trivial.
-                        TypeVariableOrigin {
-                            kind: TypeVariableOriginKind::TypeInference,
-                            span: pat.span,
-                        },
-                    ))
-                });
-                let element_tys = tcx.mk_substs(element_tys_iter);
-                let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
-                if let Some(mut err) = self.demand_eqtype_diag(pat.span, expected, pat_ty) {
-                    err.emit();
-                    // Walk subpatterns with an expected type of `err` in this case to silence
-                    // further errors being emitted when using the bindings. #50333
-                    let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
-                    for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
-                        self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
-                    }
-                    tcx.mk_tup(element_tys_iter)
-                } else {
-                    for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
-                        self.check_pat_walk(
-                            elem,
-                            &element_tys[i].expect_ty(),
-                            def_bm,
-                            discrim_span,
-                        );
-                    }
-                    pat_ty
-                }
+                self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, discrim_span)
             }
             PatKind::Box(ref inner) => {
                 let inner_ty = self.next_ty_var(TypeVariableOrigin {
@@ -807,7 +766,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             pat.hir_id);
         if !pat_ty.is_fn() {
             report_unexpected_res(res);
-            return self.tcx.types.err;
+            return tcx.types.err;
         }
 
         let variant = match res {
@@ -833,8 +792,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         self.demand_eqtype_pat(pat.span, expected, pat_ty, match_arm_pat_span);
 
         // Type-check subpatterns.
-        if subpats.len() == variant.fields.len() ||
-                subpats.len() < variant.fields.len() && ddpos.is_some() {
+        if subpats.len() == variant.fields.len()
+            || subpats.len() < variant.fields.len() && ddpos.is_some()
+        {
             let substs = match pat_ty.sty {
                 ty::Adt(_, substs) => substs,
                 _ => bug!("unexpected pattern type {:?}", pat_ty),
@@ -861,6 +821,59 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         pat_ty
     }
 
+    fn check_pat_tuple(
+        &self,
+        span: Span,
+        elements: &'tcx [P<hir::Pat>],
+        ddpos: Option<usize>,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        discrim_span: Option<Span>,
+    ) -> Ty<'tcx> {
+        let tcx = self.tcx;
+        let mut expected_len = elements.len();
+        if ddpos.is_some() {
+            // Require known type only when `..` is present.
+            if let ty::Tuple(ref tys) = self.structurally_resolved_type(span, expected).sty {
+                expected_len = tys.len();
+            }
+        }
+        let max_len = cmp::max(expected_len, elements.len());
+
+        let element_tys_iter = (0..max_len).map(|_| {
+            Kind::from(self.next_ty_var(
+                // FIXME: `MiscVariable` for now -- obtaining the span and name information
+                // from all tuple elements isn't trivial.
+                TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::TypeInference,
+                    span,
+                },
+            ))
+        });
+        let element_tys = tcx.mk_substs(element_tys_iter);
+        let pat_ty = tcx.mk_ty(ty::Tuple(element_tys));
+        if let Some(mut err) = self.demand_eqtype_diag(span, expected, pat_ty) {
+            err.emit();
+            // Walk subpatterns with an expected type of `err` in this case to silence
+            // further errors being emitted when using the bindings. #50333
+            let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
+            for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
+                self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
+            }
+            tcx.mk_tup(element_tys_iter)
+        } else {
+            for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
+                self.check_pat_walk(
+                    elem,
+                    &element_tys[i].expect_ty(),
+                    def_bm,
+                    discrim_span,
+                );
+            }
+            pat_ty
+        }
+    }
+
     fn check_struct_pat_fields(
         &self,
         adt_ty: Ty<'tcx>,

From 3de221a862b064430bc8c5727e9e1346ad85c27e Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 04:39:23 +0200
Subject: [PATCH 184/943] typeck/pat.rs: extract `check_pat_box`.

---
 src/librustc_typeck/check/pat.rs | 46 ++++++++++++++++++++------------
 1 file changed, 29 insertions(+), 17 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index be128ea358e7e..f740dc73db540 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -108,23 +108,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, discrim_span)
             }
             PatKind::Box(ref inner) => {
-                let inner_ty = self.next_ty_var(TypeVariableOrigin {
-                    kind: TypeVariableOriginKind::TypeInference,
-                    span: inner.span,
-                });
-                let uniq_ty = tcx.mk_box(inner_ty);
-
-                if self.check_dereferencable(pat.span, expected, &inner) {
-                    // Here, `demand::subtype` is good enough, but I don't
-                    // think any errors can be introduced by using
-                    // `demand::eqtype`.
-                    self.demand_eqtype_pat(pat.span, expected, uniq_ty, discrim_span);
-                    self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
-                    uniq_ty
-                } else {
-                    self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
-                    tcx.types.err
-                }
+                self.check_pat_box(pat.span, inner, expected, def_bm, discrim_span)
             }
             PatKind::Ref(ref inner, mutbl) => {
                 let expected = self.shallow_resolve(expected);
@@ -1047,4 +1031,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
         no_field_errors
     }
+
+    fn check_pat_box(
+        &self,
+        span: Span,
+        inner: &'tcx hir::Pat,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        discrim_span: Option<Span>,
+    ) -> Ty<'tcx> {
+        let tcx = self.tcx;
+        let inner_ty = self.next_ty_var(TypeVariableOrigin {
+            kind: TypeVariableOriginKind::TypeInference,
+            span: inner.span,
+        });
+        let uniq_ty = tcx.mk_box(inner_ty);
+
+        if self.check_dereferencable(span, expected, &inner) {
+            // Here, `demand::subtype` is good enough, but I don't
+            // think any errors can be introduced by using
+            // `demand::eqtype`.
+            self.demand_eqtype_pat(span, expected, uniq_ty, discrim_span);
+            self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
+            uniq_ty
+        } else {
+            self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
+            tcx.types.err
+        }
+    }
 }

From b4a4e718deee509408407a39b561461ece58355c Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 04:45:59 +0200
Subject: [PATCH 185/943] typeck/pat.rs: extract `check_pat_ref`.

---
 src/librustc_typeck/check/pat.rs | 99 ++++++++++++++++++--------------
 1 file changed, 55 insertions(+), 44 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index f740dc73db540..55a9360b83f19 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -111,50 +111,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_pat_box(pat.span, inner, expected, def_bm, discrim_span)
             }
             PatKind::Ref(ref inner, mutbl) => {
-                let expected = self.shallow_resolve(expected);
-                if self.check_dereferencable(pat.span, expected, &inner) {
-                    // `demand::subtype` would be good enough, but using
-                    // `eqtype` turns out to be equally general. See (*)
-                    // below for details.
-
-                    // Take region, inner-type from expected type if we
-                    // can, to avoid creating needless variables.  This
-                    // also helps with the bad interactions of the given
-                    // hack detailed in (*) below.
-                    debug!("check_pat_walk: expected={:?}", expected);
-                    let (rptr_ty, inner_ty) = match expected.sty {
-                        ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
-                            (expected, r_ty)
-                        }
-                        _ => {
-                            let inner_ty = self.next_ty_var(
-                                TypeVariableOrigin {
-                                    kind: TypeVariableOriginKind::TypeInference,
-                                    span: inner.span,
-                                }
-                            );
-                            let mt = ty::TypeAndMut { ty: inner_ty, mutbl: mutbl };
-                            let region = self.next_region_var(infer::PatternRegion(pat.span));
-                            let rptr_ty = tcx.mk_ref(region, mt);
-                            debug!("check_pat_walk: demanding {:?} = {:?}", expected, rptr_ty);
-                            let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
-
-                            // Look for a case like `fn foo(&foo: u32)` and suggest
-                            // `fn foo(foo: &u32)`
-                            if let Some(mut err) = err {
-                                self.borrow_pat_suggestion(&mut err, &pat, &inner, &expected);
-                                err.emit();
-                            }
-                            (rptr_ty, inner_ty)
-                        }
-                    };
-
-                    self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
-                    rptr_ty
-                } else {
-                    self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
-                    tcx.types.err
-                }
+                self.check_pat_ref(pat, inner, mutbl, expected, def_bm, discrim_span)
             }
             PatKind::Slice(ref before, ref slice, ref after) => {
                 let expected_ty = self.structurally_resolved_type(pat.span, expected);
@@ -1059,4 +1016,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             tcx.types.err
         }
     }
+
+    fn check_pat_ref(
+        &self,
+        pat: &hir::Pat,
+        inner: &'tcx hir::Pat,
+        mutbl: hir::Mutability,
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        discrim_span: Option<Span>,
+    ) -> Ty<'tcx> {
+        let tcx = self.tcx;
+        let expected = self.shallow_resolve(expected);
+        if self.check_dereferencable(pat.span, expected, &inner) {
+            // `demand::subtype` would be good enough, but using `eqtype` turns
+            // out to be equally general. See (*) below for details.
+
+            // Take region, inner-type from expected type if we can,
+            // to avoid creating needless variables. This also helps with
+            // the bad  interactions of the given hack detailed in (*) below.
+            debug!("check_pat_ref: expected={:?}", expected);
+            let (rptr_ty, inner_ty) = match expected.sty {
+                ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
+                    (expected, r_ty)
+                }
+                _ => {
+                    let inner_ty = self.next_ty_var(
+                        TypeVariableOrigin {
+                            kind: TypeVariableOriginKind::TypeInference,
+                            span: inner.span,
+                        }
+                    );
+                    let mt = ty::TypeAndMut { ty: inner_ty, mutbl };
+                    let region = self.next_region_var(infer::PatternRegion(pat.span));
+                    let rptr_ty = tcx.mk_ref(region, mt);
+                    debug!("check_pat_ref: demanding {:?} = {:?}", expected, rptr_ty);
+                    let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
+
+                    // Look for a case like `fn foo(&foo: u32)` and suggest
+                    // `fn foo(foo: &u32)`
+                    if let Some(mut err) = err {
+                        self.borrow_pat_suggestion(&mut err, &pat, &inner, &expected);
+                        err.emit();
+                    }
+                    (rptr_ty, inner_ty)
+                }
+            };
+
+            self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
+            rptr_ty
+        } else {
+            self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
+            tcx.types.err
+        }
+    }
 }

From f09f1a71396c8e416f67ac16ca559dc1d62f05df Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 05:08:49 +0200
Subject: [PATCH 186/943] typeck/pat.rs: extract `check_pat_slice`.

---
 src/librustc_typeck/check/pat.rs | 159 +++++++++++++++++--------------
 1 file changed, 86 insertions(+), 73 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 55a9360b83f19..7b78474e79979 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -52,8 +52,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         def_bm: ty::BindingMode,
         discrim_span: Option<Span>,
     ) {
-        let tcx = self.tcx;
-
         debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
 
         let path_resolution = match &pat.node {
@@ -114,77 +112,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.check_pat_ref(pat, inner, mutbl, expected, def_bm, discrim_span)
             }
             PatKind::Slice(ref before, ref slice, ref after) => {
-                let expected_ty = self.structurally_resolved_type(pat.span, expected);
-                let (inner_ty, slice_ty) = match expected_ty.sty {
-                    ty::Array(inner_ty, size) => {
-                        if let Some(size) = size.try_eval_usize(tcx, self.param_env) {
-                            let min_len = before.len() as u64 + after.len() as u64;
-                            if slice.is_none() {
-                                if min_len != size {
-                                    struct_span_err!(
-                                        tcx.sess, pat.span, E0527,
-                                        "pattern requires {} elements but array has {}",
-                                        min_len, size)
-                                        .span_label(pat.span, format!("expected {} elements", size))
-                                        .emit();
-                                }
-                                (inner_ty, tcx.types.err)
-                            } else if let Some(rest) = size.checked_sub(min_len) {
-                                (inner_ty, tcx.mk_array(inner_ty, rest))
-                            } else {
-                                struct_span_err!(tcx.sess, pat.span, E0528,
-                                        "pattern requires at least {} elements but array has {}",
-                                        min_len, size)
-                                    .span_label(pat.span,
-                                        format!("pattern cannot match array of {} elements", size))
-                                    .emit();
-                                (inner_ty, tcx.types.err)
-                            }
-                        } else {
-                            struct_span_err!(
-                                tcx.sess,
-                                pat.span,
-                                E0730,
-                                "cannot pattern-match on an array without a fixed length",
-                            ).emit();
-                            (inner_ty, tcx.types.err)
-                        }
-                    }
-                    ty::Slice(inner_ty) => (inner_ty, expected_ty),
-                    _ => {
-                        if !expected_ty.references_error() {
-                            let mut err = struct_span_err!(
-                                tcx.sess, pat.span, E0529,
-                                "expected an array or slice, found `{}`",
-                                expected_ty);
-                            if let ty::Ref(_, ty, _) = expected_ty.sty {
-                                match ty.sty {
-                                    ty::Array(..) | ty::Slice(..) => {
-                                        err.help("the semantics of slice patterns changed \
-                                                  recently; see issue #62254");
-                                    }
-                                    _ => {}
-                                }
-                            }
-
-                            err.span_label( pat.span,
-                                format!("pattern cannot match with input type `{}`", expected_ty)
-                            ).emit();
-                        }
-                        (tcx.types.err, tcx.types.err)
-                    }
-                };
-
-                for elt in before {
-                    self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
-                }
-                if let Some(ref slice) = *slice {
-                    self.check_pat_walk(&slice, slice_ty, def_bm, discrim_span);
-                }
-                for elt in after {
-                    self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
-                }
-                expected_ty
+                let slice = slice.as_deref();
+                self.check_pat_slice(pat.span, before, slice, after, expected, def_bm, discrim_span)
             }
         };
 
@@ -1070,4 +999,88 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             tcx.types.err
         }
     }
+
+    fn check_pat_slice(
+        &self,
+        span: Span,
+        before: &'tcx [P<hir::Pat>],
+        slice: Option<&'tcx hir::Pat>,
+        after: &'tcx [P<hir::Pat>],
+        expected: Ty<'tcx>,
+        def_bm: ty::BindingMode,
+        discrim_span: Option<Span>,
+    ) -> Ty<'tcx> {
+        let tcx = self.tcx;
+        let expected_ty = self.structurally_resolved_type(span, expected);
+        let (inner_ty, slice_ty) = match expected_ty.sty {
+            ty::Array(inner_ty, size) => {
+                if let Some(size) = size.try_eval_usize(tcx, self.param_env) {
+                    let min_len = before.len() as u64 + after.len() as u64;
+                    if slice.is_none() {
+                        if min_len != size {
+                            struct_span_err!(
+                                tcx.sess, span, E0527,
+                                "pattern requires {} elements but array has {}",
+                                min_len, size
+                            )
+                            .span_label(span, format!("expected {} elements", size))
+                            .emit();
+                        }
+                        (inner_ty, tcx.types.err)
+                    } else if let Some(rest) = size.checked_sub(min_len) {
+                        (inner_ty, tcx.mk_array(inner_ty, rest))
+                    } else {
+                        let msg = format!("pattern cannot match array of {} elements", size);
+                        struct_span_err!(
+                            tcx.sess, span, E0528,
+                            "pattern requires at least {} elements but array has {}",
+                            min_len, size
+                        )
+                        .span_label(span, msg)
+                        .emit();
+                        (inner_ty, tcx.types.err)
+                    }
+                } else {
+                    struct_span_err!(
+                        tcx.sess, span, E0730,
+                        "cannot pattern-match on an array without a fixed length",
+                    )
+                    .emit();
+                    (inner_ty, tcx.types.err)
+                }
+            }
+            ty::Slice(inner_ty) => (inner_ty, expected_ty),
+            _ => {
+                if !expected_ty.references_error() {
+                    let mut err = struct_span_err!(
+                        tcx.sess, span, E0529,
+                        "expected an array or slice, found `{}`",
+                        expected_ty
+                    );
+                    if let ty::Ref(_, ty, _) = expected_ty.sty {
+                        if let ty::Array(..) | ty::Slice(..) = ty.sty {
+                            err.help("the semantics of slice patterns changed \
+                                     recently; see issue #62254");
+                        }
+                    }
+
+                    let msg = format!("pattern cannot match with input type `{}`", expected_ty);
+                    err.span_label(span, msg);
+                    err.emit();
+                }
+                (tcx.types.err, tcx.types.err)
+            }
+        };
+
+        for elt in before {
+            self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
+        }
+        if let Some(slice) = slice {
+            self.check_pat_walk(&slice, slice_ty, def_bm, discrim_span);
+        }
+        for elt in after {
+            self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
+        }
+        expected_ty
+    }
 }

From 862bb385d1dea925c179dfad996150ee1bd5b2ed Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 05:13:57 +0200
Subject: [PATCH 187/943] typeck/pat.rs: simplify `check_pat_walk`.

---
 src/librustc_typeck/check/pat.rs | 42 +++++++++++++++-----------------
 1 file changed, 19 insertions(+), 23 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 7b78474e79979..c08d777c34e3e 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -61,57 +61,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let is_nrp = self.is_non_ref_pat(pat, path_resolution.map(|(res, ..)| res));
         let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, is_nrp);
 
-        let ty = match pat.node {
-            PatKind::Wild => {
-                expected
-            }
-            PatKind::Lit(ref lt) => {
-                self.check_pat_lit(pat.span, lt, expected, discrim_span)
-            }
-            PatKind::Range(ref begin, ref end, _) => {
+        let ty = match &pat.node {
+            PatKind::Wild => expected,
+            PatKind::Lit(lt) => self.check_pat_lit(pat.span, lt, expected, discrim_span),
+            PatKind::Range(begin, end, _) => {
                 match self.check_pat_range(pat.span, begin, end, expected, discrim_span) {
                     None => return,
                     Some(ty) => ty,
                 }
             }
-            PatKind::Binding(ba, var_id, _, ref sub) => {
+            PatKind::Binding(ba, var_id, _, sub) => {
                 let sub = sub.as_deref();
-                self.check_pat_ident(pat, ba, var_id, sub, expected, def_bm, discrim_span)
+                self.check_pat_ident(pat, *ba, *var_id, sub, expected, def_bm, discrim_span)
             }
-            PatKind::TupleStruct(ref qpath, ref subpats, ddpos) => {
+            PatKind::TupleStruct(qpath, subpats, ddpos) => {
                 self.check_pat_tuple_struct(
                     pat,
                     qpath,
-                    &subpats,
-                    ddpos,
+                    subpats,
+                    *ddpos,
                     expected,
                     def_bm,
                     discrim_span,
                 )
             }
-            PatKind::Path(ref qpath) => {
+            PatKind::Path(qpath) => {
                 self.check_pat_path(pat, path_resolution.unwrap(), qpath, expected)
             }
-            PatKind::Struct(ref qpath, ref fields, etc) => {
-                self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, discrim_span)
+            PatKind::Struct(qpath, fields, etc) => {
+                self.check_pat_struct(pat, qpath, fields, *etc, expected, def_bm, discrim_span)
             }
-            PatKind::Or(ref pats) => {
+            PatKind::Or(pats) => {
                 let expected_ty = self.structurally_resolved_type(pat.span, expected);
                 for pat in pats {
                     self.check_pat_walk(pat, expected, def_bm, discrim_span);
                 }
                 expected_ty
             }
-            PatKind::Tuple(ref elements, ddpos) => {
-                self.check_pat_tuple(pat.span, elements, ddpos, expected, def_bm, discrim_span)
+            PatKind::Tuple(elements, ddpos) => {
+                self.check_pat_tuple(pat.span, elements, *ddpos, expected, def_bm, discrim_span)
             }
-            PatKind::Box(ref inner) => {
+            PatKind::Box(inner) => {
                 self.check_pat_box(pat.span, inner, expected, def_bm, discrim_span)
             }
-            PatKind::Ref(ref inner, mutbl) => {
-                self.check_pat_ref(pat, inner, mutbl, expected, def_bm, discrim_span)
+            PatKind::Ref(inner, mutbl) => {
+                self.check_pat_ref(pat, inner, *mutbl, expected, def_bm, discrim_span)
             }
-            PatKind::Slice(ref before, ref slice, ref after) => {
+            PatKind::Slice(before, slice, after) => {
                 let slice = slice.as_deref();
                 self.check_pat_slice(pat.span, before, slice, after, expected, def_bm, discrim_span)
             }

From 9d69783a46a9f6096b8c2f284876d6a68e2b6455 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 13:40:42 +0200
Subject: [PATCH 188/943] typeck/pat.rs: `(*)` -> `(note_1)` for clarity.

---
 src/librustc_typeck/check/pat.rs | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index c08d777c34e3e..59244ec33ca33 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -115,12 +115,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         self.write_ty(pat.hir_id, ty);
 
-        // (*) In most of the cases above (literals and constants being
-        // the exception), we relate types using strict equality, even
-        // though subtyping would be sufficient. There are a few reasons
-        // for this, some of which are fairly subtle and which cost me
-        // (nmatsakis) an hour or two debugging to remember, so I thought
-        // I'd write them down this time.
+        // (note_1): In most of the cases where (note_1) is referenced
+        // (literals and constants being the exception), we relate types
+        // using strict equality, even though subtyping would be sufficient.
+        // There are a few reasons for this, some of which are fairly subtle
+        // and which cost me (nmatsakis) an hour or two debugging to remember,
+        // so I thought I'd write them down this time.
         //
         // 1. There is no loss of expressiveness here, though it does
         // cause some inconvenience. What we are saying is that the type
@@ -427,12 +427,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)`
                 // is required. However, we use equality, which is stronger.
-                // See (*) for an explanation.
+                // See (note_1) for an explanation.
                 region_ty
             }
             // Otherwise, the type of x is the expected type `T`.
             ty::BindByValue(_) => {
-                // As above, `T <: typeof(x)` is required, but we use equality, see (*) below.
+                // As above, `T <: typeof(x)` is required, but we use equality, see (note_1).
                 expected
             }
         };
@@ -955,11 +955,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let expected = self.shallow_resolve(expected);
         if self.check_dereferencable(pat.span, expected, &inner) {
             // `demand::subtype` would be good enough, but using `eqtype` turns
-            // out to be equally general. See (*) below for details.
+            // out to be equally general. See (note_1) for details.
 
             // Take region, inner-type from expected type if we can,
             // to avoid creating needless variables. This also helps with
-            // the bad  interactions of the given hack detailed in (*) below.
+            // the bad  interactions of the given hack detailed in (note_1).
             debug!("check_pat_ref: expected={:?}", expected);
             let (rptr_ty, inner_ty) = match expected.sty {
                 ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {

From 365ff62fca0e1fb6511a47f5f50c4af4df250dfa Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sat, 24 Aug 2019 18:25:34 +0100
Subject: [PATCH 189/943] Don't unwrap the result of `span_to_snippet`

It can return `Err` due to macros being expanded across crates or
files.
---
 src/librustc_mir/borrow_check/move_errors.rs  | 84 ++++++++++---------
 .../borrow_check/mutability_errors.rs         |  4 +-
 .../ui/borrowck/move-error-snippets-ext.rs    |  7 ++
 src/test/ui/borrowck/move-error-snippets.rs   | 23 +++++
 .../ui/borrowck/move-error-snippets.stderr    | 15 ++++
 5 files changed, 90 insertions(+), 43 deletions(-)
 create mode 100644 src/test/ui/borrowck/move-error-snippets-ext.rs
 create mode 100644 src/test/ui/borrowck/move-error-snippets.rs
 create mode 100644 src/test/ui/borrowck/move-error-snippets.stderr

diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index 738a091b0dd76..f10ff71b15e68 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -415,20 +415,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             "{:?}",
             move_place.ty(self.body, self.infcx.tcx).ty,
         );
-        let snippet = self.infcx.tcx.sess.source_map().span_to_snippet(span).unwrap();
-        let is_option = move_ty.starts_with("std::option::Option");
-        let is_result = move_ty.starts_with("std::result::Result");
-        if  is_option || is_result {
-            err.span_suggestion(
-                span,
-                &format!("consider borrowing the `{}`'s content", if is_option {
-                    "Option"
-                } else {
-                    "Result"
-                }),
-                format!("{}.as_ref()", snippet),
-                Applicability::MaybeIncorrect,
-            );
+        if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
+            let is_option = move_ty.starts_with("std::option::Option");
+            let is_result = move_ty.starts_with("std::result::Result");
+            if is_option || is_result {
+                err.span_suggestion(
+                    span,
+                    &format!("consider borrowing the `{}`'s content", if is_option {
+                        "Option"
+                    } else {
+                        "Result"
+                    }),
+                    format!("{}.as_ref()", snippet),
+                    Applicability::MaybeIncorrect,
+                );
+            }
         }
         err
     }
@@ -439,19 +440,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         err: &mut DiagnosticBuilder<'a>,
         span: Span,
     ) {
-        let snippet = self.infcx.tcx.sess.source_map().span_to_snippet(span).unwrap();
         match error {
             GroupedMoveError::MovesFromPlace {
                 mut binds_to,
                 move_from,
                 ..
             } => {
-                err.span_suggestion(
-                    span,
-                    "consider borrowing here",
-                    format!("&{}", snippet),
-                    Applicability::Unspecified,
-                );
+                if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
+                    err.span_suggestion(
+                        span,
+                        "consider borrowing here",
+                        format!("&{}", snippet),
+                        Applicability::Unspecified,
+                    );
+                }
 
                 if binds_to.is_empty() {
                     let place_ty = move_from.ty(self.body, self.infcx.tcx).ty;
@@ -517,27 +519,27 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     ..
                 }))
             ) = bind_to.is_user_variable {
-                let pat_snippet = self.infcx.tcx.sess.source_map()
-                    .span_to_snippet(pat_span)
-                    .unwrap();
-                if pat_snippet.starts_with('&') {
-                    let pat_snippet = pat_snippet[1..].trim_start();
-                    let suggestion;
-                    let to_remove;
-                    if pat_snippet.starts_with("mut")
-                        && pat_snippet["mut".len()..].starts_with(Pattern_White_Space)
-                    {
-                        suggestion = pat_snippet["mut".len()..].trim_start();
-                        to_remove = "&mut";
-                    } else {
-                        suggestion = pat_snippet;
-                        to_remove = "&";
+                if let Ok(pat_snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(pat_span)
+                {
+                    if pat_snippet.starts_with('&') {
+                        let pat_snippet = pat_snippet[1..].trim_start();
+                        let suggestion;
+                        let to_remove;
+                        if pat_snippet.starts_with("mut")
+                            && pat_snippet["mut".len()..].starts_with(Pattern_White_Space)
+                        {
+                            suggestion = pat_snippet["mut".len()..].trim_start();
+                            to_remove = "&mut";
+                        } else {
+                            suggestion = pat_snippet;
+                            to_remove = "&";
+                        }
+                        suggestions.push((
+                            pat_span,
+                            to_remove,
+                            suggestion.to_owned(),
+                        ));
                     }
-                    suggestions.push((
-                        pat_span,
-                        to_remove,
-                        suggestion.to_owned(),
-                    ));
                 }
             }
         }
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 937c6383be341..e7f37431e5009 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -711,8 +711,8 @@ fn annotate_struct_field(
 }
 
 /// If possible, suggest replacing `ref` with `ref mut`.
-fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<(String)> {
-    let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).unwrap();
+fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<String> {
+    let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).ok()?;
     if hi_src.starts_with("ref")
         && hi_src["ref".len()..].starts_with(Pattern_White_Space)
     {
diff --git a/src/test/ui/borrowck/move-error-snippets-ext.rs b/src/test/ui/borrowck/move-error-snippets-ext.rs
new file mode 100644
index 0000000000000..c77f6c8276e70
--- /dev/null
+++ b/src/test/ui/borrowck/move-error-snippets-ext.rs
@@ -0,0 +1,7 @@
+// ignore-test
+
+macro_rules! aaa {
+    ($c:ident) => {{
+        let a = $c;
+    }}
+}
diff --git a/src/test/ui/borrowck/move-error-snippets.rs b/src/test/ui/borrowck/move-error-snippets.rs
new file mode 100644
index 0000000000000..64f9565382886
--- /dev/null
+++ b/src/test/ui/borrowck/move-error-snippets.rs
@@ -0,0 +1,23 @@
+// Test that we don't ICE after trying to construct a cross-file snippet #63800.
+
+// compile-flags: --test
+
+#[macro_use]
+#[path = "move-error-snippets-ext.rs"]
+mod move_error_snippets_ext;
+
+struct A;
+
+macro_rules! sss {
+    () => {
+        #[test]
+        fn fff() {
+            static D: A = A;
+            aaa!(D);         //~ ERROR cannot move
+        }
+    };
+}
+
+sss!();
+
+fn main() {}
diff --git a/src/test/ui/borrowck/move-error-snippets.stderr b/src/test/ui/borrowck/move-error-snippets.stderr
new file mode 100644
index 0000000000000..77463c48591bc
--- /dev/null
+++ b/src/test/ui/borrowck/move-error-snippets.stderr
@@ -0,0 +1,15 @@
+error[E0507]: cannot move out of static item `D`
+  --> $DIR/move-error-snippets.rs:16:18
+   |
+LL | | #[macro_use]
+   | |__________________^ move occurs because `D` has type `A`, which does not implement the `Copy` trait
+...
+LL |               aaa!(D);
+   |  __________________^
+...
+LL |   sss!();
+   |   ------- in this macro invocation
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.

From 65deeae76dfcb8d0aeb389bbe12ef9990caf2f6f Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 13:47:07 +0200
Subject: [PATCH 190/943] typeck/pat.rs: `check_pat_top` is the entry point.

This clarifies the fact that type checking patterns unconditionally
starts with `BindByValue` as the default binding mode making the
notion of a default binding mode internal to type checking patterns.
---
 src/librustc_typeck/check/_match.rs |  5 ++---
 src/librustc_typeck/check/mod.rs    | 10 ++--------
 src/librustc_typeck/check/pat.rs    | 12 +++++++++++-
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 8cb365d91fa79..efc37cc04b212 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -3,7 +3,7 @@ use crate::check::coercion::CoerceMany;
 use rustc::hir::{self, ExprKind};
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc::traits::{ObligationCause, ObligationCauseCode};
-use rustc::ty::{self, Ty};
+use rustc::ty::Ty;
 use syntax_pos::Span;
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -59,8 +59,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let mut all_pats_diverge = Diverges::WarnedAlways;
             for p in &arm.pats {
                 self.diverges.set(Diverges::Maybe);
-                let binding_mode = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable);
-                self.check_pat_walk(&p, discrim_ty, binding_mode, Some(discrim.span));
+                self.check_pat_top(&p, discrim_ty, Some(discrim.span));
                 all_pats_diverge &= self.diverges.get();
             }
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a130d11a5e645..ee505b2487532 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1104,8 +1104,7 @@ fn check_fn<'a, 'tcx>(
     // Add formal parameters.
     for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
         // Check the pattern.
-        let binding_mode = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable);
-        fcx.check_pat_walk(&arg.pat, arg_ty, binding_mode, None);
+        fcx.check_pat_top(&arg.pat, arg_ty, None);
 
         // Check that argument is Sized.
         // The check for a non-trivial pattern is a hack to avoid duplicate warnings
@@ -3631,12 +3630,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        self.check_pat_walk(
-            &local.pat,
-            t,
-            ty::BindingMode::BindByValue(hir::Mutability::MutImmutable),
-            None,
-        );
+        self.check_pat_top(&local.pat, t, None);
         let pat_ty = self.node_ty(local.pat.hir_id);
         if pat_ty.references_error() {
             self.write_ty(local.hir_id, pat_ty);
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 59244ec33ca33..fc52684b5a24c 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -29,6 +29,16 @@ You can read more about trait objects in the Trait Objects section of the Refere
 https://doc.rust-lang.org/reference/types.html#trait-objects";
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
+    pub fn check_pat_top(
+        &self,
+        pat: &'tcx hir::Pat,
+        expected: Ty<'tcx>,
+        discrim_span: Option<Span>,
+    ) {
+        let def_bm = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable);
+        self.check_pat_walk(pat, expected, def_bm, discrim_span);
+    }
+
     /// `discrim_span` argument having a `Span` indicates that this pattern is part of a match
     /// expression arm guard, and it points to the match discriminant to add context in type errors.
     /// In the following example, `discrim_span` corresponds to the `a + b` expression:
@@ -45,7 +55,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ///   = note: expected type `usize`
     ///              found type `std::result::Result<_, _>`
     /// ```
-    pub fn check_pat_walk(
+    fn check_pat_walk(
         &self,
         pat: &'tcx hir::Pat,
         expected: Ty<'tcx>,

From 41e8aed3cfeabba102b1576db43871aa5f27eabd Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 14:01:59 +0200
Subject: [PATCH 191/943] typeck/pat.rs: `check_pat_walk` -> `check_pat`.

It's just shorter and we usually don't use the `_walk` suffix.
---
 src/librustc_typeck/check/pat.rs | 44 ++++++++++++++------------------
 1 file changed, 19 insertions(+), 25 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index fc52684b5a24c..083d41f0963a6 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -36,7 +36,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         discrim_span: Option<Span>,
     ) {
         let def_bm = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable);
-        self.check_pat_walk(pat, expected, def_bm, discrim_span);
+        self.check_pat(pat, expected, def_bm, discrim_span);
     }
 
     /// `discrim_span` argument having a `Span` indicates that this pattern is part of a match
@@ -55,14 +55,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ///   = note: expected type `usize`
     ///              found type `std::result::Result<_, _>`
     /// ```
-    fn check_pat_walk(
+    fn check_pat(
         &self,
         pat: &'tcx hir::Pat,
         expected: Ty<'tcx>,
         def_bm: ty::BindingMode,
         discrim_span: Option<Span>,
     ) {
-        debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
+        debug!("check_pat(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
 
         let path_resolution = match &pat.node {
             PatKind::Path(qpath) => Some(self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span)),
@@ -104,7 +104,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             PatKind::Or(pats) => {
                 let expected_ty = self.structurally_resolved_type(pat.span, expected);
                 for pat in pats {
-                    self.check_pat_walk(pat, expected, def_bm, discrim_span);
+                    self.check_pat(pat, expected, def_bm, discrim_span);
                 }
                 expected_ty
             }
@@ -456,7 +456,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         if let Some(p) = sub {
-            self.check_pat_walk(&p, expected, def_bm, discrim_span);
+            self.check_pat(&p, expected, def_bm, discrim_span);
         }
 
         local_ty
@@ -544,7 +544,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             variant_ty
         } else {
             for field in fields {
-                self.check_pat_walk(&field.pat, self.tcx.types.err, def_bm, discrim_span);
+                self.check_pat(&field.pat, self.tcx.types.err, def_bm, discrim_span);
             }
             return self.tcx.types.err;
         };
@@ -607,7 +607,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let tcx = self.tcx;
         let on_error = || {
             for pat in subpats {
-                self.check_pat_walk(&pat, tcx.types.err, def_bm, match_arm_pat_span);
+                self.check_pat(&pat, tcx.types.err, def_bm, match_arm_pat_span);
             }
         };
         let report_unexpected_res = |res: Res| {
@@ -677,7 +677,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
             for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) {
                 let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs);
-                self.check_pat_walk(&subpat, field_ty, def_bm, match_arm_pat_span);
+                self.check_pat(&subpat, field_ty, def_bm, match_arm_pat_span);
 
                 self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
             }
@@ -734,17 +734,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // further errors being emitted when using the bindings. #50333
             let element_tys_iter = (0..max_len).map(|_| tcx.types.err);
             for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
-                self.check_pat_walk(elem, &tcx.types.err, def_bm, discrim_span);
+                self.check_pat(elem, &tcx.types.err, def_bm, discrim_span);
             }
             tcx.mk_tup(element_tys_iter)
         } else {
             for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
-                self.check_pat_walk(
-                    elem,
-                    &element_tys[i].expect_ty(),
-                    def_bm,
-                    discrim_span,
-                );
+                self.check_pat(elem, &element_tys[i].expect_ty(), def_bm, discrim_span);
             }
             pat_ty
         }
@@ -813,7 +808,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             };
 
-            self.check_pat_walk(&field.pat, field_ty, def_bm, None);
+            self.check_pat(&field.pat, field_ty, def_bm, None);
         }
         let mut unmentioned_fields = variant.fields
                 .iter()
@@ -941,13 +936,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if self.check_dereferencable(span, expected, &inner) {
             // Here, `demand::subtype` is good enough, but I don't
-            // think any errors can be introduced by using
-            // `demand::eqtype`.
+            // think any errors can be introduced by using `demand::eqtype`.
             self.demand_eqtype_pat(span, expected, uniq_ty, discrim_span);
-            self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
+            self.check_pat(&inner, inner_ty, def_bm, discrim_span);
             uniq_ty
         } else {
-            self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
+            self.check_pat(&inner, tcx.types.err, def_bm, discrim_span);
             tcx.types.err
         }
     }
@@ -998,10 +992,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             };
 
-            self.check_pat_walk(&inner, inner_ty, def_bm, discrim_span);
+            self.check_pat(&inner, inner_ty, def_bm, discrim_span);
             rptr_ty
         } else {
-            self.check_pat_walk(&inner, tcx.types.err, def_bm, discrim_span);
+            self.check_pat(&inner, tcx.types.err, def_bm, discrim_span);
             tcx.types.err
         }
     }
@@ -1079,13 +1073,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         for elt in before {
-            self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
+            self.check_pat(&elt, inner_ty, def_bm, discrim_span);
         }
         if let Some(slice) = slice {
-            self.check_pat_walk(&slice, slice_ty, def_bm, discrim_span);
+            self.check_pat(&slice, slice_ty, def_bm, discrim_span);
         }
         for elt in after {
-            self.check_pat_walk(&elt, inner_ty, def_bm, discrim_span);
+            self.check_pat(&elt, inner_ty, def_bm, discrim_span);
         }
         expected_ty
     }

From 97986b57046a7af6d5ec1eeca7a19346131dec59 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 14:49:32 +0200
Subject: [PATCH 192/943] typeck/pat.rs: some common imports.

---
 src/librustc_typeck/check/pat.rs | 81 +++++++++++++++-----------------
 1 file changed, 38 insertions(+), 43 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 083d41f0963a6..1f6f7901c9e6e 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -1,13 +1,13 @@
 use crate::check::FnCtxt;
 use crate::util::nodemap::FxHashMap;
 use errors::{Applicability, DiagnosticBuilder};
-use rustc::hir::{self, PatKind, Pat};
+use rustc::hir::{self, PatKind, Pat, HirId};
 use rustc::hir::def::{Res, DefKind, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
 use rustc::hir::ptr::P;
 use rustc::infer;
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc::ty::{self, Ty, TypeFoldable};
+use rustc::ty::{self, Ty, BindingMode, TypeFoldable};
 use rustc::ty::subst::Kind;
 use syntax::ast;
 use syntax::util::lev_distance::find_best_match_for_name;
@@ -29,13 +29,8 @@ You can read more about trait objects in the Trait Objects section of the Refere
 https://doc.rust-lang.org/reference/types.html#trait-objects";
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-    pub fn check_pat_top(
-        &self,
-        pat: &'tcx hir::Pat,
-        expected: Ty<'tcx>,
-        discrim_span: Option<Span>,
-    ) {
-        let def_bm = ty::BindingMode::BindByValue(hir::Mutability::MutImmutable);
+    pub fn check_pat_top(&self, pat: &'tcx Pat, expected: Ty<'tcx>, discrim_span: Option<Span>) {
+        let def_bm = BindingMode::BindByValue(hir::Mutability::MutImmutable);
         self.check_pat(pat, expected, def_bm, discrim_span);
     }
 
@@ -57,9 +52,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// ```
     fn check_pat(
         &self,
-        pat: &'tcx hir::Pat,
+        pat: &'tcx Pat,
         expected: Ty<'tcx>,
-        def_bm: ty::BindingMode,
+        def_bm: BindingMode,
         discrim_span: Option<Span>,
     ) {
         debug!("check_pat(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm);
@@ -179,11 +174,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// as well as the pattern form we are currently checking.
     fn calc_default_binding_mode(
         &self,
-        pat: &'tcx hir::Pat,
+        pat: &'tcx Pat,
         expected: Ty<'tcx>,
-        def_bm: ty::BindingMode,
+        def_bm: BindingMode,
         is_non_ref_pat: bool,
-    ) -> (Ty<'tcx>, ty::BindingMode) {
+    ) -> (Ty<'tcx>, BindingMode) {
         if is_non_ref_pat {
             debug!("pattern is non reference pattern");
             self.peel_off_references(pat, expected, def_bm)
@@ -209,7 +204,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Is the pattern a "non reference pattern"?
     /// When the pattern is a path pattern, `opt_path_res` must be `Some(res)`.
-    fn is_non_ref_pat(&self, pat: &'tcx hir::Pat, opt_path_res: Option<Res>) -> bool {
+    fn is_non_ref_pat(&self, pat: &'tcx Pat, opt_path_res: Option<Res>) -> bool {
         match pat.node {
             PatKind::Struct(..) |
             PatKind::TupleStruct(..) |
@@ -242,10 +237,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// The adjustments vector, if non-empty is stored in a table.
     fn peel_off_references(
         &self,
-        pat: &'tcx hir::Pat,
+        pat: &'tcx Pat,
         expected: Ty<'tcx>,
-        mut def_bm: ty::BindingMode,
-    ) -> (Ty<'tcx>, ty::BindingMode) {
+        mut def_bm: BindingMode,
+    ) -> (Ty<'tcx>, BindingMode) {
         let mut expected = self.resolve_type_vars_with_obligations(&expected);
 
         // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example,
@@ -403,18 +398,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_ident(
         &self,
-        pat: &hir::Pat,
+        pat: &Pat,
         ba: hir::BindingAnnotation,
-        var_id: hir::HirId,
-        sub: Option<&'tcx hir::Pat>,
+        var_id: HirId,
+        sub: Option<&'tcx Pat>,
         expected: Ty<'tcx>,
-        def_bm: ty::BindingMode,
+        def_bm: BindingMode,
         discrim_span: Option<Span>,
     ) -> Ty<'tcx> {
         // Determine the binding mode...
         let bm = match ba {
             hir::BindingAnnotation::Unannotated => def_bm,
-            _ => ty::BindingMode::convert(ba),
+            _ => BindingMode::convert(ba),
         };
         // ...and store it in a side table:
         self.inh
@@ -502,7 +497,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &hir::Pat) -> bool {
+    pub fn check_dereferencable(&self, span: Span, expected: Ty<'tcx>, inner: &Pat) -> bool {
         if let PatKind::Binding(..) = inner.node {
             if let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) {
                 if let ty::Dynamic(..) = mt.ty.sty {
@@ -530,12 +525,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_struct(
         &self,
-        pat: &'tcx hir::Pat,
+        pat: &'tcx Pat,
         qpath: &hir::QPath,
         fields: &'tcx [hir::FieldPat],
         etc: bool,
         expected: Ty<'tcx>,
-        def_bm: ty::BindingMode,
+        def_bm: BindingMode,
         discrim_span: Option<Span>,
     ) -> Ty<'tcx> {
         // Resolve the path and check the definition for errors.
@@ -563,7 +558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_path(
         &self,
-        pat: &hir::Pat,
+        pat: &Pat,
         path_resolution: (Res, Option<Ty<'tcx>>, &'b [hir::PathSegment]),
         qpath: &hir::QPath,
         expected: Ty<'tcx>,
@@ -596,12 +591,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_tuple_struct(
         &self,
-        pat: &hir::Pat,
+        pat: &Pat,
         qpath: &hir::QPath,
-        subpats: &'tcx [P<hir::Pat>],
+        subpats: &'tcx [P<Pat>],
         ddpos: Option<usize>,
         expected: Ty<'tcx>,
-        def_bm: ty::BindingMode,
+        def_bm: BindingMode,
         match_arm_pat_span: Option<Span>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
@@ -700,10 +695,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_pat_tuple(
         &self,
         span: Span,
-        elements: &'tcx [P<hir::Pat>],
+        elements: &'tcx [P<Pat>],
         ddpos: Option<usize>,
         expected: Ty<'tcx>,
-        def_bm: ty::BindingMode,
+        def_bm: BindingMode,
         discrim_span: Option<Span>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
@@ -748,12 +743,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_struct_pat_fields(
         &self,
         adt_ty: Ty<'tcx>,
-        pat_id: hir::HirId,
+        pat_id: HirId,
         span: Span,
         variant: &'tcx ty::VariantDef,
         fields: &'tcx [hir::FieldPat],
         etc: bool,
-        def_bm: ty::BindingMode,
+        def_bm: BindingMode,
     ) -> bool {
         let tcx = self.tcx;
 
@@ -922,9 +917,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_pat_box(
         &self,
         span: Span,
-        inner: &'tcx hir::Pat,
+        inner: &'tcx Pat,
         expected: Ty<'tcx>,
-        def_bm: ty::BindingMode,
+        def_bm: BindingMode,
         discrim_span: Option<Span>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
@@ -948,11 +943,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn check_pat_ref(
         &self,
-        pat: &hir::Pat,
-        inner: &'tcx hir::Pat,
+        pat: &Pat,
+        inner: &'tcx Pat,
         mutbl: hir::Mutability,
         expected: Ty<'tcx>,
-        def_bm: ty::BindingMode,
+        def_bm: BindingMode,
         discrim_span: Option<Span>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
@@ -1003,11 +998,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_pat_slice(
         &self,
         span: Span,
-        before: &'tcx [P<hir::Pat>],
-        slice: Option<&'tcx hir::Pat>,
-        after: &'tcx [P<hir::Pat>],
+        before: &'tcx [P<Pat>],
+        slice: Option<&'tcx Pat>,
+        after: &'tcx [P<Pat>],
         expected: Ty<'tcx>,
-        def_bm: ty::BindingMode,
+        def_bm: BindingMode,
         discrim_span: Option<Span>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;

From 2ab69aef03f9744381e4a0cedb397c34d191f4f7 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 15:51:48 +0200
Subject: [PATCH 193/943] typeck/pat.rs: extract `new_ref_ty`.

---
 src/librustc_typeck/check/pat.rs | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 1f6f7901c9e6e..ac025754ffbae 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -426,9 +426,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // If the binding is like `ref x | ref const x | ref mut x`
                 // then `x` is assigned a value of type `&M T` where M is the
                 // mutability and T is the expected type.
-                let region_var = self.next_region_var(infer::PatternRegion(pat.span));
-                let mt = ty::TypeAndMut { ty: expected, mutbl };
-                let region_ty = self.tcx.mk_ref(region_var, mt);
+                let region_ty = self.new_ref_ty(pat.span, mutbl, expected);
 
                 // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)`
                 // is required. However, we use equality, which is stronger.
@@ -971,9 +969,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             span: inner.span,
                         }
                     );
-                    let mt = ty::TypeAndMut { ty: inner_ty, mutbl };
-                    let region = self.next_region_var(infer::PatternRegion(pat.span));
-                    let rptr_ty = tcx.mk_ref(region, mt);
+                    let rptr_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
                     debug!("check_pat_ref: demanding {:?} = {:?}", expected, rptr_ty);
                     let err = self.demand_eqtype_diag(pat.span, expected, rptr_ty);
 
@@ -995,6 +991,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    /// Create a reference type with a fresh region variable.
+    fn new_ref_ty(&self, span: Span, mutbl: hir::Mutability, ty: Ty<'tcx>) -> Ty<'tcx> {
+        let region = self.next_region_var(infer::PatternRegion(span));
+        let mt = ty::TypeAndMut { ty, mutbl };
+        self.tcx.mk_ref(region, mt)
+    }
+
     fn check_pat_slice(
         &self,
         span: Span,

From 729fbeb70b9aabc6df58f0cc3601402b44663cf2 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 16:42:15 +0200
Subject: [PATCH 194/943] typeck/pat.rs: extract diagnostics from
 `check_pat_slice`.

---
 src/librustc_typeck/check/pat.rs | 95 ++++++++++++++++++--------------
 1 file changed, 54 insertions(+), 41 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index ac025754ffbae..ff1500e6bd877 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -1012,59 +1012,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let expected_ty = self.structurally_resolved_type(span, expected);
         let (inner_ty, slice_ty) = match expected_ty.sty {
             ty::Array(inner_ty, size) => {
-                if let Some(size) = size.try_eval_usize(tcx, self.param_env) {
+                let slice_ty = if let Some(size) = size.try_eval_usize(tcx, self.param_env) {
                     let min_len = before.len() as u64 + after.len() as u64;
                     if slice.is_none() {
                         if min_len != size {
-                            struct_span_err!(
-                                tcx.sess, span, E0527,
-                                "pattern requires {} elements but array has {}",
-                                min_len, size
-                            )
-                            .span_label(span, format!("expected {} elements", size))
-                            .emit();
+                            self.error_scrutinee_inconsistent_length(span, min_len, size)
                         }
-                        (inner_ty, tcx.types.err)
+                        tcx.types.err
                     } else if let Some(rest) = size.checked_sub(min_len) {
-                        (inner_ty, tcx.mk_array(inner_ty, rest))
+                        tcx.mk_array(inner_ty, rest)
                     } else {
-                        let msg = format!("pattern cannot match array of {} elements", size);
-                        struct_span_err!(
-                            tcx.sess, span, E0528,
-                            "pattern requires at least {} elements but array has {}",
-                            min_len, size
-                        )
-                        .span_label(span, msg)
-                        .emit();
-                        (inner_ty, tcx.types.err)
+                        self.error_scrutinee_with_rest_inconsistent_length(span, min_len, size);
+                        tcx.types.err
                     }
                 } else {
-                    struct_span_err!(
-                        tcx.sess, span, E0730,
-                        "cannot pattern-match on an array without a fixed length",
-                    )
-                    .emit();
-                    (inner_ty, tcx.types.err)
-                }
+                    self.error_scrutinee_unfixed_length(span);
+                    tcx.types.err
+                };
+                (inner_ty, slice_ty)
             }
             ty::Slice(inner_ty) => (inner_ty, expected_ty),
             _ => {
                 if !expected_ty.references_error() {
-                    let mut err = struct_span_err!(
-                        tcx.sess, span, E0529,
-                        "expected an array or slice, found `{}`",
-                        expected_ty
-                    );
-                    if let ty::Ref(_, ty, _) = expected_ty.sty {
-                        if let ty::Array(..) | ty::Slice(..) = ty.sty {
-                            err.help("the semantics of slice patterns changed \
-                                     recently; see issue #62254");
-                        }
-                    }
-
-                    let msg = format!("pattern cannot match with input type `{}`", expected_ty);
-                    err.span_label(span, msg);
-                    err.emit();
+                    self.error_expected_array_or_slice(span, expected_ty);
                 }
                 (tcx.types.err, tcx.types.err)
             }
@@ -1081,4 +1051,47 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
         expected_ty
     }
+
+    fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
+        struct_span_err!(
+            self.tcx.sess, span, E0527,
+            "pattern requires {} elements but array has {}",
+            min_len, size
+        )
+        .span_label(span, format!("expected {} elements", size))
+        .emit();
+    }
+
+    fn error_scrutinee_with_rest_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
+        struct_span_err!(
+            self.tcx.sess, span, E0528,
+            "pattern requires at least {} elements but array has {}",
+            min_len, size
+        )
+        .span_label(span, format!("pattern cannot match array of {} elements", size))
+        .emit();
+    }
+
+    fn error_scrutinee_unfixed_length(&self, span: Span) {
+        struct_span_err!(
+            self.tcx.sess, span, E0730,
+            "cannot pattern-match on an array without a fixed length",
+        )
+        .emit();
+    }
+
+    fn error_expected_array_or_slice(&self, span: Span, expected_ty: Ty<'tcx>) {
+        let mut err = struct_span_err!(
+            self.tcx.sess, span, E0529,
+            "expected an array or slice, found `{}`",
+            expected_ty
+        );
+        if let ty::Ref(_, ty, _) = expected_ty.sty {
+            if let ty::Array(..) | ty::Slice(..) = ty.sty {
+                err.help("the semantics of slice patterns changed recently; see issue #62254");
+            }
+        }
+        err.span_label(span, format!("pattern cannot match with input type `{}`", expected_ty));
+        err.emit();
+    }
 }

From 25f605ae99b1ac3565fc0bb65d97083f39444d60 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 17:34:15 +0200
Subject: [PATCH 195/943] typeck/pat.rs: extract `error_field_already_bound`.

---
 src/librustc_typeck/check/pat.rs | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index ff1500e6bd877..0aed814b2da9b 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -774,14 +774,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let ident = tcx.adjust_ident(field.ident, variant.def_id);
             let field_ty = match used_fields.entry(ident) {
                 Occupied(occupied) => {
-                    struct_span_err!(tcx.sess, span, E0025,
-                                     "field `{}` bound multiple times \
-                                      in the pattern",
-                                     field.ident)
-                        .span_label(span,
-                                    format!("multiple uses of `{}` in pattern", field.ident))
-                        .span_label(*occupied.get(), format!("first use of `{}`", field.ident))
-                        .emit();
+                    self.error_field_already_bound(span, field.ident, *occupied.get());
                     no_field_errors = false;
                     tcx.types.err
                 }
@@ -912,6 +905,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         no_field_errors
     }
 
+    fn error_field_already_bound(&self, span: Span, ident: ast::Ident, other_field: Span) {
+        struct_span_err!(
+            self.tcx.sess, span, E0025,
+            "field `{}` bound multiple times in the pattern",
+            ident
+        )
+        .span_label(span, format!("multiple uses of `{}` in pattern", ident))
+        .span_label(other_field, format!("first use of `{}`", ident))
+        .emit();
+    }
+
     fn check_pat_box(
         &self,
         span: Span,

From ba2a784c38c5e87e746457645184d4dec957941f Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 17:44:43 +0200
Subject: [PATCH 196/943] typeck/pat.rs: extract `error_unmentioned_fields`.

---
 src/librustc_typeck/check/pat.rs | 65 ++++++++++++++++++--------------
 1 file changed, 37 insertions(+), 28 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 0aed814b2da9b..265f032179bf6 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -873,34 +873,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if etc {
                 tcx.sess.span_err(span, "`..` cannot be used in union patterns");
             }
-        } else if !etc {
-            if unmentioned_fields.len() > 0 {
-                let field_names = if unmentioned_fields.len() == 1 {
-                    format!("field `{}`", unmentioned_fields[0])
-                } else {
-                    format!("fields {}",
-                            unmentioned_fields.iter()
-                                .map(|name| format!("`{}`", name))
-                                .collect::<Vec<String>>()
-                                .join(", "))
-                };
-                let mut diag = struct_span_err!(tcx.sess, span, E0027,
-                                                "pattern does not mention {}",
-                                                field_names);
-                diag.span_label(span, format!("missing {}", field_names));
-                if variant.ctor_kind == CtorKind::Fn {
-                    diag.note("trying to match a tuple variant with a struct variant pattern");
-                }
-                if tcx.sess.teach(&diag.get_code().unwrap()) {
-                    diag.note(
-                        "This error indicates that a pattern for a struct fails to specify a \
-                         sub-pattern for every one of the struct's fields. Ensure that each field \
-                         from the struct's definition is mentioned in the pattern, or use `..` to \
-                         ignore unwanted fields."
-                    );
-                }
-                diag.emit();
-            }
+        } else if !etc && unmentioned_fields.len() > 0 {
+            self.error_unmentioned_fields(span, unmentioned_fields, variant);
         }
         no_field_errors
     }
@@ -916,6 +890,41 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         .emit();
     }
 
+    fn error_unmentioned_fields(
+        &self,
+        span: Span,
+        unmentioned_fields: Vec<ast::Ident>,
+        variant: &ty::VariantDef,
+    ) {
+        let field_names = if unmentioned_fields.len() == 1 {
+            format!("field `{}`", unmentioned_fields[0])
+        } else {
+            let fields = unmentioned_fields.iter()
+                .map(|name| format!("`{}`", name))
+                .collect::<Vec<String>>()
+                .join(", ");
+            format!("fields {}", fields)
+        };
+        let mut diag = struct_span_err!(
+            self.tcx.sess, span, E0027,
+            "pattern does not mention {}",
+            field_names
+        );
+        diag.span_label(span, format!("missing {}", field_names));
+        if variant.ctor_kind == CtorKind::Fn {
+            diag.note("trying to match a tuple variant with a struct variant pattern");
+        }
+        if self.tcx.sess.teach(&diag.get_code().unwrap()) {
+            diag.note(
+                "This error indicates that a pattern for a struct fails to specify a \
+                    sub-pattern for every one of the struct's fields. Ensure that each field \
+                    from the struct's definition is mentioned in the pattern, or use `..` to \
+                    ignore unwanted fields."
+            );
+        }
+        diag.emit();
+    }
+
     fn check_pat_box(
         &self,
         span: Span,

From 5fbfcd88728a2c2c6400868fbd19117527d81e0b Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 17:54:33 +0200
Subject: [PATCH 197/943] typeck/pat.rs: extract `error_inexistent_fields`.

---
 src/librustc_typeck/check/pat.rs | 130 ++++++++++++++++++-------------
 1 file changed, 74 insertions(+), 56 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 265f032179bf6..f0ecbd674c07d 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -796,66 +796,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             self.check_pat(&field.pat, field_ty, def_bm, None);
         }
+
         let mut unmentioned_fields = variant.fields
                 .iter()
                 .map(|field| field.ident.modern())
                 .filter(|ident| !used_fields.contains_key(&ident))
                 .collect::<Vec<_>>();
-        if inexistent_fields.len() > 0 && !variant.recovered {
-            let (field_names, t, plural) = if inexistent_fields.len() == 1 {
-                (format!("a field named `{}`", inexistent_fields[0]), "this", "")
-            } else {
-                (format!("fields named {}",
-                         inexistent_fields.iter()
-                            .map(|ident| format!("`{}`", ident))
-                            .collect::<Vec<String>>()
-                            .join(", ")), "these", "s")
-            };
-            let spans = inexistent_fields.iter().map(|ident| ident.span).collect::<Vec<_>>();
-            let mut err = struct_span_err!(tcx.sess,
-                                           spans,
-                                           E0026,
-                                           "{} `{}` does not have {}",
-                                           kind_name,
-                                           tcx.def_path_str(variant.def_id),
-                                           field_names);
-            if let Some(ident) = inexistent_fields.last() {
-                err.span_label(ident.span,
-                               format!("{} `{}` does not have {} field{}",
-                                       kind_name,
-                                       tcx.def_path_str(variant.def_id),
-                                       t,
-                                       plural));
-                if plural == "" {
-                    let input = unmentioned_fields.iter().map(|field| &field.name);
-                    let suggested_name =
-                        find_best_match_for_name(input, &ident.as_str(), None);
-                    if let Some(suggested_name) = suggested_name {
-                        err.span_suggestion(
-                            ident.span,
-                            "a field with a similar name exists",
-                            suggested_name.to_string(),
-                            Applicability::MaybeIncorrect,
-                        );
 
-                        // we don't want to throw `E0027` in case we have thrown `E0026` for them
-                        unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
-                    }
-                }
-            }
-            if tcx.sess.teach(&err.get_code().unwrap()) {
-                err.note(
-                    "This error indicates that a struct pattern attempted to \
-                     extract a non-existent field from a struct. Struct fields \
-                     are identified by the name used before the colon : so struct \
-                     patterns should resemble the declaration of the struct type \
-                     being matched.\n\n\
-                     If you are using shorthand field patterns but want to refer \
-                     to the struct field by a different name, you should rename \
-                     it explicitly."
-                );
-            }
-            err.emit();
+        if inexistent_fields.len() > 0 && !variant.recovered {
+            self.error_inexistent_fields(
+                kind_name,
+                &inexistent_fields,
+                &mut unmentioned_fields,
+                variant
+            );
         }
 
         // Require `..` if struct has non_exhaustive attribute.
@@ -874,7 +828,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 tcx.sess.span_err(span, "`..` cannot be used in union patterns");
             }
         } else if !etc && unmentioned_fields.len() > 0 {
-            self.error_unmentioned_fields(span, unmentioned_fields, variant);
+            self.error_unmentioned_fields(span, &unmentioned_fields, variant);
         }
         no_field_errors
     }
@@ -890,10 +844,74 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         .emit();
     }
 
+    fn error_inexistent_fields(
+        &self,
+        kind_name: &str,
+        inexistent_fields: &[ast::Ident],
+        unmentioned_fields: &mut Vec<ast::Ident>,
+        variant: &ty::VariantDef,
+    ) {
+        let tcx = self.tcx;
+        let (field_names, t, plural) = if inexistent_fields.len() == 1 {
+            (format!("a field named `{}`", inexistent_fields[0]), "this", "")
+        } else {
+            (format!("fields named {}",
+                        inexistent_fields.iter()
+                        .map(|ident| format!("`{}`", ident))
+                        .collect::<Vec<String>>()
+                        .join(", ")), "these", "s")
+        };
+        let spans = inexistent_fields.iter().map(|ident| ident.span).collect::<Vec<_>>();
+        let mut err = struct_span_err!(tcx.sess,
+                                        spans,
+                                        E0026,
+                                        "{} `{}` does not have {}",
+                                        kind_name,
+                                        tcx.def_path_str(variant.def_id),
+                                        field_names);
+        if let Some(ident) = inexistent_fields.last() {
+            err.span_label(ident.span,
+                            format!("{} `{}` does not have {} field{}",
+                                    kind_name,
+                                    tcx.def_path_str(variant.def_id),
+                                    t,
+                                    plural));
+            if plural == "" {
+                let input = unmentioned_fields.iter().map(|field| &field.name);
+                let suggested_name =
+                    find_best_match_for_name(input, &ident.as_str(), None);
+                if let Some(suggested_name) = suggested_name {
+                    err.span_suggestion(
+                        ident.span,
+                        "a field with a similar name exists",
+                        suggested_name.to_string(),
+                        Applicability::MaybeIncorrect,
+                    );
+
+                    // we don't want to throw `E0027` in case we have thrown `E0026` for them
+                    unmentioned_fields.retain(|&x| x.as_str() != suggested_name.as_str());
+                }
+            }
+        }
+        if tcx.sess.teach(&err.get_code().unwrap()) {
+            err.note(
+                "This error indicates that a struct pattern attempted to \
+                    extract a non-existent field from a struct. Struct fields \
+                    are identified by the name used before the colon : so struct \
+                    patterns should resemble the declaration of the struct type \
+                    being matched.\n\n\
+                    If you are using shorthand field patterns but want to refer \
+                    to the struct field by a different name, you should rename \
+                    it explicitly."
+            );
+        }
+        err.emit();
+    }
+
     fn error_unmentioned_fields(
         &self,
         span: Span,
-        unmentioned_fields: Vec<ast::Ident>,
+        unmentioned_fields: &[ast::Ident],
         variant: &ty::VariantDef,
     ) {
         let field_names = if unmentioned_fields.len() == 1 {

From a4b3dbe4c1b225b4b911438861e98e4b1aa70183 Mon Sep 17 00:00:00 2001
From: Edd Barrett <vext01@gmail.com>
Date: Tue, 23 Jul 2019 10:30:13 +0100
Subject: [PATCH 198/943] Improve the documentation for std::hint::black_box.

---
 src/libcore/hint.rs | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 519212bb6cb4e..3aba07f882d97 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -104,11 +104,19 @@ pub fn spin_loop() {
     }
 }
 
-/// A function that is opaque to the optimizer, to allow benchmarks to
-/// pretend to use outputs to assist in avoiding dead-code
-/// elimination.
+/// An identity function that *__hints__* to the compiler to be maximally pessimistic about what
+/// `black_box` could do.
 ///
-/// This function is a no-op, and does not even read from `dummy`.
+/// [`std::convert::identity`]: https://doc.rust-lang.org/core/convert/fn.identity.html
+///
+/// Unlike [`std::convert::identity`], a Rust compiler is encouraged to assume that `black_box` can
+/// use `x` in any possible valid way that Rust code is allowed to without introducing undefined
+/// behavior in the calling code. This property makes `black_box` useful for writing code in which
+/// certain optimizations are not desired, such as benchmarks.
+///
+/// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The
+/// extent to which it can block optimisations may vary depending upon the platform and code-gen
+/// backend used. Programs cannot rely on `black_box` for *correctness* in any way.
 #[inline]
 #[unstable(feature = "test", issue = "27812")]
 #[allow(unreachable_code)] // this makes #[cfg] a bit easier below.

From 5299d8a191246cf55c8ead7b8be68c8aeca78d35 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 15:28:14 +0200
Subject: [PATCH 199/943] parser: extract `ban_unexpected_or_or`.

---
 src/libsyntax/parse/parser/pat.rs | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 8cfa6abbe6270..4cda14907e46c 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -31,14 +31,7 @@ impl<'a> Parser<'a> {
             pats.push(self.parse_top_level_pat()?);
 
             if self.token == token::OrOr {
-                self.struct_span_err(self.token.span, "unexpected token `||` after pattern")
-                    .span_suggestion(
-                        self.token.span,
-                        "use a single `|` to specify multiple patterns",
-                        "|".to_owned(),
-                        Applicability::MachineApplicable
-                    )
-                    .emit();
+                self.ban_unexpected_or_or();
                 self.bump();
             } else if self.eat(&token::BinOp(token::Or)) {
                 // This is a No-op. Continue the loop to parse the next
@@ -49,6 +42,17 @@ impl<'a> Parser<'a> {
         };
     }
 
+    fn ban_unexpected_or_or(&mut self) {
+        self.struct_span_err(self.token.span, "unexpected token `||` after pattern")
+            .span_suggestion(
+                self.token.span,
+                "use a single `|` to specify multiple patterns",
+                "|".to_owned(),
+                Applicability::MachineApplicable
+            )
+            .emit();
+    }
+
     /// A wrapper around `parse_pat` with some special error handling for the
     /// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contrast
     /// to subpatterns within such).
@@ -116,9 +120,7 @@ impl<'a> Parser<'a> {
         let mut pats = vec![first_pat];
 
         while self.eat(&token::BinOp(token::Or)) {
-            pats.push(self.parse_pat_with_range_pat(
-                true, expected
-            )?);
+            pats.push(self.parse_pat_with_range_pat(true, expected)?);
         }
 
         let or_pattern_span = lo.to(self.prev_span);

From 1ba7550a8996cffc07c6af89dcd6e1cdc63b24cf Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 15:31:34 +0200
Subject: [PATCH 200/943] parser: type alias `type Expected = Option<&'static
 str>;`.

---
 src/libsyntax/parse/parser/pat.rs | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 4cda14907e46c..36d5ed5c4aa64 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -12,12 +12,11 @@ use crate::ThinVec;
 
 use errors::{Applicability, DiagnosticBuilder};
 
+type Expected = Option<&'static str>;
+
 impl<'a> Parser<'a> {
     /// Parses a pattern.
-    pub fn parse_pat(
-        &mut self,
-        expected: Option<&'static str>
-    ) -> PResult<'a, P<Pat>> {
+    pub fn parse_pat(&mut self, expected: Expected) -> PResult<'a, P<Pat>> {
         self.parse_pat_with_range_pat(true, expected)
     }
 
@@ -105,7 +104,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a pattern, that may be a or-pattern (e.g. `Some(Foo | Bar)`).
-    fn parse_pat_with_or(&mut self, expected: Option<&'static str>) -> PResult<'a, P<Pat>> {
+    fn parse_pat_with_or(&mut self, expected: Expected) -> PResult<'a, P<Pat>> {
         // Parse the first pattern.
         let first_pat = self.parse_pat(expected)?;
 
@@ -135,7 +134,7 @@ impl<'a> Parser<'a> {
     fn parse_pat_with_range_pat(
         &mut self,
         allow_range_pat: bool,
-        expected: Option<&'static str>,
+        expected: Expected,
     ) -> PResult<'a, P<Pat>> {
         maybe_recover_from_interpolated_ty_qpath!(self, true);
         maybe_whole!(self, NtPat, |x| x);
@@ -257,7 +256,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse `&pat` / `&mut pat`.
-    fn parse_pat_deref(&mut self, expected: Option<&'static str>) -> PResult<'a, PatKind> {
+    fn parse_pat_deref(&mut self, expected: Expected) -> PResult<'a, PatKind> {
         self.expect_and()?;
         let mutbl = self.parse_mutability();
 
@@ -363,7 +362,7 @@ impl<'a> Parser<'a> {
     fn fatal_unexpected_non_pat(
         &mut self,
         mut err: DiagnosticBuilder<'a>,
-        expected: Option<&'static str>,
+        expected: Expected,
     ) -> PResult<'a, P<Pat>> {
         self.cancel(&mut err);
 

From 0bbea47794d28f78cf313fde475a35a83d0e9842 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 15:45:44 +0200
Subject: [PATCH 201/943] parser: refactor `parse_pat_with_or` + use it in [p0,
 p1, ..] pats.

---
 src/libsyntax/parse/parser/pat.rs | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 36d5ed5c4aa64..ca5a9f2a5a882 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -104,12 +104,12 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a pattern, that may be a or-pattern (e.g. `Some(Foo | Bar)`).
-    fn parse_pat_with_or(&mut self, expected: Expected) -> PResult<'a, P<Pat>> {
+    fn parse_pat_with_or(&mut self, expected: Expected, gate_or: bool) -> PResult<'a, P<Pat>> {
         // Parse the first pattern.
         let first_pat = self.parse_pat(expected)?;
 
-        // If the next token is not a `|`, this is not an or-pattern and
-        // we should exit here.
+        // If the next token is not a `|`,
+        // this is not an or-pattern and we should exit here.
         if !self.check(&token::BinOp(token::Or)) {
             return Ok(first_pat)
         }
@@ -124,7 +124,10 @@ impl<'a> Parser<'a> {
 
         let or_pattern_span = lo.to(self.prev_span);
 
-        self.sess.gated_spans.or_patterns.borrow_mut().push(or_pattern_span);
+        // Feature gate the or-pattern if instructed:
+        if gate_or {
+            self.sess.gated_spans.or_patterns.borrow_mut().push(or_pattern_span);
+        }
 
         Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats)))
     }
@@ -145,7 +148,11 @@ impl<'a> Parser<'a> {
             token::OpenDelim(token::Paren) => self.parse_pat_tuple_or_parens()?,
             token::OpenDelim(token::Bracket) => {
                 // Parse `[pat, pat,...]` as a slice pattern.
-                PatKind::Slice(self.parse_delim_comma_seq(token::Bracket, |p| p.parse_pat(None))?.0)
+                let (pats, _) = self.parse_delim_comma_seq(
+                    token::Bracket,
+                    |p| p.parse_pat_with_or(None, true),
+                )?;
+                PatKind::Slice(pats)
             }
             token::DotDot => {
                 self.bump();
@@ -273,7 +280,7 @@ impl<'a> Parser<'a> {
     /// Parse a tuple or parenthesis pattern.
     fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> {
         let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| {
-            p.parse_pat_with_or(None)
+            p.parse_pat_with_or(None, true)
         })?;
 
         // Here, `(pat,)` is a tuple pattern.
@@ -517,7 +524,7 @@ impl<'a> Parser<'a> {
             err.span_label(self.token.span, msg);
             return Err(err);
         }
-        let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or(None))?;
+        let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or(None, true))?;
         Ok(PatKind::TupleStruct(path, fields))
     }
 
@@ -661,7 +668,7 @@ impl<'a> Parser<'a> {
             // Parsing a pattern of the form "fieldname: pat"
             let fieldname = self.parse_field_name()?;
             self.bump();
-            let pat = self.parse_pat_with_or(None)?;
+            let pat = self.parse_pat_with_or(None, true)?;
             hi = pat.span;
             (pat, fieldname, false)
         } else {

From 30b841dce0a1c0f26588f4b5791a9eda1c1f42f4 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 16:35:19 +0200
Subject: [PATCH 202/943] parser: improve or-patterns recovery.

---
 src/libsyntax/parse/parser/pat.rs | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index ca5a9f2a5a882..e52d0bc9d483b 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -110,18 +110,25 @@ impl<'a> Parser<'a> {
 
         // If the next token is not a `|`,
         // this is not an or-pattern and we should exit here.
-        if !self.check(&token::BinOp(token::Or)) {
+        if !self.check(&token::BinOp(token::Or)) && self.token != token::OrOr {
             return Ok(first_pat)
         }
 
         let lo = first_pat.span;
-
         let mut pats = vec![first_pat];
+        loop {
+            if self.token == token::OrOr {
+                // Found `||`; Recover and pretend we parsed `|`.
+                self.ban_unexpected_or_or();
+                self.bump();
+            } else if self.eat(&token::BinOp(token::Or)) {
+                // Found `|`. Working towards a proper or-pattern.
+            } else {
+                break;
+            }
 
-        while self.eat(&token::BinOp(token::Or)) {
             pats.push(self.parse_pat_with_range_pat(true, expected)?);
         }
-
         let or_pattern_span = lo.to(self.prev_span);
 
         // Feature gate the or-pattern if instructed:

From d34ee769b061975bf637776052179058c1f00bd7 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 16:45:08 +0200
Subject: [PATCH 203/943] parser: move `multiple-pattern-typo` -> `or-patterns`
 directory.

---
 .../ui/{did_you_mean => or-patterns}/multiple-pattern-typo.rs     | 0
 .../ui/{did_you_mean => or-patterns}/multiple-pattern-typo.stderr | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename src/test/ui/{did_you_mean => or-patterns}/multiple-pattern-typo.rs (100%)
 rename src/test/ui/{did_you_mean => or-patterns}/multiple-pattern-typo.stderr (100%)

diff --git a/src/test/ui/did_you_mean/multiple-pattern-typo.rs b/src/test/ui/or-patterns/multiple-pattern-typo.rs
similarity index 100%
rename from src/test/ui/did_you_mean/multiple-pattern-typo.rs
rename to src/test/ui/or-patterns/multiple-pattern-typo.rs
diff --git a/src/test/ui/did_you_mean/multiple-pattern-typo.stderr b/src/test/ui/or-patterns/multiple-pattern-typo.stderr
similarity index 100%
rename from src/test/ui/did_you_mean/multiple-pattern-typo.stderr
rename to src/test/ui/or-patterns/multiple-pattern-typo.stderr

From 5f57feec0a3038ffc085ba897717b4ffd75445ee Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 16:52:49 +0200
Subject: [PATCH 204/943] parser: `multiple-pattern-typo`: cover more
 or-pattern places.

---
 .../ui/or-patterns/multiple-pattern-typo.rs   | 33 +++++++++++++++
 .../or-patterns/multiple-pattern-typo.stderr  | 42 ++++++++++++++++++-
 2 files changed, 73 insertions(+), 2 deletions(-)

diff --git a/src/test/ui/or-patterns/multiple-pattern-typo.rs b/src/test/ui/or-patterns/multiple-pattern-typo.rs
index 14ad33d53b08c..5d1da56674ba4 100644
--- a/src/test/ui/or-patterns/multiple-pattern-typo.rs
+++ b/src/test/ui/or-patterns/multiple-pattern-typo.rs
@@ -1,7 +1,40 @@
+#![feature(or_patterns)]
+//~^ WARN the feature `or_patterns` is incomplete and may cause the compiler to crash
+
 fn main() {
     let x = 3;
+
     match x {
         1 | 2 || 3 => (), //~ ERROR unexpected token `||` after pattern
         _ => (),
     }
+
+    match x {
+        (1 | 2 || 3) => (), //~ ERROR unexpected token `||` after pattern
+        _ => (),
+    }
+
+    match (x,) {
+        (1 | 2 || 3,) => (), //~ ERROR unexpected token `||` after pattern
+        _ => (),
+    }
+
+    struct TS(u8);
+
+    match TS(x) {
+        TS(1 | 2 || 3) => (), //~ ERROR unexpected token `||` after pattern
+        _ => (),
+    }
+
+    struct NS { f: u8 }
+
+    match (NS { f: x }) {
+        NS { f: 1 | 2 || 3 } => (), //~ ERROR unexpected token `||` after pattern
+        _ => (),
+    }
+
+    match [x] {
+        [1 | 2 || 3] => (), //~ ERROR unexpected token `||` after pattern
+        _ => (),
+    }
 }
diff --git a/src/test/ui/or-patterns/multiple-pattern-typo.stderr b/src/test/ui/or-patterns/multiple-pattern-typo.stderr
index a29fa584b2924..97f3470a54aa2 100644
--- a/src/test/ui/or-patterns/multiple-pattern-typo.stderr
+++ b/src/test/ui/or-patterns/multiple-pattern-typo.stderr
@@ -1,8 +1,46 @@
 error: unexpected token `||` after pattern
-  --> $DIR/multiple-pattern-typo.rs:4:15
+  --> $DIR/multiple-pattern-typo.rs:8:15
    |
 LL |         1 | 2 || 3 => (),
    |               ^^ help: use a single `|` to specify multiple patterns: `|`
 
-error: aborting due to previous error
+error: unexpected token `||` after pattern
+  --> $DIR/multiple-pattern-typo.rs:13:16
+   |
+LL |         (1 | 2 || 3) => (),
+   |                ^^ help: use a single `|` to specify multiple patterns: `|`
+
+error: unexpected token `||` after pattern
+  --> $DIR/multiple-pattern-typo.rs:18:16
+   |
+LL |         (1 | 2 || 3,) => (),
+   |                ^^ help: use a single `|` to specify multiple patterns: `|`
+
+error: unexpected token `||` after pattern
+  --> $DIR/multiple-pattern-typo.rs:25:18
+   |
+LL |         TS(1 | 2 || 3) => (),
+   |                  ^^ help: use a single `|` to specify multiple patterns: `|`
+
+error: unexpected token `||` after pattern
+  --> $DIR/multiple-pattern-typo.rs:32:23
+   |
+LL |         NS { f: 1 | 2 || 3 } => (),
+   |                       ^^ help: use a single `|` to specify multiple patterns: `|`
+
+error: unexpected token `||` after pattern
+  --> $DIR/multiple-pattern-typo.rs:37:16
+   |
+LL |         [1 | 2 || 3] => (),
+   |                ^^ help: use a single `|` to specify multiple patterns: `|`
+
+warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
+  --> $DIR/multiple-pattern-typo.rs:1:12
+   |
+LL | #![feature(or_patterns)]
+   |            ^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: aborting due to 6 previous errors
 

From f852c7ce1c6f55bc816d90c6e7f8e9205bb6c6f2 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 16:55:52 +0200
Subject: [PATCH 205/943] parser: simplify `parse_pat_with_or`.

---
 src/libsyntax/parse/parser/pat.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index e52d0bc9d483b..89688a287a7f3 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -127,7 +127,7 @@ impl<'a> Parser<'a> {
                 break;
             }
 
-            pats.push(self.parse_pat_with_range_pat(true, expected)?);
+            pats.push(self.parse_pat(expected)?);
         }
         let or_pattern_span = lo.to(self.prev_span);
 

From 21d9b85c0da1b639f8d8b3585e08759f96d1c286 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 17:11:12 +0200
Subject: [PATCH 206/943] parser: extract `maybe_recover_unexpected_comma`.

---
 src/libsyntax/parse/parser/pat.rs | 67 +++++++++++++++++--------------
 1 file changed, 36 insertions(+), 31 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 89688a287a7f3..588e5aef8a2f4 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -57,40 +57,45 @@ impl<'a> Parser<'a> {
     /// to subpatterns within such).
     pub(super) fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {
         let pat = self.parse_pat(None)?;
-        if self.token == token::Comma {
-            // An unexpected comma after a top-level pattern is a clue that the
-            // user (perhaps more accustomed to some other language) forgot the
-            // parentheses in what should have been a tuple pattern; return a
-            // suggestion-enhanced error here rather than choking on the comma
-            // later.
-            let comma_span = self.token.span;
-            self.bump();
-            if let Err(mut err) = self.skip_pat_list() {
-                // We didn't expect this to work anyway; we just wanted
-                // to advance to the end of the comma-sequence so we know
-                // the span to suggest parenthesizing
-                err.cancel();
-            }
-            let seq_span = pat.span.to(self.prev_span);
-            let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern");
-            if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
-                err.span_suggestion(
-                    seq_span,
-                    "try adding parentheses to match on a tuple..",
-                    format!("({})", seq_snippet),
-                    Applicability::MachineApplicable
-                ).span_suggestion(
-                    seq_span,
-                    "..or a vertical bar to match on multiple alternatives",
-                    format!("{}", seq_snippet.replace(",", " |")),
-                    Applicability::MachineApplicable
-                );
-            }
-            return Err(err);
-        }
+        self.maybe_recover_unexpected_comma(pat.span)?;
         Ok(pat)
     }
 
+    fn maybe_recover_unexpected_comma(&mut self, lo: Span) -> PResult<'a, ()> {
+        if self.token != token::Comma {
+            return Ok(());
+        }
+
+        // An unexpected comma after a top-level pattern is a clue that the
+        // user (perhaps more accustomed to some other language) forgot the
+        // parentheses in what should have been a tuple pattern; return a
+        // suggestion-enhanced error here rather than choking on the comma later.
+        let comma_span = self.token.span;
+        self.bump();
+        if let Err(mut err) = self.skip_pat_list() {
+            // We didn't expect this to work anyway; we just wanted to advance to the
+            // end of the comma-sequence so we know the span to suggest parenthesizing.
+            err.cancel();
+        }
+        let seq_span = lo.to(self.prev_span);
+        let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern");
+        if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
+            err.span_suggestion(
+                seq_span,
+                "try adding parentheses to match on a tuple..",
+                format!("({})", seq_snippet),
+                Applicability::MachineApplicable
+            )
+            .span_suggestion(
+                seq_span,
+                "..or a vertical bar to match on multiple alternatives",
+                format!("{}", seq_snippet.replace(",", " |")),
+                Applicability::MachineApplicable
+            );
+        }
+        Err(err)
+    }
+
     /// Parse and throw away a parentesized comma separated
     /// sequence of patterns until `)` is reached.
     fn skip_pat_list(&mut self) -> PResult<'a, ()> {

From a4a34ab62df777e885cac71ab171225b2cd1a812 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 17:44:27 +0200
Subject: [PATCH 207/943] parser: integrate `maybe_recover_unexpected_comma` in
 `parse_pat_with_or`.

---
 src/libsyntax/parse/parser/pat.rs | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 588e5aef8a2f4..b2a026d0071e4 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -57,12 +57,12 @@ impl<'a> Parser<'a> {
     /// to subpatterns within such).
     pub(super) fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {
         let pat = self.parse_pat(None)?;
-        self.maybe_recover_unexpected_comma(pat.span)?;
+        self.maybe_recover_unexpected_comma(pat.span, true)?;
         Ok(pat)
     }
 
-    fn maybe_recover_unexpected_comma(&mut self, lo: Span) -> PResult<'a, ()> {
-        if self.token != token::Comma {
+    fn maybe_recover_unexpected_comma(&mut self, lo: Span, top_level: bool) -> PResult<'a, ()> {
+        if !top_level || self.token != token::Comma {
             return Ok(());
         }
 
@@ -109,9 +109,15 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a pattern, that may be a or-pattern (e.g. `Some(Foo | Bar)`).
-    fn parse_pat_with_or(&mut self, expected: Expected, gate_or: bool) -> PResult<'a, P<Pat>> {
+    fn parse_pat_with_or(
+        &mut self,
+        expected: Expected,
+        gate_or: bool,
+        top_level: bool
+    ) -> PResult<'a, P<Pat>> {
         // Parse the first pattern.
         let first_pat = self.parse_pat(expected)?;
+        self.maybe_recover_unexpected_comma(first_pat.span, top_level)?;
 
         // If the next token is not a `|`,
         // this is not an or-pattern and we should exit here.
@@ -132,7 +138,9 @@ impl<'a> Parser<'a> {
                 break;
             }
 
-            pats.push(self.parse_pat(expected)?);
+            let pat = self.parse_pat(expected)?;
+            self.maybe_recover_unexpected_comma(pat.span, top_level)?;
+            pats.push(pat);
         }
         let or_pattern_span = lo.to(self.prev_span);
 
@@ -162,7 +170,7 @@ impl<'a> Parser<'a> {
                 // Parse `[pat, pat,...]` as a slice pattern.
                 let (pats, _) = self.parse_delim_comma_seq(
                     token::Bracket,
-                    |p| p.parse_pat_with_or(None, true),
+                    |p| p.parse_pat_with_or(None, true, false),
                 )?;
                 PatKind::Slice(pats)
             }
@@ -292,7 +300,7 @@ impl<'a> Parser<'a> {
     /// Parse a tuple or parenthesis pattern.
     fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> {
         let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| {
-            p.parse_pat_with_or(None, true)
+            p.parse_pat_with_or(None, true, false)
         })?;
 
         // Here, `(pat,)` is a tuple pattern.
@@ -536,7 +544,7 @@ impl<'a> Parser<'a> {
             err.span_label(self.token.span, msg);
             return Err(err);
         }
-        let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or(None, true))?;
+        let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or(None, true, false))?;
         Ok(PatKind::TupleStruct(path, fields))
     }
 
@@ -680,7 +688,7 @@ impl<'a> Parser<'a> {
             // Parsing a pattern of the form "fieldname: pat"
             let fieldname = self.parse_field_name()?;
             self.bump();
-            let pat = self.parse_pat_with_or(None, true)?;
+            let pat = self.parse_pat_with_or(None, true, false)?;
             hi = pat.span;
             (pat, fieldname, false)
         } else {

From 7b59b4f14dae8c859718d60794021230e1e3ac29 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 18:13:19 +0200
Subject: [PATCH 208/943] parser: extract `eat_or_separator`.

---
 src/libsyntax/parse/parser/pat.rs | 58 +++++++++++++++----------------
 1 file changed, 28 insertions(+), 30 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index b2a026d0071e4..3af64cef74f26 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -29,27 +29,10 @@ impl<'a> Parser<'a> {
         loop {
             pats.push(self.parse_top_level_pat()?);
 
-            if self.token == token::OrOr {
-                self.ban_unexpected_or_or();
-                self.bump();
-            } else if self.eat(&token::BinOp(token::Or)) {
-                // This is a No-op. Continue the loop to parse the next
-                // pattern.
-            } else {
+            if !self.eat_or_separator() {
                 return Ok(pats);
             }
-        };
-    }
-
-    fn ban_unexpected_or_or(&mut self) {
-        self.struct_span_err(self.token.span, "unexpected token `||` after pattern")
-            .span_suggestion(
-                self.token.span,
-                "use a single `|` to specify multiple patterns",
-                "|".to_owned(),
-                Applicability::MachineApplicable
-            )
-            .emit();
+        }
     }
 
     /// A wrapper around `parse_pat` with some special error handling for the
@@ -127,17 +110,7 @@ impl<'a> Parser<'a> {
 
         let lo = first_pat.span;
         let mut pats = vec![first_pat];
-        loop {
-            if self.token == token::OrOr {
-                // Found `||`; Recover and pretend we parsed `|`.
-                self.ban_unexpected_or_or();
-                self.bump();
-            } else if self.eat(&token::BinOp(token::Or)) {
-                // Found `|`. Working towards a proper or-pattern.
-            } else {
-                break;
-            }
-
+        while self.eat_or_separator() {
             let pat = self.parse_pat(expected)?;
             self.maybe_recover_unexpected_comma(pat.span, top_level)?;
             pats.push(pat);
@@ -152,6 +125,31 @@ impl<'a> Parser<'a> {
         Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats)))
     }
 
+    /// Eat the or-pattern `|` separator.
+    /// If instead a `||` token is encountered, recover and pretend we parsed `|`.
+    fn eat_or_separator(&mut self) -> bool {
+        match self.token.kind {
+            token::OrOr => {
+                // Found `||`; Recover and pretend we parsed `|`.
+                self.ban_unexpected_or_or();
+                self.bump();
+                true
+            }
+            _ => self.eat(&token::BinOp(token::Or)),
+        }
+    }
+
+    fn ban_unexpected_or_or(&mut self) {
+        self.struct_span_err(self.token.span, "unexpected token `||` after pattern")
+            .span_suggestion(
+                self.token.span,
+                "use a single `|` to specify multiple patterns",
+                "|".to_owned(),
+                Applicability::MachineApplicable
+            )
+            .emit();
+    }
+
     /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
     /// allowed).
     fn parse_pat_with_range_pat(

From dc5bbaf7b2df8dc2be6c0f1a9973867e5519300b Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 18:15:17 +0200
Subject: [PATCH 209/943] parser: improve `parse_pat_with_or` docs.

---
 src/libsyntax/parse/parser/pat.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 3af64cef74f26..14ac509d6f706 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -91,7 +91,8 @@ impl<'a> Parser<'a> {
         Ok(())
     }
 
-    /// Parses a pattern, that may be a or-pattern (e.g. `Some(Foo | Bar)`).
+    /// Parses a pattern, that may be a or-pattern (e.g. `Foo | Bar` in `Some(Foo | Bar)`).
+    /// Corresponds to `pat<allow_top_alt>` in RFC 2535.
     fn parse_pat_with_or(
         &mut self,
         expected: Expected,

From 6498959377421876040515af39b6491a2ec2a0c5 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 18:34:35 +0200
Subject: [PATCH 210/943] parser: use `eat_or_separator` for leading vert.

---
 src/libsyntax/parse/parser/pat.rs                    | 4 ++--
 src/test/ui/or-patterns/multiple-pattern-typo.rs     | 5 +++++
 src/test/ui/or-patterns/multiple-pattern-typo.stderr | 8 +++++++-
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 14ac509d6f706..1063e34753095 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -22,8 +22,8 @@ impl<'a> Parser<'a> {
 
     /// Parses patterns, separated by '|' s.
     pub(super) fn parse_pats(&mut self) -> PResult<'a, Vec<P<Pat>>> {
-        // Allow a '|' before the pats (RFC 1925 + RFC 2530)
-        self.eat(&token::BinOp(token::Or));
+        // Allow a '|' before the pats (RFCs 1925, 2530, and 2535).
+        self.eat_or_separator();
 
         let mut pats = Vec::new();
         loop {
diff --git a/src/test/ui/or-patterns/multiple-pattern-typo.rs b/src/test/ui/or-patterns/multiple-pattern-typo.rs
index 5d1da56674ba4..e308c0adb4eb8 100644
--- a/src/test/ui/or-patterns/multiple-pattern-typo.rs
+++ b/src/test/ui/or-patterns/multiple-pattern-typo.rs
@@ -37,4 +37,9 @@ fn main() {
         [1 | 2 || 3] => (), //~ ERROR unexpected token `||` after pattern
         _ => (),
     }
+
+    match x {
+        || 1 | 2 | 3 => (), //~ ERROR unexpected token `||` after pattern
+        _ => (),
+    }
 }
diff --git a/src/test/ui/or-patterns/multiple-pattern-typo.stderr b/src/test/ui/or-patterns/multiple-pattern-typo.stderr
index 97f3470a54aa2..765c7879b12ca 100644
--- a/src/test/ui/or-patterns/multiple-pattern-typo.stderr
+++ b/src/test/ui/or-patterns/multiple-pattern-typo.stderr
@@ -34,6 +34,12 @@ error: unexpected token `||` after pattern
 LL |         [1 | 2 || 3] => (),
    |                ^^ help: use a single `|` to specify multiple patterns: `|`
 
+error: unexpected token `||` after pattern
+  --> $DIR/multiple-pattern-typo.rs:42:9
+   |
+LL |         || 1 | 2 | 3 => (),
+   |         ^^ help: use a single `|` to specify multiple patterns: `|`
+
 warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
   --> $DIR/multiple-pattern-typo.rs:1:12
    |
@@ -42,5 +48,5 @@ LL | #![feature(or_patterns)]
    |
    = note: `#[warn(incomplete_features)]` on by default
 
-error: aborting due to 6 previous errors
+error: aborting due to 7 previous errors
 

From 39f5e5bec42a4c05588db45d12ab9aafc01776aa Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 18:37:41 +0200
Subject: [PATCH 211/943] parser: move `maybe_recover_unexpected_comma` to a
 more appropriate place.

---
 src/libsyntax/parse/parser/pat.rs | 99 +++++++++++++++----------------
 1 file changed, 49 insertions(+), 50 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 1063e34753095..680a587205686 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -35,62 +35,12 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// A wrapper around `parse_pat` with some special error handling for the
-    /// "top-level" patterns in a match arm, `for` loop, `let`, &c. (in contrast
-    /// to subpatterns within such).
     pub(super) fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {
         let pat = self.parse_pat(None)?;
         self.maybe_recover_unexpected_comma(pat.span, true)?;
         Ok(pat)
     }
 
-    fn maybe_recover_unexpected_comma(&mut self, lo: Span, top_level: bool) -> PResult<'a, ()> {
-        if !top_level || self.token != token::Comma {
-            return Ok(());
-        }
-
-        // An unexpected comma after a top-level pattern is a clue that the
-        // user (perhaps more accustomed to some other language) forgot the
-        // parentheses in what should have been a tuple pattern; return a
-        // suggestion-enhanced error here rather than choking on the comma later.
-        let comma_span = self.token.span;
-        self.bump();
-        if let Err(mut err) = self.skip_pat_list() {
-            // We didn't expect this to work anyway; we just wanted to advance to the
-            // end of the comma-sequence so we know the span to suggest parenthesizing.
-            err.cancel();
-        }
-        let seq_span = lo.to(self.prev_span);
-        let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern");
-        if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
-            err.span_suggestion(
-                seq_span,
-                "try adding parentheses to match on a tuple..",
-                format!("({})", seq_snippet),
-                Applicability::MachineApplicable
-            )
-            .span_suggestion(
-                seq_span,
-                "..or a vertical bar to match on multiple alternatives",
-                format!("{}", seq_snippet.replace(",", " |")),
-                Applicability::MachineApplicable
-            );
-        }
-        Err(err)
-    }
-
-    /// Parse and throw away a parentesized comma separated
-    /// sequence of patterns until `)` is reached.
-    fn skip_pat_list(&mut self) -> PResult<'a, ()> {
-        while !self.check(&token::CloseDelim(token::Paren)) {
-            self.parse_pat(None)?;
-            if !self.eat(&token::Comma) {
-                return Ok(())
-            }
-        }
-        Ok(())
-    }
-
     /// Parses a pattern, that may be a or-pattern (e.g. `Foo | Bar` in `Some(Foo | Bar)`).
     /// Corresponds to `pat<allow_top_alt>` in RFC 2535.
     fn parse_pat_with_or(
@@ -151,6 +101,55 @@ impl<'a> Parser<'a> {
             .emit();
     }
 
+    /// Some special error handling for the "top-level" patterns in a match arm,
+    /// `for` loop, `let`, &c. (in contrast to subpatterns within such).
+    fn maybe_recover_unexpected_comma(&mut self, lo: Span, top_level: bool) -> PResult<'a, ()> {
+        if !top_level || self.token != token::Comma {
+            return Ok(());
+        }
+
+        // An unexpected comma after a top-level pattern is a clue that the
+        // user (perhaps more accustomed to some other language) forgot the
+        // parentheses in what should have been a tuple pattern; return a
+        // suggestion-enhanced error here rather than choking on the comma later.
+        let comma_span = self.token.span;
+        self.bump();
+        if let Err(mut err) = self.skip_pat_list() {
+            // We didn't expect this to work anyway; we just wanted to advance to the
+            // end of the comma-sequence so we know the span to suggest parenthesizing.
+            err.cancel();
+        }
+        let seq_span = lo.to(self.prev_span);
+        let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern");
+        if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
+            err.span_suggestion(
+                seq_span,
+                "try adding parentheses to match on a tuple..",
+                format!("({})", seq_snippet),
+                Applicability::MachineApplicable
+            )
+            .span_suggestion(
+                seq_span,
+                "..or a vertical bar to match on multiple alternatives",
+                format!("{}", seq_snippet.replace(",", " |")),
+                Applicability::MachineApplicable
+            );
+        }
+        Err(err)
+    }
+
+    /// Parse and throw away a parentesized comma separated
+    /// sequence of patterns until `)` is reached.
+    fn skip_pat_list(&mut self) -> PResult<'a, ()> {
+        while !self.check(&token::CloseDelim(token::Paren)) {
+            self.parse_pat(None)?;
+            if !self.eat(&token::Comma) {
+                return Ok(())
+            }
+        }
+        Ok(())
+    }
+
     /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
     /// allowed).
     fn parse_pat_with_range_pat(

From 8f6a0cdb0fd453580bed74586c6930b1498aa26f Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 18:38:36 +0200
Subject: [PATCH 212/943] parser: document `ban_unexpected_or_or`.

---
 src/libsyntax/parse/parser/pat.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 680a587205686..8fab8884ca018 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -90,6 +90,7 @@ impl<'a> Parser<'a> {
         }
     }
 
+    /// We have parsed `||` instead of `|`. Error and suggest `|` instead.
     fn ban_unexpected_or_or(&mut self) {
         self.struct_span_err(self.token.span, "unexpected token `||` after pattern")
             .span_suggestion(

From b7178ef9836fe8e98ffb3f8d4d870c94e6fe816d Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 22:04:28 +0200
Subject: [PATCH 213/943] parser: `parse_pats` -> `parse_top_pat{_unpack}`.

---
 src/libsyntax/parse/parser/expr.rs | 12 +++++++-----
 src/libsyntax/parse/parser/pat.rs  | 28 +++++++++++++++++-----------
 2 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 5da9b75d53b04..b9dd851817160 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -1241,11 +1241,12 @@ impl<'a> Parser<'a> {
         Ok(cond)
     }
 
-    /// Parses a `let $pats = $expr` pseudo-expression.
+    /// Parses a `let $pat = $expr` pseudo-expression.
     /// The `let` token has already been eaten.
     fn parse_let_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         let lo = self.prev_span;
-        let pats = self.parse_pats()?;
+        // FIXME(or_patterns, Centril | dlrobertson): use `parse_top_pat` instead.
+        let pat = self.parse_top_pat_unpack(false)?;
         self.expect(&token::Eq)?;
         let expr = self.with_res(
             Restrictions::NO_STRUCT_LITERAL,
@@ -1253,7 +1254,7 @@ impl<'a> Parser<'a> {
         )?;
         let span = lo.to(expr.span);
         self.sess.gated_spans.let_chains.borrow_mut().push(span);
-        Ok(self.mk_expr(span, ExprKind::Let(pats, expr), attrs))
+        Ok(self.mk_expr(span, ExprKind::Let(pat, expr), attrs))
     }
 
     /// `else` token already eaten
@@ -1387,7 +1388,8 @@ impl<'a> Parser<'a> {
     crate fn parse_arm(&mut self) -> PResult<'a, Arm> {
         let attrs = self.parse_outer_attributes()?;
         let lo = self.token.span;
-        let pats = self.parse_pats()?;
+        // FIXME(or_patterns, Centril | dlrobertson): use `parse_top_pat` instead.
+        let pat = self.parse_top_pat_unpack(false)?;
         let guard = if self.eat_keyword(kw::If) {
             Some(self.parse_expr()?)
         } else {
@@ -1448,7 +1450,7 @@ impl<'a> Parser<'a> {
 
         Ok(ast::Arm {
             attrs,
-            pats,
+            pats: pat, // FIXME(or_patterns, Centril | dlrobertson): this should just be `pat,`.
             guard,
             body: expr,
             span: lo.to(hi),
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 8fab8884ca018..e4a9dc0097752 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -20,19 +20,25 @@ impl<'a> Parser<'a> {
         self.parse_pat_with_range_pat(true, expected)
     }
 
-    /// Parses patterns, separated by '|' s.
-    pub(super) fn parse_pats(&mut self) -> PResult<'a, Vec<P<Pat>>> {
-        // Allow a '|' before the pats (RFCs 1925, 2530, and 2535).
-        self.eat_or_separator();
-
-        let mut pats = Vec::new();
-        loop {
-            pats.push(self.parse_top_level_pat()?);
+    // FIXME(or_patterns, Centril | dlrobertson):
+    // remove this and use `parse_top_pat` everywhere it is used instead.
+    pub(super) fn parse_top_pat_unpack(&mut self, gate_or: bool) -> PResult<'a, Vec<P<Pat>>> {
+        self.parse_top_pat(gate_or)
+            .map(|pat| pat.and_then(|pat| match pat.node {
+                PatKind::Or(pats) => pats,
+                node => vec![self.mk_pat(pat.span, node)],
+            }))
+    }
 
-            if !self.eat_or_separator() {
-                return Ok(pats);
-            }
+    /// Entry point to the main pattern parser.
+    /// Corresponds to `top_pat` in RFC 2535 and allows or-pattern at the top level.
+    pub(super) fn parse_top_pat(&mut self, gate_or: bool) -> PResult<'a, P<Pat>> {
+        // Allow a '|' before the pats (RFCs 1925, 2530, and 2535).
+        if self.eat_or_separator() && gate_or {
+            self.sess.gated_spans.or_patterns.borrow_mut().push(self.prev_span);
         }
+
+        self.parse_pat_with_or(None, gate_or, true)
     }
 
     pub(super) fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {

From 92d66a131711bc7817e599c81d081847f689654c Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 22:35:53 +0200
Subject: [PATCH 214/943] parser: document `parse_pat`.

---
 src/libsyntax/parse/parser/pat.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index e4a9dc0097752..021e52798af26 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -16,6 +16,10 @@ type Expected = Option<&'static str>;
 
 impl<'a> Parser<'a> {
     /// Parses a pattern.
+    ///
+    /// Corresponds to `pat<no_top_alt>` in RFC 2535 and does not admit or-patterns
+    /// at the top level. Used when parsing the parameters of lambda expressions,
+    /// functions, function pointers, and `pat` macro fragments.
     pub fn parse_pat(&mut self, expected: Expected) -> PResult<'a, P<Pat>> {
         self.parse_pat_with_range_pat(true, expected)
     }

From 95792b4d5a12276068e32f54c5d1561b8528a952 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 22:54:07 +0200
Subject: [PATCH 215/943] parser: `let` stmts & `for` exprs: allow or-patterns.

---
 src/libsyntax/parse/parser/expr.rs         | 2 +-
 src/libsyntax/parse/parser/pat.rs          | 6 ------
 src/libsyntax/parse/parser/stmt.rs         | 2 +-
 src/test/ui/parser/bad-match.rs            | 2 +-
 src/test/ui/parser/bad-match.stderr        | 4 ++--
 src/test/ui/parser/bad-name.stderr         | 4 ++--
 src/test/ui/parser/issue-22647.rs          | 2 +-
 src/test/ui/parser/issue-22647.stderr      | 4 ++--
 src/test/ui/parser/issue-22712.rs          | 2 +-
 src/test/ui/parser/issue-22712.stderr      | 4 ++--
 src/test/ui/parser/issue-24197.rs          | 2 +-
 src/test/ui/parser/issue-24197.stderr      | 4 ++--
 src/test/ui/parser/mut-patterns.rs         | 3 ++-
 src/test/ui/parser/mut-patterns.stderr     | 4 ++--
 src/test/ui/parser/pat-lt-bracket-5.rs     | 2 +-
 src/test/ui/parser/pat-lt-bracket-5.stderr | 4 ++--
 src/test/ui/parser/pat-ranges-1.rs         | 2 +-
 src/test/ui/parser/pat-ranges-1.stderr     | 4 ++--
 src/test/ui/parser/pat-ranges-2.rs         | 2 +-
 src/test/ui/parser/pat-ranges-2.stderr     | 4 ++--
 src/test/ui/parser/pat-ranges-3.rs         | 2 +-
 src/test/ui/parser/pat-ranges-3.stderr     | 4 ++--
 src/test/ui/parser/pat-ranges-4.rs         | 2 +-
 src/test/ui/parser/pat-ranges-4.stderr     | 4 ++--
 24 files changed, 35 insertions(+), 40 deletions(-)

diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index b9dd851817160..25a858b47353f 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -1284,7 +1284,7 @@ impl<'a> Parser<'a> {
             _ => None,
         };
 
-        let pat = self.parse_top_level_pat()?;
+        let pat = self.parse_top_pat(true)?;
         if !self.eat_keyword(kw::In) {
             let in_span = self.prev_span.between(self.token.span);
             self.struct_span_err(in_span, "missing `in` in `for` loop")
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 021e52798af26..e77d9120bce78 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -45,12 +45,6 @@ impl<'a> Parser<'a> {
         self.parse_pat_with_or(None, gate_or, true)
     }
 
-    pub(super) fn parse_top_level_pat(&mut self) -> PResult<'a, P<Pat>> {
-        let pat = self.parse_pat(None)?;
-        self.maybe_recover_unexpected_comma(pat.span, true)?;
-        Ok(pat)
-    }
-
     /// Parses a pattern, that may be a or-pattern (e.g. `Foo | Bar` in `Some(Foo | Bar)`).
     /// Corresponds to `pat<allow_top_alt>` in RFC 2535.
     fn parse_pat_with_or(
diff --git a/src/libsyntax/parse/parser/stmt.rs b/src/libsyntax/parse/parser/stmt.rs
index c911caba4cd41..3c8cb4ea5a582 100644
--- a/src/libsyntax/parse/parser/stmt.rs
+++ b/src/libsyntax/parse/parser/stmt.rs
@@ -207,7 +207,7 @@ impl<'a> Parser<'a> {
     /// Parses a local variable declaration.
     fn parse_local(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Local>> {
         let lo = self.prev_span;
-        let pat = self.parse_top_level_pat()?;
+        let pat = self.parse_top_pat(true)?;
 
         let (err, ty) = if self.eat(&token::Colon) {
             // Save the state of the parser before parsing type normally, in case there is a `:`
diff --git a/src/test/ui/parser/bad-match.rs b/src/test/ui/parser/bad-match.rs
index 79bc7eec3113e..04100d1701ddb 100644
--- a/src/test/ui/parser/bad-match.rs
+++ b/src/test/ui/parser/bad-match.rs
@@ -1,4 +1,4 @@
 fn main() {
-  let isize x = 5; //~ ERROR expected one of `:`, `;`, `=`, or `@`, found `x`
+  let isize x = 5; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `x`
   match x;
 }
diff --git a/src/test/ui/parser/bad-match.stderr b/src/test/ui/parser/bad-match.stderr
index 2f29b978e9c91..d5baaf5e93b35 100644
--- a/src/test/ui/parser/bad-match.stderr
+++ b/src/test/ui/parser/bad-match.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:`, `;`, `=`, or `@`, found `x`
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `x`
   --> $DIR/bad-match.rs:2:13
    |
 LL |   let isize x = 5;
-   |             ^ expected one of `:`, `;`, `=`, or `@` here
+   |             ^ expected one of `:`, `;`, `=`, `@`, or `|` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/bad-name.stderr b/src/test/ui/parser/bad-name.stderr
index 15e61cf06cae9..dce4dabedf5c8 100644
--- a/src/test/ui/parser/bad-name.stderr
+++ b/src/test/ui/parser/bad-name.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:`, `;`, `=`, or `@`, found `.`
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
   --> $DIR/bad-name.rs:4:8
    |
 LL |   let x.y::<isize>.z foo;
-   |        ^ expected one of `:`, `;`, `=`, or `@` here
+   |        ^ expected one of `:`, `;`, `=`, `@`, or `|` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-22647.rs b/src/test/ui/parser/issue-22647.rs
index 25cd7ffce5a97..a6861410682cb 100644
--- a/src/test/ui/parser/issue-22647.rs
+++ b/src/test/ui/parser/issue-22647.rs
@@ -1,5 +1,5 @@
 fn main() {
-    let caller<F> = |f: F|  //~ ERROR expected one of `:`, `;`, `=`, or `@`, found `<`
+    let caller<F> = |f: F|  //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
     where F: Fn() -> i32
     {
         let x = f();
diff --git a/src/test/ui/parser/issue-22647.stderr b/src/test/ui/parser/issue-22647.stderr
index 2dc56a5eca3a6..4b1ef4f3dfc78 100644
--- a/src/test/ui/parser/issue-22647.stderr
+++ b/src/test/ui/parser/issue-22647.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:`, `;`, `=`, or `@`, found `<`
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
   --> $DIR/issue-22647.rs:2:15
    |
 LL |     let caller<F> = |f: F|
-   |               ^ expected one of `:`, `;`, `=`, or `@` here
+   |               ^ expected one of `:`, `;`, `=`, `@`, or `|` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-22712.rs b/src/test/ui/parser/issue-22712.rs
index b03d578e3d638..774de9c7e6448 100644
--- a/src/test/ui/parser/issue-22712.rs
+++ b/src/test/ui/parser/issue-22712.rs
@@ -3,7 +3,7 @@ struct Foo<B> {
 }
 
 fn bar() {
-    let Foo<Vec<u8>>  //~ ERROR expected one of `:`, `;`, `=`, or `@`, found `<`
+    let Foo<Vec<u8>>  //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
 }
 
 fn main() {}
diff --git a/src/test/ui/parser/issue-22712.stderr b/src/test/ui/parser/issue-22712.stderr
index 167eaf962e0f4..d9e83144b367a 100644
--- a/src/test/ui/parser/issue-22712.stderr
+++ b/src/test/ui/parser/issue-22712.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:`, `;`, `=`, or `@`, found `<`
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
   --> $DIR/issue-22712.rs:6:12
    |
 LL |     let Foo<Vec<u8>>
-   |            ^ expected one of `:`, `;`, `=`, or `@` here
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-24197.rs b/src/test/ui/parser/issue-24197.rs
index 005ff9fa2e0ec..aaf5137461fa6 100644
--- a/src/test/ui/parser/issue-24197.rs
+++ b/src/test/ui/parser/issue-24197.rs
@@ -1,3 +1,3 @@
 fn main() {
-    let buf[0] = 0; //~ ERROR expected one of `:`, `;`, `=`, or `@`, found `[`
+    let buf[0] = 0; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
 }
diff --git a/src/test/ui/parser/issue-24197.stderr b/src/test/ui/parser/issue-24197.stderr
index 2dfb31432bc99..24818db622ad4 100644
--- a/src/test/ui/parser/issue-24197.stderr
+++ b/src/test/ui/parser/issue-24197.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:`, `;`, `=`, or `@`, found `[`
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
   --> $DIR/issue-24197.rs:2:12
    |
 LL |     let buf[0] = 0;
-   |            ^ expected one of `:`, `;`, `=`, or `@` here
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/mut-patterns.rs b/src/test/ui/parser/mut-patterns.rs
index a5eb48252394f..bffeb1e2e7c40 100644
--- a/src/test/ui/parser/mut-patterns.rs
+++ b/src/test/ui/parser/mut-patterns.rs
@@ -2,5 +2,6 @@
 
 pub fn main() {
     struct Foo { x: isize }
-    let mut Foo { x: x } = Foo { x: 3 }; //~ ERROR: expected one of `:`, `;`, `=`, or `@`, found `{`
+    let mut Foo { x: x } = Foo { x: 3 };
+    //~^ ERROR: expected one of `:`, `;`, `=`, `@`, or `|`, found `{`
 }
diff --git a/src/test/ui/parser/mut-patterns.stderr b/src/test/ui/parser/mut-patterns.stderr
index 286956440ec34..b39209afd4295 100644
--- a/src/test/ui/parser/mut-patterns.stderr
+++ b/src/test/ui/parser/mut-patterns.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:`, `;`, `=`, or `@`, found `{`
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `{`
   --> $DIR/mut-patterns.rs:5:17
    |
 LL |     let mut Foo { x: x } = Foo { x: 3 };
-   |                 ^ expected one of `:`, `;`, `=`, or `@` here
+   |                 ^ expected one of `:`, `;`, `=`, `@`, or `|` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-lt-bracket-5.rs b/src/test/ui/parser/pat-lt-bracket-5.rs
index c4b9dd469f54c..aaece1f6bd9cb 100644
--- a/src/test/ui/parser/pat-lt-bracket-5.rs
+++ b/src/test/ui/parser/pat-lt-bracket-5.rs
@@ -1,3 +1,3 @@
 fn main() {
-    let v[0] = v[1]; //~ ERROR expected one of `:`, `;`, `=`, or `@`, found `[`
+    let v[0] = v[1]; //~ ERROR expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
 }
diff --git a/src/test/ui/parser/pat-lt-bracket-5.stderr b/src/test/ui/parser/pat-lt-bracket-5.stderr
index ce4cc05db19b2..167314dde0650 100644
--- a/src/test/ui/parser/pat-lt-bracket-5.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-5.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:`, `;`, `=`, or `@`, found `[`
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
   --> $DIR/pat-lt-bracket-5.rs:2:10
    |
 LL |     let v[0] = v[1];
-   |          ^ expected one of `:`, `;`, `=`, or `@` here
+   |          ^ expected one of `:`, `;`, `=`, `@`, or `|` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-ranges-1.rs b/src/test/ui/parser/pat-ranges-1.rs
index ce953b2eb2299..1dafb5a07bb5a 100644
--- a/src/test/ui/parser/pat-ranges-1.rs
+++ b/src/test/ui/parser/pat-ranges-1.rs
@@ -1,5 +1,5 @@
 // Parsing of range patterns
 
 fn main() {
-    let macropus!() ..= 11 = 12; //~ error: expected one of `:`, `;`, or `=`, found `..=`
+    let macropus!() ..= 11 = 12; //~ error: expected one of `:`, `;`, `=`, or `|`, found `..=`
 }
diff --git a/src/test/ui/parser/pat-ranges-1.stderr b/src/test/ui/parser/pat-ranges-1.stderr
index 6e0deccab8ca2..4e2c5d28381d8 100644
--- a/src/test/ui/parser/pat-ranges-1.stderr
+++ b/src/test/ui/parser/pat-ranges-1.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:`, `;`, or `=`, found `..=`
+error: expected one of `:`, `;`, `=`, or `|`, found `..=`
   --> $DIR/pat-ranges-1.rs:4:21
    |
 LL |     let macropus!() ..= 11 = 12;
-   |                     ^^^ expected one of `:`, `;`, or `=` here
+   |                     ^^^ expected one of `:`, `;`, `=`, or `|` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-ranges-2.rs b/src/test/ui/parser/pat-ranges-2.rs
index 9f736ed328c5c..1593222acca1b 100644
--- a/src/test/ui/parser/pat-ranges-2.rs
+++ b/src/test/ui/parser/pat-ranges-2.rs
@@ -1,5 +1,5 @@
 // Parsing of range patterns
 
 fn main() {
-    let 10 ..= makropulos!() = 12; //~ error: expected one of `::`, `:`, `;`, or `=`, found `!`
+    let 10 ..= makropulos!() = 12; //~ error: expected one of `::`, `:`, `;`, `=`, or `|`, found `!`
 }
diff --git a/src/test/ui/parser/pat-ranges-2.stderr b/src/test/ui/parser/pat-ranges-2.stderr
index d180bb429110a..64df56f5a61b1 100644
--- a/src/test/ui/parser/pat-ranges-2.stderr
+++ b/src/test/ui/parser/pat-ranges-2.stderr
@@ -1,8 +1,8 @@
-error: expected one of `::`, `:`, `;`, or `=`, found `!`
+error: expected one of `::`, `:`, `;`, `=`, or `|`, found `!`
   --> $DIR/pat-ranges-2.rs:4:26
    |
 LL |     let 10 ..= makropulos!() = 12;
-   |                          ^ expected one of `::`, `:`, `;`, or `=` here
+   |                          ^ expected one of `::`, `:`, `;`, `=`, or `|` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-ranges-3.rs b/src/test/ui/parser/pat-ranges-3.rs
index 65da55e3bda8c..8976dcf0d90f9 100644
--- a/src/test/ui/parser/pat-ranges-3.rs
+++ b/src/test/ui/parser/pat-ranges-3.rs
@@ -1,5 +1,5 @@
 // Parsing of range patterns
 
 fn main() {
-    let 10 ..= 10 + 3 = 12; //~ expected one of `:`, `;`, or `=`, found `+`
+    let 10 ..= 10 + 3 = 12; //~ expected one of `:`, `;`, `=`, or `|`, found `+`
 }
diff --git a/src/test/ui/parser/pat-ranges-3.stderr b/src/test/ui/parser/pat-ranges-3.stderr
index aaa85e3c2ddd8..c32c18d98dce7 100644
--- a/src/test/ui/parser/pat-ranges-3.stderr
+++ b/src/test/ui/parser/pat-ranges-3.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:`, `;`, or `=`, found `+`
+error: expected one of `:`, `;`, `=`, or `|`, found `+`
   --> $DIR/pat-ranges-3.rs:4:19
    |
 LL |     let 10 ..= 10 + 3 = 12;
-   |                   ^ expected one of `:`, `;`, or `=` here
+   |                   ^ expected one of `:`, `;`, `=`, or `|` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/pat-ranges-4.rs b/src/test/ui/parser/pat-ranges-4.rs
index 7f4a5f3239e76..61188976b028c 100644
--- a/src/test/ui/parser/pat-ranges-4.rs
+++ b/src/test/ui/parser/pat-ranges-4.rs
@@ -2,5 +2,5 @@
 
 fn main() {
     let 10 - 3 ..= 10 = 8;
-    //~^ error: expected one of `...`, `..=`, `..`, `:`, `;`, or `=`, found `-`
+    //~^ error: expected one of `...`, `..=`, `..`, `:`, `;`, `=`, or `|`, found `-`
 }
diff --git a/src/test/ui/parser/pat-ranges-4.stderr b/src/test/ui/parser/pat-ranges-4.stderr
index 0a1d7a1f6b8ab..53e38bc670beb 100644
--- a/src/test/ui/parser/pat-ranges-4.stderr
+++ b/src/test/ui/parser/pat-ranges-4.stderr
@@ -1,8 +1,8 @@
-error: expected one of `...`, `..=`, `..`, `:`, `;`, or `=`, found `-`
+error: expected one of `...`, `..=`, `..`, `:`, `;`, `=`, or `|`, found `-`
   --> $DIR/pat-ranges-4.rs:4:12
    |
 LL |     let 10 - 3 ..= 10 = 8;
-   |            ^ expected one of `...`, `..=`, `..`, `:`, `;`, or `=` here
+   |            ^ expected one of 7 possible tokens here
 
 error: aborting due to previous error
 

From 5f6bec8ecf5a9018bb368becc0aaea703334795a Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 22:57:34 +0200
Subject: [PATCH 216/943] parser: drive-by: simplify `parse_arg_general`.

---
 src/libsyntax/parse/parser.rs | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 89725d8b3395c..002e9bccec72a 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -971,15 +971,12 @@ impl<'a> Parser<'a> {
     /// Skips unexpected attributes and doc comments in this position and emits an appropriate
     /// error.
     /// This version of parse arg doesn't necessarily require identifier names.
-    fn parse_arg_general<F>(
+    fn parse_arg_general(
         &mut self,
         is_trait_item: bool,
         allow_c_variadic: bool,
-        is_name_required: F,
-    ) -> PResult<'a, Arg>
-    where
-        F: Fn(&token::Token) -> bool
-    {
+        is_name_required: impl Fn(&token::Token) -> bool,
+    ) -> PResult<'a, Arg> {
         let lo = self.token.span;
         let attrs = self.parse_arg_attributes()?;
         if let Some(mut arg) = self.parse_self_arg()? {

From a9af18bed544ede37b6b817cca1d4613aad4696f Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 23:07:21 +0200
Subject: [PATCH 217/943] move `ui/or-pattern-mismatch` -> `ui/or-patterns/`.

---
 src/test/ui/{ => or-patterns}/or-pattern-mismatch.rs     | 0
 src/test/ui/{ => or-patterns}/or-pattern-mismatch.stderr | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename src/test/ui/{ => or-patterns}/or-pattern-mismatch.rs (100%)
 rename src/test/ui/{ => or-patterns}/or-pattern-mismatch.stderr (100%)

diff --git a/src/test/ui/or-pattern-mismatch.rs b/src/test/ui/or-patterns/or-pattern-mismatch.rs
similarity index 100%
rename from src/test/ui/or-pattern-mismatch.rs
rename to src/test/ui/or-patterns/or-pattern-mismatch.rs
diff --git a/src/test/ui/or-pattern-mismatch.stderr b/src/test/ui/or-patterns/or-pattern-mismatch.stderr
similarity index 100%
rename from src/test/ui/or-pattern-mismatch.stderr
rename to src/test/ui/or-patterns/or-pattern-mismatch.stderr

From f35432e1889a4361388adf514634b122aefa746b Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 23:53:08 +0200
Subject: [PATCH 218/943] or-patterns: add syntactic tests.

---
 .../or-patterns/or-patterns-syntactic-fail.rs | 56 +++++++++++++
 .../or-patterns-syntactic-fail.stderr         | 75 ++++++++++++++++++
 .../or-patterns/or-patterns-syntactic-pass.rs | 78 +++++++++++++++++++
 .../or-patterns-syntactic-pass.stderr         |  8 ++
 4 files changed, 217 insertions(+)
 create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
 create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
 create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
 create mode 100644 src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr

diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
new file mode 100644
index 0000000000000..43c9214bd98f7
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
@@ -0,0 +1,56 @@
+// Test some cases where or-patterns may ostensibly be allowed but are in fact not.
+// This is not a semantic test. We only test parsing.
+
+#![feature(or_patterns)]
+//~^ WARN the feature `or_patterns` is incomplete and may cause the compiler to crash
+
+fn main() {}
+
+// Test the `pat` macro fragment parser:
+macro_rules! accept_pat {
+    ($p:pat) => {}
+}
+
+accept_pat!(p | q); //~ ERROR no rules expected the token `|`
+accept_pat!(| p | q); //~ ERROR no rules expected the token `|`
+
+// Non-macro tests:
+
+enum E { A, B }
+use E::*;
+
+fn no_top_level_or_patterns() {
+    // We do *not* allow or-patterns at the top level of lambdas...
+    let _ = |A | B: E| (); //~ ERROR binary operation `|` cannot be applied to type `E`
+    //           -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`.
+
+    // ...and for now neither do we allow or-patterns at the top level of functions.
+    fn fun(A | B: E) {} //~ ERROR expected one of `:` or `@`, found `|`
+}
+
+// We also do not allow a leading `|` when not in a top level position:
+
+#[cfg(FALSE)]
+fn no_leading_parens() {
+    let ( | A | B); //~ ERROR expected pattern, found `|`
+}
+
+#[cfg(FALSE)]
+fn no_leading_tuple() {
+    let ( | A | B,); //~ ERROR expected pattern, found `|`
+}
+
+#[cfg(FALSE)]
+fn no_leading_slice() {
+    let [ | A | B ]; //~ ERROR expected pattern, found `|`
+}
+
+#[cfg(FALSE)]
+fn no_leading_tuple_struct() {
+    let TS( | A | B ); //~ ERROR expected pattern, found `|`
+}
+
+#[cfg(FALSE)]
+fn no_leading_struct() {
+    let NS { f: | A | B }; //~ ERROR expected pattern, found `|`
+}
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
new file mode 100644
index 0000000000000..809ff272f6204
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
@@ -0,0 +1,75 @@
+error: expected one of `:` or `@`, found `|`
+  --> $DIR/or-patterns-syntactic-fail.rs:28:14
+   |
+LL |     fn fun(A | B: E) {}
+   |              ^ expected one of `:` or `@` here
+
+error: expected pattern, found `|`
+  --> $DIR/or-patterns-syntactic-fail.rs:35:11
+   |
+LL |     let ( | A | B);
+   |           ^ expected pattern
+
+error: expected pattern, found `|`
+  --> $DIR/or-patterns-syntactic-fail.rs:40:11
+   |
+LL |     let ( | A | B,);
+   |           ^ expected pattern
+
+error: expected pattern, found `|`
+  --> $DIR/or-patterns-syntactic-fail.rs:45:11
+   |
+LL |     let [ | A | B ];
+   |           ^ expected pattern
+
+error: expected pattern, found `|`
+  --> $DIR/or-patterns-syntactic-fail.rs:50:13
+   |
+LL |     let TS( | A | B );
+   |             ^ expected pattern
+
+error: expected pattern, found `|`
+  --> $DIR/or-patterns-syntactic-fail.rs:55:17
+   |
+LL |     let NS { f: | A | B };
+   |                 ^ expected pattern
+
+error: no rules expected the token `|`
+  --> $DIR/or-patterns-syntactic-fail.rs:14:15
+   |
+LL | macro_rules! accept_pat {
+   | ----------------------- when calling this macro
+...
+LL | accept_pat!(p | q);
+   |               ^ no rules expected this token in macro call
+
+error: no rules expected the token `|`
+  --> $DIR/or-patterns-syntactic-fail.rs:15:13
+   |
+LL | macro_rules! accept_pat {
+   | ----------------------- when calling this macro
+...
+LL | accept_pat!(| p | q);
+   |             ^ no rules expected this token in macro call
+
+warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
+  --> $DIR/or-patterns-syntactic-fail.rs:4:12
+   |
+LL | #![feature(or_patterns)]
+   |            ^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0369]: binary operation `|` cannot be applied to type `E`
+  --> $DIR/or-patterns-syntactic-fail.rs:24:22
+   |
+LL |     let _ = |A | B: E| ();
+   |                  ----^ -- ()
+   |                  |
+   |                  E
+   |
+   = note: an implementation of `std::ops::BitOr` might be missing for `E`
+
+error: aborting due to 9 previous errors
+
+For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
new file mode 100644
index 0000000000000..5fe72caf9c1ff
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
@@ -0,0 +1,78 @@
+// Here we test all the places `|` is *syntactically* allowed.
+// This is not a semantic test. We only test parsing.
+
+// check-pass
+
+#![feature(or_patterns)]
+
+fn main() {}
+
+// Test the `pat` macro fragment parser:
+macro_rules! accept_pat {
+    ($p:pat) => {}
+}
+
+accept_pat!((p | q));
+accept_pat!((p | q,));
+accept_pat!(TS(p | q));
+accept_pat!(NS { f: p | q });
+accept_pat!([p | q]);
+
+// Non-macro tests:
+
+#[cfg(FALSE)]
+fn or_patterns() {
+    // Top level of `let`:
+    let | A | B;
+    let A | B;
+    let A | B: u8;
+    let A | B = 0;
+    let A | B: u8 = 0;
+
+    // Top level of `for`:
+    for | A | B in 0 {}
+    for A | B in 0 {}
+
+    // Top level of `while`:
+    while let | A | B = 0 {}
+    while let A | B = 0 {}
+
+    // Top level of `if`:
+    if let | A | B = 0 {}
+    if let A | B = 0 {}
+
+    // Top level of `match` arms:
+    match 0 {
+        | A | B => {},
+        A | B => {},
+    }
+
+    // Functions:
+    fn fun((A | B): _) {}
+
+    // Lambdas:
+    let _ = |(A | B): u8| ();
+
+    // Parenthesis and tuple patterns:
+    let (A | B);
+    let (A | B,);
+
+    // Tuple struct patterns:
+    let A(B | C);
+    let E::V(B | C);
+
+    // Struct patterns:
+    let S { f1: B | C, f2 };
+    let E::V { f1: B | C, f2 };
+
+    // Slice patterns:
+    let [A | B, .. | ..];
+
+    // These bind as `(prefix p) | q` as opposed to `prefix (p | q)`:
+    let box 0 | 1; // Unstable; we *can* the precedence if we want.
+    let &0 | 1;
+    let &mut 0 | 1;
+    let x @ 0 | 1;
+    let ref x @ 0 | 1;
+    let ref mut x @ 0 | 1;
+}
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr
new file mode 100644
index 0000000000000..3145a2e9f2a6e
--- /dev/null
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.stderr
@@ -0,0 +1,8 @@
+warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
+  --> $DIR/or-patterns-syntactic-pass.rs:6:12
+   |
+LL | #![feature(or_patterns)]
+   |            ^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+

From d3b3bceffb1f0fa7727c4d63aa37ecb9444e88c5 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 18 Aug 2019 23:57:43 +0200
Subject: [PATCH 219/943] move `feature-gate-or_patterns.*` ->
 `ui/or-patterns/`

---
 .../ui/{feature-gate => or-patterns}/feature-gate-or_patterns.rs  | 0
 .../{feature-gate => or-patterns}/feature-gate-or_patterns.stderr | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename src/test/ui/{feature-gate => or-patterns}/feature-gate-or_patterns.rs (100%)
 rename src/test/ui/{feature-gate => or-patterns}/feature-gate-or_patterns.stderr (100%)

diff --git a/src/test/ui/feature-gate/feature-gate-or_patterns.rs b/src/test/ui/or-patterns/feature-gate-or_patterns.rs
similarity index 100%
rename from src/test/ui/feature-gate/feature-gate-or_patterns.rs
rename to src/test/ui/or-patterns/feature-gate-or_patterns.rs
diff --git a/src/test/ui/feature-gate/feature-gate-or_patterns.stderr b/src/test/ui/or-patterns/feature-gate-or_patterns.stderr
similarity index 100%
rename from src/test/ui/feature-gate/feature-gate-or_patterns.stderr
rename to src/test/ui/or-patterns/feature-gate-or_patterns.stderr

From 1ffea18ddbe9ebaba4ff301a3c42e44a55741355 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 19 Aug 2019 00:19:40 +0200
Subject: [PATCH 220/943] or-patterns: harden feature gating tests.

---
 .../or-patterns/feature-gate-or_patterns.rs   |  47 ++++-
 .../feature-gate-or_patterns.stderr           | 182 +++++++++++++++++-
 2 files changed, 227 insertions(+), 2 deletions(-)

diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns.rs b/src/test/ui/or-patterns/feature-gate-or_patterns.rs
index 036a6095965bd..560db20e66862 100644
--- a/src/test/ui/or-patterns/feature-gate-or_patterns.rs
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns.rs
@@ -1,4 +1,4 @@
-#![crate_type="lib"]
+fn main() {}
 
 pub fn example(x: Option<usize>) {
     match x {
@@ -7,3 +7,48 @@ pub fn example(x: Option<usize>) {
         _ => {}
     }
 }
+
+// Test the `pat` macro fragment parser:
+macro_rules! accept_pat {
+    ($p:pat) => {}
+}
+
+accept_pat!((p | q)); //~ ERROR or-patterns syntax is experimental
+accept_pat!((p | q,)); //~ ERROR or-patterns syntax is experimental
+accept_pat!(TS(p | q)); //~ ERROR or-patterns syntax is experimental
+accept_pat!(NS { f: p | q }); //~ ERROR or-patterns syntax is experimental
+accept_pat!([p | q]); //~ ERROR or-patterns syntax is experimental
+
+// Non-macro tests:
+
+#[cfg(FALSE)]
+fn or_patterns() {
+    // Gated:
+
+    let | A | B; //~ ERROR or-patterns syntax is experimental
+    //~^ ERROR or-patterns syntax is experimental
+    let A | B; //~ ERROR or-patterns syntax is experimental
+    for | A | B in 0 {} //~ ERROR or-patterns syntax is experimental
+    //~^ ERROR or-patterns syntax is experimental
+    for A | B in 0 {} //~ ERROR or-patterns syntax is experimental
+    fn fun((A | B): _) {} //~ ERROR or-patterns syntax is experimental
+    let _ = |(A | B): u8| (); //~ ERROR or-patterns syntax is experimental
+    let (A | B); //~ ERROR or-patterns syntax is experimental
+    let (A | B,); //~ ERROR or-patterns syntax is experimental
+    let A(B | C); //~ ERROR or-patterns syntax is experimental
+    let E::V(B | C); //~ ERROR or-patterns syntax is experimental
+    let S { f1: B | C, f2 }; //~ ERROR or-patterns syntax is experimental
+    let E::V { f1: B | C, f2 }; //~ ERROR or-patterns syntax is experimental
+    let [A | B]; //~ ERROR or-patterns syntax is experimental
+
+    // Top level of `while`, `if`, and `match` arms are allowed:
+
+    while let | A = 0 {}
+    while let A | B = 0 {}
+    if let | A = 0 {}
+    if let A | B = 0 {}
+    match 0 {
+        | A => {},
+        A | B => {},
+    }
+}
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns.stderr b/src/test/ui/or-patterns/feature-gate-or_patterns.stderr
index aaabb54c1f017..e2abfbfd5254d 100644
--- a/src/test/ui/or-patterns/feature-gate-or_patterns.stderr
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns.stderr
@@ -7,6 +7,186 @@ LL |         Some(0 | 1 | 2) => {}
    = note: for more information, see https://github.com/rust-lang/rust/issues/54883
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:28:9
+   |
+LL |     let | A | B;
+   |         ^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:28:11
+   |
+LL |     let | A | B;
+   |           ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:30:9
+   |
+LL |     let A | B;
+   |         ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:31:9
+   |
+LL |     for | A | B in 0 {}
+   |         ^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:31:11
+   |
+LL |     for | A | B in 0 {}
+   |           ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:33:9
+   |
+LL |     for A | B in 0 {}
+   |         ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:34:13
+   |
+LL |     fn fun((A | B): _) {}
+   |             ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:35:15
+   |
+LL |     let _ = |(A | B): u8| ();
+   |               ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:36:10
+   |
+LL |     let (A | B);
+   |          ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:37:10
+   |
+LL |     let (A | B,);
+   |          ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:38:11
+   |
+LL |     let A(B | C);
+   |           ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:39:14
+   |
+LL |     let E::V(B | C);
+   |              ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:40:17
+   |
+LL |     let S { f1: B | C, f2 };
+   |                 ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:41:20
+   |
+LL |     let E::V { f1: B | C, f2 };
+   |                    ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:42:10
+   |
+LL |     let [A | B];
+   |          ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:16:14
+   |
+LL | accept_pat!((p | q));
+   |              ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:17:14
+   |
+LL | accept_pat!((p | q,));
+   |              ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:18:16
+   |
+LL | accept_pat!(TS(p | q));
+   |                ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:19:21
+   |
+LL | accept_pat!(NS { f: p | q });
+   |                     ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns.rs:20:14
+   |
+LL | accept_pat!([p | q]);
+   |              ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error: aborting due to 21 previous errors
 
 For more information about this error, try `rustc --explain E0658`.

From b205055c7bc92c0f873755996e6fac3e694c7e72 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 19 Aug 2019 02:40:24 +0200
Subject: [PATCH 221/943] parser: better recovery for || in inner pats.

---
 src/libsyntax/parse/parser/pat.rs             | 27 ++++++-
 .../or-patterns/or-patterns-syntactic-fail.rs | 39 ++++------
 .../or-patterns-syntactic-fail.stderr         | 77 ++++++++++++++-----
 3 files changed, 96 insertions(+), 47 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index e77d9120bce78..b9871be229ce5 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -155,6 +155,25 @@ impl<'a> Parser<'a> {
         Ok(())
     }
 
+    /// Recursive possibly-or-pattern parser with recovery for an erroneous leading `|`.
+    /// See `parse_pat_with_or` for details on parsing or-patterns.
+    fn parse_pat_with_or_inner(&mut self, expected: Expected) -> PResult<'a, P<Pat>> {
+        // Recover if `|` or `||` is here.
+        // The user is thinking that a leading `|` is allowed in this position.
+        if let token::BinOp(token::Or) | token::OrOr = self.token.kind {
+            let span = self.token.span;
+            let rm_msg = format!("remove the `{}`", pprust::token_to_string(&self.token));
+
+            self.struct_span_err(span, "a leading `|` is only allowed in a top-level pattern")
+                .span_suggestion(span, &rm_msg, String::new(), Applicability::MachineApplicable)
+                .emit();
+
+            self.bump();
+        }
+
+        self.parse_pat_with_or(expected, true, false)
+    }
+
     /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
     /// allowed).
     fn parse_pat_with_range_pat(
@@ -173,7 +192,7 @@ impl<'a> Parser<'a> {
                 // Parse `[pat, pat,...]` as a slice pattern.
                 let (pats, _) = self.parse_delim_comma_seq(
                     token::Bracket,
-                    |p| p.parse_pat_with_or(None, true, false),
+                    |p| p.parse_pat_with_or_inner(None),
                 )?;
                 PatKind::Slice(pats)
             }
@@ -303,7 +322,7 @@ impl<'a> Parser<'a> {
     /// Parse a tuple or parenthesis pattern.
     fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> {
         let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| {
-            p.parse_pat_with_or(None, true, false)
+            p.parse_pat_with_or_inner(None)
         })?;
 
         // Here, `(pat,)` is a tuple pattern.
@@ -547,7 +566,7 @@ impl<'a> Parser<'a> {
             err.span_label(self.token.span, msg);
             return Err(err);
         }
-        let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or(None, true, false))?;
+        let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or_inner(None))?;
         Ok(PatKind::TupleStruct(path, fields))
     }
 
@@ -691,7 +710,7 @@ impl<'a> Parser<'a> {
             // Parsing a pattern of the form "fieldname: pat"
             let fieldname = self.parse_field_name()?;
             self.bump();
-            let pat = self.parse_pat_with_or(None, true, false)?;
+            let pat = self.parse_pat_with_or_inner(None)?;
             hi = pat.span;
             (pat, fieldname, false)
         } else {
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
index 43c9214bd98f7..7959812f5b39c 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
@@ -30,27 +30,20 @@ fn no_top_level_or_patterns() {
 
 // We also do not allow a leading `|` when not in a top level position:
 
-#[cfg(FALSE)]
-fn no_leading_parens() {
-    let ( | A | B); //~ ERROR expected pattern, found `|`
-}
-
-#[cfg(FALSE)]
-fn no_leading_tuple() {
-    let ( | A | B,); //~ ERROR expected pattern, found `|`
-}
-
-#[cfg(FALSE)]
-fn no_leading_slice() {
-    let [ | A | B ]; //~ ERROR expected pattern, found `|`
-}
-
-#[cfg(FALSE)]
-fn no_leading_tuple_struct() {
-    let TS( | A | B ); //~ ERROR expected pattern, found `|`
-}
-
-#[cfg(FALSE)]
-fn no_leading_struct() {
-    let NS { f: | A | B }; //~ ERROR expected pattern, found `|`
+fn no_leading_inner() {
+    struct TS(E);
+    struct NS { f: E }
+
+    let ( | A | B) = E::A; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let ( | A | B,) = (E::B,); //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let [ | A | B ] = [E::A]; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let TS( | A | B ); //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let NS { f: | A | B }; //~ ERROR a leading `|` is only allowed in a top-level pattern
+
+    let ( || A | B) = E::A; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let [ || A | B ] = [E::A]; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let TS( || A | B ); //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let NS { f: || A | B }; //~ ERROR a leading `|` is only allowed in a top-level pattern
+
+    let recovery_witness: String = 0; //~ ERROR mismatched types
 }
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
index 809ff272f6204..dd4c309ce85a3 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
@@ -4,35 +4,59 @@ error: expected one of `:` or `@`, found `|`
 LL |     fn fun(A | B: E) {}
    |              ^ expected one of `:` or `@` here
 
-error: expected pattern, found `|`
-  --> $DIR/or-patterns-syntactic-fail.rs:35:11
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/or-patterns-syntactic-fail.rs:37:11
    |
-LL |     let ( | A | B);
-   |           ^ expected pattern
+LL |     let ( | A | B) = E::A;
+   |           ^ help: remove the `|`
 
-error: expected pattern, found `|`
-  --> $DIR/or-patterns-syntactic-fail.rs:40:11
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/or-patterns-syntactic-fail.rs:38:11
    |
-LL |     let ( | A | B,);
-   |           ^ expected pattern
+LL |     let ( | A | B,) = (E::B,);
+   |           ^ help: remove the `|`
 
-error: expected pattern, found `|`
-  --> $DIR/or-patterns-syntactic-fail.rs:45:11
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/or-patterns-syntactic-fail.rs:39:11
    |
-LL |     let [ | A | B ];
-   |           ^ expected pattern
+LL |     let [ | A | B ] = [E::A];
+   |           ^ help: remove the `|`
 
-error: expected pattern, found `|`
-  --> $DIR/or-patterns-syntactic-fail.rs:50:13
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/or-patterns-syntactic-fail.rs:40:13
    |
 LL |     let TS( | A | B );
-   |             ^ expected pattern
+   |             ^ help: remove the `|`
 
-error: expected pattern, found `|`
-  --> $DIR/or-patterns-syntactic-fail.rs:55:17
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/or-patterns-syntactic-fail.rs:41:17
    |
 LL |     let NS { f: | A | B };
-   |                 ^ expected pattern
+   |                 ^ help: remove the `|`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/or-patterns-syntactic-fail.rs:43:11
+   |
+LL |     let ( || A | B) = E::A;
+   |           ^^ help: remove the `||`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/or-patterns-syntactic-fail.rs:44:11
+   |
+LL |     let [ || A | B ] = [E::A];
+   |           ^^ help: remove the `||`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/or-patterns-syntactic-fail.rs:45:13
+   |
+LL |     let TS( || A | B );
+   |             ^^ help: remove the `||`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/or-patterns-syntactic-fail.rs:46:17
+   |
+LL |     let NS { f: || A | B };
+   |                 ^^ help: remove the `||`
 
 error: no rules expected the token `|`
   --> $DIR/or-patterns-syntactic-fail.rs:14:15
@@ -70,6 +94,19 @@ LL |     let _ = |A | B: E| ();
    |
    = note: an implementation of `std::ops::BitOr` might be missing for `E`
 
-error: aborting due to 9 previous errors
+error[E0308]: mismatched types
+  --> $DIR/or-patterns-syntactic-fail.rs:48:36
+   |
+LL |     let recovery_witness: String = 0;
+   |                                    ^
+   |                                    |
+   |                                    expected struct `std::string::String`, found integer
+   |                                    help: try using a conversion method: `0.to_string()`
+   |
+   = note: expected type `std::string::String`
+              found type `{integer}`
+
+error: aborting due to 14 previous errors
 
-For more information about this error, try `rustc --explain E0369`.
+Some errors have detailed explanations: E0308, E0369.
+For more information about an error, try `rustc --explain E0308`.

From b2966e651de3bf83ab9c712a1afaeba84162cab1 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 21:43:28 +0200
Subject: [PATCH 222/943] parser: bool -> GateOr.

---
 src/libsyntax/parse/parser/expr.rs |  7 ++++---
 src/libsyntax/parse/parser/pat.rs  | 16 ++++++++++------
 src/libsyntax/parse/parser/stmt.rs |  3 ++-
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 25a858b47353f..83e5a84a8c6ae 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -1,6 +1,7 @@
 use super::{Parser, PResult, Restrictions, PrevTokenKind, TokenType, PathStyle};
 use super::{BlockMode, SemiColonMode};
 use super::{SeqSep, TokenExpectType};
+use super::pat::GateOr;
 
 use crate::maybe_recover_from_interpolated_ty_qpath;
 use crate::ptr::P;
@@ -1246,7 +1247,7 @@ impl<'a> Parser<'a> {
     fn parse_let_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         let lo = self.prev_span;
         // FIXME(or_patterns, Centril | dlrobertson): use `parse_top_pat` instead.
-        let pat = self.parse_top_pat_unpack(false)?;
+        let pat = self.parse_top_pat_unpack(GateOr::No)?;
         self.expect(&token::Eq)?;
         let expr = self.with_res(
             Restrictions::NO_STRUCT_LITERAL,
@@ -1284,7 +1285,7 @@ impl<'a> Parser<'a> {
             _ => None,
         };
 
-        let pat = self.parse_top_pat(true)?;
+        let pat = self.parse_top_pat(GateOr::Yes)?;
         if !self.eat_keyword(kw::In) {
             let in_span = self.prev_span.between(self.token.span);
             self.struct_span_err(in_span, "missing `in` in `for` loop")
@@ -1389,7 +1390,7 @@ impl<'a> Parser<'a> {
         let attrs = self.parse_outer_attributes()?;
         let lo = self.token.span;
         // FIXME(or_patterns, Centril | dlrobertson): use `parse_top_pat` instead.
-        let pat = self.parse_top_pat_unpack(false)?;
+        let pat = self.parse_top_pat_unpack(GateOr::No)?;
         let guard = if self.eat_keyword(kw::If) {
             Some(self.parse_expr()?)
         } else {
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index b9871be229ce5..3d89ec56ffafa 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -14,6 +14,10 @@ use errors::{Applicability, DiagnosticBuilder};
 
 type Expected = Option<&'static str>;
 
+/// Whether or not an or-pattern should be gated when occurring in the current context.
+#[derive(PartialEq)]
+pub enum GateOr { Yes, No }
+
 impl<'a> Parser<'a> {
     /// Parses a pattern.
     ///
@@ -26,7 +30,7 @@ impl<'a> Parser<'a> {
 
     // FIXME(or_patterns, Centril | dlrobertson):
     // remove this and use `parse_top_pat` everywhere it is used instead.
-    pub(super) fn parse_top_pat_unpack(&mut self, gate_or: bool) -> PResult<'a, Vec<P<Pat>>> {
+    pub(super) fn parse_top_pat_unpack(&mut self, gate_or: GateOr) -> PResult<'a, Vec<P<Pat>>> {
         self.parse_top_pat(gate_or)
             .map(|pat| pat.and_then(|pat| match pat.node {
                 PatKind::Or(pats) => pats,
@@ -36,9 +40,9 @@ impl<'a> Parser<'a> {
 
     /// Entry point to the main pattern parser.
     /// Corresponds to `top_pat` in RFC 2535 and allows or-pattern at the top level.
-    pub(super) fn parse_top_pat(&mut self, gate_or: bool) -> PResult<'a, P<Pat>> {
+    pub(super) fn parse_top_pat(&mut self, gate_or: GateOr) -> PResult<'a, P<Pat>> {
         // Allow a '|' before the pats (RFCs 1925, 2530, and 2535).
-        if self.eat_or_separator() && gate_or {
+        if self.eat_or_separator() && gate_or == GateOr::Yes {
             self.sess.gated_spans.or_patterns.borrow_mut().push(self.prev_span);
         }
 
@@ -50,7 +54,7 @@ impl<'a> Parser<'a> {
     fn parse_pat_with_or(
         &mut self,
         expected: Expected,
-        gate_or: bool,
+        gate_or: GateOr,
         top_level: bool
     ) -> PResult<'a, P<Pat>> {
         // Parse the first pattern.
@@ -73,7 +77,7 @@ impl<'a> Parser<'a> {
         let or_pattern_span = lo.to(self.prev_span);
 
         // Feature gate the or-pattern if instructed:
-        if gate_or {
+        if gate_or == GateOr::Yes {
             self.sess.gated_spans.or_patterns.borrow_mut().push(or_pattern_span);
         }
 
@@ -171,7 +175,7 @@ impl<'a> Parser<'a> {
             self.bump();
         }
 
-        self.parse_pat_with_or(expected, true, false)
+        self.parse_pat_with_or(expected, GateOr::Yes, false)
     }
 
     /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
diff --git a/src/libsyntax/parse/parser/stmt.rs b/src/libsyntax/parse/parser/stmt.rs
index 3c8cb4ea5a582..651ebf6342e71 100644
--- a/src/libsyntax/parse/parser/stmt.rs
+++ b/src/libsyntax/parse/parser/stmt.rs
@@ -1,6 +1,7 @@
 use super::{Parser, PResult, Restrictions, PrevTokenKind, SemiColonMode, BlockMode};
 use super::expr::LhsExpr;
 use super::path::PathStyle;
+use super::pat::GateOr;
 
 use crate::ptr::P;
 use crate::{maybe_whole, ThinVec};
@@ -207,7 +208,7 @@ impl<'a> Parser<'a> {
     /// Parses a local variable declaration.
     fn parse_local(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Local>> {
         let lo = self.prev_span;
-        let pat = self.parse_top_pat(true)?;
+        let pat = self.parse_top_pat(GateOr::Yes)?;
 
         let (err, ty) = if self.eat(&token::Colon) {
             // Save the state of the parser before parsing type normally, in case there is a `:`

From a9ef8592e47808539ffd9237c22ce5518aa7b188 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 22:12:19 +0200
Subject: [PATCH 223/943] parser: bool -> TopLevel.

---
 src/libsyntax/parse/parser/pat.rs | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 3d89ec56ffafa..c168d03378133 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -18,6 +18,10 @@ type Expected = Option<&'static str>;
 #[derive(PartialEq)]
 pub enum GateOr { Yes, No }
 
+/// Whether or not this is the top level pattern context.
+#[derive(PartialEq, Copy, Clone)]
+enum TopLevel { Yes, No }
+
 impl<'a> Parser<'a> {
     /// Parses a pattern.
     ///
@@ -46,7 +50,7 @@ impl<'a> Parser<'a> {
             self.sess.gated_spans.or_patterns.borrow_mut().push(self.prev_span);
         }
 
-        self.parse_pat_with_or(None, gate_or, true)
+        self.parse_pat_with_or(None, gate_or, TopLevel::Yes)
     }
 
     /// Parses a pattern, that may be a or-pattern (e.g. `Foo | Bar` in `Some(Foo | Bar)`).
@@ -55,7 +59,7 @@ impl<'a> Parser<'a> {
         &mut self,
         expected: Expected,
         gate_or: GateOr,
-        top_level: bool
+        top_level: TopLevel,
     ) -> PResult<'a, P<Pat>> {
         // Parse the first pattern.
         let first_pat = self.parse_pat(expected)?;
@@ -112,8 +116,8 @@ impl<'a> Parser<'a> {
 
     /// Some special error handling for the "top-level" patterns in a match arm,
     /// `for` loop, `let`, &c. (in contrast to subpatterns within such).
-    fn maybe_recover_unexpected_comma(&mut self, lo: Span, top_level: bool) -> PResult<'a, ()> {
-        if !top_level || self.token != token::Comma {
+    fn maybe_recover_unexpected_comma(&mut self, lo: Span, top_level: TopLevel) -> PResult<'a, ()> {
+        if top_level == TopLevel::No || self.token != token::Comma {
             return Ok(());
         }
 
@@ -175,7 +179,7 @@ impl<'a> Parser<'a> {
             self.bump();
         }
 
-        self.parse_pat_with_or(expected, GateOr::Yes, false)
+        self.parse_pat_with_or(expected, GateOr::Yes, TopLevel::No)
     }
 
     /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are

From 3a405421e7c1437416e225ea8d2f0fdfb501df7b Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 22:46:17 +0200
Subject: [PATCH 224/943] parse_top_pat: silence leading vert gating sometimes.

---
 src/libsyntax/parse/parser/pat.rs             | 18 ++++++--
 .../feature-gate-or_patterns-leading-for.rs   |  8 ++++
 ...eature-gate-or_patterns-leading-for.stderr | 12 +++++
 .../feature-gate-or_patterns-leading-let.rs   |  8 ++++
 ...eature-gate-or_patterns-leading-let.stderr | 12 +++++
 .../feature-gate-or_patterns-leading.stderr   | 12 +++++
 .../or-patterns/feature-gate-or_patterns.rs   |  2 -
 .../feature-gate-or_patterns.stderr           | 44 ++++++-------------
 8 files changed, 80 insertions(+), 36 deletions(-)
 create mode 100644 src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.rs
 create mode 100644 src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.stderr
 create mode 100644 src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.rs
 create mode 100644 src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr
 create mode 100644 src/test/ui/or-patterns/feature-gate-or_patterns-leading.stderr

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index c168d03378133..724edbcfaed79 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -46,11 +46,23 @@ impl<'a> Parser<'a> {
     /// Corresponds to `top_pat` in RFC 2535 and allows or-pattern at the top level.
     pub(super) fn parse_top_pat(&mut self, gate_or: GateOr) -> PResult<'a, P<Pat>> {
         // Allow a '|' before the pats (RFCs 1925, 2530, and 2535).
-        if self.eat_or_separator() && gate_or == GateOr::Yes {
-            self.sess.gated_spans.or_patterns.borrow_mut().push(self.prev_span);
+        let gated_leading_vert = self.eat_or_separator() && gate_or == GateOr::Yes;
+
+        // Parse the possibly-or-pattern.
+        let pat = self.parse_pat_with_or(None, gate_or, TopLevel::Yes)?;
+
+        // If we parsed a leading `|` which should be gated,
+        // and no other gated or-pattern has been parsed thus far,
+        // then we should really gate the leading `|`.
+        // This complicated procedure is done purely for diagnostics UX.
+        if gated_leading_vert {
+            let mut or_pattern_spans = self.sess.gated_spans.or_patterns.borrow_mut();
+            if or_pattern_spans.is_empty() {
+                or_pattern_spans.push(self.prev_span);
+            }
         }
 
-        self.parse_pat_with_or(None, gate_or, TopLevel::Yes)
+        Ok(pat)
     }
 
     /// Parses a pattern, that may be a or-pattern (e.g. `Foo | Bar` in `Some(Foo | Bar)`).
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.rs b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.rs
new file mode 100644
index 0000000000000..de8e1bba5576c
--- /dev/null
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.rs
@@ -0,0 +1,8 @@
+// Test feature gating for a sole leading `|` in `let`.
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn gated_leading_vert_in_let() {
+    for | A in 0 {} //~ ERROR or-patterns syntax is experimental
+}
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.stderr b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.stderr
new file mode 100644
index 0000000000000..83804d564f3e4
--- /dev/null
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.stderr
@@ -0,0 +1,12 @@
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns-leading-for.rs:7:11
+   |
+LL |     for | A in 0 {}
+   |           ^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.rs b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.rs
new file mode 100644
index 0000000000000..a4ea4e25d861e
--- /dev/null
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.rs
@@ -0,0 +1,8 @@
+// Test feature gating for a sole leading `|` in `let`.
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn gated_leading_vert_in_let() {
+    let | A; //~ ERROR or-patterns syntax is experimental
+}
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr
new file mode 100644
index 0000000000000..f7954ad7a8ce1
--- /dev/null
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr
@@ -0,0 +1,12 @@
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns-leading-let.rs:7:11
+   |
+LL |     let | A;
+   |           ^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns-leading.stderr b/src/test/ui/or-patterns/feature-gate-or_patterns-leading.stderr
new file mode 100644
index 0000000000000..8b18082fca7df
--- /dev/null
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns-leading.stderr
@@ -0,0 +1,12 @@
+error[E0658]: or-patterns syntax is experimental
+  --> $DIR/feature-gate-or_patterns-leading.rs:7:11
+   |
+LL |     let | A;
+   |           ^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
+   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns.rs b/src/test/ui/or-patterns/feature-gate-or_patterns.rs
index 560db20e66862..e638838147a4d 100644
--- a/src/test/ui/or-patterns/feature-gate-or_patterns.rs
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns.rs
@@ -26,10 +26,8 @@ fn or_patterns() {
     // Gated:
 
     let | A | B; //~ ERROR or-patterns syntax is experimental
-    //~^ ERROR or-patterns syntax is experimental
     let A | B; //~ ERROR or-patterns syntax is experimental
     for | A | B in 0 {} //~ ERROR or-patterns syntax is experimental
-    //~^ ERROR or-patterns syntax is experimental
     for A | B in 0 {} //~ ERROR or-patterns syntax is experimental
     fn fun((A | B): _) {} //~ ERROR or-patterns syntax is experimental
     let _ = |(A | B): u8| (); //~ ERROR or-patterns syntax is experimental
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns.stderr b/src/test/ui/or-patterns/feature-gate-or_patterns.stderr
index e2abfbfd5254d..aae6644dac2e0 100644
--- a/src/test/ui/or-patterns/feature-gate-or_patterns.stderr
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns.stderr
@@ -7,15 +7,6 @@ LL |         Some(0 | 1 | 2) => {}
    = note: for more information, see https://github.com/rust-lang/rust/issues/54883
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
-error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:28:9
-   |
-LL |     let | A | B;
-   |         ^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
-   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
-
 error[E0658]: or-patterns syntax is experimental
   --> $DIR/feature-gate-or_patterns.rs:28:11
    |
@@ -26,7 +17,7 @@ LL |     let | A | B;
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:30:9
+  --> $DIR/feature-gate-or_patterns.rs:29:9
    |
 LL |     let A | B;
    |         ^^^^^
@@ -35,16 +26,7 @@ LL |     let A | B;
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:31:9
-   |
-LL |     for | A | B in 0 {}
-   |         ^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
-   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
-
-error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:31:11
+  --> $DIR/feature-gate-or_patterns.rs:30:11
    |
 LL |     for | A | B in 0 {}
    |           ^^^^^
@@ -53,7 +35,7 @@ LL |     for | A | B in 0 {}
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:33:9
+  --> $DIR/feature-gate-or_patterns.rs:31:9
    |
 LL |     for A | B in 0 {}
    |         ^^^^^
@@ -62,7 +44,7 @@ LL |     for A | B in 0 {}
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:34:13
+  --> $DIR/feature-gate-or_patterns.rs:32:13
    |
 LL |     fn fun((A | B): _) {}
    |             ^^^^^
@@ -71,7 +53,7 @@ LL |     fn fun((A | B): _) {}
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:35:15
+  --> $DIR/feature-gate-or_patterns.rs:33:15
    |
 LL |     let _ = |(A | B): u8| ();
    |               ^^^^^
@@ -80,7 +62,7 @@ LL |     let _ = |(A | B): u8| ();
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:36:10
+  --> $DIR/feature-gate-or_patterns.rs:34:10
    |
 LL |     let (A | B);
    |          ^^^^^
@@ -89,7 +71,7 @@ LL |     let (A | B);
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:37:10
+  --> $DIR/feature-gate-or_patterns.rs:35:10
    |
 LL |     let (A | B,);
    |          ^^^^^
@@ -98,7 +80,7 @@ LL |     let (A | B,);
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:38:11
+  --> $DIR/feature-gate-or_patterns.rs:36:11
    |
 LL |     let A(B | C);
    |           ^^^^^
@@ -107,7 +89,7 @@ LL |     let A(B | C);
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:39:14
+  --> $DIR/feature-gate-or_patterns.rs:37:14
    |
 LL |     let E::V(B | C);
    |              ^^^^^
@@ -116,7 +98,7 @@ LL |     let E::V(B | C);
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:40:17
+  --> $DIR/feature-gate-or_patterns.rs:38:17
    |
 LL |     let S { f1: B | C, f2 };
    |                 ^^^^^
@@ -125,7 +107,7 @@ LL |     let S { f1: B | C, f2 };
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:41:20
+  --> $DIR/feature-gate-or_patterns.rs:39:20
    |
 LL |     let E::V { f1: B | C, f2 };
    |                    ^^^^^
@@ -134,7 +116,7 @@ LL |     let E::V { f1: B | C, f2 };
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:42:10
+  --> $DIR/feature-gate-or_patterns.rs:40:10
    |
 LL |     let [A | B];
    |          ^^^^^
@@ -187,6 +169,6 @@ LL | accept_pat!([p | q]);
    = note: for more information, see https://github.com/rust-lang/rust/issues/54883
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
-error: aborting due to 21 previous errors
+error: aborting due to 19 previous errors
 
 For more information about this error, try `rustc --explain E0658`.

From e3747722fbb8a44f9053922e4c39338a3a1f9597 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 23:10:46 +0200
Subject: [PATCH 225/943] parser: extract recover_inner_leading_vert.

---
 src/libsyntax/parse/parser/pat.rs | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 724edbcfaed79..dc6632cf10da9 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -178,8 +178,13 @@ impl<'a> Parser<'a> {
     /// Recursive possibly-or-pattern parser with recovery for an erroneous leading `|`.
     /// See `parse_pat_with_or` for details on parsing or-patterns.
     fn parse_pat_with_or_inner(&mut self, expected: Expected) -> PResult<'a, P<Pat>> {
-        // Recover if `|` or `||` is here.
-        // The user is thinking that a leading `|` is allowed in this position.
+        self.recover_inner_leading_vert();
+        self.parse_pat_with_or(expected, GateOr::Yes, TopLevel::No)
+    }
+
+    /// Recover if `|` or `||` is here.
+    /// The user is thinking that a leading `|` is allowed in this position.
+    fn recover_inner_leading_vert(&mut self) {
         if let token::BinOp(token::Or) | token::OrOr = self.token.kind {
             let span = self.token.span;
             let rm_msg = format!("remove the `{}`", pprust::token_to_string(&self.token));
@@ -190,8 +195,6 @@ impl<'a> Parser<'a> {
 
             self.bump();
         }
-
-        self.parse_pat_with_or(expected, GateOr::Yes, TopLevel::No)
     }
 
     /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are

From 0ab84303326fff65d5d0a168fd47448e05135c9f Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 24 Aug 2019 23:44:28 +0200
Subject: [PATCH 226/943] parser: reword || recovery.

---
 src/libsyntax/parse/parser/pat.rs                  |  2 +-
 .../ui/or-patterns/multiple-pattern-typo.stderr    | 14 +++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index dc6632cf10da9..0b3de57fd6f30 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -119,7 +119,7 @@ impl<'a> Parser<'a> {
         self.struct_span_err(self.token.span, "unexpected token `||` after pattern")
             .span_suggestion(
                 self.token.span,
-                "use a single `|` to specify multiple patterns",
+                "use a single `|` to separate multiple alternative patterns",
                 "|".to_owned(),
                 Applicability::MachineApplicable
             )
diff --git a/src/test/ui/or-patterns/multiple-pattern-typo.stderr b/src/test/ui/or-patterns/multiple-pattern-typo.stderr
index 765c7879b12ca..c61b5cb208251 100644
--- a/src/test/ui/or-patterns/multiple-pattern-typo.stderr
+++ b/src/test/ui/or-patterns/multiple-pattern-typo.stderr
@@ -2,43 +2,43 @@ error: unexpected token `||` after pattern
   --> $DIR/multiple-pattern-typo.rs:8:15
    |
 LL |         1 | 2 || 3 => (),
-   |               ^^ help: use a single `|` to specify multiple patterns: `|`
+   |               ^^ help: use a single `|` to separate multiple alternative patterns: `|`
 
 error: unexpected token `||` after pattern
   --> $DIR/multiple-pattern-typo.rs:13:16
    |
 LL |         (1 | 2 || 3) => (),
-   |                ^^ help: use a single `|` to specify multiple patterns: `|`
+   |                ^^ help: use a single `|` to separate multiple alternative patterns: `|`
 
 error: unexpected token `||` after pattern
   --> $DIR/multiple-pattern-typo.rs:18:16
    |
 LL |         (1 | 2 || 3,) => (),
-   |                ^^ help: use a single `|` to specify multiple patterns: `|`
+   |                ^^ help: use a single `|` to separate multiple alternative patterns: `|`
 
 error: unexpected token `||` after pattern
   --> $DIR/multiple-pattern-typo.rs:25:18
    |
 LL |         TS(1 | 2 || 3) => (),
-   |                  ^^ help: use a single `|` to specify multiple patterns: `|`
+   |                  ^^ help: use a single `|` to separate multiple alternative patterns: `|`
 
 error: unexpected token `||` after pattern
   --> $DIR/multiple-pattern-typo.rs:32:23
    |
 LL |         NS { f: 1 | 2 || 3 } => (),
-   |                       ^^ help: use a single `|` to specify multiple patterns: `|`
+   |                       ^^ help: use a single `|` to separate multiple alternative patterns: `|`
 
 error: unexpected token `||` after pattern
   --> $DIR/multiple-pattern-typo.rs:37:16
    |
 LL |         [1 | 2 || 3] => (),
-   |                ^^ help: use a single `|` to specify multiple patterns: `|`
+   |                ^^ help: use a single `|` to separate multiple alternative patterns: `|`
 
 error: unexpected token `||` after pattern
   --> $DIR/multiple-pattern-typo.rs:42:9
    |
 LL |         || 1 | 2 | 3 => (),
-   |         ^^ help: use a single `|` to specify multiple patterns: `|`
+   |         ^^ help: use a single `|` to separate multiple alternative patterns: `|`
 
 warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
   --> $DIR/multiple-pattern-typo.rs:1:12

From 3890befa8ea9def7e1c9c57a321c7b8c9f759f1f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 24 Aug 2019 14:54:35 -0700
Subject: [PATCH 227/943] review comment

---
 src/librustc/ty/sty.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 7b7e2b8bfbdc8..f41fffe507d97 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -385,7 +385,6 @@ impl<'tcx> ClosureSubsts<'tcx> {
         let ty = self.closure_sig_ty(def_id, tcx);
         match ty.sty {
             ty::FnPtr(sig) => sig,
-            ty::Infer(_) | ty::Error => ty::Binder::dummy(FnSig::fake()),  // ignore errors
             _ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty.sty),
         }
     }

From 4f7532765967ea174816a23c11188aa8c7865966 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 25 Aug 2019 00:08:28 +0200
Subject: [PATCH 228/943] typeck/pat.rs: dedup in `check_pat_ref`.

---
 src/librustc_typeck/check/pat.rs | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index f0ecbd674c07d..7506cbdd5104a 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -981,7 +981,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let expected = self.shallow_resolve(expected);
-        if self.check_dereferencable(pat.span, expected, &inner) {
+        let (rptr_ty, inner_ty) = if self.check_dereferencable(pat.span, expected, &inner) {
             // `demand::subtype` would be good enough, but using `eqtype` turns
             // out to be equally general. See (note_1) for details.
 
@@ -989,10 +989,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // to avoid creating needless variables. This also helps with
             // the bad  interactions of the given hack detailed in (note_1).
             debug!("check_pat_ref: expected={:?}", expected);
-            let (rptr_ty, inner_ty) = match expected.sty {
-                ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
-                    (expected, r_ty)
-                }
+            match expected.sty {
+                ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
                 _ => {
                     let inner_ty = self.next_ty_var(
                         TypeVariableOrigin {
@@ -1012,14 +1010,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
                     (rptr_ty, inner_ty)
                 }
-            };
-
-            self.check_pat(&inner, inner_ty, def_bm, discrim_span);
-            rptr_ty
+            }
         } else {
-            self.check_pat(&inner, tcx.types.err, def_bm, discrim_span);
-            tcx.types.err
-        }
+            (tcx.types.err, tcx.types.err)
+        };
+        self.check_pat(&inner, inner_ty, def_bm, discrim_span);
+        rptr_ty
     }
 
     /// Create a reference type with a fresh region variable.

From c8619ae7916459bec1b7e5583d75c69b10f06df9 Mon Sep 17 00:00:00 2001
From: Marcin Mielniczuk <marmistrz.dev@zoho.eu>
Date: Sun, 25 Aug 2019 00:09:12 +0200
Subject: [PATCH 229/943] Document platform-specific behavior of the iterator
 returned by std::fs::read_dir

---
 src/libstd/fs.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 5f76875bd66c4..90d911a6f9ac0 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -1956,7 +1956,8 @@ pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// # Platform-specific behavior
 ///
 /// This function currently corresponds to the `opendir` function on Unix
-/// and the `FindFirstFile` function on Windows.
+/// and the `FindFirstFile` function on Windows. Advancing the iterator
+/// currently corresponds to `readdir` on Unix and `FindNextFile` on Windows.
 /// Note that, this [may change in the future][changes].
 ///
 /// [changes]: ../io/index.html#platform-specific-behavior

From 5a7e1cb46a05fd176e5488beb58f72a05f4b1a0d Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 25 Aug 2019 00:27:55 +0200
Subject: [PATCH 230/943] typeck/pat.rs: dedup in `check_pat_box`.

---
 src/librustc_typeck/check/pat.rs | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 7506cbdd5104a..3f6fc95360a5e 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -952,22 +952,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         discrim_span: Option<Span>,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
-        let inner_ty = self.next_ty_var(TypeVariableOrigin {
-            kind: TypeVariableOriginKind::TypeInference,
-            span: inner.span,
-        });
-        let uniq_ty = tcx.mk_box(inner_ty);
-
-        if self.check_dereferencable(span, expected, &inner) {
+        let (box_ty, inner_ty) = if self.check_dereferencable(span, expected, &inner) {
             // Here, `demand::subtype` is good enough, but I don't
             // think any errors can be introduced by using `demand::eqtype`.
-            self.demand_eqtype_pat(span, expected, uniq_ty, discrim_span);
-            self.check_pat(&inner, inner_ty, def_bm, discrim_span);
-            uniq_ty
+            let inner_ty = self.next_ty_var(TypeVariableOrigin {
+                kind: TypeVariableOriginKind::TypeInference,
+                span: inner.span,
+            });
+            let box_ty = tcx.mk_box(inner_ty);
+            self.demand_eqtype_pat(span, expected, box_ty, discrim_span);
+            (box_ty, inner_ty)
         } else {
-            self.check_pat(&inner, tcx.types.err, def_bm, discrim_span);
-            tcx.types.err
-        }
+            (tcx.types.err, tcx.types.err)
+        };
+        self.check_pat(&inner, inner_ty, def_bm, discrim_span);
+        box_ty
     }
 
     fn check_pat_ref(

From 1202cb0e2b168b0a913b33e3cb3c1d9339683e28 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 25 Aug 2019 01:00:19 +0200
Subject: [PATCH 231/943] parser: simplify parse_pat_with_or_{inner}

---
 src/libsyntax/parse/parser/pat.rs | 27 ++++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 0b3de57fd6f30..7c09dc4e56634 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -49,7 +49,7 @@ impl<'a> Parser<'a> {
         let gated_leading_vert = self.eat_or_separator() && gate_or == GateOr::Yes;
 
         // Parse the possibly-or-pattern.
-        let pat = self.parse_pat_with_or(None, gate_or, TopLevel::Yes)?;
+        let pat = self.parse_pat_with_or(gate_or, TopLevel::Yes)?;
 
         // If we parsed a leading `|` which should be gated,
         // and no other gated or-pattern has been parsed thus far,
@@ -67,14 +67,9 @@ impl<'a> Parser<'a> {
 
     /// Parses a pattern, that may be a or-pattern (e.g. `Foo | Bar` in `Some(Foo | Bar)`).
     /// Corresponds to `pat<allow_top_alt>` in RFC 2535.
-    fn parse_pat_with_or(
-        &mut self,
-        expected: Expected,
-        gate_or: GateOr,
-        top_level: TopLevel,
-    ) -> PResult<'a, P<Pat>> {
+    fn parse_pat_with_or(&mut self, gate_or: GateOr, top_level: TopLevel) -> PResult<'a, P<Pat>> {
         // Parse the first pattern.
-        let first_pat = self.parse_pat(expected)?;
+        let first_pat = self.parse_pat(None)?;
         self.maybe_recover_unexpected_comma(first_pat.span, top_level)?;
 
         // If the next token is not a `|`,
@@ -86,7 +81,7 @@ impl<'a> Parser<'a> {
         let lo = first_pat.span;
         let mut pats = vec![first_pat];
         while self.eat_or_separator() {
-            let pat = self.parse_pat(expected)?;
+            let pat = self.parse_pat(None)?;
             self.maybe_recover_unexpected_comma(pat.span, top_level)?;
             pats.push(pat);
         }
@@ -177,9 +172,9 @@ impl<'a> Parser<'a> {
 
     /// Recursive possibly-or-pattern parser with recovery for an erroneous leading `|`.
     /// See `parse_pat_with_or` for details on parsing or-patterns.
-    fn parse_pat_with_or_inner(&mut self, expected: Expected) -> PResult<'a, P<Pat>> {
+    fn parse_pat_with_or_inner(&mut self) -> PResult<'a, P<Pat>> {
         self.recover_inner_leading_vert();
-        self.parse_pat_with_or(expected, GateOr::Yes, TopLevel::No)
+        self.parse_pat_with_or(GateOr::Yes, TopLevel::No)
     }
 
     /// Recover if `|` or `||` is here.
@@ -215,7 +210,7 @@ impl<'a> Parser<'a> {
                 // Parse `[pat, pat,...]` as a slice pattern.
                 let (pats, _) = self.parse_delim_comma_seq(
                     token::Bracket,
-                    |p| p.parse_pat_with_or_inner(None),
+                    |p| p.parse_pat_with_or_inner(),
                 )?;
                 PatKind::Slice(pats)
             }
@@ -344,9 +339,7 @@ impl<'a> Parser<'a> {
 
     /// Parse a tuple or parenthesis pattern.
     fn parse_pat_tuple_or_parens(&mut self) -> PResult<'a, PatKind> {
-        let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| {
-            p.parse_pat_with_or_inner(None)
-        })?;
+        let (fields, trailing_comma) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or_inner())?;
 
         // Here, `(pat,)` is a tuple pattern.
         // For backward compatibility, `(..)` is a tuple pattern as well.
@@ -589,7 +582,7 @@ impl<'a> Parser<'a> {
             err.span_label(self.token.span, msg);
             return Err(err);
         }
-        let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or_inner(None))?;
+        let (fields, _) = self.parse_paren_comma_seq(|p| p.parse_pat_with_or_inner())?;
         Ok(PatKind::TupleStruct(path, fields))
     }
 
@@ -733,7 +726,7 @@ impl<'a> Parser<'a> {
             // Parsing a pattern of the form "fieldname: pat"
             let fieldname = self.parse_field_name()?;
             self.bump();
-            let pat = self.parse_pat_with_or_inner(None)?;
+            let pat = self.parse_pat_with_or_inner()?;
             hi = pat.span;
             (pat, fieldname, false)
         } else {

From 083963e58c752f1a51b67d65dc6a207bf69f1d64 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 25 Aug 2019 01:50:21 +0200
Subject: [PATCH 232/943] parser: 'while parsing this or-pattern...'

---
 src/libsyntax/parse/parser/pat.rs                      |  5 ++++-
 .../ui/or-patterns/while-parsing-this-or-pattern.rs    |  9 +++++++++
 .../or-patterns/while-parsing-this-or-pattern.stderr   | 10 ++++++++++
 3 files changed, 23 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/or-patterns/while-parsing-this-or-pattern.rs
 create mode 100644 src/test/ui/or-patterns/while-parsing-this-or-pattern.stderr

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 7c09dc4e56634..a0278fa407765 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -81,7 +81,10 @@ impl<'a> Parser<'a> {
         let lo = first_pat.span;
         let mut pats = vec![first_pat];
         while self.eat_or_separator() {
-            let pat = self.parse_pat(None)?;
+            let pat = self.parse_pat(None).map_err(|mut err| {
+                err.span_label(lo, "while parsing this or-pattern staring here");
+                err
+            })?;
             self.maybe_recover_unexpected_comma(pat.span, top_level)?;
             pats.push(pat);
         }
diff --git a/src/test/ui/or-patterns/while-parsing-this-or-pattern.rs b/src/test/ui/or-patterns/while-parsing-this-or-pattern.rs
new file mode 100644
index 0000000000000..4a9fae1406af7
--- /dev/null
+++ b/src/test/ui/or-patterns/while-parsing-this-or-pattern.rs
@@ -0,0 +1,9 @@
+// Test the parser for the "while parsing this or-pattern..." label here.
+
+fn main() {
+    match Some(42) {
+        Some(42) | .=. => {} //~ ERROR expected pattern, found `.`
+        //~^ while parsing this or-pattern staring here
+        //~| NOTE expected pattern
+    }
+}
diff --git a/src/test/ui/or-patterns/while-parsing-this-or-pattern.stderr b/src/test/ui/or-patterns/while-parsing-this-or-pattern.stderr
new file mode 100644
index 0000000000000..21fece6c64fe5
--- /dev/null
+++ b/src/test/ui/or-patterns/while-parsing-this-or-pattern.stderr
@@ -0,0 +1,10 @@
+error: expected pattern, found `.`
+  --> $DIR/while-parsing-this-or-pattern.rs:5:20
+   |
+LL |         Some(42) | .=. => {}
+   |         --------   ^ expected pattern
+   |         |
+   |         while parsing this or-pattern staring here
+
+error: aborting due to previous error
+

From 59c063302f3ce8e3020a94183c1cf4f203119ab2 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Sat, 24 Aug 2019 14:16:56 -0700
Subject: [PATCH 233/943] Allow lifetime parameters to be inferred

---
 src/librustc/mir/mod.rs                     | 6 +++---
 src/librustc_mir/dataflow/move_paths/mod.rs | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 11701a6637744..654d3d780fcb2 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1555,7 +1555,7 @@ pub struct Statement<'tcx> {
 #[cfg(target_arch = "x86_64")]
 static_assert_size!(Statement<'_>, 56);
 
-impl<'tcx> Statement<'tcx> {
+impl Statement<'_> {
     /// Changes a statement to a nop. This is both faster than deleting instructions and avoids
     /// invalidating statement indices in `Location`s.
     pub fn make_nop(&mut self) {
@@ -1677,7 +1677,7 @@ pub struct InlineAsm<'tcx> {
     pub inputs: Box<[(Span, Operand<'tcx>)]>,
 }
 
-impl<'tcx> Debug for Statement<'tcx> {
+impl Debug for Statement<'_> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
         use self::StatementKind::*;
         match self.kind {
@@ -2047,7 +2047,7 @@ impl<'p, 'tcx> Iterator for ProjectionsIter<'p, 'tcx> {
 
 impl<'p, 'tcx> FusedIterator for ProjectionsIter<'p, 'tcx> {}
 
-impl<'tcx> Debug for Place<'tcx> {
+impl Debug for Place<'_> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
         self.iterate(|_place_base, place_projections| {
             // FIXME: remove this collect once we have migrated to slices
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index 5c2255882b2c7..e5a19572170a7 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -240,7 +240,7 @@ impl MovePathLookup {
     // alternative will *not* create a MovePath on the fly for an
     // unknown place, but will rather return the nearest available
     // parent.
-    pub fn find(&self, place_ref: PlaceRef<'cx, 'tcx>) -> LookupResult {
+    pub fn find(&self, place_ref: PlaceRef<'_, '_>) -> LookupResult {
         place_ref.iterate(|place_base, place_projection| {
             let mut result = match place_base {
                 PlaceBase::Local(local) => self.locals[*local],

From 717e8a5219c491d0e8e865cc6abafc6fce6c4dff Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Sat, 24 Aug 2019 14:19:32 -0700
Subject: [PATCH 234/943] Join arms patterns, body is empty in all arms

---
 src/librustc/mir/visit.rs | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 2d16e7bcc8371..24420cb4d7e91 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -724,10 +724,6 @@ macro_rules! make_mir_visitor {
                 }
 
                 match & $($mutability)? proj.elem {
-                    ProjectionElem::Deref => {
-                    }
-                    ProjectionElem::Subslice { from: _, to: _ } => {
-                    }
                     ProjectionElem::Field(_field, ty) => {
                         self.visit_ty(ty, TyContext::Location(location));
                     }
@@ -738,11 +734,12 @@ macro_rules! make_mir_visitor {
                             location
                         );
                     }
+                    ProjectionElem::Deref |
+                    ProjectionElem::Subslice { from: _, to: _ } |
                     ProjectionElem::ConstantIndex { offset: _,
                                                     min_length: _,
-                                                    from_end: _ } => {
-                    }
-                    ProjectionElem::Downcast(_name, _variant_index) => {
+                                                    from_end: _ } |
+                    ProjectionElem::Downcast(_, _) => {
                     }
                 }
             }

From 53f47347941de87dff536f3875f0a62a7fda4459 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Sat, 24 Aug 2019 15:26:25 -0700
Subject: [PATCH 235/943] Add a period at the end of the sentence

---
 src/librustc_mir/borrow_check/prefixes.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs
index ecafd4eb1157e..4c6be23de28be 100644
--- a/src/librustc_mir/borrow_check/prefixes.rs
+++ b/src/librustc_mir/borrow_check/prefixes.rs
@@ -136,7 +136,7 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
                 }
                 PrefixSet::All => {
                     // all prefixes: just blindly enqueue the base
-                    // of the projection
+                    // of the projection.
                     self.next = Some(PlaceRef {
                         base: cursor.base,
                         projection: &proj.base,

From fbe3f3e98f1cd5203b18ffacb176c70590390a63 Mon Sep 17 00:00:00 2001
From: Philip Craig <philipjcraig@gmail.com>
Date: Sun, 25 Aug 2019 13:01:46 +1000
Subject: [PATCH 236/943] debuginfo: give unique names to closure and generator
 types

Closure types have been moved to the namespace where they
are defined, and both closure and generator type names now
include the disambiguator.

This fixes an exception when lldb prints nested closures.

Fixes #57822
---
 .../debuginfo/metadata.rs                     | 10 +++-
 .../debuginfo/type_names.rs                   | 12 +++-
 src/test/debuginfo/issue-57822.rs             | 55 +++++++++++++++++++
 3 files changed, 72 insertions(+), 5 deletions(-)
 create mode 100644 src/test/debuginfo/issue-57822.rs

diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 51e789b17880a..928532a1f4760 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -683,11 +683,13 @@ pub fn type_metadata(
         }
         ty::Closure(def_id, substs) => {
             let upvar_tys : Vec<_> = substs.upvar_tys(def_id, cx.tcx).collect();
+            let containing_scope = get_namespace_for_item(cx, def_id);
             prepare_tuple_metadata(cx,
                                    t,
                                    &upvar_tys,
                                    unique_type_id,
-                                   usage_site_span).finalize(cx)
+                                   usage_site_span,
+                                   Some(containing_scope)).finalize(cx)
         }
         ty::Generator(def_id, substs,  _) => {
             let upvar_tys : Vec<_> = substs.prefix_tys(def_id, cx.tcx).map(|t| {
@@ -728,7 +730,8 @@ pub fn type_metadata(
                                    t,
                                    &tys,
                                    unique_type_id,
-                                   usage_site_span).finalize(cx)
+                                   usage_site_span,
+                                   NO_SCOPE_METADATA).finalize(cx)
         }
         _ => {
             bug!("debuginfo: unexpected type in type_metadata: {:?}", t)
@@ -1205,6 +1208,7 @@ fn prepare_tuple_metadata(
     component_types: &[Ty<'tcx>],
     unique_type_id: UniqueTypeId,
     span: Span,
+    containing_scope: Option<&'ll DIScope>,
 ) -> RecursiveTypeDescription<'ll, 'tcx> {
     let tuple_name = compute_debuginfo_type_name(cx.tcx, tuple_type, false);
 
@@ -1212,7 +1216,7 @@ fn prepare_tuple_metadata(
                                          tuple_type,
                                          &tuple_name[..],
                                          unique_type_id,
-                                         NO_SCOPE_METADATA);
+                                         containing_scope);
 
     create_and_register_recursive_type_forward_declaration(
         cx,
diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs
index ea39913d4b91b..b7c782528de0c 100644
--- a/src/librustc_codegen_ssa/debuginfo/type_names.rs
+++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs
@@ -190,11 +190,19 @@ pub fn push_debuginfo_type_name<'tcx>(
             // processing
             visited.remove(t);
         },
-        ty::Closure(..) => {
+        ty::Closure(def_id, ..) => {
             output.push_str("closure");
+            let disambiguator = tcx.def_key(def_id).disambiguated_data.disambiguator;
+            if disambiguator != 0 {
+                output.push_str(&format!("-{}", disambiguator));
+            }
         }
-        ty::Generator(..) => {
+        ty::Generator(def_id, ..) => {
             output.push_str("generator");
+            let disambiguator = tcx.def_key(def_id).disambiguated_data.disambiguator;
+            if disambiguator != 0 {
+                output.push_str(&format!("-{}", disambiguator));
+            }
         }
         ty::Error |
         ty::Infer(_) |
diff --git a/src/test/debuginfo/issue-57822.rs b/src/test/debuginfo/issue-57822.rs
new file mode 100644
index 0000000000000..ba5e8e0f2192a
--- /dev/null
+++ b/src/test/debuginfo/issue-57822.rs
@@ -0,0 +1,55 @@
+// This test makes sure that the LLDB pretty printer does not throw an exception
+// for nested closures and generators.
+
+// Require LLVM with DW_TAG_variant_part and a gdb that can read it.
+// min-system-llvm-version: 8.0
+// min-gdb-version: 8.2
+// ignore-tidy-linelength
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:run
+
+// gdb-command:print g
+// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure (1))
+
+// gdb-command:print b
+// gdb-check:$2 = issue_57822::main::generator-3 {__0: issue_57822::main::generator-2 {__0: 2, <<variant>>: {[...]}}, <<variant>>: {[...]}}
+
+// === LLDB TESTS ==================================================================================
+
+// lldb-command:run
+
+// lldb-command:print g
+// lldbg-check:(issue_57822::main::closure-1) $0 = closure-1(closure(1))
+
+// lldb-command:print b
+// lldbg-check:(issue_57822::main::generator-3) $1 = generator-3(generator-2(2))
+
+#![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
+#![omit_gdb_pretty_printer_section]
+
+use std::ops::Generator;
+use std::pin::Pin;
+
+fn main() {
+    let mut x = 1;
+    let f = move || x;
+    let g = move || f();
+
+    let mut y = 2;
+    let mut a = move || {
+        y += 1;
+        yield;
+    };
+    let mut b = move || {
+        Pin::new(&mut a).resume();
+        yield;
+    };
+
+    zzz(); // #break
+}
+
+fn zzz() { () }

From 1caaa40768fecb91b322b1e1befc91c54b56817c Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 25 Aug 2019 04:39:28 +0200
Subject: [PATCH 237/943] parser: gracefully handle `fn foo(A | B: type)`.

---
 src/libsyntax/parse/parser.rs                 |  2 +-
 src/libsyntax/parse/parser/expr.rs            |  4 +-
 src/libsyntax/parse/parser/pat.rs             | 46 +++++++++++++++----
 src/test/ui/anon-params-denied-2018.rs        |  2 +-
 src/test/ui/anon-params-denied-2018.stderr    | 16 +++----
 .../feature-gate-or_patterns-leading.stderr   | 12 -----
 .../or-patterns/or-patterns-syntactic-fail.rs |  6 ++-
 .../or-patterns-syntactic-fail.stderr         | 42 +++++++++++------
 src/test/ui/parser/inverted-parameters.rs     | 12 ++---
 src/test/ui/parser/inverted-parameters.stderr | 24 +++++-----
 src/test/ui/parser/issue-33413.rs             |  2 +-
 src/test/ui/parser/issue-33413.stderr         |  4 +-
 src/test/ui/parser/issue-63135.rs             |  2 +-
 src/test/ui/parser/issue-63135.stderr         | 12 ++---
 src/test/ui/parser/omitted-arg-in-item-fn.rs  |  2 +-
 .../ui/parser/omitted-arg-in-item-fn.stderr   |  4 +-
 src/test/ui/parser/pat-lt-bracket-2.rs        |  2 +-
 src/test/ui/parser/pat-lt-bracket-2.stderr    |  4 +-
 src/test/ui/parser/removed-syntax-mode.rs     |  2 +-
 src/test/ui/parser/removed-syntax-mode.stderr |  4 +-
 .../rfc-2565-param-attrs/param-attrs-2018.rs  |  2 +-
 .../param-attrs-2018.stderr                   |  4 +-
 src/test/ui/span/issue-34264.stderr           | 12 ++---
 23 files changed, 125 insertions(+), 97 deletions(-)
 delete mode 100644 src/test/ui/or-patterns/feature-gate-or_patterns-leading.stderr

diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 002e9bccec72a..25ad2d4404cac 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -988,7 +988,7 @@ impl<'a> Parser<'a> {
         let (pat, ty) = if is_name_required || self.is_named_argument() {
             debug!("parse_arg_general parse_pat (is_name_required:{})", is_name_required);
 
-            let pat = self.parse_pat(Some("argument name"))?;
+            let pat = self.parse_fn_param_pat()?;
             if let Err(mut err) = self.expect(&token::Colon) {
                 if let Some(ident) = self.argument_without_type(
                     &mut err,
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 83e5a84a8c6ae..f7c090b5135e9 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -1,7 +1,7 @@
 use super::{Parser, PResult, Restrictions, PrevTokenKind, TokenType, PathStyle};
 use super::{BlockMode, SemiColonMode};
 use super::{SeqSep, TokenExpectType};
-use super::pat::GateOr;
+use super::pat::{GateOr, PARAM_EXPECTED};
 
 use crate::maybe_recover_from_interpolated_ty_qpath;
 use crate::ptr::P;
@@ -1176,7 +1176,7 @@ impl<'a> Parser<'a> {
     fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
         let lo = self.token.span;
         let attrs = self.parse_arg_attributes()?;
-        let pat = self.parse_pat(Some("argument name"))?;
+        let pat = self.parse_pat(PARAM_EXPECTED)?;
         let t = if self.eat(&token::Colon) {
             self.parse_ty()?
         } else {
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index a0278fa407765..1541031ec2539 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -14,6 +14,9 @@ use errors::{Applicability, DiagnosticBuilder};
 
 type Expected = Option<&'static str>;
 
+/// `Expected` for function and lambda parameter patterns.
+pub(super) const PARAM_EXPECTED: Expected = Some("parameter name");
+
 /// Whether or not an or-pattern should be gated when occurring in the current context.
 #[derive(PartialEq)]
 pub enum GateOr { Yes, No }
@@ -49,7 +52,7 @@ impl<'a> Parser<'a> {
         let gated_leading_vert = self.eat_or_separator() && gate_or == GateOr::Yes;
 
         // Parse the possibly-or-pattern.
-        let pat = self.parse_pat_with_or(gate_or, TopLevel::Yes)?;
+        let pat = self.parse_pat_with_or(None, gate_or, TopLevel::Yes)?;
 
         // If we parsed a leading `|` which should be gated,
         // and no other gated or-pattern has been parsed thus far,
@@ -65,11 +68,38 @@ impl<'a> Parser<'a> {
         Ok(pat)
     }
 
+    /// Parse the pattern for a function or function pointer parameter.
+    /// Special recovery is provided for or-patterns and leading `|`.
+    pub(super) fn parse_fn_param_pat(&mut self) -> PResult<'a, P<Pat>> {
+        self.recover_leading_vert("not allowed in a parameter pattern");
+        let pat = self.parse_pat_with_or(PARAM_EXPECTED, GateOr::No, TopLevel::No)?;
+
+        if let PatKind::Or(..) = &pat.node {
+            self.ban_illegal_fn_param_or_pat(&pat);
+        }
+
+        Ok(pat)
+    }
+
+    /// Ban `A | B` immediately in a parameter pattern and suggest wrapping in parens.
+    fn ban_illegal_fn_param_or_pat(&self, pat: &Pat) {
+        let msg = "wrap the pattern in parenthesis";
+        let fix = format!("({})", pprust::pat_to_string(pat));
+        self.struct_span_err(pat.span, "an or-pattern parameter must be wrapped in parenthesis")
+            .span_suggestion(pat.span, msg, fix, Applicability::MachineApplicable)
+            .emit();
+    }
+
     /// Parses a pattern, that may be a or-pattern (e.g. `Foo | Bar` in `Some(Foo | Bar)`).
     /// Corresponds to `pat<allow_top_alt>` in RFC 2535.
-    fn parse_pat_with_or(&mut self, gate_or: GateOr, top_level: TopLevel) -> PResult<'a, P<Pat>> {
+    fn parse_pat_with_or(
+        &mut self,
+        expected: Expected,
+        gate_or: GateOr,
+        top_level: TopLevel,
+    ) -> PResult<'a, P<Pat>> {
         // Parse the first pattern.
-        let first_pat = self.parse_pat(None)?;
+        let first_pat = self.parse_pat(expected)?;
         self.maybe_recover_unexpected_comma(first_pat.span, top_level)?;
 
         // If the next token is not a `|`,
@@ -81,7 +111,7 @@ impl<'a> Parser<'a> {
         let lo = first_pat.span;
         let mut pats = vec![first_pat];
         while self.eat_or_separator() {
-            let pat = self.parse_pat(None).map_err(|mut err| {
+            let pat = self.parse_pat(expected).map_err(|mut err| {
                 err.span_label(lo, "while parsing this or-pattern staring here");
                 err
             })?;
@@ -176,18 +206,18 @@ impl<'a> Parser<'a> {
     /// Recursive possibly-or-pattern parser with recovery for an erroneous leading `|`.
     /// See `parse_pat_with_or` for details on parsing or-patterns.
     fn parse_pat_with_or_inner(&mut self) -> PResult<'a, P<Pat>> {
-        self.recover_inner_leading_vert();
-        self.parse_pat_with_or(GateOr::Yes, TopLevel::No)
+        self.recover_leading_vert("only allowed in a top-level pattern");
+        self.parse_pat_with_or(None, GateOr::Yes, TopLevel::No)
     }
 
     /// Recover if `|` or `||` is here.
     /// The user is thinking that a leading `|` is allowed in this position.
-    fn recover_inner_leading_vert(&mut self) {
+    fn recover_leading_vert(&mut self, ctx: &str) {
         if let token::BinOp(token::Or) | token::OrOr = self.token.kind {
             let span = self.token.span;
             let rm_msg = format!("remove the `{}`", pprust::token_to_string(&self.token));
 
-            self.struct_span_err(span, "a leading `|` is only allowed in a top-level pattern")
+            self.struct_span_err(span, &format!("a leading `|` is {}", ctx))
                 .span_suggestion(span, &rm_msg, String::new(), Applicability::MachineApplicable)
                 .emit();
 
diff --git a/src/test/ui/anon-params-denied-2018.rs b/src/test/ui/anon-params-denied-2018.rs
index abff8275064e2..5721f5d235783 100644
--- a/src/test/ui/anon-params-denied-2018.rs
+++ b/src/test/ui/anon-params-denied-2018.rs
@@ -3,7 +3,7 @@
 // edition:2018
 
 trait T {
-    fn foo(i32); //~ expected one of `:` or `@`, found `)`
+    fn foo(i32); //~ expected one of `:`, `@`, or `|`, found `)`
 
     fn bar_with_default_impl(String, String) {}
     //~^ ERROR expected one of `:`
diff --git a/src/test/ui/anon-params-denied-2018.stderr b/src/test/ui/anon-params-denied-2018.stderr
index 438bcf4274daa..a58998e4891e0 100644
--- a/src/test/ui/anon-params-denied-2018.stderr
+++ b/src/test/ui/anon-params-denied-2018.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:` or `@`, found `)`
+error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/anon-params-denied-2018.rs:6:15
    |
 LL |     fn foo(i32);
-   |               ^ expected one of `:` or `@` here
+   |               ^ expected one of `:`, `@`, or `|` here
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
@@ -14,11 +14,11 @@ help: if this is a type, explicitly ignore the parameter name
 LL |     fn foo(_: i32);
    |            ^^^^^^
 
-error: expected one of `:` or `@`, found `,`
+error: expected one of `:`, `@`, or `|`, found `,`
   --> $DIR/anon-params-denied-2018.rs:8:36
    |
 LL |     fn bar_with_default_impl(String, String) {}
-   |                                    ^ expected one of `:` or `@` here
+   |                                    ^ expected one of `:`, `@`, or `|` here
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
@@ -30,11 +30,11 @@ help: if this is a type, explicitly ignore the parameter name
 LL |     fn bar_with_default_impl(_: String, String) {}
    |                              ^^^^^^^^^
 
-error: expected one of `:` or `@`, found `)`
+error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/anon-params-denied-2018.rs:8:44
    |
 LL |     fn bar_with_default_impl(String, String) {}
-   |                                            ^ expected one of `:` or `@` here
+   |                                            ^ expected one of `:`, `@`, or `|` here
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
@@ -46,11 +46,11 @@ help: if this is a type, explicitly ignore the parameter name
 LL |     fn bar_with_default_impl(String, _: String) {}
    |                                      ^^^^^^^^^
 
-error: expected one of `:` or `@`, found `,`
+error: expected one of `:`, `@`, or `|`, found `,`
   --> $DIR/anon-params-denied-2018.rs:13:22
    |
 LL |     fn baz(a:usize, b, c: usize) -> usize {
-   |                      ^ expected one of `:` or `@` here
+   |                      ^ expected one of `:`, `@`, or `|` here
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns-leading.stderr b/src/test/ui/or-patterns/feature-gate-or_patterns-leading.stderr
deleted file mode 100644
index 8b18082fca7df..0000000000000
--- a/src/test/ui/or-patterns/feature-gate-or_patterns-leading.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns-leading.rs:7:11
-   |
-LL |     let | A;
-   |           ^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/54883
-   = help: add `#![feature(or_patterns)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
index 7959812f5b39c..b676ea851a3ba 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
@@ -25,7 +25,11 @@ fn no_top_level_or_patterns() {
     //           -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`.
 
     // ...and for now neither do we allow or-patterns at the top level of functions.
-    fn fun(A | B: E) {} //~ ERROR expected one of `:` or `@`, found `|`
+    fn fun1(A | B: E) {} //~ ERROR an or-pattern parameter must be wrapped in parenthesis
+
+    fn fun2(| A | B: E) {}
+    //~^ ERROR a leading `|` is not allowed in a parameter pattern
+    //~| ERROR an or-pattern parameter must be wrapped in parenthesis
 }
 
 // We also do not allow a leading `|` when not in a top level position:
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
index dd4c309ce85a3..2a3a6abfb7b62 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
@@ -1,59 +1,71 @@
-error: expected one of `:` or `@`, found `|`
-  --> $DIR/or-patterns-syntactic-fail.rs:28:14
+error: an or-pattern parameter must be wrapped in parenthesis
+  --> $DIR/or-patterns-syntactic-fail.rs:28:13
    |
-LL |     fn fun(A | B: E) {}
-   |              ^ expected one of `:` or `@` here
+LL |     fn fun1(A | B: E) {}
+   |             ^^^^^ help: wrap the pattern in parenthesis: `(A | B)`
+
+error: a leading `|` is not allowed in a parameter pattern
+  --> $DIR/or-patterns-syntactic-fail.rs:30:13
+   |
+LL |     fn fun2(| A | B: E) {}
+   |             ^ help: remove the `|`
+
+error: an or-pattern parameter must be wrapped in parenthesis
+  --> $DIR/or-patterns-syntactic-fail.rs:30:15
+   |
+LL |     fn fun2(| A | B: E) {}
+   |               ^^^^^ help: wrap the pattern in parenthesis: `(A | B)`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:37:11
+  --> $DIR/or-patterns-syntactic-fail.rs:41:11
    |
 LL |     let ( | A | B) = E::A;
    |           ^ help: remove the `|`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:38:11
+  --> $DIR/or-patterns-syntactic-fail.rs:42:11
    |
 LL |     let ( | A | B,) = (E::B,);
    |           ^ help: remove the `|`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:39:11
+  --> $DIR/or-patterns-syntactic-fail.rs:43:11
    |
 LL |     let [ | A | B ] = [E::A];
    |           ^ help: remove the `|`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:40:13
+  --> $DIR/or-patterns-syntactic-fail.rs:44:13
    |
 LL |     let TS( | A | B );
    |             ^ help: remove the `|`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:41:17
+  --> $DIR/or-patterns-syntactic-fail.rs:45:17
    |
 LL |     let NS { f: | A | B };
    |                 ^ help: remove the `|`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:43:11
+  --> $DIR/or-patterns-syntactic-fail.rs:47:11
    |
 LL |     let ( || A | B) = E::A;
    |           ^^ help: remove the `||`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:44:11
+  --> $DIR/or-patterns-syntactic-fail.rs:48:11
    |
 LL |     let [ || A | B ] = [E::A];
    |           ^^ help: remove the `||`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:45:13
+  --> $DIR/or-patterns-syntactic-fail.rs:49:13
    |
 LL |     let TS( || A | B );
    |             ^^ help: remove the `||`
 
 error: a leading `|` is only allowed in a top-level pattern
-  --> $DIR/or-patterns-syntactic-fail.rs:46:17
+  --> $DIR/or-patterns-syntactic-fail.rs:50:17
    |
 LL |     let NS { f: || A | B };
    |                 ^^ help: remove the `||`
@@ -95,7 +107,7 @@ LL |     let _ = |A | B: E| ();
    = note: an implementation of `std::ops::BitOr` might be missing for `E`
 
 error[E0308]: mismatched types
-  --> $DIR/or-patterns-syntactic-fail.rs:48:36
+  --> $DIR/or-patterns-syntactic-fail.rs:52:36
    |
 LL |     let recovery_witness: String = 0;
    |                                    ^
@@ -106,7 +118,7 @@ LL |     let recovery_witness: String = 0;
    = note: expected type `std::string::String`
               found type `{integer}`
 
-error: aborting due to 14 previous errors
+error: aborting due to 16 previous errors
 
 Some errors have detailed explanations: E0308, E0369.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/inverted-parameters.rs b/src/test/ui/parser/inverted-parameters.rs
index f06b951041731..d6efc8be072bd 100644
--- a/src/test/ui/parser/inverted-parameters.rs
+++ b/src/test/ui/parser/inverted-parameters.rs
@@ -2,29 +2,29 @@ struct S;
 
 impl S {
     fn foo(&self, &str bar) {}
-    //~^ ERROR expected one of `:` or `@`
+    //~^ ERROR expected one of `:`, `@`
     //~| HELP declare the type after the parameter binding
     //~| SUGGESTION <identifier>: <type>
 }
 
 fn baz(S quux, xyzzy: i32) {}
-//~^ ERROR expected one of `:` or `@`
+//~^ ERROR expected one of `:`, `@`
 //~| HELP declare the type after the parameter binding
 //~| SUGGESTION <identifier>: <type>
 
 fn one(i32 a b) {}
-//~^ ERROR expected one of `:` or `@`
+//~^ ERROR expected one of `:`, `@`
 
 fn pattern((i32, i32) (a, b)) {}
-//~^ ERROR expected `:`
+//~^ ERROR expected one of `:`
 
 fn fizz(i32) {}
-//~^ ERROR expected one of `:` or `@`
+//~^ ERROR expected one of `:`, `@`
 //~| HELP if this was a parameter name, give it a type
 //~| HELP if this is a type, explicitly ignore the parameter name
 
 fn missing_colon(quux S) {}
-//~^ ERROR expected one of `:` or `@`
+//~^ ERROR expected one of `:`, `@`
 //~| HELP declare the type after the parameter binding
 //~| SUGGESTION <identifier>: <type>
 
diff --git a/src/test/ui/parser/inverted-parameters.stderr b/src/test/ui/parser/inverted-parameters.stderr
index fb48bd1fe9383..2bda4460031a0 100644
--- a/src/test/ui/parser/inverted-parameters.stderr
+++ b/src/test/ui/parser/inverted-parameters.stderr
@@ -1,38 +1,38 @@
-error: expected one of `:` or `@`, found `bar`
+error: expected one of `:`, `@`, or `|`, found `bar`
   --> $DIR/inverted-parameters.rs:4:24
    |
 LL |     fn foo(&self, &str bar) {}
    |                   -----^^^
    |                   |    |
-   |                   |    expected one of `:` or `@` here
+   |                   |    expected one of `:`, `@`, or `|` here
    |                   help: declare the type after the parameter binding: `<identifier>: <type>`
 
-error: expected one of `:` or `@`, found `quux`
+error: expected one of `:`, `@`, or `|`, found `quux`
   --> $DIR/inverted-parameters.rs:10:10
    |
 LL | fn baz(S quux, xyzzy: i32) {}
    |        --^^^^
    |        | |
-   |        | expected one of `:` or `@` here
+   |        | expected one of `:`, `@`, or `|` here
    |        help: declare the type after the parameter binding: `<identifier>: <type>`
 
-error: expected one of `:` or `@`, found `a`
+error: expected one of `:`, `@`, or `|`, found `a`
   --> $DIR/inverted-parameters.rs:15:12
    |
 LL | fn one(i32 a b) {}
-   |            ^ expected one of `:` or `@` here
+   |            ^ expected one of `:`, `@`, or `|` here
 
-error: expected `:`, found `(`
+error: expected one of `:` or `|`, found `(`
   --> $DIR/inverted-parameters.rs:18:23
    |
 LL | fn pattern((i32, i32) (a, b)) {}
-   |                       ^ expected `:`
+   |                       ^ expected one of `:` or `|` here
 
-error: expected one of `:` or `@`, found `)`
+error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/inverted-parameters.rs:21:12
    |
 LL | fn fizz(i32) {}
-   |            ^ expected one of `:` or `@` here
+   |            ^ expected one of `:`, `@`, or `|` here
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
@@ -44,13 +44,13 @@ help: if this is a type, explicitly ignore the parameter name
 LL | fn fizz(_: i32) {}
    |         ^^^^^^
 
-error: expected one of `:` or `@`, found `S`
+error: expected one of `:`, `@`, or `|`, found `S`
   --> $DIR/inverted-parameters.rs:26:23
    |
 LL | fn missing_colon(quux S) {}
    |                  -----^
    |                  |    |
-   |                  |    expected one of `:` or `@` here
+   |                  |    expected one of `:`, `@`, or `|` here
    |                  help: declare the type after the parameter binding: `<identifier>: <type>`
 
 error: aborting due to 6 previous errors
diff --git a/src/test/ui/parser/issue-33413.rs b/src/test/ui/parser/issue-33413.rs
index 2ec86958174a4..22f80a8aae866 100644
--- a/src/test/ui/parser/issue-33413.rs
+++ b/src/test/ui/parser/issue-33413.rs
@@ -2,7 +2,7 @@ struct S;
 
 impl S {
     fn f(*, a: u8) -> u8 {}
-    //~^ ERROR expected argument name, found `*`
+    //~^ ERROR expected parameter name, found `*`
 }
 
 fn main() {}
diff --git a/src/test/ui/parser/issue-33413.stderr b/src/test/ui/parser/issue-33413.stderr
index f6f096b1b9a44..9e1178e8ac1f3 100644
--- a/src/test/ui/parser/issue-33413.stderr
+++ b/src/test/ui/parser/issue-33413.stderr
@@ -1,8 +1,8 @@
-error: expected argument name, found `*`
+error: expected parameter name, found `*`
   --> $DIR/issue-33413.rs:4:10
    |
 LL |     fn f(*, a: u8) -> u8 {}
-   |          ^ expected argument name
+   |          ^ expected parameter name
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-63135.rs b/src/test/ui/parser/issue-63135.rs
index d5f5f1469f35a..a5a8de85466bb 100644
--- a/src/test/ui/parser/issue-63135.rs
+++ b/src/test/ui/parser/issue-63135.rs
@@ -1,3 +1,3 @@
-// error-pattern: aborting due to 6 previous errors
+// error-pattern: aborting due to 5 previous errors
 
 fn i(n{...,f #
diff --git a/src/test/ui/parser/issue-63135.stderr b/src/test/ui/parser/issue-63135.stderr
index c0286d90af744..a077ad454a9df 100644
--- a/src/test/ui/parser/issue-63135.stderr
+++ b/src/test/ui/parser/issue-63135.stderr
@@ -28,17 +28,11 @@ error: expected `[`, found `}`
 LL | fn i(n{...,f #
    |               ^ expected `[`
 
-error: expected `:`, found `)`
+error: expected one of `:` or `|`, found `)`
   --> $DIR/issue-63135.rs:3:15
    |
 LL | fn i(n{...,f #
-   |               ^ expected `:`
+   |               ^ expected one of `:` or `|` here
 
-error: expected one of `->`, `where`, or `{`, found `<eof>`
-  --> $DIR/issue-63135.rs:3:15
-   |
-LL | fn i(n{...,f #
-   |               ^ expected one of `->`, `where`, or `{` here
-
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/parser/omitted-arg-in-item-fn.rs b/src/test/ui/parser/omitted-arg-in-item-fn.rs
index 5ee9daf464055..49cbc4d6bf40f 100644
--- a/src/test/ui/parser/omitted-arg-in-item-fn.rs
+++ b/src/test/ui/parser/omitted-arg-in-item-fn.rs
@@ -1,4 +1,4 @@
-fn foo(x) { //~ ERROR expected one of `:` or `@`, found `)`
+fn foo(x) { //~ ERROR expected one of `:`, `@`, or `|`, found `)`
 }
 
 fn main() {}
diff --git a/src/test/ui/parser/omitted-arg-in-item-fn.stderr b/src/test/ui/parser/omitted-arg-in-item-fn.stderr
index e501f235d6d3b..7feb15592c54f 100644
--- a/src/test/ui/parser/omitted-arg-in-item-fn.stderr
+++ b/src/test/ui/parser/omitted-arg-in-item-fn.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:` or `@`, found `)`
+error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/omitted-arg-in-item-fn.rs:1:9
    |
 LL | fn foo(x) {
-   |         ^ expected one of `:` or `@` here
+   |         ^ expected one of `:`, `@`, or `|` here
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
diff --git a/src/test/ui/parser/pat-lt-bracket-2.rs b/src/test/ui/parser/pat-lt-bracket-2.rs
index 6eb01c1c93337..3a778ed14f637 100644
--- a/src/test/ui/parser/pat-lt-bracket-2.rs
+++ b/src/test/ui/parser/pat-lt-bracket-2.rs
@@ -1,4 +1,4 @@
 fn a(B<) {}
-   //~^ error: expected one of `:` or `@`, found `<`
+   //~^ error: expected one of `:`, `@`, or `|`, found `<`
 
 fn main() {}
diff --git a/src/test/ui/parser/pat-lt-bracket-2.stderr b/src/test/ui/parser/pat-lt-bracket-2.stderr
index cce1a17e9e8df..dbc8d0f5865c6 100644
--- a/src/test/ui/parser/pat-lt-bracket-2.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-2.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:` or `@`, found `<`
+error: expected one of `:`, `@`, or `|`, found `<`
   --> $DIR/pat-lt-bracket-2.rs:1:7
    |
 LL | fn a(B<) {}
-   |       ^ expected one of `:` or `@` here
+   |       ^ expected one of `:`, `@`, or `|` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/removed-syntax-mode.rs b/src/test/ui/parser/removed-syntax-mode.rs
index 23851b5f70b37..a438db3b0c18b 100644
--- a/src/test/ui/parser/removed-syntax-mode.rs
+++ b/src/test/ui/parser/removed-syntax-mode.rs
@@ -1,4 +1,4 @@
 fn f(+x: isize) {}
-//~^ ERROR expected argument name, found `+`
+//~^ ERROR expected parameter name, found `+`
 
 fn main() {}
diff --git a/src/test/ui/parser/removed-syntax-mode.stderr b/src/test/ui/parser/removed-syntax-mode.stderr
index 5e7139d6bfd85..d0393b379f06d 100644
--- a/src/test/ui/parser/removed-syntax-mode.stderr
+++ b/src/test/ui/parser/removed-syntax-mode.stderr
@@ -1,8 +1,8 @@
-error: expected argument name, found `+`
+error: expected parameter name, found `+`
   --> $DIR/removed-syntax-mode.rs:1:6
    |
 LL | fn f(+x: isize) {}
-   |      ^ expected argument name
+   |      ^ expected parameter name
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs
index e900ccab4fd83..d71711336b06e 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs
@@ -3,6 +3,6 @@
 #![feature(param_attrs)]
 
 trait Trait2015 { fn foo(#[allow(C)] i32); }
-//~^ ERROR expected one of `:` or `@`, found `)`
+//~^ ERROR expected one of `:`, `@`, or `|`, found `)`
 
 fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
index d0ed65f288011..26b414e426805 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
@@ -1,8 +1,8 @@
-error: expected one of `:` or `@`, found `)`
+error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/param-attrs-2018.rs:5:41
    |
 LL | trait Trait2015 { fn foo(#[allow(C)] i32); }
-   |                                         ^ expected one of `:` or `@` here
+   |                                         ^ expected one of `:`, `@`, or `|` here
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
diff --git a/src/test/ui/span/issue-34264.stderr b/src/test/ui/span/issue-34264.stderr
index 5dd9895c6e4f4..cc0eccd37a26f 100644
--- a/src/test/ui/span/issue-34264.stderr
+++ b/src/test/ui/span/issue-34264.stderr
@@ -1,14 +1,14 @@
-error: expected one of `:` or `@`, found `<`
+error: expected one of `:`, `@`, or `|`, found `<`
   --> $DIR/issue-34264.rs:1:14
    |
 LL | fn foo(Option<i32>, String) {}
-   |              ^ expected one of `:` or `@` here
+   |              ^ expected one of `:`, `@`, or `|` here
 
-error: expected one of `:` or `@`, found `)`
+error: expected one of `:`, `@`, or `|`, found `)`
   --> $DIR/issue-34264.rs:1:27
    |
 LL | fn foo(Option<i32>, String) {}
-   |                           ^ expected one of `:` or `@` here
+   |                           ^ expected one of `:`, `@`, or `|` here
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type
@@ -20,11 +20,11 @@ help: if this is a type, explicitly ignore the parameter name
 LL | fn foo(Option<i32>, _: String) {}
    |                     ^^^^^^^^^
 
-error: expected one of `:` or `@`, found `,`
+error: expected one of `:`, `@`, or `|`, found `,`
   --> $DIR/issue-34264.rs:3:9
    |
 LL | fn bar(x, y: usize) {}
-   |         ^ expected one of `:` or `@` here
+   |         ^ expected one of `:`, `@`, or `|` here
    |
    = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
 help: if this was a parameter name, give it a type

From 6a73199da6c06c0b71ed6eeca578b00925137664 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 25 Aug 2019 05:45:51 +0200
Subject: [PATCH 238/943] or_patterns: add run-rustfix tests.

---
 .../ui/or-patterns/fn-param-wrap-parens.fixed | 14 ++++
 .../ui/or-patterns/fn-param-wrap-parens.rs    | 14 ++++
 .../or-patterns/fn-param-wrap-parens.stderr   |  8 +++
 .../ui/or-patterns/remove-leading-vert.fixed  | 23 +++++++
 .../ui/or-patterns/remove-leading-vert.rs     | 23 +++++++
 .../ui/or-patterns/remove-leading-vert.stderr | 68 +++++++++++++++++++
 6 files changed, 150 insertions(+)
 create mode 100644 src/test/ui/or-patterns/fn-param-wrap-parens.fixed
 create mode 100644 src/test/ui/or-patterns/fn-param-wrap-parens.rs
 create mode 100644 src/test/ui/or-patterns/fn-param-wrap-parens.stderr
 create mode 100644 src/test/ui/or-patterns/remove-leading-vert.fixed
 create mode 100644 src/test/ui/or-patterns/remove-leading-vert.rs
 create mode 100644 src/test/ui/or-patterns/remove-leading-vert.stderr

diff --git a/src/test/ui/or-patterns/fn-param-wrap-parens.fixed b/src/test/ui/or-patterns/fn-param-wrap-parens.fixed
new file mode 100644
index 0000000000000..08730fe8b07b7
--- /dev/null
+++ b/src/test/ui/or-patterns/fn-param-wrap-parens.fixed
@@ -0,0 +1,14 @@
+// Test the suggestion to wrap an or-pattern as a function parameter in parens.
+
+// run-rustfix
+
+#![feature(or_patterns)]
+#![allow(warnings)]
+
+fn main() {}
+
+enum E { A, B }
+use E::*;
+
+#[cfg(FALSE)]
+fn fun1((A | B): E) {} //~ ERROR an or-pattern parameter must be wrapped in parenthesis
diff --git a/src/test/ui/or-patterns/fn-param-wrap-parens.rs b/src/test/ui/or-patterns/fn-param-wrap-parens.rs
new file mode 100644
index 0000000000000..ed667e0e66067
--- /dev/null
+++ b/src/test/ui/or-patterns/fn-param-wrap-parens.rs
@@ -0,0 +1,14 @@
+// Test the suggestion to wrap an or-pattern as a function parameter in parens.
+
+// run-rustfix
+
+#![feature(or_patterns)]
+#![allow(warnings)]
+
+fn main() {}
+
+enum E { A, B }
+use E::*;
+
+#[cfg(FALSE)]
+fn fun1(A | B: E) {} //~ ERROR an or-pattern parameter must be wrapped in parenthesis
diff --git a/src/test/ui/or-patterns/fn-param-wrap-parens.stderr b/src/test/ui/or-patterns/fn-param-wrap-parens.stderr
new file mode 100644
index 0000000000000..2c6e4d9838ddc
--- /dev/null
+++ b/src/test/ui/or-patterns/fn-param-wrap-parens.stderr
@@ -0,0 +1,8 @@
+error: an or-pattern parameter must be wrapped in parenthesis
+  --> $DIR/fn-param-wrap-parens.rs:14:9
+   |
+LL | fn fun1(A | B: E) {}
+   |         ^^^^^ help: wrap the pattern in parenthesis: `(A | B)`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/or-patterns/remove-leading-vert.fixed b/src/test/ui/or-patterns/remove-leading-vert.fixed
new file mode 100644
index 0000000000000..e96d76061ac28
--- /dev/null
+++ b/src/test/ui/or-patterns/remove-leading-vert.fixed
@@ -0,0 +1,23 @@
+// Test the suggestion to remove a leading `|`.
+
+// run-rustfix
+
+#![feature(or_patterns)]
+#![allow(warnings)]
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn leading_vert() {
+    fn fun1(  A: E) {} //~ ERROR a leading `|` is not allowed in a parameter pattern
+    fn fun2(  A: E) {} //~ ERROR a leading `|` is not allowed in a parameter pattern
+    let (  A): E; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let (  A): (E); //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let (  A,): (E,); //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let [  A ]: [E; 1]; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let [  A ]: [E; 1]; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let TS(  A ): TS; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let TS(  A ): TS; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let NS { f:  A }: NS; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let NS { f:  A }: NS; //~ ERROR a leading `|` is only allowed in a top-level pattern
+}
diff --git a/src/test/ui/or-patterns/remove-leading-vert.rs b/src/test/ui/or-patterns/remove-leading-vert.rs
new file mode 100644
index 0000000000000..3790b17553fe3
--- /dev/null
+++ b/src/test/ui/or-patterns/remove-leading-vert.rs
@@ -0,0 +1,23 @@
+// Test the suggestion to remove a leading `|`.
+
+// run-rustfix
+
+#![feature(or_patterns)]
+#![allow(warnings)]
+
+fn main() {}
+
+#[cfg(FALSE)]
+fn leading_vert() {
+    fn fun1( | A: E) {} //~ ERROR a leading `|` is not allowed in a parameter pattern
+    fn fun2( || A: E) {} //~ ERROR a leading `|` is not allowed in a parameter pattern
+    let ( | A): E; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let ( || A): (E); //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let ( | A,): (E,); //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let [ | A ]: [E; 1]; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let [ || A ]: [E; 1]; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let TS( | A ): TS; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let TS( || A ): TS; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let NS { f: | A }: NS; //~ ERROR a leading `|` is only allowed in a top-level pattern
+    let NS { f: || A }: NS; //~ ERROR a leading `|` is only allowed in a top-level pattern
+}
diff --git a/src/test/ui/or-patterns/remove-leading-vert.stderr b/src/test/ui/or-patterns/remove-leading-vert.stderr
new file mode 100644
index 0000000000000..cbe06f997296a
--- /dev/null
+++ b/src/test/ui/or-patterns/remove-leading-vert.stderr
@@ -0,0 +1,68 @@
+error: a leading `|` is not allowed in a parameter pattern
+  --> $DIR/remove-leading-vert.rs:12:14
+   |
+LL |     fn fun1( | A: E) {}
+   |              ^ help: remove the `|`
+
+error: a leading `|` is not allowed in a parameter pattern
+  --> $DIR/remove-leading-vert.rs:13:14
+   |
+LL |     fn fun2( || A: E) {}
+   |              ^^ help: remove the `||`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/remove-leading-vert.rs:14:11
+   |
+LL |     let ( | A): E;
+   |           ^ help: remove the `|`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/remove-leading-vert.rs:15:11
+   |
+LL |     let ( || A): (E);
+   |           ^^ help: remove the `||`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/remove-leading-vert.rs:16:11
+   |
+LL |     let ( | A,): (E,);
+   |           ^ help: remove the `|`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/remove-leading-vert.rs:17:11
+   |
+LL |     let [ | A ]: [E; 1];
+   |           ^ help: remove the `|`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/remove-leading-vert.rs:18:11
+   |
+LL |     let [ || A ]: [E; 1];
+   |           ^^ help: remove the `||`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/remove-leading-vert.rs:19:13
+   |
+LL |     let TS( | A ): TS;
+   |             ^ help: remove the `|`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/remove-leading-vert.rs:20:13
+   |
+LL |     let TS( || A ): TS;
+   |             ^^ help: remove the `||`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/remove-leading-vert.rs:21:17
+   |
+LL |     let NS { f: | A }: NS;
+   |                 ^ help: remove the `|`
+
+error: a leading `|` is only allowed in a top-level pattern
+  --> $DIR/remove-leading-vert.rs:22:17
+   |
+LL |     let NS { f: || A }: NS;
+   |                 ^^ help: remove the `||`
+
+error: aborting due to 11 previous errors
+

From acb11305e8d7298750797d45324c0ecb3cc6c256 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 25 Aug 2019 06:15:11 +0200
Subject: [PATCH 239/943] parser: TopLevel -> RecoverComma.

---
 src/libsyntax/parse/parser/pat.rs | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 1541031ec2539..f2e269e03baf9 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -21,9 +21,9 @@ pub(super) const PARAM_EXPECTED: Expected = Some("parameter name");
 #[derive(PartialEq)]
 pub enum GateOr { Yes, No }
 
-/// Whether or not this is the top level pattern context.
+/// Whether or not to recover a `,` when parsing or-patterns.
 #[derive(PartialEq, Copy, Clone)]
-enum TopLevel { Yes, No }
+enum RecoverComma { Yes, No }
 
 impl<'a> Parser<'a> {
     /// Parses a pattern.
@@ -52,7 +52,7 @@ impl<'a> Parser<'a> {
         let gated_leading_vert = self.eat_or_separator() && gate_or == GateOr::Yes;
 
         // Parse the possibly-or-pattern.
-        let pat = self.parse_pat_with_or(None, gate_or, TopLevel::Yes)?;
+        let pat = self.parse_pat_with_or(None, gate_or, RecoverComma::Yes)?;
 
         // If we parsed a leading `|` which should be gated,
         // and no other gated or-pattern has been parsed thus far,
@@ -72,7 +72,7 @@ impl<'a> Parser<'a> {
     /// Special recovery is provided for or-patterns and leading `|`.
     pub(super) fn parse_fn_param_pat(&mut self) -> PResult<'a, P<Pat>> {
         self.recover_leading_vert("not allowed in a parameter pattern");
-        let pat = self.parse_pat_with_or(PARAM_EXPECTED, GateOr::No, TopLevel::No)?;
+        let pat = self.parse_pat_with_or(PARAM_EXPECTED, GateOr::No, RecoverComma::No)?;
 
         if let PatKind::Or(..) = &pat.node {
             self.ban_illegal_fn_param_or_pat(&pat);
@@ -96,11 +96,11 @@ impl<'a> Parser<'a> {
         &mut self,
         expected: Expected,
         gate_or: GateOr,
-        top_level: TopLevel,
+        rc: RecoverComma,
     ) -> PResult<'a, P<Pat>> {
         // Parse the first pattern.
         let first_pat = self.parse_pat(expected)?;
-        self.maybe_recover_unexpected_comma(first_pat.span, top_level)?;
+        self.maybe_recover_unexpected_comma(first_pat.span, rc)?;
 
         // If the next token is not a `|`,
         // this is not an or-pattern and we should exit here.
@@ -115,7 +115,7 @@ impl<'a> Parser<'a> {
                 err.span_label(lo, "while parsing this or-pattern staring here");
                 err
             })?;
-            self.maybe_recover_unexpected_comma(pat.span, top_level)?;
+            self.maybe_recover_unexpected_comma(pat.span, rc)?;
             pats.push(pat);
         }
         let or_pattern_span = lo.to(self.prev_span);
@@ -156,8 +156,8 @@ impl<'a> Parser<'a> {
 
     /// Some special error handling for the "top-level" patterns in a match arm,
     /// `for` loop, `let`, &c. (in contrast to subpatterns within such).
-    fn maybe_recover_unexpected_comma(&mut self, lo: Span, top_level: TopLevel) -> PResult<'a, ()> {
-        if top_level == TopLevel::No || self.token != token::Comma {
+    fn maybe_recover_unexpected_comma(&mut self, lo: Span, rc: RecoverComma) -> PResult<'a, ()> {
+        if rc == RecoverComma::No || self.token != token::Comma {
             return Ok(());
         }
 
@@ -207,7 +207,7 @@ impl<'a> Parser<'a> {
     /// See `parse_pat_with_or` for details on parsing or-patterns.
     fn parse_pat_with_or_inner(&mut self) -> PResult<'a, P<Pat>> {
         self.recover_leading_vert("only allowed in a top-level pattern");
-        self.parse_pat_with_or(None, GateOr::Yes, TopLevel::No)
+        self.parse_pat_with_or(None, GateOr::Yes, RecoverComma::No)
     }
 
     /// Recover if `|` or `||` is here.

From c9d9616e825fecd4301beaf7bcd9115d5d7d393f Mon Sep 17 00:00:00 2001
From: Pascal Hertleif <pascal@technocreatives.com>
Date: Sat, 24 Aug 2019 17:50:21 +0200
Subject: [PATCH 240/943] Introduce and use `Feature` type for feature gates

This replaces the ad-hoc tuples used in the different feature gate files
and unifies their content into a common type, leading to more readable
matches and other good stuff that comes from having named fields. It
also contains the description of each feature as extracted from the doc
comment.
---
 src/libsyntax/feature_gate/accepted.rs | 16 ++++++++++---
 src/libsyntax/feature_gate/active.rs   | 10 ++++++++
 src/libsyntax/feature_gate/check.rs    | 33 ++++++++++++++------------
 src/libsyntax/feature_gate/mod.rs      | 33 ++++++++++++++++++++++++++
 src/libsyntax/feature_gate/removed.rs  | 29 ++++++++++++++++++----
 5 files changed, 98 insertions(+), 23 deletions(-)

diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs
index 28e4d2c073c7c..6c0b271c6c5e9 100644
--- a/src/libsyntax/feature_gate/accepted.rs
+++ b/src/libsyntax/feature_gate/accepted.rs
@@ -1,14 +1,24 @@
 //! List of the accepted feature gates.
 
-use crate::symbol::{Symbol, sym};
+use crate::symbol::sym;
+use super::{State, Feature};
 
 macro_rules! declare_features {
     ($(
         $(#[doc = $doc:tt])* (accepted, $feature:ident, $ver:expr, $issue:expr, None),
     )+) => {
         /// Those language feature has since been Accepted (it was once Active)
-        pub const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, None)),+
+        pub const ACCEPTED_FEATURES: &[Feature] = &[
+            $(
+                Feature {
+                    state: State::Accepted,
+                    name: sym::$feature,
+                    since: $ver,
+                    issue: $issue,
+                    edition: None,
+                    description: concat!($($doc,)*),
+                }
+            ),+
         ];
     }
 }
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index 4008b79b141eb..c947b09fdcb57 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -65,6 +65,16 @@ macro_rules! declare_features {
     };
 }
 
+impl Feature {
+    /// Set this feature in `Features`. Panics if called on a non-active feature.
+    pub fn set(&self, features: &mut Features, span: Span) {
+        match self.state {
+            State::Active { set } => set(features, span),
+            _ => panic!("Called `set` on feature `{}` which is not `active`", self.name)
+        }
+    }
+}
+
 // If you change this, please modify `src/doc/unstable-book` as well.
 //
 // Don't ever remove anything from this list; move them to `removed.rs`.
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index d82b287b6fb05..344e5fd6e46c2 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -1,4 +1,4 @@
-use super::active::{ACTIVE_FEATURES, Features};
+use super::{active::{ACTIVE_FEATURES, Features}, Feature, State as FeatureState};
 use super::accepted::ACCEPTED_FEATURES;
 use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
 use super::builtin_attrs::{AttributeGate, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
@@ -127,17 +127,16 @@ pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features:
 }
 
 fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
-    if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) {
-        let issue = info.2;
+    if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.name == feature) {
         // FIXME (#28244): enforce that active features have issue numbers
-        // assert!(issue.is_some())
-        issue
+        // assert!(info.issue.is_some())
+        info.issue
     } else {
         // search in Accepted, Removed, or Stable Removed features
         let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES)
-            .find(|t| t.0 == feature);
+            .find(|t| t.name == feature);
         match found {
-            Some(&(_, _, issue, _)) => issue,
+            Some(&Feature { issue, .. }) => issue,
             None => panic!("Feature `{}` is not declared anywhere", feature),
         }
     }
@@ -829,14 +828,18 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
                 continue;
             }
 
-            let removed = REMOVED_FEATURES.iter().find(|f| name == f.0);
-            let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.0);
-            if let Some((.., reason)) = removed.or(stable_removed) {
-                feature_removed(span_handler, mi.span(), *reason);
-                continue;
+            let removed = REMOVED_FEATURES.iter().find(|f| name == f.name);
+            let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.name);
+            if let Some(Feature { state, .. }) = removed.or(stable_removed) {
+                if let FeatureState::Removed { reason }
+                | FeatureState::Stabilized { reason } = state
+                {
+                    feature_removed(span_handler, mi.span(), *reason);
+                    continue;
+                }
             }
 
-            if let Some((_, since, ..)) = ACCEPTED_FEATURES.iter().find(|f| name == f.0) {
+            if let Some(Feature { since, .. }) = ACCEPTED_FEATURES.iter().find(|f| name == f.name) {
                 let since = Some(Symbol::intern(since));
                 features.declared_lang_features.push((name, mi.span(), since));
                 continue;
@@ -851,8 +854,8 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
                 }
             }
 
-            if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) {
-                set(&mut features, mi.span());
+            if let Some(f) = ACTIVE_FEATURES.iter().find(|f| name == f.name) {
+                f.set(&mut features, mi.span());
                 features.declared_lang_features.push((name, mi.span(), None));
                 continue;
             }
diff --git a/src/libsyntax/feature_gate/mod.rs b/src/libsyntax/feature_gate/mod.rs
index 97793bca1f589..1e41667ea411e 100644
--- a/src/libsyntax/feature_gate/mod.rs
+++ b/src/libsyntax/feature_gate/mod.rs
@@ -18,6 +18,39 @@ mod active;
 mod builtin_attrs;
 mod check;
 
+use std::fmt;
+use crate::{edition::Edition, symbol::Symbol};
+use syntax_pos::Span;
+
+#[derive(Clone, Copy)]
+pub enum State {
+    Accepted,
+    Active { set: fn(&mut Features, Span) },
+    Removed { reason: Option<&'static str> },
+    Stabilized { reason: Option<&'static str> },
+}
+
+impl fmt::Debug for State {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            State::Accepted { .. } => write!(f, "accepted"),
+            State::Active { .. } => write!(f, "active"),
+            State::Removed { .. } => write!(f, "removed"),
+            State::Stabilized { .. } => write!(f, "stabilized"),
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Feature {
+    state: State,
+    name: Symbol,
+    since: &'static str,
+    issue: Option<u32>,
+    edition: Option<Edition>,
+    description: &'static str,
+}
+
 pub use active::{Features, INCOMPLETE_FEATURES};
 pub use builtin_attrs::{
     AttributeGate, AttributeType, GatedCfg,
diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs
index 6494c82e1228b..ad7d69b3e7372 100644
--- a/src/libsyntax/feature_gate/removed.rs
+++ b/src/libsyntax/feature_gate/removed.rs
@@ -1,14 +1,24 @@
 //! List of the removed feature gates.
 
-use crate::symbol::{Symbol, sym};
+use crate::symbol::sym;
+use super::{State, Feature};
 
 macro_rules! declare_features {
     ($(
         $(#[doc = $doc:tt])* (removed, $feature:ident, $ver:expr, $issue:expr, None, $reason:expr),
     )+) => {
         /// Represents unstable features which have since been removed (it was once Active)
-        pub const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, $reason)),+
+        pub const REMOVED_FEATURES: &[Feature] = &[
+            $(
+                Feature {
+                    state: State::Removed { reason: $reason },
+                    name: sym::$feature,
+                    since: $ver,
+                    issue: $issue,
+                    edition: None,
+                    description: concat!($($doc,)*),
+                }
+            ),+
         ];
     };
 
@@ -16,8 +26,17 @@ macro_rules! declare_features {
         $(#[doc = $doc:tt])* (stable_removed, $feature:ident, $ver:expr, $issue:expr, None),
     )+) => {
         /// Represents stable features which have since been removed (it was once Accepted)
-        pub const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[
-            $((sym::$feature, $ver, $issue, None)),+
+        pub const STABLE_REMOVED_FEATURES: &[Feature] = &[
+            $(
+                Feature {
+                    state: State::Stabilized { reason: None },
+                    name: sym::$feature,
+                    since: $ver,
+                    issue: $issue,
+                    edition: None,
+                    description: concat!($($doc,)*),
+                }
+            ),+
         ];
     };
 }

From fcbbf8d312c01b6287f4011f27ddb953c3182501 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Sat, 24 Aug 2019 15:18:16 +0200
Subject: [PATCH 241/943] Fix system theme detection

---
 src/librustdoc/html/static/storage.js | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index c55b1e414436c..ab2cf8f796d48 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -118,7 +118,8 @@ function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
 }
 
 function getSystemValue() {
-    return getComputedStyle(document.documentElement).getPropertyValue('content');
+    var property = getComputedStyle(document.documentElement).getPropertyValue('content');
+    return property.replace(/\"\'/g, "");
 }
 
 switchTheme(currentTheme, mainTheme,

From 4f30d2ae5a4bae7ab5ce661f4b98efd76e0b1615 Mon Sep 17 00:00:00 2001
From: Philipp Hansch <dev@phansch.net>
Date: Sun, 25 Aug 2019 12:54:31 +0200
Subject: [PATCH 242/943] submodules: update clippy from
 2bcb6155948e2f8b86db08152a5f54bd5af625e5 to
 05f603e6cec63d0b2681a84d4a64a51bccac1624

---
 src/tools/clippy | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/clippy b/src/tools/clippy
index 2bcb6155948e2..05f603e6cec63 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit 2bcb6155948e2f8b86db08152a5f54bd5af625e5
+Subproject commit 05f603e6cec63d0b2681a84d4a64a51bccac1624

From d86516d91e643fd87eadf057096989ce454f4d81 Mon Sep 17 00:00:00 2001
From: Thomas de Zeeuw <thomasdezeeuw@gmail.com>
Date: Sun, 25 Aug 2019 13:06:49 +0200
Subject: [PATCH 243/943] Stabilise weak_ptr_eq

---
 src/liballoc/rc.rs   | 4 +---
 src/liballoc/sync.rs | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 2b222caf13f3d..1752c1342c856 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -1843,7 +1843,6 @@ impl<T: ?Sized> Weak<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(weak_ptr_eq)]
     /// use std::rc::Rc;
     ///
     /// let first_rc = Rc::new(5);
@@ -1861,7 +1860,6 @@ impl<T: ?Sized> Weak<T> {
     /// Comparing `Weak::new`.
     ///
     /// ```
-    /// #![feature(weak_ptr_eq)]
     /// use std::rc::{Rc, Weak};
     ///
     /// let first = Weak::new();
@@ -1873,7 +1871,7 @@ impl<T: ?Sized> Weak<T> {
     /// assert!(!first.ptr_eq(&third));
     /// ```
     #[inline]
-    #[unstable(feature = "weak_ptr_eq", issue = "55981")]
+    #[stable(feature = "weak_ptr_eq", since = "1.39.0")]
     pub fn ptr_eq(&self, other: &Self) -> bool {
         self.ptr.as_ptr() == other.ptr.as_ptr()
     }
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 9ffc1673e5ab8..e89433d67bdd6 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -1562,7 +1562,6 @@ impl<T: ?Sized> Weak<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(weak_ptr_eq)]
     /// use std::sync::Arc;
     ///
     /// let first_rc = Arc::new(5);
@@ -1580,7 +1579,6 @@ impl<T: ?Sized> Weak<T> {
     /// Comparing `Weak::new`.
     ///
     /// ```
-    /// #![feature(weak_ptr_eq)]
     /// use std::sync::{Arc, Weak};
     ///
     /// let first = Weak::new();
@@ -1592,7 +1590,7 @@ impl<T: ?Sized> Weak<T> {
     /// assert!(!first.ptr_eq(&third));
     /// ```
     #[inline]
-    #[unstable(feature = "weak_ptr_eq", issue = "55981")]
+    #[stable(feature = "weak_ptr_eq", since = "1.39.0")]
     pub fn ptr_eq(&self, other: &Self) -> bool {
         self.ptr.as_ptr() == other.ptr.as_ptr()
     }

From 307804a00d191b6f15d1a1a5b98fbae5ea6593b0 Mon Sep 17 00:00:00 2001
From: Thomas de Zeeuw <thomasdezeeuw@gmail.com>
Date: Sun, 25 Aug 2019 13:02:45 +0200
Subject: [PATCH 244/943] Update {rc, sync}::Weak::ptr_eq doc about comparing
 Weak::new

---
 src/liballoc/rc.rs   | 5 +++--
 src/liballoc/sync.rs | 6 +++---
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 1752c1342c856..a10f7c60031e0 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -1832,8 +1832,9 @@ impl<T: ?Sized> Weak<T> {
         }
     }
 
-    /// Returns `true` if the two `Weak`s point to the same value (not just values
-    /// that compare as equal).
+    /// Returns `true` if the two `Weak`s point to the same value (not just
+    /// values that compare as equal), or if both don't point to any value
+    /// (because they were created with `Weak::new()`).
     ///
     /// # Notes
     ///
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index e89433d67bdd6..716d750915e12 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -1550,15 +1550,15 @@ impl<T: ?Sized> Weak<T> {
         }
     }
 
-    /// Returns `true` if the two `Weak`s point to the same value (not just values
-    /// that compare as equal).
+    /// Returns `true` if the two `Weak`s point to the same value (not just
+    /// values that compare as equal), or if both don't point to any value
+    /// (because they were created with `Weak::new()`).
     ///
     /// # Notes
     ///
     /// Since this compares pointers it means that `Weak::new()` will equal each
     /// other, even though they don't point to any value.
     ///
-    ///
     /// # Examples
     ///
     /// ```

From 92e75c0f88a5cc09642285fe61a4c1be14fe314d Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Aug 2019 13:57:46 +0200
Subject: [PATCH 245/943] factor wide ptr metadata checking into separate
 method

also fat -> wide
---
 src/librustc_mir/interpret/validity.rs        | 75 +++++++++++--------
 .../consts/const-eval/union-ub-fat-ptr.stderr | 12 +--
 2 files changed, 48 insertions(+), 39 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 82d6d7db01c8d..f358a21f4af76 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -11,7 +11,7 @@ use std::hash::Hash;
 
 use super::{
     GlobalAlloc, InterpResult,
-    OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
+    Scalar, OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
 };
 
 macro_rules! throw_validation_failure {
@@ -250,6 +250,44 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
         self.path.truncate(path_len);
         Ok(())
     }
+
+    fn check_wide_ptr_meta(
+        &mut self,
+        meta: Option<Scalar<M::PointerTag>>,
+        pointee: TyLayout<'tcx>,
+    ) -> InterpResult<'tcx> {
+        let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env);
+        match tail.sty {
+            ty::Dynamic(..) => {
+                let vtable = meta.unwrap();
+                try_validation!(
+                    self.ecx.memory.check_ptr_access(
+                        vtable,
+                        3*self.ecx.tcx.data_layout.pointer_size, // drop, size, align
+                        self.ecx.tcx.data_layout.pointer_align.abi,
+                    ),
+                    "dangling or unaligned vtable pointer in wide pointer or too small vtable",
+                    self.path
+                );
+                try_validation!(self.ecx.read_drop_type_from_vtable(vtable),
+                    "invalid drop fn in vtable", self.path);
+                try_validation!(self.ecx.read_size_and_align_from_vtable(vtable),
+                    "invalid size or align in vtable", self.path);
+                // FIXME: More checks for the vtable.
+            }
+            ty::Slice(..) | ty::Str => {
+                try_validation!(meta.unwrap().to_usize(self.ecx),
+                    "non-integer slice length in wide pointer", self.path);
+            }
+            ty::Foreign(..) => {
+                // Unsized, but not wide.
+            }
+            _ =>
+                bug!("Unexpected unsized type tail: {:?}", tail),
+        }
+
+        Ok(())
+    }
 }
 
 impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
@@ -353,44 +391,15 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                 }
             }
             _ if ty.is_box() || ty.is_region_ptr() => {
-                // Handle fat pointers.
+                // Handle wide pointers.
                 // Check metadata early, for better diagnostics
                 let ptr = try_validation!(value.to_scalar_ptr(),
                     "undefined address in pointer", self.path);
                 let meta = try_validation!(value.to_meta(),
-                    "uninitialized data in fat pointer metadata", self.path);
+                    "uninitialized data in wide pointer metadata", self.path);
                 let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
                 if layout.is_unsized() {
-                    let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(layout.ty,
-                                                                          self.ecx.param_env);
-                    match tail.sty {
-                        ty::Dynamic(..) => {
-                            let vtable = meta.unwrap();
-                            try_validation!(
-                                self.ecx.memory.check_ptr_access(
-                                    vtable,
-                                    3*self.ecx.tcx.data_layout.pointer_size, // drop, size, align
-                                    self.ecx.tcx.data_layout.pointer_align.abi,
-                                ),
-                                "dangling or unaligned vtable pointer or too small vtable",
-                                self.path
-                            );
-                            try_validation!(self.ecx.read_drop_type_from_vtable(vtable),
-                                "invalid drop fn in vtable", self.path);
-                            try_validation!(self.ecx.read_size_and_align_from_vtable(vtable),
-                                "invalid size or align in vtable", self.path);
-                            // FIXME: More checks for the vtable.
-                        }
-                        ty::Slice(..) | ty::Str => {
-                            try_validation!(meta.unwrap().to_usize(self.ecx),
-                                "non-integer slice length in fat pointer", self.path);
-                        }
-                        ty::Foreign(..) => {
-                            // Unsized, but not fat.
-                        }
-                        _ =>
-                            bug!("Unexpected unsized type tail: {:?}", tail),
-                    }
+                    self.check_wide_ptr_meta(meta, layout)?;
                 }
                 // Make sure this is dereferencable and all.
                 let (size, align) = self.ecx.size_and_align_of(meta, layout)?
diff --git a/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr b/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr
index aac32ecc5b747..54c33006d2b15 100644
--- a/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr
+++ b/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr
@@ -10,7 +10,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:81:1
    |
 LL | const C: &str = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.str};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -18,7 +18,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:84:1
    |
 LL | const C2: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.my_str};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -34,7 +34,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:93:1
    |
 LL | const C3: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -42,7 +42,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:97:1
    |
 LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -50,7 +50,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:100:1
    |
 LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -58,7 +58,7 @@ error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ub-fat-ptr.rs:103:1
    |
 LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 

From 96baf1c54e4049b7fe2fe699ede58bde1dcb2232 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Aug 2019 14:26:56 +0200
Subject: [PATCH 246/943] validate raw wide pointers

---
 src/librustc_mir/interpret/validity.rs        |  11 +-
 .../{union-ub-fat-ptr.rs => ub-wide-ptr.rs}   |  72 +++++++----
 ...n-ub-fat-ptr.stderr => ub-wide-ptr.stderr} | 116 +++++++++++-------
 3 files changed, 131 insertions(+), 68 deletions(-)
 rename src/test/ui/consts/const-eval/{union-ub-fat-ptr.rs => ub-wide-ptr.rs} (61%)
 rename src/test/ui/consts/const-eval/{union-ub-fat-ptr.stderr => ub-wide-ptr.stderr} (62%)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index f358a21f4af76..f3ce7df8d0677 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -379,16 +379,23 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
                 }
             }
             ty::RawPtr(..) => {
+                // Check pointer part.
                 if self.ref_tracking_for_consts.is_some() {
                     // Integers/floats in CTFE: For consistency with integers, we do not
                     // accept undef.
                     let _ptr = try_validation!(value.to_scalar_ptr(),
                         "undefined address in raw pointer", self.path);
-                    let _meta = try_validation!(value.to_meta(),
-                        "uninitialized data in raw fat pointer metadata", self.path);
                 } else {
                     // Remain consistent with `usize`: Accept anything.
                 }
+
+                // Check metadata.
+                let meta = try_validation!(value.to_meta(),
+                    "uninitialized data in wide pointer metadata", self.path);
+                let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
+                if layout.is_unsized() {
+                    self.check_wide_ptr_meta(meta, layout)?;
+                }
             }
             _ if ty.is_box() || ty.is_region_ptr() => {
                 // Handle wide pointers.
diff --git a/src/test/ui/consts/const-eval/union-ub-fat-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
similarity index 61%
rename from src/test/ui/consts/const-eval/union-ub-fat-ptr.rs
rename to src/test/ui/consts/const-eval/ub-wide-ptr.rs
index d5405f3441fec..23a82bb10ea17 100644
--- a/src/test/ui/consts/const-eval/union-ub-fat-ptr.rs
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
@@ -1,3 +1,4 @@
+// ignore-tidy-linelength
 #![allow(unused)]
 #![allow(const_err)] // make sure we cannot allow away the errors tested here
 
@@ -28,7 +29,9 @@ struct BadSliceRepr {
 union SliceTransmute {
     repr: SliceRepr,
     bad: BadSliceRepr,
+    addr: usize,
     slice: &'static [u8],
+    raw_slice: *const [u8],
     str: &'static str,
     my_str: &'static MyStr,
     my_slice: &'static MySliceBool,
@@ -59,7 +62,9 @@ union DynTransmute {
     repr: DynRepr,
     repr2: DynRepr2,
     bad: BadDynRepr,
+    addr: usize,
     rust: &'static dyn Trait,
+    raw_rust: *const dyn Trait,
 }
 
 trait Trait {}
@@ -72,39 +77,37 @@ struct MyStr(str);
 struct MySlice<T: ?Sized>(bool, T);
 type MySliceBool = MySlice<[bool]>;
 
+// # str
 // OK
-const A: &str = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 1 } }.str};
+const STR_VALID: &str = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 1 } }.str};
 // bad str
-const B: &str = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.str};
+const STR_TOO_LONG: &str = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.str};
 //~^ ERROR it is undefined behavior to use this value
 // bad str
-const C: &str = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.str};
+const STR_LENGTH_PTR: &str = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.str};
 //~^ ERROR it is undefined behavior to use this value
 // bad str in user-defined unsized type
-const C2: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.my_str};
+const MY_STR_LENGTH_PTR: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.my_str};
 //~^ ERROR it is undefined behavior to use this value
 
-// OK
-const A2: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 1 } }.slice};
-// bad slice
-const B2: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.slice};
+// invalid UTF-8
+const J1: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
 //~^ ERROR it is undefined behavior to use this value
-// bad slice
-const C3: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice};
+// invalid UTF-8 in user-defined str-like
+const J2: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my_str };
 //~^ ERROR it is undefined behavior to use this value
 
-// bad trait object
-const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
-//~^ ERROR it is undefined behavior to use this value
-// bad trait object
-const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
+// # slice
+// OK
+const SLICE_VALID: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 1 } }.slice};
+// bad slice: length uninit
+const SLICE_LENGTH_UNINIT: &[u8] = unsafe { SliceTransmute { addr: 42 }.slice};
 //~^ ERROR it is undefined behavior to use this value
-// bad trait object
-const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
+// bad slice: length too big
+const SLICE_TOO_LONG: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.slice};
 //~^ ERROR it is undefined behavior to use this value
-
-// bad data *inside* the trait object
-const G: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
+// bad slice: length not an int
+const SLICE_LENGTH_PTR: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice};
 //~^ ERROR it is undefined behavior to use this value
 
 // bad data *inside* the slice
@@ -120,12 +123,33 @@ const I2: &MySliceBool = &MySlice(unsafe { BoolTransmute { val: 3 }.bl }, [false
 const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]);
 //~^ ERROR it is undefined behavior to use this value
 
-// invalid UTF-8
-const J1: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
+// # raw slice
+const RAW_SLICE_VALID: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 1 } }.raw_slice}; // ok
+const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.raw_slice}; // ok because raw
+const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
 //~^ ERROR it is undefined behavior to use this value
-// invalid UTF-8 in user-defined str-like
-const J2: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my_str };
+
+// # trait object
+// bad trait object
+const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
+//~^ ERROR it is undefined behavior to use this value
+// bad trait object
+const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
+//~^ ERROR it is undefined behavior to use this value
+// bad trait object
+const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
+//~^ ERROR it is undefined behavior to use this value
+
+// bad data *inside* the trait object
+const G: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
+//~^ ERROR it is undefined behavior to use this value
+
+// # raw trait object
+const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 0 } }.rust};
+//~^ ERROR it is undefined behavior to use this value
+const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.raw_rust};
 //~^ ERROR it is undefined behavior to use this value
+const RAW_TRAIT_OBJ_CONTENT_INVALID: *const dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl } as *const _; // ok because raw
 
 fn main() {
 }
diff --git a/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
similarity index 62%
rename from src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr
rename to src/test/ui/consts/const-eval/ub-wide-ptr.stderr
index 54c33006d2b15..985df3b1c8bc5 100644
--- a/src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -1,77 +1,69 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:78:1
+  --> $DIR/ub-wide-ptr.rs:84:1
    |
-LL | const B: &str = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.str};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (not entirely in bounds)
+LL | const STR_TOO_LONG: &str = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.str};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (not entirely in bounds)
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:81:1
+  --> $DIR/ub-wide-ptr.rs:87:1
    |
-LL | const C: &str = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.str};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
+LL | const STR_LENGTH_PTR: &str = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.str};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:84:1
+  --> $DIR/ub-wide-ptr.rs:90:1
    |
-LL | const C2: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.my_str};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
+LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.my_str};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:90:1
+  --> $DIR/ub-wide-ptr.rs:94:1
    |
-LL | const B2: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.slice};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (not entirely in bounds)
+LL | const J1: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:93:1
+  --> $DIR/ub-wide-ptr.rs:97:1
    |
-LL | const C3: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
+LL | const J2: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my_str };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>.0
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:97:1
+  --> $DIR/ub-wide-ptr.rs:104:1
    |
-LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
+LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { SliceTransmute { addr: 42 }.slice};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:100:1
+  --> $DIR/ub-wide-ptr.rs:107:1
    |
-LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
+LL | const SLICE_TOO_LONG: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.slice};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (not entirely in bounds)
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:103:1
+  --> $DIR/ub-wide-ptr.rs:110:1
    |
-LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
+LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:107:1
-   |
-LL | const G: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.<dyn-downcast>, but expected something less or equal to 1
-   |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
-
-error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:111:1
+  --> $DIR/ub-wide-ptr.rs:114:1
    |
 LL | const H: &[bool] = &[unsafe { BoolTransmute { val: 3 }.bl }];
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>[0], but expected something less or equal to 1
@@ -79,7 +71,7 @@ LL | const H: &[bool] = &[unsafe { BoolTransmute { val: 3 }.bl }];
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:117:1
+  --> $DIR/ub-wide-ptr.rs:120:1
    |
 LL | const I2: &MySliceBool = &MySlice(unsafe { BoolTransmute { val: 3 }.bl }, [false]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.0, but expected something less or equal to 1
@@ -87,7 +79,7 @@ LL | const I2: &MySliceBool = &MySlice(unsafe { BoolTransmute { val: 3 }.bl }, [
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:120:1
+  --> $DIR/ub-wide-ptr.rs:123:1
    |
 LL | const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.1[0], but expected something less or equal to 1
@@ -95,21 +87,61 @@ LL | const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:124:1
+  --> $DIR/ub-wide-ptr.rs:129:1
    |
-LL | const J1: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>
+LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub-fat-ptr.rs:127:1
+  --> $DIR/ub-wide-ptr.rs:134:1
    |
-LL | const J2: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my_str };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>.0
+LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-wide-ptr.rs:137:1
+   |
+LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-wide-ptr.rs:140:1
+   |
+LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-wide-ptr.rs:144:1
+   |
+LL | const G: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.<dyn-downcast>, but expected something less or equal to 1
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-wide-ptr.rs:148:1
+   |
+LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 0 } }.rust};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-wide-ptr.rs:150:1
+   |
+LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.raw_rust};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
-error: aborting due to 14 previous errors
+error: aborting due to 18 previous errors
 
 For more information about this error, try `rustc --explain E0080`.

From 0c1cb32b8440319d8a15d920a3d35e124ae52b43 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 25 Aug 2019 14:47:01 +0200
Subject: [PATCH 247/943] test for too long slices

---
 src/librustc_mir/interpret/validity.rs        | 16 ++++++++++++--
 src/test/ui/consts/const-eval/ub-wide-ptr.rs  |  2 ++
 .../ui/consts/const-eval/ub-wide-ptr.stderr   | 22 +++++++++++++------
 3 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index f3ce7df8d0677..7af55a2a3a376 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -3,7 +3,7 @@ use std::ops::RangeInclusive;
 
 use syntax_pos::symbol::{sym, Symbol};
 use rustc::hir;
-use rustc::ty::layout::{self, TyLayout, LayoutOf, VariantIdx};
+use rustc::ty::layout::{self, Size, TyLayout, LayoutOf, VariantIdx};
 use rustc::ty;
 use rustc_data_structures::fx::FxHashSet;
 
@@ -276,8 +276,20 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
                 // FIXME: More checks for the vtable.
             }
             ty::Slice(..) | ty::Str => {
-                try_validation!(meta.unwrap().to_usize(self.ecx),
+                let len = try_validation!(meta.unwrap().to_usize(self.ecx),
                     "non-integer slice length in wide pointer", self.path);
+                // check max slice length
+                let elem_size = match tail.sty {
+                    ty::Str => Size::from_bytes(1),
+                    ty::Slice(ty) => self.ecx.layout_of(ty)?.size,
+                    _ => bug!("It cannot be another type"),
+                };
+                if elem_size.checked_mul(len, &*self.ecx.tcx).is_none() {
+                    throw_validation_failure!(
+                        "too large slice (longer than isize::MAX bytes)",
+                        self.path
+                    );
+                }
             }
             ty::Foreign(..) => {
                 // Unsized, but not wide.
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
index 23a82bb10ea17..20d1a5b08cdad 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
@@ -126,6 +126,8 @@ const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]
 // # raw slice
 const RAW_SLICE_VALID: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 1 } }.raw_slice}; // ok
 const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.raw_slice}; // ok because raw
+const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: usize::max_value() } }.raw_slice};
+//~^ ERROR it is undefined behavior to use this value
 const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
 //~^ ERROR it is undefined behavior to use this value
 
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
index 985df3b1c8bc5..264bb675506f6 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -89,13 +89,21 @@ LL | const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:129:1
    |
+LL | const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: usize::max_value() } }.raw_slice};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too large slice (longer than isize::MAX bytes)
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/ub-wide-ptr.rs:131:1
+   |
 LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:134:1
+  --> $DIR/ub-wide-ptr.rs:136:1
    |
 LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -103,7 +111,7 @@ LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vta
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:137:1
+  --> $DIR/ub-wide-ptr.rs:139:1
    |
 LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -111,7 +119,7 @@ LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, v
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:140:1
+  --> $DIR/ub-wide-ptr.rs:142:1
    |
 LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -119,7 +127,7 @@ LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, v
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:144:1
+  --> $DIR/ub-wide-ptr.rs:146:1
    |
 LL | const G: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.<dyn-downcast>, but expected something less or equal to 1
@@ -127,7 +135,7 @@ LL | const G: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:148:1
+  --> $DIR/ub-wide-ptr.rs:150:1
    |
 LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 0 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -135,13 +143,13 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { DynTransmute {
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:150:1
+  --> $DIR/ub-wide-ptr.rs:152:1
    |
 LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.raw_rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
-error: aborting due to 18 previous errors
+error: aborting due to 19 previous errors
 
 For more information about this error, try `rustc --explain E0080`.

From 39412ca9695dbf965c69f6f673c0e49313d3f1fb Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Wed, 27 Feb 2019 17:21:31 -0700
Subject: [PATCH 248/943] Permit unwinding through FFI by default

See #58794 for context.
---
 src/librustc_mir/build/mod.rs     | 2 +-
 src/test/ui/abi/abort-on-c-abi.rs | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 4e970aee42cf4..6a3bb8b8b86a2 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -502,7 +502,7 @@ fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool {
     // This is a special case: some functions have a C abi but are meant to
     // unwind anyway. Don't stop them.
     match unwind_attr {
-        None => true,
+        None => false, // FIXME(#58794)
         Some(UnwindAttr::Allowed) => false,
         Some(UnwindAttr::Aborts) => true,
     }
diff --git a/src/test/ui/abi/abort-on-c-abi.rs b/src/test/ui/abi/abort-on-c-abi.rs
index cd7dd1b6a452f..2f08730ec6132 100644
--- a/src/test/ui/abi/abort-on-c-abi.rs
+++ b/src/test/ui/abi/abort-on-c-abi.rs
@@ -1,6 +1,7 @@
 // run-pass
 
 #![allow(unused_must_use)]
+#![feature(unwind_attributes)]
 // Since we mark some ABIs as "nounwind" to LLVM, we must make sure that
 // we never unwind through them.
 
@@ -13,6 +14,7 @@ use std::io::prelude::*;
 use std::io;
 use std::process::{Command, Stdio};
 
+#[unwind(aborts)] // FIXME(#58794)
 extern "C" fn panic_in_ffi() {
     panic!("Test");
 }

From d810e77f4ed7a76aaac71b6430b7bfb049b3649c Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Tue, 2 Apr 2019 14:53:57 -0700
Subject: [PATCH 249/943] Revert "Allow a dirty MirBuilt for make_extern and
 make_method_extern"

This reverts commit b4a6f597934f16f89e27058a32a514c9572f148f.
---
 src/test/incremental/hashes/function_interfaces.rs | 2 +-
 src/test/incremental/hashes/inherent_impls.rs      | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs
index 84680a52ff3ce..4515e36166eb8 100644
--- a/src/test/incremental/hashes/function_interfaces.rs
+++ b/src/test/incremental/hashes/function_interfaces.rs
@@ -94,7 +94,7 @@ pub unsafe fn make_unsafe() {}
 pub fn make_extern() {}
 
 #[cfg(not(cfail1))]
-#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, mir_built, typeck_tables_of, fn_sig")]
+#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, typeck_tables_of, fn_sig")]
 #[rustc_clean(cfg = "cfail3")]
 pub extern "C" fn make_extern() {}
 
diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs
index 882383e841957..538fd2c29203b 100644
--- a/src/test/incremental/hashes/inherent_impls.rs
+++ b/src/test/incremental/hashes/inherent_impls.rs
@@ -263,7 +263,7 @@ impl Foo {
 #[rustc_clean(cfg="cfail2")]
 #[rustc_clean(cfg="cfail3")]
 impl Foo {
-    #[rustc_clean(cfg="cfail2", except="Hir,HirBody,mir_built,fn_sig,typeck_tables_of")]
+    #[rustc_clean(cfg="cfail2", except="Hir,HirBody,fn_sig,typeck_tables_of")]
     #[rustc_clean(cfg="cfail3")]
     pub extern fn make_method_extern(&self) { }
 }

From 367b793790d7f362fa41313143e1015607b21700 Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Fri, 10 May 2019 15:10:15 -0700
Subject: [PATCH 250/943] Force #[unwind(aborts)] in test/codegen/c-variadic.rs

---
 src/test/codegen/c-variadic.rs | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/test/codegen/c-variadic.rs b/src/test/codegen/c-variadic.rs
index 13be5ced27fa9..bb90a9653f573 100644
--- a/src/test/codegen/c-variadic.rs
+++ b/src/test/codegen/c-variadic.rs
@@ -2,6 +2,7 @@
 
 #![crate_type = "lib"]
 #![feature(c_variadic)]
+#![feature(unwind_attributes)]
 #![no_std]
 use core::ffi::VaList;
 
@@ -10,6 +11,7 @@ extern "C" {
     fn foreign_c_variadic_1(_: VaList, ...);
 }
 
+#[unwind(aborts)] // FIXME(#58794)
 pub unsafe extern "C" fn use_foreign_c_variadic_0() {
     // Ensure that we correctly call foreign C-variadic functions.
     // CHECK: invoke void (i32, ...) @foreign_c_variadic_0(i32 0)
@@ -24,20 +26,24 @@ pub unsafe extern "C" fn use_foreign_c_variadic_0() {
 
 // Ensure that we do not remove the `va_list` passed to the foreign function when
 // removing the "spoofed" `VaListImpl` that is used by Rust defined C-variadics.
+#[unwind(aborts)] // FIXME(#58794)
 pub unsafe extern "C" fn use_foreign_c_variadic_1_0(ap: VaList) {
     // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap)
     foreign_c_variadic_1(ap);
 }
 
+#[unwind(aborts)] // FIXME(#58794)
 pub unsafe extern "C" fn use_foreign_c_variadic_1_1(ap: VaList) {
     // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 42)
     foreign_c_variadic_1(ap, 42i32);
 }
+#[unwind(aborts)] // FIXME(#58794)
 pub unsafe extern "C" fn use_foreign_c_variadic_1_2(ap: VaList) {
     // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 2, i32 42)
     foreign_c_variadic_1(ap, 2i32, 42i32);
 }
 
+#[unwind(aborts)] // FIXME(#58794)
 pub unsafe extern "C" fn use_foreign_c_variadic_1_3(ap: VaList) {
     // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 2, i32 42, i32 0)
     foreign_c_variadic_1(ap, 2i32, 42i32, 0i32);

From 5b7df0922ef15a8b105aceda8770faedc58ec67b Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sun, 25 Aug 2019 20:41:52 +0300
Subject: [PATCH 251/943] pprust: Do not print spaces before some tokens

---
 src/libsyntax/print/pprust.rs                      | 14 +++++++++++++-
 src/test/pretty/attr-literals.rs                   |  4 ++--
 src/test/pretty/block-comment-wchar.pp             |  5 +----
 src/test/pretty/delimited-token-groups.rs          |  2 +-
 src/test/pretty/do1.rs                             |  2 +-
 src/test/pretty/match-block-expr.rs                |  2 +-
 src/test/ui/macros/macro-first-set.rs              |  2 +-
 .../proc-macro/auxiliary/attr-stmt-expr-rpass.rs   |  4 ++--
 src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs |  4 ++--
 9 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 4dc00af486013..83a926a6217e7 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -152,6 +152,18 @@ pub fn to_string<F>(f: F) -> String where
     printer.s.eof()
 }
 
+// This makes comma-separated lists look slightly nicer,
+// and also addresses a specific regression described in issue #63896.
+fn tt_prepend_space(tt: &TokenTree) -> bool {
+    match tt {
+        TokenTree::Token(token) => match token.kind {
+            token::Comma => false,
+            _ => true,
+        }
+        _ => true,
+    }
+}
+
 fn binop_to_string(op: BinOpToken) -> &'static str {
     match op {
         token::Plus     => "+",
@@ -696,7 +708,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target=pp::Printer> + std::ops::DerefM
 
     fn print_tts(&mut self, tts: tokenstream::TokenStream, convert_dollar_crate: bool) {
         for (i, tt) in tts.into_trees().enumerate() {
-            if i != 0 {
+            if i != 0 && tt_prepend_space(&tt) {
                 self.space();
             }
             self.print_tt(tt, convert_dollar_crate);
diff --git a/src/test/pretty/attr-literals.rs b/src/test/pretty/attr-literals.rs
index bcd6ffaaf815b..9db7e27b16103 100644
--- a/src/test/pretty/attr-literals.rs
+++ b/src/test/pretty/attr-literals.rs
@@ -5,10 +5,10 @@
 #![feature(rustc_attrs)]
 
 fn main() {
-    #![rustc_dummy("hi" , 1 , 2 , 1.012 , pi = 3.14 , bye , name ("John"))]
+    #![rustc_dummy("hi", 1, 2, 1.012, pi = 3.14, bye, name ("John"))]
     #[rustc_dummy = 8]
     fn f() { }
 
-    #[rustc_dummy(1 , 2 , 3)]
+    #[rustc_dummy(1, 2, 3)]
     fn g() { }
 }
diff --git a/src/test/pretty/block-comment-wchar.pp b/src/test/pretty/block-comment-wchar.pp
index f15d7cdc44ccd..9317b36ba497b 100644
--- a/src/test/pretty/block-comment-wchar.pp
+++ b/src/test/pretty/block-comment-wchar.pp
@@ -99,8 +99,5 @@
          '\u{2004}', '\u{2005}', '\u{2006}', '\u{2007}', '\u{2008}',
          '\u{2009}', '\u{200A}', '\u{2028}', '\u{2029}', '\u{202F}',
          '\u{205F}', '\u{3000}'];
-    for c in &chars {
-        let ws = c.is_whitespace();
-        println!("{} {}" , c , ws);
-    }
+    for c in &chars { let ws = c.is_whitespace(); println!("{} {}", c, ws); }
 }
diff --git a/src/test/pretty/delimited-token-groups.rs b/src/test/pretty/delimited-token-groups.rs
index 768f27ad23a8e..7bbb7dc911f93 100644
--- a/src/test/pretty/delimited-token-groups.rs
+++ b/src/test/pretty/delimited-token-groups.rs
@@ -5,7 +5,7 @@
 macro_rules! mac { ($ ($ tt : tt) *) => () }
 
 mac! {
-    struct S { field1 : u8 , field2 : u16 , } impl Clone for S
+    struct S { field1 : u8, field2 : u16, } impl Clone for S
     {
         fn clone () -> S
         {
diff --git a/src/test/pretty/do1.rs b/src/test/pretty/do1.rs
index 7be835cb22f2d..233ccdb0098b3 100644
--- a/src/test/pretty/do1.rs
+++ b/src/test/pretty/do1.rs
@@ -2,4 +2,4 @@
 
 fn f<F>(f: F) where F: Fn(isize) { f(10) }
 
-fn main() { f(|i| { assert_eq!(i , 10) }) }
+fn main() { f(|i| { assert_eq!(i, 10) }) }
diff --git a/src/test/pretty/match-block-expr.rs b/src/test/pretty/match-block-expr.rs
index 0db6574b0737f..10903e928cda8 100644
--- a/src/test/pretty/match-block-expr.rs
+++ b/src/test/pretty/match-block-expr.rs
@@ -2,5 +2,5 @@
 
 fn main() {
     let x = match { 5 } { 1 => 5, 2 => 6, _ => 7, };
-    assert_eq!(x , 7);
+    assert_eq!(x, 7);
 }
diff --git a/src/test/ui/macros/macro-first-set.rs b/src/test/ui/macros/macro-first-set.rs
index a21e4cd201a4f..34529cdaa64f1 100644
--- a/src/test/ui/macros/macro-first-set.rs
+++ b/src/test/ui/macros/macro-first-set.rs
@@ -25,7 +25,7 @@ macro_rules! foo_26444 {
 }
 
 fn test_26444() {
-    assert_eq!("a , b , c , d , e", foo_26444!(a, b; c; d, e));
+    assert_eq!("a, b, c, d, e", foo_26444!(a, b; c; d, e));
     assert_eq!("f", foo_26444!(; f ;));
 }
 
diff --git a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs
index d81e16d9d2961..f1de3709b166b 100644
--- a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs
+++ b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs
@@ -17,7 +17,7 @@ pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream {
 #[proc_macro_attribute]
 pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream {
     assert!(attr.to_string().is_empty());
-    assert_eq!(item.to_string(), "println!(\"{}\" , string);");
+    assert_eq!(item.to_string(), "println!(\"{}\", string);");
     item
 }
 
@@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
 #[proc_macro_attribute]
 pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
     assert!(attr.to_string().is_empty());
-    assert_eq!(item.to_string(), "println!(\"{}\" , string)");
+    assert_eq!(item.to_string(), "println!(\"{}\", string)");
     item
 }
 
diff --git a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs
index 0a82cbedd77ce..d2180def5b760 100644
--- a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs
+++ b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs
@@ -17,7 +17,7 @@ pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream {
 #[proc_macro_attribute]
 pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream {
     assert!(attr.to_string().is_empty());
-    assert_eq!(item.to_string(), "println!(\"{}\" , string);");
+    assert_eq!(item.to_string(), "println!(\"{}\", string);");
     item
 }
 
@@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
 #[proc_macro_attribute]
 pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
     assert!(attr.to_string().is_empty());
-    assert_eq!(item.to_string(), "println!(\"{}\" , string)");
+    assert_eq!(item.to_string(), "println!(\"{}\", string)");
     item
 }
 

From 94e8ff4f0b94c788ec9e9a28d3aa6f87062e2966 Mon Sep 17 00:00:00 2001
From: Pascal Hertleif <pascal@technocreatives.com>
Date: Sat, 24 Aug 2019 17:50:21 +0200
Subject: [PATCH 252/943] Refactor feature gate checking code

Tries to clarify the filtering of active features and make the code more
expressive.
---
 src/libsyntax/feature_gate/check.rs | 40 ++++++++++++++++-------------
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 344e5fd6e46c2..f3a9d135125ae 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -732,13 +732,9 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
         }
     }
 
-    for &(name, .., f_edition, set) in ACTIVE_FEATURES {
-        if let Some(f_edition) = f_edition {
-            if f_edition <= crate_edition {
-                set(&mut features, DUMMY_SP);
-                edition_enabled_features.insert(name, crate_edition);
-            }
-        }
+    for feature in active_features_up_to(crate_edition) {
+        feature.set(&mut features, DUMMY_SP);
+        edition_enabled_features.insert(feature.name, crate_edition);
     }
 
     // Process the edition umbrella feature-gates first, to ensure
@@ -760,20 +756,17 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
 
             let name = mi.name_or_empty();
 
-            if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) {
-                if *edition <= crate_edition {
+            let edition = ALL_EDITIONS.iter().find(|e| name == e.feature_name()).copied();
+            if let Some(edition) = edition {
+                if edition <= crate_edition {
                     continue;
                 }
 
-                for &(name, .., f_edition, set) in ACTIVE_FEATURES {
-                    if let Some(f_edition) = f_edition {
-                        if f_edition <= *edition {
-                            // FIXME(Manishearth) there is currently no way to set
-                            // lib features by edition
-                            set(&mut features, DUMMY_SP);
-                            edition_enabled_features.insert(name, *edition);
-                        }
-                    }
+                for feature in active_features_up_to(edition) {
+                    // FIXME(Manishearth) there is currently no way to set
+                    // lib features by edition
+                    feature.set(&mut features, DUMMY_SP);
+                    edition_enabled_features.insert(feature.name, edition);
                 }
             }
         }
@@ -867,6 +860,17 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
     features
 }
 
+fn active_features_up_to(edition: Edition) -> impl Iterator<Item=&'static Feature> {
+    ACTIVE_FEATURES.iter()
+    .filter(move |feature| {
+        if let Some(feature_edition) = feature.edition {
+            feature_edition <= edition
+        } else {
+            false
+        }
+    })
+}
+
 pub fn check_crate(krate: &ast::Crate,
                    sess: &ParseSess,
                    features: &Features,

From 8458eba41bb1ae7848143f33c610b59e9614ec9b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 25 Aug 2019 13:34:57 -0700
Subject: [PATCH 253/943] Point at method call on missing annotation error

Make it clearer where the type name that couldn't be infered comes from.
---
 .../infer/error_reporting/need_type_info.rs   | 39 +++++++++++++++----
 .../error_reporting/region_name.rs            |  6 +--
 .../issue-42234-unknown-receiver-type.stderr  |  4 +-
 .../ui/span/type-annotations-needed-expr.rs   |  3 ++
 .../span/type-annotations-needed-expr.stderr  | 11 ++++++
 5 files changed, 51 insertions(+), 12 deletions(-)
 create mode 100644 src/test/ui/span/type-annotations-needed-expr.rs
 create mode 100644 src/test/ui/span/type-annotations-needed-expr.stderr

diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index 3267505708b81..5e0f973fdd310 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -150,12 +150,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         &self,
         ty: Ty<'tcx>,
         highlight: Option<ty::print::RegionHighlightMode>,
-    ) -> String {
+    ) -> (String, Option<Span>) {
         if let ty::Infer(ty::TyVar(ty_vid)) = ty.sty {
             let ty_vars = self.type_variables.borrow();
-            if let TypeVariableOriginKind::TypeParameterDefinition(name) =
-                ty_vars.var_origin(ty_vid).kind {
-                return name.to_string();
+            let var_origin = ty_vars.var_origin(ty_vid);
+            if let TypeVariableOriginKind::TypeParameterDefinition(name) = var_origin.kind {
+                return (name.to_string(), Some(var_origin.span));
             }
         }
 
@@ -165,7 +165,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             printer.region_highlight_mode = highlight;
         }
         let _ = ty.print(printer);
-        s
+        (s, None)
     }
 
     pub fn need_type_info_err(
@@ -175,7 +175,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         ty: Ty<'tcx>,
     ) -> DiagnosticBuilder<'tcx> {
         let ty = self.resolve_vars_if_possible(&ty);
-        let name = self.extract_type_name(&ty, None);
+        let (name, name_sp) = self.extract_type_name(&ty, None);
 
         let mut local_visitor = FindLocalByTypeVisitor::new(&self, ty, &self.tcx.hir());
         let ty_to_string = |ty: Ty<'tcx>| -> String {
@@ -200,6 +200,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         }
         let err_span = if let Some(pattern) = local_visitor.found_arg_pattern {
             pattern.span
+        } else if let Some(span) = name_sp {
+            // `span` here lets us point at `sum` instead of the entire right hand side expr:
+            // error[E0282]: type annotations needed
+            //  --> file2.rs:3:15
+            //   |
+            // 3 |     let _ = x.sum() as f64;
+            //   |               ^^^ cannot infer type for `S`
+            span
         } else {
             span
         };
@@ -325,6 +333,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             };
             err.span_label(pattern.span, msg);
         }
+        // Instead of the following:
+        // error[E0282]: type annotations needed
+        //  --> file2.rs:3:15
+        //   |
+        // 3 |     let _ = x.sum() as f64;
+        //   |             --^^^--------- cannot infer type for `S`
+        //   |
+        //   = note: type must be known at this point
+        // We want:
+        // error[E0282]: type annotations needed
+        //  --> file2.rs:3:15
+        //   |
+        // 3 |     let _ = x.sum() as f64;
+        //   |               ^^^ cannot infer type for `S`
+        //   |
+        //   = note: type must be known at this point
+        let span = name_sp.unwrap_or(span);
         if !err.span.span_labels().iter().any(|span_label| {
                 span_label.label.is_some() && span_label.span == span
             }) && local_visitor.found_arg_pattern.is_none()
@@ -342,7 +367,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         ty: Ty<'tcx>,
     ) -> DiagnosticBuilder<'tcx> {
         let ty = self.resolve_vars_if_possible(&ty);
-        let name = self.extract_type_name(&ty, None);
+        let name = self.extract_type_name(&ty, None).0;
         let mut err = struct_span_err!(
             self.tcx.sess, span, E0698, "type inside {} must be known in this context", kind,
         );
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index ca68b9e31b6b9..75a31628a54b6 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -413,7 +413,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     ) -> Option<RegionName> {
         let mut highlight = RegionHighlightMode::default();
         highlight.highlighting_region_vid(needle_fr, *counter);
-        let type_name = infcx.extract_type_name(&argument_ty, Some(highlight));
+        let type_name = infcx.extract_type_name(&argument_ty, Some(highlight)).0;
 
         debug!(
             "give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
@@ -695,7 +695,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
         let mut highlight = RegionHighlightMode::default();
         highlight.highlighting_region_vid(fr, *counter);
-        let type_name = infcx.extract_type_name(&return_ty, Some(highlight));
+        let type_name = infcx.extract_type_name(&return_ty, Some(highlight)).0;
 
         let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir");
 
@@ -758,7 +758,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
         let mut highlight = RegionHighlightMode::default();
         highlight.highlighting_region_vid(fr, *counter);
-        let type_name = infcx.extract_type_name(&yield_ty, Some(highlight));
+        let type_name = infcx.extract_type_name(&yield_ty, Some(highlight)).0;
 
         let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir");
 
diff --git a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr
index 04c2870d83297..30c9adb1dce72 100644
--- a/src/test/ui/span/issue-42234-unknown-receiver-type.stderr
+++ b/src/test/ui/span/issue-42234-unknown-receiver-type.stderr
@@ -1,10 +1,10 @@
 error[E0282]: type annotations needed for `std::option::Option<_>`
-  --> $DIR/issue-42234-unknown-receiver-type.rs:7:5
+  --> $DIR/issue-42234-unknown-receiver-type.rs:7:7
    |
 LL |     let x: Option<_> = None;
    |         - consider giving `x` the explicit type `std::option::Option<_>`, where the type parameter `T` is specified
 LL |     x.unwrap().method_that_could_exist_on_some_type();
-   |     ^^^^^^^^^^ cannot infer type for `T`
+   |       ^^^^^^ cannot infer type for `T`
    |
    = note: type must be known at this point
 
diff --git a/src/test/ui/span/type-annotations-needed-expr.rs b/src/test/ui/span/type-annotations-needed-expr.rs
new file mode 100644
index 0000000000000..f64dab4d7bc68
--- /dev/null
+++ b/src/test/ui/span/type-annotations-needed-expr.rs
@@ -0,0 +1,3 @@
+fn main() {
+    let _ = (vec![1,2,3]).into_iter().sum() as f64; //~ ERROR E0282
+}
diff --git a/src/test/ui/span/type-annotations-needed-expr.stderr b/src/test/ui/span/type-annotations-needed-expr.stderr
new file mode 100644
index 0000000000000..e32a542bb7a8c
--- /dev/null
+++ b/src/test/ui/span/type-annotations-needed-expr.stderr
@@ -0,0 +1,11 @@
+error[E0282]: type annotations needed
+  --> $DIR/type-annotations-needed-expr.rs:2:39
+   |
+LL |     let _ = (vec![1,2,3]).into_iter().sum() as f64;
+   |                                       ^^^ cannot infer type for `S`
+   |
+   = note: type must be known at this point
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.

From 0e3bc62f399b262bb56eb3de146a85729cdb882c Mon Sep 17 00:00:00 2001
From: Nathan <nathan.whitaker01@gmail.com>
Date: Sun, 25 Aug 2019 19:17:32 -0400
Subject: [PATCH 254/943] Allow checking of both compile & run output for
 run-pass tests

---
 src/tools/compiletest/src/common.rs  |  4 ++-
 src/tools/compiletest/src/runtest.rs | 48 ++++++++++++++++++----------
 2 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 66e030e979355..edb9eb7d860e2 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -333,10 +333,12 @@ pub fn expected_output_path(
     testpaths.file.with_extension(extension)
 }
 
-pub const UI_EXTENSIONS: &[&str] = &[UI_STDERR, UI_STDOUT, UI_FIXED];
+pub const UI_EXTENSIONS: &[&str] = &[UI_STDERR, UI_STDOUT, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT];
 pub const UI_STDERR: &str = "stderr";
 pub const UI_STDOUT: &str = "stdout";
 pub const UI_FIXED: &str = "fixed";
+pub const UI_RUN_STDERR: &str = "run.stderr";
+pub const UI_RUN_STDOUT: &str = "run.stdout";
 
 /// Absolute path to the directory where all output for all tests in the given
 /// `relative_dir` group should reside. Example:
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index c1f8caa474e2d..7b5e0752b3673 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2,6 +2,7 @@
 
 use crate::common::{CompareMode, PassMode};
 use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
+use crate::common::{UI_RUN_STDERR, UI_RUN_STDOUT};
 use crate::common::{output_base_dir, output_base_name, output_testname_unique};
 use crate::common::{Codegen, CodegenUnits, Rustdoc};
 use crate::common::{DebugInfoCdb, DebugInfoGdbLldb, DebugInfoGdb, DebugInfoLldb};
@@ -288,6 +289,11 @@ enum ReadFrom {
     Stdin(String),
 }
 
+enum TestOutput {
+    Compile,
+    Run,
+}
+
 impl<'test> TestCx<'test> {
     /// Code executed for each revision in turn (or, if there are no
     /// revisions, exactly once, with revision == None).
@@ -2934,9 +2940,16 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    fn load_compare_outputs(&self, proc_res: &ProcRes, explicit_format: bool) -> usize {
-        let expected_stderr = self.load_expected_output(UI_STDERR);
-        let expected_stdout = self.load_expected_output(UI_STDOUT);
+    fn load_compare_outputs(&self, proc_res: &ProcRes,
+        output_kind: TestOutput, explicit_format: bool) -> usize {
+
+        let (stderr_kind, stdout_kind) = match output_kind {
+            TestOutput::Compile => (UI_STDERR, UI_STDOUT),
+            TestOutput::Run => (UI_RUN_STDERR, UI_RUN_STDOUT)
+        };
+
+        let expected_stderr = self.load_expected_output(stderr_kind);
+        let expected_stdout = self.load_expected_output(stdout_kind);
 
         let normalized_stdout =
             self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout);
@@ -2949,11 +2962,19 @@ impl<'test> TestCx<'test> {
 
         let normalized_stderr = self.normalize_output(&stderr, &self.props.normalize_stderr);
         let mut errors = 0;
-        if !self.props.dont_check_compiler_stdout {
-            errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout);
-        }
-        if !self.props.dont_check_compiler_stderr {
-            errors += self.compare_output("stderr", &normalized_stderr, &expected_stderr);
+        match output_kind {
+            TestOutput::Compile => {
+                if !self.props.dont_check_compiler_stdout {
+                    errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout);
+                }
+                if !self.props.dont_check_compiler_stderr {
+                    errors += self.compare_output("stderr", &normalized_stderr, &expected_stderr);
+                }
+            }
+            TestOutput::Run => {
+                errors += self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);
+                errors += self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);
+            }
         }
         errors
     }
@@ -2975,14 +2996,7 @@ impl<'test> TestCx<'test> {
         let modes_to_prune = vec![CompareMode::Nll];
         self.prune_duplicate_outputs(&modes_to_prune);
 
-        // if the user specified to check the results of the
-        // run-pass test, delay loading and comparing output
-        // until execution of the binary
-        let mut errors = if !self.props.check_run_results {
-            self.load_compare_outputs(&proc_res, explicit)
-        } else {
-            0
-        };
+        let mut errors = self.load_compare_outputs(&proc_res, TestOutput::Compile, explicit);
 
         if self.config.compare_mode.is_some() {
             // don't test rustfix with nll right now
@@ -3062,7 +3076,7 @@ impl<'test> TestCx<'test> {
         if self.should_run_successfully() {
             let proc_res = self.exec_compiled_test();
             let run_output_errors = if self.props.check_run_results {
-                self.load_compare_outputs(&proc_res, explicit)
+                self.load_compare_outputs(&proc_res, TestOutput::Run, explicit)
             } else {
                 0
             };

From c8a69e2567c714b870bbb7b2135153a3017c990c Mon Sep 17 00:00:00 2001
From: Hristo Venev <hristo@venev.name>
Date: Mon, 26 Aug 2019 13:14:30 +0000
Subject: [PATCH 255/943] ty: use Align for ReprOptions pack and align.

---
 src/librustc/ty/layout.rs        | 49 +++++++++++++-------------------
 src/librustc/ty/mod.rs           | 28 +++++++++++-------
 src/librustc_typeck/check/mod.rs | 14 +++++----
 3 files changed, 45 insertions(+), 46 deletions(-)

diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 8febcfd0754c9..5ec4754c4535b 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -273,14 +273,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                              repr: &ReprOptions,
                              kind: StructKind) -> Result<LayoutDetails, LayoutError<'tcx>> {
         let dl = self.data_layout();
-        let packed = repr.packed();
-        if packed && repr.align > 0 {
+        let pack = repr.pack;
+        if pack.is_some() && repr.align.is_some() {
             bug!("struct cannot be packed and aligned");
         }
 
-        let pack = Align::from_bytes(repr.pack as u64).unwrap();
-
-        let mut align = if packed {
+        let mut align = if pack.is_some() {
             dl.i8_align
         } else {
             dl.aggregate_align
@@ -303,7 +301,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             };
             let optimizing = &mut inverse_memory_index[..end];
             let field_align = |f: &TyLayout<'_>| {
-                if packed { f.align.abi.min(pack) } else { f.align.abi }
+                if let Some(pack) = pack { f.align.abi.min(pack) } else { f.align.abi }
             };
             match kind {
                 StructKind::AlwaysSized |
@@ -334,7 +332,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         let mut largest_niche_available = 0;
 
         if let StructKind::Prefixed(prefix_size, prefix_align) = kind {
-            let prefix_align = if packed {
+            let prefix_align = if let Some(pack) = pack {
                 prefix_align.min(pack)
             } else {
                 prefix_align
@@ -355,7 +353,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
             }
 
             // Invariant: offset < dl.obj_size_bound() <= 1<<61
-            let field_align = if packed {
+            let field_align = if let Some(pack) = pack {
                 field.align.min(AbiAndPrefAlign::new(pack))
             } else {
                 field.align
@@ -379,10 +377,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 .ok_or(LayoutError::SizeOverflow(ty))?;
         }
 
-        if repr.align > 0 {
-            let repr_align = repr.align as u64;
-            align = align.max(AbiAndPrefAlign::new(Align::from_bytes(repr_align).unwrap()));
-            debug!("univariant repr_align: {:?}", repr_align);
+        if let Some(repr_align) = repr.align {
+            align = align.max(AbiAndPrefAlign::new(repr_align));
         }
 
         debug!("univariant min_size: {:?}", offset);
@@ -730,23 +726,18 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                 }).collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
 
                 if def.is_union() {
-                    let packed = def.repr.packed();
-                    if packed && def.repr.align > 0 {
-                        bug!("Union cannot be packed and aligned");
+                    if def.repr.pack.is_some() && def.repr.align.is_some() {
+                        bug!("union cannot be packed and aligned");
                     }
 
-                    let pack = Align::from_bytes(def.repr.pack as u64).unwrap();
-
-                    let mut align = if packed {
+                    let mut align = if def.repr.pack.is_some() {
                         dl.i8_align
                     } else {
                         dl.aggregate_align
                     };
 
-                    if def.repr.align > 0 {
-                        let repr_align = def.repr.align as u64;
-                        align = align.max(
-                            AbiAndPrefAlign::new(Align::from_bytes(repr_align).unwrap()));
+                    if let Some(repr_align) = def.repr.align {
+                        align = align.max(AbiAndPrefAlign::new(repr_align));
                     }
 
                     let optimize = !def.repr.inhibit_union_abi_opt();
@@ -755,13 +746,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                     let index = VariantIdx::new(0);
                     for field in &variants[index] {
                         assert!(!field.is_unsized());
-
-                        let field_align = if packed {
-                            field.align.min(AbiAndPrefAlign::new(pack))
-                        } else {
-                            field.align
-                        };
-                        align = align.max(field_align);
+                        align = align.max(field.align);
 
                         // If all non-ZST fields have the same ABI, forward this ABI
                         if optimize && !field.is_zst() {
@@ -796,6 +781,10 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                         size = cmp::max(size, field.size);
                     }
 
+                    if let Some(pack) = def.repr.pack {
+                        align = align.min(AbiAndPrefAlign::new(pack));
+                    }
+
                     return Ok(tcx.intern_layout(LayoutDetails {
                         variants: Variants::Single { index },
                         fields: FieldPlacement::Union(variants[index].len()),
@@ -1637,7 +1626,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
         };
 
         let adt_kind = adt_def.adt_kind();
-        let adt_packed = adt_def.repr.packed();
+        let adt_packed = adt_def.repr.pack.is_some();
 
         let build_variant_info = |n: Option<Ident>,
                                   flds: &[ast::Name],
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 0b81f193df409..bafd65673e613 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -33,6 +33,7 @@ use arena::SyncDroplessArena;
 use crate::session::DataTypeKind;
 
 use rustc_serialize::{self, Encodable, Encoder};
+use rustc_target::abi::Align;
 use std::cell::RefCell;
 use std::cmp::{self, Ordering};
 use std::fmt;
@@ -2057,8 +2058,8 @@ impl_stable_hash_for!(struct ReprFlags {
 #[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Default)]
 pub struct ReprOptions {
     pub int: Option<attr::IntType>,
-    pub align: u32,
-    pub pack: u32,
+    pub align: Option<Align>,
+    pub pack: Option<Align>,
     pub flags: ReprFlags,
 }
 
@@ -2073,18 +2074,19 @@ impl ReprOptions {
     pub fn new(tcx: TyCtxt<'_>, did: DefId) -> ReprOptions {
         let mut flags = ReprFlags::empty();
         let mut size = None;
-        let mut max_align = 0;
-        let mut min_pack = 0;
+        let mut max_align: Option<Align> = None;
+        let mut min_pack: Option<Align> = None;
         for attr in tcx.get_attrs(did).iter() {
             for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
                 flags.insert(match r {
                     attr::ReprC => ReprFlags::IS_C,
                     attr::ReprPacked(pack) => {
-                        min_pack = if min_pack > 0 {
-                            cmp::min(pack, min_pack)
+                        let pack = Align::from_bytes(pack as u64).unwrap();
+                        min_pack = Some(if let Some(min_pack) = min_pack {
+                            min_pack.min(pack)
                         } else {
                             pack
-                        };
+                        });
                         ReprFlags::empty()
                     },
                     attr::ReprTransparent => ReprFlags::IS_TRANSPARENT,
@@ -2094,7 +2096,7 @@ impl ReprOptions {
                         ReprFlags::empty()
                     },
                     attr::ReprAlign(align) => {
-                        max_align = cmp::max(align, max_align);
+                        max_align = max_align.max(Some(Align::from_bytes(align as u64).unwrap()));
                         ReprFlags::empty()
                     },
                 });
@@ -2113,7 +2115,7 @@ impl ReprOptions {
     #[inline]
     pub fn c(&self) -> bool { self.flags.contains(ReprFlags::IS_C) }
     #[inline]
-    pub fn packed(&self) -> bool { self.pack > 0 }
+    pub fn packed(&self) -> bool { self.pack.is_some() }
     #[inline]
     pub fn transparent(&self) -> bool { self.flags.contains(ReprFlags::IS_TRANSPARENT) }
     #[inline]
@@ -2133,8 +2135,12 @@ impl ReprOptions {
     /// Returns `true` if this `#[repr()]` should inhibit struct field reordering
     /// optimizations, such as with `repr(C)`, `repr(packed(1))`, or `repr(<int>)`.
     pub fn inhibit_struct_field_reordering_opt(&self) -> bool {
-        self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.pack == 1 ||
-            self.int.is_some()
+        if let Some(pack) = self.pack {
+            if pack.bytes() == 1 {
+                return true;
+            }
+        }
+        self.flags.intersects(ReprFlags::IS_UNOPTIMISABLE) || self.int.is_some()
     }
 
     /// Returns `true` if this `#[repr()]` should inhibit union ABI optimisations.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c4dbe97a7bd96..fa5414fc22b08 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1859,14 +1859,18 @@ fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) {
         for attr in tcx.get_attrs(def_id).iter() {
             for r in attr::find_repr_attrs(&tcx.sess.parse_sess, attr) {
                 if let attr::ReprPacked(pack) = r {
-                    if pack != repr.pack {
-                        struct_span_err!(tcx.sess, sp, E0634,
-                                         "type has conflicting packed representation hints").emit();
+                    if let Some(repr_pack) = repr.pack {
+                        if pack as u64 != repr_pack.bytes() {
+                            struct_span_err!(
+                                tcx.sess, sp, E0634,
+                                "type has conflicting packed representation hints"
+                            ).emit();
+                        }
                     }
                 }
             }
         }
-        if repr.align > 0 {
+        if repr.align.is_some() {
             struct_span_err!(tcx.sess, sp, E0587,
                              "type has conflicting packed and align representation hints").emit();
         }
@@ -1885,7 +1889,7 @@ fn check_packed_inner(tcx: TyCtxt<'_>, def_id: DefId, stack: &mut Vec<DefId>) ->
     }
     if let ty::Adt(def, substs) = t.sty {
         if def.is_struct() || def.is_union() {
-            if tcx.adt_def(def.did).repr.align > 0 {
+            if tcx.adt_def(def.did).repr.align.is_some() {
                 return true;
             }
             // push struct def_id before checking fields

From fa7ea104b232fbc2b72f7717393181e849d39dfe Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Mon, 26 Aug 2019 17:51:52 +0000
Subject: [PATCH 256/943] Error when generator trait is not found

---
 src/librustc_typeck/check/closure.rs          |  4 ++--
 src/test/ui/lang-item-missing-generator.rs    | 19 +++++++++++++++++++
 .../ui/lang-item-missing-generator.stderr     |  4 ++++
 3 files changed, 25 insertions(+), 2 deletions(-)
 create mode 100644 src/test/ui/lang-item-missing-generator.rs
 create mode 100644 src/test/ui/lang-item-missing-generator.stderr

diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index d2f2f89cf0b1c..06b1e7bfd4eaf 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -3,7 +3,7 @@
 use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
 
 use crate::astconv::AstConv;
-use crate::middle::region;
+use crate::middle::{lang_items, region};
 use rustc::hir::def_id::DefId;
 use rustc::infer::{InferOk, InferResult};
 use rustc::infer::LateBoundRegionConversionTime;
@@ -266,7 +266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let trait_ref = projection.to_poly_trait_ref(tcx);
 
         let is_fn = tcx.lang_items().fn_trait_kind(trait_ref.def_id()).is_some();
-        let gen_trait = tcx.lang_items().gen_trait().unwrap();
+        let gen_trait = tcx.require_lang_item(lang_items::GeneratorTraitLangItem);
         let is_gen = gen_trait == trait_ref.def_id();
         if !is_fn && !is_gen {
             debug!("deduce_sig_from_projection: not fn or generator");
diff --git a/src/test/ui/lang-item-missing-generator.rs b/src/test/ui/lang-item-missing-generator.rs
new file mode 100644
index 0000000000000..0c329542928c5
--- /dev/null
+++ b/src/test/ui/lang-item-missing-generator.rs
@@ -0,0 +1,19 @@
+// error-pattern: requires `generator` lang_item
+#![feature(no_core, lang_items, unboxed_closures)]
+#![no_core]
+
+#[lang = "sized"] pub trait Sized { }
+
+#[lang = "fn_once"]
+#[rustc_paren_sugar]
+pub trait FnOnce<Args> {
+    type Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
+
+pub fn abc() -> impl FnOnce(f32) {
+    |_| {}
+}
+
+fn main() {}
diff --git a/src/test/ui/lang-item-missing-generator.stderr b/src/test/ui/lang-item-missing-generator.stderr
new file mode 100644
index 0000000000000..d0cc4b81be685
--- /dev/null
+++ b/src/test/ui/lang-item-missing-generator.stderr
@@ -0,0 +1,4 @@
+error: requires `generator` lang_item
+
+error: aborting due to previous error
+

From ae788620588029bef52d27d01ce66010a3c9a4b2 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 26 Aug 2019 19:48:56 +0200
Subject: [PATCH 257/943] raw slices do not have to comply to the size limit

---
 src/librustc_mir/interpret/validity.rs | 19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index 7af55a2a3a376..c2505547c5b4f 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -3,7 +3,7 @@ use std::ops::RangeInclusive;
 
 use syntax_pos::symbol::{sym, Symbol};
 use rustc::hir;
-use rustc::ty::layout::{self, Size, TyLayout, LayoutOf, VariantIdx};
+use rustc::ty::layout::{self, TyLayout, LayoutOf, VariantIdx};
 use rustc::ty;
 use rustc_data_structures::fx::FxHashSet;
 
@@ -276,20 +276,11 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
                 // FIXME: More checks for the vtable.
             }
             ty::Slice(..) | ty::Str => {
-                let len = try_validation!(meta.unwrap().to_usize(self.ecx),
+                let _len = try_validation!(meta.unwrap().to_usize(self.ecx),
                     "non-integer slice length in wide pointer", self.path);
-                // check max slice length
-                let elem_size = match tail.sty {
-                    ty::Str => Size::from_bytes(1),
-                    ty::Slice(ty) => self.ecx.layout_of(ty)?.size,
-                    _ => bug!("It cannot be another type"),
-                };
-                if elem_size.checked_mul(len, &*self.ecx.tcx).is_none() {
-                    throw_validation_failure!(
-                        "too large slice (longer than isize::MAX bytes)",
-                        self.path
-                    );
-                }
+                // We do not check that `len * elem_size <= isize::MAX`:
+                // that is only required for references, and there it falls out of the
+                // "dereferencable" check performed by Stacked Borrows.
             }
             ty::Foreign(..) => {
                 // Unsized, but not wide.

From 633f67ad74179ee51aaaf913d14d3d9ab65f4a65 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 26 Aug 2019 20:40:30 +0200
Subject: [PATCH 258/943] add link to FileCheck docs

---
 src/test/codegen/README.md | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 src/test/codegen/README.md

diff --git a/src/test/codegen/README.md b/src/test/codegen/README.md
new file mode 100644
index 0000000000000..00de55eeab1f4
--- /dev/null
+++ b/src/test/codegen/README.md
@@ -0,0 +1,2 @@
+The files here use the LLVM FileCheck framework, documented at
+<https://llvm.org/docs/CommandGuide/FileCheck.html>.

From 1478ef45287c4da0da0daf1715d00e8b06fa333b Mon Sep 17 00:00:00 2001
From: Christian Veenman <46896178+DevQps@users.noreply.github.com>
Date: Mon, 26 Aug 2019 22:05:26 +0200
Subject: [PATCH 259/943] Update src/libstd/time.rs

Co-Authored-By: lzutao <taolzu@gmail.com>
---
 src/libstd/time.rs | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index f03020bb4954e..c05f02389dfa0 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -70,7 +70,9 @@ pub use core::time::Duration;
 /// |    UNIX   | [mach_absolute_time](https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html)                           |
 /// |  VXWorks  | [clock_gettime (Monotonic Clock)](https://linux.die.net/man/3/clock_gettime)                                |
 /// |    WASI   | [__wasi_clock_time_get (Monotonic Clock)](https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get)      |
-/// |  Windows  | [QueryPerformanceCounter](https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter)                      |
+/// |  Windows  | [QueryPerformanceCounter] |
+
+[QueryPerformanceCounter]: https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter
 ///
 /// **Disclaimer:** These system calls might change over time.
 ///

From 2bd27fbdfe309f3f6abd76f72f379247d49048b7 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 26 Aug 2019 22:14:31 +0200
Subject: [PATCH 260/943] parser: fix span for leading vert.

---
 src/libsyntax/parse/parser/pat.rs                             | 3 ++-
 .../or-patterns/feature-gate-or_patterns-leading-for.stderr   | 4 ++--
 .../or-patterns/feature-gate-or_patterns-leading-let.stderr   | 4 ++--
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index f2e269e03baf9..78c9a289b3702 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -50,6 +50,7 @@ impl<'a> Parser<'a> {
     pub(super) fn parse_top_pat(&mut self, gate_or: GateOr) -> PResult<'a, P<Pat>> {
         // Allow a '|' before the pats (RFCs 1925, 2530, and 2535).
         let gated_leading_vert = self.eat_or_separator() && gate_or == GateOr::Yes;
+        let leading_vert_span = self.prev_span;
 
         // Parse the possibly-or-pattern.
         let pat = self.parse_pat_with_or(None, gate_or, RecoverComma::Yes)?;
@@ -61,7 +62,7 @@ impl<'a> Parser<'a> {
         if gated_leading_vert {
             let mut or_pattern_spans = self.sess.gated_spans.or_patterns.borrow_mut();
             if or_pattern_spans.is_empty() {
-                or_pattern_spans.push(self.prev_span);
+                or_pattern_spans.push(leading_vert_span);
             }
         }
 
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.stderr b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.stderr
index 83804d564f3e4..f520409e8bad6 100644
--- a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.stderr
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-for.stderr
@@ -1,8 +1,8 @@
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns-leading-for.rs:7:11
+  --> $DIR/feature-gate-or_patterns-leading-for.rs:7:9
    |
 LL |     for | A in 0 {}
-   |           ^
+   |         ^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/54883
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr
index f7954ad7a8ce1..30fd6a1a95eff 100644
--- a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr
@@ -1,8 +1,8 @@
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns-leading-let.rs:7:11
+  --> $DIR/feature-gate-or_patterns-leading-let.rs:7:9
    |
 LL |     let | A;
-   |           ^
+   |         ^
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/54883
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable

From 04580b6235188ffd6bb20387e8eeb9a102fafb50 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 26 Aug 2019 22:19:47 +0200
Subject: [PATCH 261/943] adjust tests

---
 src/test/ui/consts/const-eval/ub-wide-ptr.rs  |  3 +--
 .../ui/consts/const-eval/ub-wide-ptr.stderr   | 24 +++++++------------
 2 files changed, 9 insertions(+), 18 deletions(-)

diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
index 20d1a5b08cdad..765ed60ee9742 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
@@ -126,8 +126,7 @@ const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]
 // # raw slice
 const RAW_SLICE_VALID: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 1 } }.raw_slice}; // ok
 const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.raw_slice}; // ok because raw
-const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: usize::max_value() } }.raw_slice};
-//~^ ERROR it is undefined behavior to use this value
+const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: usize::max_value() } }.raw_slice}; // ok because raw
 const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
 //~^ ERROR it is undefined behavior to use this value
 
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
index 264bb675506f6..88d8af8026193 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -87,15 +87,7 @@ LL | const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:129:1
-   |
-LL | const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: usize::max_value() } }.raw_slice};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too large slice (longer than isize::MAX bytes)
-   |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
-
-error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:131:1
+  --> $DIR/ub-wide-ptr.rs:130:1
    |
 LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
@@ -103,7 +95,7 @@ LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:136:1
+  --> $DIR/ub-wide-ptr.rs:135:1
    |
 LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -111,7 +103,7 @@ LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vta
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:139:1
+  --> $DIR/ub-wide-ptr.rs:138:1
    |
 LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -119,7 +111,7 @@ LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, v
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:142:1
+  --> $DIR/ub-wide-ptr.rs:141:1
    |
 LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -127,7 +119,7 @@ LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, v
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:146:1
+  --> $DIR/ub-wide-ptr.rs:145:1
    |
 LL | const G: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.<dyn-downcast>, but expected something less or equal to 1
@@ -135,7 +127,7 @@ LL | const G: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:150:1
+  --> $DIR/ub-wide-ptr.rs:149:1
    |
 LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 0 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -143,13 +135,13 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { DynTransmute {
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:152:1
+  --> $DIR/ub-wide-ptr.rs:151:1
    |
 LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.raw_rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
-error: aborting due to 19 previous errors
+error: aborting due to 18 previous errors
 
 For more information about this error, try `rustc --explain E0080`.

From 7def99af8a311139c43c961e13872ff27dd235c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 26 Aug 2019 13:25:27 -0700
Subject: [PATCH 262/943] review comment

---
 src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs | 2 +-
 src/test/ui/lint/lint-dead-code-unused-variant-pub.rs    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs b/src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs
index 2b06fcb69ceee..15b04496ba7b1 100644
--- a/src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs
+++ b/src/test/ui/lint/lint-dead-code-empty-unused-enum-pub.rs
@@ -1,4 +1,4 @@
-// run-pass
+// build-pass
 #![deny(unused)]
 
 pub enum E {}
diff --git a/src/test/ui/lint/lint-dead-code-unused-variant-pub.rs b/src/test/ui/lint/lint-dead-code-unused-variant-pub.rs
index 918300ba79354..3a9061340eb81 100644
--- a/src/test/ui/lint/lint-dead-code-unused-variant-pub.rs
+++ b/src/test/ui/lint/lint-dead-code-unused-variant-pub.rs
@@ -1,4 +1,4 @@
-// run-pass
+// build-pass
 #![deny(unused)]
 
 pub struct F;

From ec45b87957c4158934fc3f5a821594ad0686ea4e Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sat, 24 Aug 2019 21:12:13 +0300
Subject: [PATCH 263/943] resolve: Block expansion of a derive container until
 all its derives are resolved

Also mark derive helpers as known as a part of the derive container's expansion instead of expansion of the derives themselves which may happen too late.
---
 src/librustc_metadata/decoder.rs              |   4 +-
 src/librustc_resolve/macros.rs                |  41 +++----
 src/libsyntax/ext/base.rs                     |  20 ++-
 src/libsyntax/ext/expand.rs                   | 114 ++++++++++--------
 src/libsyntax/ext/proc_macro.rs               |   6 +-
 src/test/ui/derives/deriving-bounds.stderr    |  24 ++--
 .../issue-43106-gating-of-derive-2.stderr     |   4 +-
 .../issue-43106-gating-of-derive.rs           |   3 -
 .../issue-43106-gating-of-derive.stderr       |  16 +--
 src/test/ui/issues/issue-36617.rs             |   1 +
 src/test/ui/issues/issue-36617.stderr         |  10 +-
 .../ui/proc-macro/derive-helper-configured.rs |  18 +++
 .../ui/proc-macro/derive-helper-shadowing.rs  |   3 +-
 .../proc-macro/derive-helper-shadowing.stderr |   8 +-
 src/test/ui/proc-macro/resolve-error.stderr   |  76 ++++++------
 15 files changed, 195 insertions(+), 153 deletions(-)
 create mode 100644 src/test/ui/proc-macro/derive-helper-configured.rs

diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 5b9cb966af235..7d2414f9a1dfa 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -538,9 +538,7 @@ impl<'a, 'tcx> CrateMetadata {
                     attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
                 (
                     trait_name,
-                    SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive {
-                        client, attrs: helper_attrs.clone()
-                    })),
+                    SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive { client })),
                     helper_attrs,
                 )
             }
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 719167eb057b2..20418633dc682 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -13,7 +13,7 @@ use rustc::{ty, lint, span_bug};
 use syntax::ast::{self, NodeId, Ident};
 use syntax::attr::StabilityLevel;
 use syntax::edition::Edition;
-use syntax::ext::base::{self, Indeterminate, SpecialDerives};
+use syntax::ext::base::{self, InvocationRes, Indeterminate, SpecialDerives};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
 use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind};
@@ -142,7 +142,7 @@ impl<'a> base::Resolver for Resolver<'a> {
 
     fn resolve_macro_invocation(
         &mut self, invoc: &Invocation, eager_expansion_root: ExpnId, force: bool
-    ) -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> {
+    ) -> Result<InvocationRes, Indeterminate> {
         let invoc_id = invoc.expansion_data.id;
         let parent_scope = match self.invocation_parent_scopes.get(&invoc_id) {
             Some(parent_scope) => *parent_scope,
@@ -165,25 +165,24 @@ impl<'a> base::Resolver for Resolver<'a> {
             InvocationKind::Derive { ref path, .. } =>
                 (path, MacroKind::Derive, &[][..], false),
             InvocationKind::DeriveContainer { ref derives, .. } => {
-                // Block expansion of derives in the container until we know whether one of them
-                // is a built-in `Copy`. Skip the resolution if there's only one derive - either
-                // it's not a `Copy` and we don't need to do anything, or it's a `Copy` and it
-                // will automatically knows about itself.
-                let mut result = Ok(None);
-                if derives.len() > 1 {
-                    for path in derives {
-                        match self.resolve_macro_path(path, Some(MacroKind::Derive),
-                                                      &parent_scope, true, force) {
-                            Ok((Some(ref ext), _)) if ext.is_derive_copy => {
-                                self.add_derives(invoc_id, SpecialDerives::COPY);
-                                return Ok(None);
-                            }
-                            Err(Determinacy::Undetermined) => result = Err(Indeterminate),
-                            _ => {}
-                        }
-                    }
+                // Block expansion of the container until we resolve all derives in it.
+                // This is required for two reasons:
+                // - Derive helper attributes are in scope for the item to which the `#[derive]`
+                //   is applied, so they have to be produced by the container's expansion rather
+                //   than by individual derives.
+                // - Derives in the container need to know whether one of them is a built-in `Copy`.
+                // FIXME: Try to avoid repeated resolutions for derives here and in expansion.
+                let mut exts = Vec::new();
+                for path in derives {
+                    exts.push(match self.resolve_macro_path(
+                        path, Some(MacroKind::Derive), &parent_scope, true, force
+                    ) {
+                        Ok((Some(ext), _)) => ext,
+                        Ok(_) | Err(Determinacy::Determined) => self.dummy_ext(MacroKind::Derive),
+                        Err(Determinacy::Undetermined) => return Err(Indeterminate),
+                    })
                 }
-                return result;
+                return Ok(InvocationRes::DeriveContainer(exts));
             }
         };
 
@@ -203,7 +202,7 @@ impl<'a> base::Resolver for Resolver<'a> {
             self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id);
         }
 
-        Ok(Some(ext))
+        Ok(InvocationRes::Single(ext))
     }
 
     fn check_unused_macros(&self) {
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index a63c4181d5e03..f0397558a1d60 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -11,6 +11,7 @@ use crate::ptr::P;
 use crate::symbol::{kw, sym, Ident, Symbol};
 use crate::{ThinVec, MACRO_ARGUMENTS};
 use crate::tokenstream::{self, TokenStream, TokenTree};
+use crate::visit::Visitor;
 
 use errors::{DiagnosticBuilder, DiagnosticId};
 use smallvec::{smallvec, SmallVec};
@@ -72,6 +73,17 @@ impl Annotatable {
         }
     }
 
+    pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) {
+        match self {
+            Annotatable::Item(item) => visitor.visit_item(item),
+            Annotatable::TraitItem(trait_item) => visitor.visit_trait_item(trait_item),
+            Annotatable::ImplItem(impl_item) => visitor.visit_impl_item(impl_item),
+            Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item),
+            Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt),
+            Annotatable::Expr(expr) => visitor.visit_expr(expr),
+        }
+    }
+
     pub fn expect_item(self) -> P<ast::Item> {
         match self {
             Annotatable::Item(i) => i,
@@ -637,6 +649,12 @@ impl SyntaxExtension {
 
 pub type NamedSyntaxExtension = (Name, SyntaxExtension);
 
+/// Result of resolving a macro invocation.
+pub enum InvocationRes {
+    Single(Lrc<SyntaxExtension>),
+    DeriveContainer(Vec<Lrc<SyntaxExtension>>),
+}
+
 /// Error type that denotes indeterminacy.
 pub struct Indeterminate;
 
@@ -664,7 +682,7 @@ pub trait Resolver {
 
     fn resolve_macro_invocation(
         &mut self, invoc: &Invocation, eager_expansion_root: ExpnId, force: bool
-    ) -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate>;
+    ) -> Result<InvocationRes, Indeterminate>;
 
     fn check_unused_macros(&self);
 
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index a6b56e4d5979f..7b4a516744642 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -4,7 +4,7 @@ use crate::attr::{self, HasAttrs};
 use crate::source_map::respan;
 use crate::config::StripUnconfigured;
 use crate::ext::base::*;
-use crate::ext::proc_macro::collect_derives;
+use crate::ext::proc_macro::{collect_derives, MarkAttrs};
 use crate::ext::hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind};
 use crate::ext::tt::macro_rules::annotate_err_with_kind;
 use crate::ext::placeholders::{placeholder, PlaceholderExpander};
@@ -307,10 +307,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
 
             let eager_expansion_root =
                 if self.monotonic { invoc.expansion_data.id } else { orig_expansion_data.id };
-            let ext = match self.cx.resolver.resolve_macro_invocation(
+            let res = match self.cx.resolver.resolve_macro_invocation(
                 &invoc, eager_expansion_root, force
             ) {
-                Ok(ext) => ext,
+                Ok(res) => res,
                 Err(Indeterminate) => {
                     undetermined_invocations.push(invoc);
                     continue
@@ -322,54 +322,72 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             self.cx.current_expansion = invoc.expansion_data.clone();
 
             // FIXME(jseyfried): Refactor out the following logic
-            let (expanded_fragment, new_invocations) = if let Some(ext) = ext {
-                let fragment = self.expand_invoc(invoc, &ext.kind);
-                self.collect_invocations(fragment, &[])
-            } else if let InvocationKind::DeriveContainer { derives: traits, item } = invoc.kind {
-                if !item.derive_allowed() {
-                    let attr = attr::find_by_name(item.attrs(), sym::derive)
-                        .expect("`derive` attribute should exist");
-                    let span = attr.span;
-                    let mut err = self.cx.mut_span_err(span,
-                                                        "`derive` may only be applied to \
-                                                        structs, enums and unions");
-                    if let ast::AttrStyle::Inner = attr.style {
-                        let trait_list = traits.iter()
-                            .map(|t| t.to_string()).collect::<Vec<_>>();
-                        let suggestion = format!("#[derive({})]", trait_list.join(", "));
-                        err.span_suggestion(
-                            span, "try an outer attribute", suggestion,
-                            // We don't 𝑘𝑛𝑜𝑤 that the following item is an ADT
-                            Applicability::MaybeIncorrect
-                        );
-                    }
-                    err.emit();
+            let (expanded_fragment, new_invocations) = match res {
+                InvocationRes::Single(ext) => {
+                    let fragment = self.expand_invoc(invoc, &ext.kind);
+                    self.collect_invocations(fragment, &[])
                 }
+                InvocationRes::DeriveContainer(exts) => {
+                    let (derives, item) = match invoc.kind {
+                        InvocationKind::DeriveContainer { derives, item } => (derives, item),
+                        _ => unreachable!(),
+                    };
+                    if !item.derive_allowed() {
+                        let attr = attr::find_by_name(item.attrs(), sym::derive)
+                            .expect("`derive` attribute should exist");
+                        let span = attr.span;
+                        let mut err = self.cx.mut_span_err(span,
+                            "`derive` may only be applied to structs, enums and unions");
+                        if let ast::AttrStyle::Inner = attr.style {
+                            let trait_list = derives.iter()
+                                .map(|t| t.to_string()).collect::<Vec<_>>();
+                            let suggestion = format!("#[derive({})]", trait_list.join(", "));
+                            err.span_suggestion(
+                                span, "try an outer attribute", suggestion,
+                                // We don't 𝑘𝑛𝑜𝑤 that the following item is an ADT
+                                Applicability::MaybeIncorrect
+                            );
+                        }
+                        err.emit();
+                    }
 
-                let mut item = self.fully_configure(item);
-                item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive));
-                let derive_placeholders =
-                    all_derive_placeholders.entry(invoc.expansion_data.id).or_default();
-
-                derive_placeholders.reserve(traits.len());
-                invocations.reserve(traits.len());
-                for path in traits {
-                    let expn_id = ExpnId::fresh(None);
-                    derive_placeholders.push(NodeId::placeholder_from_expn_id(expn_id));
-                    invocations.push(Invocation {
-                        kind: InvocationKind::Derive { path, item: item.clone() },
-                        fragment_kind: invoc.fragment_kind,
-                        expansion_data: ExpansionData {
-                            id: expn_id,
-                            ..invoc.expansion_data.clone()
-                        },
-                    });
+                    let mut item = self.fully_configure(item);
+                    item.visit_attrs(|attrs| attrs.retain(|a| a.path != sym::derive));
+                    let mut helper_attrs = Vec::new();
+                    let mut has_copy = false;
+                    for ext in exts {
+                        helper_attrs.extend(&ext.helper_attrs);
+                        has_copy |= ext.is_derive_copy;
+                    }
+                    // Mark derive helpers inside this item as known and used.
+                    // FIXME: This is a hack, derive helpers should be integrated with regular name
+                    // resolution instead. For example, helpers introduced by a derive container
+                    // can be in scope for all code produced by that container's expansion.
+                    item.visit_with(&mut MarkAttrs(&helper_attrs));
+                    if has_copy {
+                        self.cx.resolver.add_derives(invoc.expansion_data.id, SpecialDerives::COPY);
+                    }
+
+                    let derive_placeholders =
+                        all_derive_placeholders.entry(invoc.expansion_data.id).or_default();
+                    derive_placeholders.reserve(derives.len());
+                    invocations.reserve(derives.len());
+                    for path in derives {
+                        let expn_id = ExpnId::fresh(None);
+                        derive_placeholders.push(NodeId::placeholder_from_expn_id(expn_id));
+                        invocations.push(Invocation {
+                            kind: InvocationKind::Derive { path, item: item.clone() },
+                            fragment_kind: invoc.fragment_kind,
+                            expansion_data: ExpansionData {
+                                id: expn_id,
+                                ..invoc.expansion_data.clone()
+                            },
+                        });
+                    }
+                    let fragment = invoc.fragment_kind
+                        .expect_from_annotatables(::std::iter::once(item));
+                    self.collect_invocations(fragment, derive_placeholders)
                 }
-                let fragment = invoc.fragment_kind
-                    .expect_from_annotatables(::std::iter::once(item));
-                self.collect_invocations(fragment, derive_placeholders)
-            } else {
-                unreachable!()
             };
 
             if expanded_fragments.len() < depth {
diff --git a/src/libsyntax/ext/proc_macro.rs b/src/libsyntax/ext/proc_macro.rs
index c17b6f6b4248a..4a44c9a9f1f31 100644
--- a/src/libsyntax/ext/proc_macro.rs
+++ b/src/libsyntax/ext/proc_macro.rs
@@ -78,7 +78,6 @@ pub struct ProcMacroDerive {
     pub client: proc_macro::bridge::client::Client<
         fn(proc_macro::TokenStream) -> proc_macro::TokenStream,
     >,
-    pub attrs: Vec<ast::Name>,
 }
 
 impl MultiItemModifier for ProcMacroDerive {
@@ -111,9 +110,6 @@ impl MultiItemModifier for ProcMacroDerive {
             }
         }
 
-        // Mark attributes as known, and used.
-        MarkAttrs(&self.attrs).visit_item(&item);
-
         let token = token::Interpolated(Lrc::new(token::NtItem(item)));
         let input = tokenstream::TokenTree::token(token, DUMMY_SP).into();
 
@@ -164,7 +160,7 @@ impl MultiItemModifier for ProcMacroDerive {
     }
 }
 
-struct MarkAttrs<'a>(&'a [ast::Name]);
+crate struct MarkAttrs<'a>(crate &'a [ast::Name]);
 
 impl<'a> Visitor<'a> for MarkAttrs<'a> {
     fn visit_attribute(&mut self, attr: &Attribute) {
diff --git a/src/test/ui/derives/deriving-bounds.stderr b/src/test/ui/derives/deriving-bounds.stderr
index 99976da72da1d..b18df3511817d 100644
--- a/src/test/ui/derives/deriving-bounds.stderr
+++ b/src/test/ui/derives/deriving-bounds.stderr
@@ -1,15 +1,3 @@
-error: cannot find derive macro `Send` in this scope
-  --> $DIR/deriving-bounds.rs:1:10
-   |
-LL | #[derive(Send)]
-   |          ^^^^
-   |
-note: unsafe traits like `Send` should be implemented explicitly
-  --> $DIR/deriving-bounds.rs:1:10
-   |
-LL | #[derive(Send)]
-   |          ^^^^
-
 error: cannot find derive macro `Sync` in this scope
   --> $DIR/deriving-bounds.rs:5:10
    |
@@ -22,5 +10,17 @@ note: unsafe traits like `Sync` should be implemented explicitly
 LL | #[derive(Sync)]
    |          ^^^^
 
+error: cannot find derive macro `Send` in this scope
+  --> $DIR/deriving-bounds.rs:1:10
+   |
+LL | #[derive(Send)]
+   |          ^^^^
+   |
+note: unsafe traits like `Send` should be implemented explicitly
+  --> $DIR/deriving-bounds.rs:1:10
+   |
+LL | #[derive(Send)]
+   |          ^^^^
+
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.stderr
index be3536aa789c1..f14591c85e62e 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-derive-2.stderr
@@ -1,5 +1,5 @@
 error: cannot find derive macro `x3300` in this scope
-  --> $DIR/issue-43106-gating-of-derive-2.rs:4:14
+  --> $DIR/issue-43106-gating-of-derive-2.rs:12:14
    |
 LL |     #[derive(x3300)]
    |              ^^^^^
@@ -11,7 +11,7 @@ LL |     #[derive(x3300)]
    |              ^^^^^
 
 error: cannot find derive macro `x3300` in this scope
-  --> $DIR/issue-43106-gating-of-derive-2.rs:12:14
+  --> $DIR/issue-43106-gating-of-derive-2.rs:4:14
    |
 LL |     #[derive(x3300)]
    |              ^^^^^
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-derive.rs b/src/test/ui/feature-gate/issue-43106-gating-of-derive.rs
index 1397412988491..c5d9e0db4d389 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-derive.rs
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-derive.rs
@@ -1,9 +1,6 @@
 // `#![derive]` raises errors when it occurs at contexts other than ADT
 // definitions.
 
-#![derive(Debug)]
-//~^ ERROR `derive` may only be applied to structs, enums and unions
-
 #[derive(Debug)]
 //~^ ERROR `derive` may only be applied to structs, enums and unions
 mod derive {
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-derive.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-derive.stderr
index 25f160983d3df..db29a2bddd35c 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-derive.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-derive.stderr
@@ -1,38 +1,32 @@
 error: `derive` may only be applied to structs, enums and unions
   --> $DIR/issue-43106-gating-of-derive.rs:4:1
    |
-LL | #![derive(Debug)]
-   | ^^^^^^^^^^^^^^^^^ help: try an outer attribute: `#[derive(Debug)]`
-
-error: `derive` may only be applied to structs, enums and unions
-  --> $DIR/issue-43106-gating-of-derive.rs:7:1
-   |
 LL | #[derive(Debug)]
    | ^^^^^^^^^^^^^^^^
 
 error: `derive` may only be applied to structs, enums and unions
-  --> $DIR/issue-43106-gating-of-derive.rs:10:17
+  --> $DIR/issue-43106-gating-of-derive.rs:7:17
    |
 LL |     mod inner { #![derive(Debug)] }
    |                 ^^^^^^^^^^^^^^^^^ help: try an outer attribute: `#[derive(Debug)]`
 
 error: `derive` may only be applied to structs, enums and unions
-  --> $DIR/issue-43106-gating-of-derive.rs:13:5
+  --> $DIR/issue-43106-gating-of-derive.rs:10:5
    |
 LL |     #[derive(Debug)]
    |     ^^^^^^^^^^^^^^^^
 
 error: `derive` may only be applied to structs, enums and unions
-  --> $DIR/issue-43106-gating-of-derive.rs:26:5
+  --> $DIR/issue-43106-gating-of-derive.rs:23:5
    |
 LL |     #[derive(Debug)]
    |     ^^^^^^^^^^^^^^^^
 
 error: `derive` may only be applied to structs, enums and unions
-  --> $DIR/issue-43106-gating-of-derive.rs:30:5
+  --> $DIR/issue-43106-gating-of-derive.rs:27:5
    |
 LL |     #[derive(Debug)]
    |     ^^^^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/issues/issue-36617.rs b/src/test/ui/issues/issue-36617.rs
index 87092689a281d..1102f3c4640a1 100644
--- a/src/test/ui/issues/issue-36617.rs
+++ b/src/test/ui/issues/issue-36617.rs
@@ -1,3 +1,4 @@
 #![derive(Copy)] //~ ERROR `derive` may only be applied to structs, enums and unions
+                 //~| ERROR cannot determine resolution for the derive macro `Copy`
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-36617.stderr b/src/test/ui/issues/issue-36617.stderr
index 296fec46d80a6..b5db98f306bd3 100644
--- a/src/test/ui/issues/issue-36617.stderr
+++ b/src/test/ui/issues/issue-36617.stderr
@@ -4,5 +4,13 @@ error: `derive` may only be applied to structs, enums and unions
 LL | #![derive(Copy)]
    | ^^^^^^^^^^^^^^^^ help: try an outer attribute: `#[derive(Copy)]`
 
-error: aborting due to previous error
+error: cannot determine resolution for the derive macro `Copy`
+  --> $DIR/issue-36617.rs:1:11
+   |
+LL | #![derive(Copy)]
+   |           ^^^^
+   |
+   = note: import resolution is stuck, try simplifying macro imports
+
+error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/proc-macro/derive-helper-configured.rs b/src/test/ui/proc-macro/derive-helper-configured.rs
new file mode 100644
index 0000000000000..243cf685e8145
--- /dev/null
+++ b/src/test/ui/proc-macro/derive-helper-configured.rs
@@ -0,0 +1,18 @@
+// Derive helpers are resolved successfully inside `cfg_attr`.
+
+// check-pass
+// compile-flats:--cfg TRUE
+// aux-build:test-macros.rs
+
+#[macro_use]
+extern crate test_macros;
+
+#[cfg_attr(TRUE, empty_helper)]
+#[derive(Empty)]
+#[cfg_attr(TRUE, empty_helper)]
+struct S {
+    #[cfg_attr(TRUE, empty_helper)]
+    field: u8,
+}
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.rs b/src/test/ui/proc-macro/derive-helper-shadowing.rs
index 59ba1390e1323..21af4093a037d 100644
--- a/src/test/ui/proc-macro/derive-helper-shadowing.rs
+++ b/src/test/ui/proc-macro/derive-helper-shadowing.rs
@@ -19,7 +19,8 @@ struct S {
         struct U;
 
         mod inner {
-            #[empty_helper] //~ ERROR cannot find attribute macro `empty_helper` in this scope
+            // FIXME No ambiguity, attributes in non-macro positions are not resolved properly
+            #[empty_helper]
             struct V;
         }
 
diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr
index 149f6eef443c1..2ba517ce29ee7 100644
--- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr
+++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr
@@ -1,9 +1,3 @@
-error: cannot find attribute macro `empty_helper` in this scope
-  --> $DIR/derive-helper-shadowing.rs:22:15
-   |
-LL |             #[empty_helper]
-   |               ^^^^^^^^^^^^
-
 error[E0659]: `empty_helper` is ambiguous (derive helper attribute vs any other name)
   --> $DIR/derive-helper-shadowing.rs:8:3
    |
@@ -22,6 +16,6 @@ LL | use test_macros::empty_attr as empty_helper;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = help: use `crate::empty_helper` to refer to this attribute macro unambiguously
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0659`.
diff --git a/src/test/ui/proc-macro/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr
index 3c9b2baacbd91..2a5f2b883813d 100644
--- a/src/test/ui/proc-macro/resolve-error.stderr
+++ b/src/test/ui/proc-macro/resolve-error.stderr
@@ -1,32 +1,26 @@
-error: cannot find derive macro `FooWithLongNan` in this scope
-  --> $DIR/resolve-error.rs:22:10
-   |
-LL | #[derive(FooWithLongNan)]
-   |          ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName`
-
-error: cannot find attribute macro `attr_proc_macra` in this scope
-  --> $DIR/resolve-error.rs:27:3
+error: cannot find macro `bang_proc_macrp!` in this scope
+  --> $DIR/resolve-error.rs:56:5
    |
-LL | #[attr_proc_macra]
-   |   ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro`
+LL |     bang_proc_macrp!();
+   |     ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro`
 
-error: cannot find attribute macro `FooWithLongNan` in this scope
-  --> $DIR/resolve-error.rs:31:3
+error: cannot find macro `Dlona!` in this scope
+  --> $DIR/resolve-error.rs:53:5
    |
-LL | #[FooWithLongNan]
-   |   ^^^^^^^^^^^^^^
+LL |     Dlona!();
+   |     ^^^^^
 
-error: cannot find derive macro `Dlone` in this scope
-  --> $DIR/resolve-error.rs:34:10
+error: cannot find macro `attr_proc_macra!` in this scope
+  --> $DIR/resolve-error.rs:50:5
    |
-LL | #[derive(Dlone)]
-   |          ^^^^^ help: a derive macro with a similar name exists: `Clone`
+LL |     attr_proc_macra!();
+   |     ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `attr_proc_mac`
 
-error: cannot find derive macro `Dlona` in this scope
-  --> $DIR/resolve-error.rs:38:10
+error: cannot find macro `FooWithLongNama!` in this scope
+  --> $DIR/resolve-error.rs:47:5
    |
-LL | #[derive(Dlona)]
-   |          ^^^^^ help: a derive macro with a similar name exists: `Clona`
+LL |     FooWithLongNama!();
+   |     ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `FooWithLongNam`
 
 error: cannot find derive macro `attr_proc_macra` in this scope
   --> $DIR/resolve-error.rs:42:10
@@ -34,29 +28,35 @@ error: cannot find derive macro `attr_proc_macra` in this scope
 LL | #[derive(attr_proc_macra)]
    |          ^^^^^^^^^^^^^^^
 
-error: cannot find macro `FooWithLongNama!` in this scope
-  --> $DIR/resolve-error.rs:47:5
+error: cannot find derive macro `Dlona` in this scope
+  --> $DIR/resolve-error.rs:38:10
    |
-LL |     FooWithLongNama!();
-   |     ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `FooWithLongNam`
+LL | #[derive(Dlona)]
+   |          ^^^^^ help: a derive macro with a similar name exists: `Clona`
 
-error: cannot find macro `attr_proc_macra!` in this scope
-  --> $DIR/resolve-error.rs:50:5
+error: cannot find derive macro `Dlone` in this scope
+  --> $DIR/resolve-error.rs:34:10
    |
-LL |     attr_proc_macra!();
-   |     ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `attr_proc_mac`
+LL | #[derive(Dlone)]
+   |          ^^^^^ help: a derive macro with a similar name exists: `Clone`
 
-error: cannot find macro `Dlona!` in this scope
-  --> $DIR/resolve-error.rs:53:5
+error: cannot find attribute macro `FooWithLongNan` in this scope
+  --> $DIR/resolve-error.rs:31:3
    |
-LL |     Dlona!();
-   |     ^^^^^
+LL | #[FooWithLongNan]
+   |   ^^^^^^^^^^^^^^
 
-error: cannot find macro `bang_proc_macrp!` in this scope
-  --> $DIR/resolve-error.rs:56:5
+error: cannot find attribute macro `attr_proc_macra` in this scope
+  --> $DIR/resolve-error.rs:27:3
    |
-LL |     bang_proc_macrp!();
-   |     ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro`
+LL | #[attr_proc_macra]
+   |   ^^^^^^^^^^^^^^^ help: an attribute macro with a similar name exists: `attr_proc_macro`
+
+error: cannot find derive macro `FooWithLongNan` in this scope
+  --> $DIR/resolve-error.rs:22:10
+   |
+LL | #[derive(FooWithLongNan)]
+   |          ^^^^^^^^^^^^^^ help: a derive macro with a similar name exists: `FooWithLongName`
 
 error: aborting due to 10 previous errors
 

From 32e5acb3eba7a92029488b9684d7bb27bc716294 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 20 Aug 2019 02:26:40 +0300
Subject: [PATCH 264/943] proc_macro: Turn `quote` into a regular built-in
 macro

Previously in was implemented using a special hack in the metadata loader
---
 src/libproc_macro/lib.rs                | 10 ++++++----
 src/libproc_macro/quote.rs              |  4 ++--
 src/librustc_metadata/cstore_impl.rs    | 12 +-----------
 src/libsyntax_ext/lib.rs                |  8 ++++++++
 src/test/ui/auxiliary/cond_plugin.rs    |  1 +
 src/test/ui/auxiliary/proc_macro_def.rs |  1 +
 6 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index c0f7714ca211a..d408fef75153e 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -19,12 +19,15 @@
 
 #![feature(nll)]
 #![feature(staged_api)]
+#![feature(allow_internal_unstable)]
 #![feature(const_fn)]
+#![feature(decl_macro)]
 #![feature(extern_types)]
 #![feature(in_band_lifetimes)]
 #![feature(optin_builtin_traits)]
 #![feature(mem_take)]
 #![feature(non_exhaustive)]
+#![feature(rustc_attrs)]
 #![feature(specialization)]
 
 #![recursion_limit="256"]
@@ -222,11 +225,10 @@ pub mod token_stream {
 ///
 /// Unquoting is done with `$`, and works by taking the single next ident as the unquoted term.
 /// To quote `$` itself, use `$$`.
-///
-/// This is a dummy macro, the actual implementation is in `quote::quote`.`
 #[unstable(feature = "proc_macro_quote", issue = "54722")]
-#[macro_export]
-macro_rules! quote { () => {} }
+#[allow_internal_unstable(proc_macro_def_site)]
+#[cfg_attr(not(bootstrap), rustc_builtin_macro)]
+pub macro quote ($($t:tt)*) { /* compiler built-in */ }
 
 #[unstable(feature = "proc_macro_internals", issue = "27812")]
 #[doc(hidden)]
diff --git a/src/libproc_macro/quote.rs b/src/libproc_macro/quote.rs
index e3d31b78f4a09..144e2d6bac43b 100644
--- a/src/libproc_macro/quote.rs
+++ b/src/libproc_macro/quote.rs
@@ -57,9 +57,9 @@ macro_rules! quote {
 }
 
 /// Quote a `TokenStream` into a `TokenStream`.
-/// This is the actual `quote!()` proc macro.
+/// This is the actual implementation of the `quote!()` proc macro.
 ///
-/// It is manually loaded in `CStore::load_macro_untracked`.
+/// It is loaded by the compiler in `register_builtin_macros`.
 #[unstable(feature = "proc_macro_quote", issue = "54722")]
 pub fn quote(stream: TokenStream) -> TokenStream {
     if stream.is_empty() {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 7aeeef00ea934..f4c04770c1505 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -30,11 +30,9 @@ use syntax::ast;
 use syntax::attr;
 use syntax::source_map;
 use syntax::edition::Edition;
-use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind};
-use syntax::ext::proc_macro::BangProcMacro;
 use syntax::parse::source_file_to_stream;
 use syntax::parse::parser::emit_unclosed_delims;
-use syntax::symbol::{Symbol, sym};
+use syntax::symbol::Symbol;
 use syntax_pos::{Span, FileName};
 use rustc_data_structures::bit_set::BitSet;
 
@@ -437,14 +435,6 @@ impl cstore::CStore {
         let data = self.get_crate_data(id.krate);
         if data.is_proc_macro_crate() {
             return LoadedMacro::ProcMacro(data.get_proc_macro(id.index, sess).ext);
-        } else if data.name == sym::proc_macro && data.item_name(id.index) == sym::quote {
-            let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
-            let kind = SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client }));
-            let ext = SyntaxExtension {
-                allow_internal_unstable: Some([sym::proc_macro_def_site][..].into()),
-                ..SyntaxExtension::default(kind, data.root.edition)
-            };
-            return LoadedMacro::ProcMacro(Lrc::new(ext));
         }
 
         let def = data.get_macro(id.index);
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 4add2261c6cda..1a6176916623b 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -7,13 +7,18 @@
 #![feature(decl_macro)]
 #![feature(mem_take)]
 #![feature(nll)]
+#![feature(proc_macro_internals)]
+#![feature(proc_macro_quote)]
 #![feature(rustc_diagnostic_macros)]
 
+extern crate proc_macro;
+
 use crate::deriving::*;
 
 use syntax::ast::Ident;
 use syntax::edition::Edition;
 use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind, MacroExpanderFn};
+use syntax::ext::proc_macro::BangProcMacro;
 use syntax::symbol::sym;
 
 mod error_codes;
@@ -100,4 +105,7 @@ pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, e
         RustcDecodable: decodable::expand_deriving_rustc_decodable,
         RustcEncodable: encodable::expand_deriving_rustc_encodable,
     }
+
+    let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
+    register(sym::quote, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })));
 }
diff --git a/src/test/ui/auxiliary/cond_plugin.rs b/src/test/ui/auxiliary/cond_plugin.rs
index 1f97b556a0767..2819541bf6966 100644
--- a/src/test/ui/auxiliary/cond_plugin.rs
+++ b/src/test/ui/auxiliary/cond_plugin.rs
@@ -3,6 +3,7 @@
 
 #![crate_type = "proc-macro"]
 #![feature(proc_macro_hygiene)]
+#![feature(proc_macro_quote)]
 
 extern crate proc_macro;
 
diff --git a/src/test/ui/auxiliary/proc_macro_def.rs b/src/test/ui/auxiliary/proc_macro_def.rs
index dfc5a42d19c69..49cfb5518ba9c 100644
--- a/src/test/ui/auxiliary/proc_macro_def.rs
+++ b/src/test/ui/auxiliary/proc_macro_def.rs
@@ -3,6 +3,7 @@
 
 #![crate_type = "proc-macro"]
 #![feature(proc_macro_hygiene)]
+#![feature(proc_macro_quote)]
 
 extern crate proc_macro;
 

From 52c62eaae42ebc0efe370848a142c2858ac7fffc Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 20 Aug 2019 21:22:32 +0300
Subject: [PATCH 265/943] Respect attributes on proc macro definitions

---
 src/librustc_metadata/decoder.rs              | 18 ++---
 src/libsyntax/ext/base.rs                     | 67 +++++++++++++++++-
 src/libsyntax/ext/tt/macro_rules.rs           | 70 ++++---------------
 .../proc-macro/attributes-on-definitions.rs   | 12 ++++
 .../attributes-on-definitions.stderr          |  8 +++
 .../auxiliary/attributes-on-definitions.rs    | 23 ++++++
 6 files changed, 131 insertions(+), 67 deletions(-)
 create mode 100644 src/test/ui/proc-macro/attributes-on-definitions.rs
 create mode 100644 src/test/ui/proc-macro/attributes-on-definitions.stderr
 create mode 100644 src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs

diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 5b9cb966af235..fffeee82d8d24 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -530,7 +530,6 @@ impl<'a, 'tcx> CrateMetadata {
                         id: DefIndex,
                         sess: &Session)
                         -> FullProcMacro {
-
         let raw_macro = self.raw_proc_macro(id);
         let (name, kind, helper_attrs) = match *raw_macro {
             ProcMacro::CustomDerive { trait_name, attributes, client } => {
@@ -551,16 +550,19 @@ impl<'a, 'tcx> CrateMetadata {
                 name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()
             )
         };
-
-        let span = self.get_span(id, sess);
+        let name = Symbol::intern(name);
 
         FullProcMacro {
-            name: Symbol::intern(name),
-            ext: Lrc::new(SyntaxExtension {
-                span,
+            name,
+            ext: Lrc::new(SyntaxExtension::new(
+                &sess.parse_sess,
+                kind,
+                self.get_span(id, sess),
                 helper_attrs,
-                ..SyntaxExtension::default(kind, root.edition)
-            })
+                root.edition,
+                name,
+                &self.get_attributes(&self.entry(id), sess),
+            )),
         }
     }
 
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index a63c4181d5e03..10ff1b17285fe 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -1,11 +1,11 @@
 use crate::ast::{self, NodeId, Attribute, Name, PatKind};
-use crate::attr::{HasAttrs, Stability, Deprecation};
+use crate::attr::{self, HasAttrs, Stability, Deprecation};
 use crate::source_map::SourceMap;
 use crate::edition::Edition;
 use crate::ext::expand::{self, AstFragment, Invocation};
 use crate::ext::hygiene::{ExpnId, Transparency};
 use crate::mut_visit::{self, MutVisitor};
-use crate::parse::{self, parser, DirectoryOwnership};
+use crate::parse::{self, parser, ParseSess, DirectoryOwnership};
 use crate::parse::token;
 use crate::ptr::P;
 use crate::symbol::{kw, sym, Ident, Symbol};
@@ -601,6 +601,69 @@ impl SyntaxExtension {
         }
     }
 
+    /// Constructs a syntax extension with the given properties
+    /// and other properties converted from attributes.
+    pub fn new(
+        sess: &ParseSess,
+        kind: SyntaxExtensionKind,
+        span: Span,
+        helper_attrs: Vec<Symbol>,
+        edition: Edition,
+        name: Name,
+        attrs: &[ast::Attribute],
+    ) -> SyntaxExtension {
+        let allow_internal_unstable =
+            attr::find_by_name(attrs, sym::allow_internal_unstable).map(|attr| {
+                attr.meta_item_list()
+                    .map(|list| {
+                        list.iter()
+                            .filter_map(|it| {
+                                let name = it.ident().map(|ident| ident.name);
+                                if name.is_none() {
+                                    sess.span_diagnostic.span_err(
+                                        it.span(), "allow internal unstable expects feature names"
+                                    )
+                                }
+                                name
+                            })
+                            .collect::<Vec<Symbol>>()
+                            .into()
+                    })
+                    .unwrap_or_else(|| {
+                        sess.span_diagnostic.span_warn(
+                            attr.span,
+                            "allow_internal_unstable expects list of feature names. In the future \
+                             this will become a hard error. Please use `allow_internal_unstable(\
+                             foo, bar)` to only allow the `foo` and `bar` features",
+                        );
+                        vec![sym::allow_internal_unstable_backcompat_hack].into()
+                    })
+            });
+
+        let mut local_inner_macros = false;
+        if let Some(macro_export) = attr::find_by_name(attrs, sym::macro_export) {
+            if let Some(l) = macro_export.meta_item_list() {
+                local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
+            }
+        }
+
+        let is_builtin = attr::contains_name(attrs, sym::rustc_builtin_macro);
+
+        SyntaxExtension {
+            kind,
+            span,
+            allow_internal_unstable,
+            allow_internal_unsafe: attr::contains_name(attrs, sym::allow_internal_unsafe),
+            local_inner_macros,
+            stability: attr::find_stability(&sess, attrs, span),
+            deprecation: attr::find_deprecation(&sess, attrs, span),
+            helper_attrs,
+            edition,
+            is_builtin,
+            is_derive_copy: is_builtin && name == sym::Copy,
+        }
+    }
+
     pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
         fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: &[TokenTree])
                          -> Box<dyn MacResult + 'cx> {
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 37cb8467ff5ee..46ffa52f7f572 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -1,3 +1,5 @@
+use crate::ast;
+use crate::attr::{self, TransparencyError};
 use crate::edition::Edition;
 use crate::ext::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander};
 use crate::ext::base::{SyntaxExtension, SyntaxExtensionKind};
@@ -15,7 +17,6 @@ use crate::parse::token::{self, NtTT, Token};
 use crate::parse::{Directory, ParseSess};
 use crate::symbol::{kw, sym, Symbol};
 use crate::tokenstream::{DelimSpan, TokenStream, TokenTree};
-use crate::{ast, attr, attr::TransparencyError};
 
 use errors::{DiagnosticBuilder, FatalError};
 use log::debug;
@@ -290,6 +291,7 @@ pub fn compile(
     def: &ast::Item,
     edition: Edition,
 ) -> SyntaxExtension {
+    let diag = &sess.span_diagnostic;
     let lhs_nm = ast::Ident::new(sym::lhs, def.span);
     let rhs_nm = ast::Ident::new(sym::rhs, def.span);
     let tt_spec = ast::Ident::new(sym::tt, def.span);
@@ -423,13 +425,9 @@ pub fn compile(
     let (transparency, transparency_error) = attr::find_transparency(&def.attrs, body.legacy);
     match transparency_error {
         Some(TransparencyError::UnknownTransparency(value, span)) =>
-            sess.span_diagnostic.span_err(
-                span, &format!("unknown macro transparency: `{}`", value)
-            ),
+            diag.span_err(span, &format!("unknown macro transparency: `{}`", value)),
         Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) =>
-            sess.span_diagnostic.span_err(
-                vec![old_span, new_span], "multiple macro transparency attributes"
-            ),
+            diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes"),
         None => {}
     }
 
@@ -437,57 +435,15 @@ pub fn compile(
         name: def.ident, span: def.span, transparency, lhses, rhses, valid
     });
 
-    let allow_internal_unstable =
-        attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| {
-            attr.meta_item_list()
-                .map(|list| {
-                    list.iter()
-                        .filter_map(|it| {
-                            let name = it.ident().map(|ident| ident.name);
-                            if name.is_none() {
-                                sess.span_diagnostic.span_err(
-                                    it.span(),
-                                    "allow internal unstable expects feature names",
-                                )
-                            }
-                            name
-                        })
-                        .collect::<Vec<Symbol>>()
-                        .into()
-                })
-                .unwrap_or_else(|| {
-                    sess.span_diagnostic.span_warn(
-                        attr.span,
-                        "allow_internal_unstable expects list of feature names. In the \
-                         future this will become a hard error. Please use `allow_internal_unstable(\
-                         foo, bar)` to only allow the `foo` and `bar` features",
-                    );
-                    vec![sym::allow_internal_unstable_backcompat_hack].into()
-                })
-        });
-
-    let mut local_inner_macros = false;
-    if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) {
-        if let Some(l) = macro_export.meta_item_list() {
-            local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros);
-        }
-    }
-
-    let is_builtin = attr::contains_name(&def.attrs, sym::rustc_builtin_macro);
-
-    SyntaxExtension {
-        kind: SyntaxExtensionKind::LegacyBang(expander),
-        span: def.span,
-        allow_internal_unstable,
-        allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe),
-        local_inner_macros,
-        stability: attr::find_stability(&sess, &def.attrs, def.span),
-        deprecation: attr::find_deprecation(&sess, &def.attrs, def.span),
-        helper_attrs: Vec::new(),
+    SyntaxExtension::new(
+        sess,
+        SyntaxExtensionKind::LegacyBang(expander),
+        def.span,
+        Vec::new(),
         edition,
-        is_builtin,
-        is_derive_copy: is_builtin && def.ident.name == sym::Copy,
-    }
+        def.ident.name,
+        &def.attrs,
+    )
 }
 
 fn check_lhs_nt_follows(
diff --git a/src/test/ui/proc-macro/attributes-on-definitions.rs b/src/test/ui/proc-macro/attributes-on-definitions.rs
new file mode 100644
index 0000000000000..055781d2c6048
--- /dev/null
+++ b/src/test/ui/proc-macro/attributes-on-definitions.rs
@@ -0,0 +1,12 @@
+// check-pass
+// aux-build:attributes-on-definitions.rs
+
+#![forbid(unsafe_code)]
+
+extern crate attributes_on_definitions;
+
+attributes_on_definitions::with_attrs!();
+//~^ WARN use of deprecated item
+// No errors about the use of unstable and unsafe code inside the macro.
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/attributes-on-definitions.stderr b/src/test/ui/proc-macro/attributes-on-definitions.stderr
new file mode 100644
index 0000000000000..c61e043b22971
--- /dev/null
+++ b/src/test/ui/proc-macro/attributes-on-definitions.stderr
@@ -0,0 +1,8 @@
+warning: use of deprecated item 'attributes_on_definitions::with_attrs': test
+  --> $DIR/attributes-on-definitions.rs:8:1
+   |
+LL | attributes_on_definitions::with_attrs!();
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(deprecated)]` on by default
+
diff --git a/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs b/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs
new file mode 100644
index 0000000000000..93a339840d621
--- /dev/null
+++ b/src/test/ui/proc-macro/auxiliary/attributes-on-definitions.rs
@@ -0,0 +1,23 @@
+// force-host
+// no-prefer-dynamic
+
+#![feature(allow_internal_unsafe)]
+#![feature(allow_internal_unstable)]
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+#[proc_macro]
+#[allow_internal_unstable(proc_macro_internals)]
+#[allow_internal_unsafe]
+#[deprecated(since = "1.0.0", note = "test")]
+pub fn with_attrs(_: TokenStream) -> TokenStream {
+    "
+    extern crate proc_macro;
+    use ::proc_macro::bridge;
+
+    fn contains_unsafe() { unsafe {} }
+    ".parse().unwrap()
+}

From 2065ee9accc87a461897d06414195cfa3e92fb89 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 20 Aug 2019 23:18:55 +0300
Subject: [PATCH 266/943] metadata: Eliminate `FullProcMacro`

Fix caching of loaded proc macros
---
 src/librustc_metadata/cstore.rs             |  7 +--
 src/librustc_metadata/cstore_impl.rs        |  2 +-
 src/librustc_metadata/decoder.rs            | 53 +++++++--------------
 src/librustc_resolve/build_reduced_graph.rs | 12 ++---
 src/librustc_resolve/macros.rs              |  4 +-
 5 files changed, 28 insertions(+), 50 deletions(-)

diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index efc77699313e0..5bf4067431f24 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -95,11 +95,6 @@ pub struct CrateMetadata {
     pub raw_proc_macros: Option<&'static [ProcMacro]>,
 }
 
-pub struct FullProcMacro {
-    pub name: ast::Name,
-    pub ext: Lrc<SyntaxExtension>
-}
-
 pub struct CStore {
     metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
     /// Map from NodeId's of local extern crate statements to crate numbers
@@ -109,7 +104,7 @@ pub struct CStore {
 
 pub enum LoadedMacro {
     MacroDef(ast::Item),
-    ProcMacro(Lrc<SyntaxExtension>),
+    ProcMacro(SyntaxExtension),
 }
 
 impl CStore {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index f4c04770c1505..5bfb315da473f 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -434,7 +434,7 @@ impl cstore::CStore {
     pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
         let data = self.get_crate_data(id.krate);
         if data.is_proc_macro_crate() {
-            return LoadedMacro::ProcMacro(data.get_proc_macro(id.index, sess).ext);
+            return LoadedMacro::ProcMacro(data.load_proc_macro(id.index, sess));
         }
 
         let def = data.get_macro(id.index);
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index fffeee82d8d24..c777b5ea409a4 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1,6 +1,6 @@
 // Decoding metadata from a single crate's metadata
 
-use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule, FullProcMacro};
+use crate::cstore::{self, CrateMetadata, MetadataBlob, NativeLibrary, ForeignModule};
 use crate::schema::*;
 
 use rustc_data_structures::indexed_vec::IndexVec;
@@ -512,26 +512,8 @@ impl<'a, 'tcx> CrateMetadata {
         self.entry(index).span.decode((self, sess))
     }
 
-
-    pub fn get_proc_macro(&self, id: DefIndex, sess: &Session) -> FullProcMacro {
-        if sess.opts.debugging_opts.dual_proc_macros {
-            let host_lib = self.host_lib.as_ref().unwrap();
-            self.load_proc_macro(
-                &host_lib.metadata.get_root(),
-                id,
-                sess
-            )
-        } else {
-            self.load_proc_macro(&self.root, id, sess)
-        }
-    }
-
-    fn load_proc_macro(&self, root: &CrateRoot<'_>,
-                        id: DefIndex,
-                        sess: &Session)
-                        -> FullProcMacro {
-        let raw_macro = self.raw_proc_macro(id);
-        let (name, kind, helper_attrs) = match *raw_macro {
+    crate fn load_proc_macro(&self, id: DefIndex, sess: &Session) -> SyntaxExtension {
+        let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) {
             ProcMacro::CustomDerive { trait_name, attributes, client } => {
                 let helper_attrs =
                     attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
@@ -550,20 +532,21 @@ impl<'a, 'tcx> CrateMetadata {
                 name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new()
             )
         };
-        let name = Symbol::intern(name);
-
-        FullProcMacro {
-            name,
-            ext: Lrc::new(SyntaxExtension::new(
-                &sess.parse_sess,
-                kind,
-                self.get_span(id, sess),
-                helper_attrs,
-                root.edition,
-                name,
-                &self.get_attributes(&self.entry(id), sess),
-            )),
-        }
+        let edition = if sess.opts.debugging_opts.dual_proc_macros {
+            self.host_lib.as_ref().unwrap().metadata.get_root().edition
+        } else {
+            self.root.edition
+        };
+
+        SyntaxExtension::new(
+            &sess.parse_sess,
+            kind,
+            self.get_span(id, sess),
+            helper_attrs,
+            edition,
+            Symbol::intern(name),
+            &self.get_attributes(&self.entry(id), sess),
+        )
     }
 
     pub fn get_trait_def(&self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 9a794ade729c2..165a4c707bb6d 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -150,12 +150,12 @@ impl<'a> Resolver<'a> {
             return Some(ext.clone());
         }
 
-        let macro_def = match self.cstore.load_macro_untracked(def_id, &self.session) {
-            LoadedMacro::MacroDef(macro_def) => macro_def,
-            LoadedMacro::ProcMacro(ext) => return Some(ext),
-        };
+        let ext = Lrc::new(match self.cstore.load_macro_untracked(def_id, &self.session) {
+            LoadedMacro::MacroDef(item) =>
+                self.compile_macro(&item, self.cstore.crate_edition_untracked(def_id.krate)),
+            LoadedMacro::ProcMacro(ext) => ext,
+        });
 
-        let ext = self.compile_macro(&macro_def, self.cstore.crate_edition_untracked(def_id.krate));
         self.macro_map.insert(def_id, ext.clone());
         Some(ext)
     }
@@ -1104,7 +1104,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         let expansion = parent_scope.expansion;
         let (ext, ident, span, is_legacy) = match &item.node {
             ItemKind::MacroDef(def) => {
-                let ext = self.r.compile_macro(item, self.r.session.edition());
+                let ext = Lrc::new(self.r.compile_macro(item, self.r.session.edition()));
                 (ext, item.ident, item.span, def.legacy)
             }
             ItemKind::Fn(..) => match Self::proc_macro_stub(item) {
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 719167eb057b2..cc78e928380a8 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -800,7 +800,7 @@ impl<'a> Resolver<'a> {
 
     /// Compile the macro into a `SyntaxExtension` and possibly replace it with a pre-defined
     /// extension partially or entirely for built-in macros and legacy plugin macros.
-    crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> Lrc<SyntaxExtension> {
+    crate fn compile_macro(&mut self, item: &ast::Item, edition: Edition) -> SyntaxExtension {
         let mut result = macro_rules::compile(
             &self.session.parse_sess, self.session.features_untracked(), item, edition
         );
@@ -822,6 +822,6 @@ impl<'a> Resolver<'a> {
             }
         }
 
-        Lrc::new(result)
+        result
     }
 }

From c476b55e528ce854b6198de5bcfdd20b08440c9d Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Tue, 20 Aug 2019 23:35:03 +0300
Subject: [PATCH 267/943] proc_macro: Update `Span::def_site` to use the proc
 macro definition location

Which is no longer dummy and is available from metadata now.
---
 src/libsyntax/ext/proc_macro_server.rs        |   7 +-
 src/libsyntax/parse/parser.rs                 |   9 +-
 .../macros/auxiliary/proc_macro_sequence.rs   |  20 ++-
 src/test/ui/macros/same-sequence-span.stderr  |  12 +-
 src/test/ui/proc-macro/multispan.stderr       | 133 ++++++++++++++----
 src/test/ui/proc-macro/three-equals.stderr    |  19 ++-
 6 files changed, 151 insertions(+), 49 deletions(-)

diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index b1bbd2aaac971..1a26b17dac782 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -360,12 +360,11 @@ pub(crate) struct Rustc<'a> {
 
 impl<'a> Rustc<'a> {
     pub fn new(cx: &'a ExtCtxt<'_>) -> Self {
-        // No way to determine def location for a proc macro right now, so use call location.
-        let location = cx.current_expansion.id.expn_data().call_site;
+        let expn_data = cx.current_expansion.id.expn_data();
         Rustc {
             sess: cx.parse_sess,
-            def_site: cx.with_def_site_ctxt(location),
-            call_site: cx.with_call_site_ctxt(location),
+            def_site: cx.with_def_site_ctxt(expn_data.def_site),
+            call_site: cx.with_call_site_ctxt(expn_data.call_site),
         }
     }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 89725d8b3395c..47243b1ac5678 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -375,10 +375,11 @@ impl<'a> Parser<'a> {
         if let Some(directory) = directory {
             parser.directory = directory;
         } else if !parser.token.span.is_dummy() {
-            if let FileName::Real(mut path) =
-                    sess.source_map().span_to_unmapped_path(parser.token.span) {
-                path.pop();
-                parser.directory.path = Cow::from(path);
+            if let Some(FileName::Real(path)) =
+                    &sess.source_map().lookup_char_pos(parser.token.span.lo()).file.unmapped_path {
+                if let Some(directory_path) = path.parent() {
+                    parser.directory.path = Cow::from(directory_path.to_path_buf());
+                }
             }
         }
 
diff --git a/src/test/ui/macros/auxiliary/proc_macro_sequence.rs b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs
index b50ed7ca92ad5..c460db36f1aa3 100644
--- a/src/test/ui/macros/auxiliary/proc_macro_sequence.rs
+++ b/src/test/ui/macros/auxiliary/proc_macro_sequence.rs
@@ -6,7 +6,7 @@
 
 extern crate proc_macro;
 
-use proc_macro::{quote, Span, TokenStream};
+use proc_macro::{quote, Span, TokenStream, TokenTree};
 
 fn assert_same_span(a: Span, b: Span) {
     assert_eq!(a.start(), b.start());
@@ -24,12 +24,22 @@ pub fn make_foo(_: TokenStream) -> TokenStream {
     };
 
     // Check that all spans are equal.
-    let mut span = None;
+    // FIXME: `quote!` gives def-site spans to idents and literals,
+    // but leaves (default) call-site spans on groups and punctuation.
+    let mut span_call = None;
+    let mut span_def = None;
     for tt in result.clone() {
-        match span {
-            None => span = Some(tt.span()),
-            Some(span) => assert_same_span(tt.span(), span),
+        match tt {
+            TokenTree::Ident(..) | TokenTree::Literal(..) => match span_def {
+                None => span_def = Some(tt.span()),
+                Some(span) => assert_same_span(tt.span(), span),
+            }
+            TokenTree::Punct(..) | TokenTree::Group(..) => match span_call {
+                None => span_call = Some(tt.span()),
+                Some(span) => assert_same_span(tt.span(), span),
+            }
         }
+
     }
 
     result
diff --git a/src/test/ui/macros/same-sequence-span.stderr b/src/test/ui/macros/same-sequence-span.stderr
index 250773a1853ec..0eef4a2a678b6 100644
--- a/src/test/ui/macros/same-sequence-span.stderr
+++ b/src/test/ui/macros/same-sequence-span.stderr
@@ -17,11 +17,15 @@ LL |                $(= $z:tt)*
 error: `$x:expr` may be followed by `$y:tt`, which is not allowed for `expr` fragments
   --> $DIR/same-sequence-span.rs:20:1
    |
-LL | proc_macro_sequence::make_foo!();
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |   proc_macro_sequence::make_foo!();
+   |   ^--------------------------------
+   |   |
+   |  _in this macro invocation
    | |
-   | not allowed after `expr` fragments
-   | in this macro invocation
+LL | |
+LL | |
+LL | | fn main() {}
+...  |
    |
    = note: allowed there are: `=>`, `,` or `;`
 
diff --git a/src/test/ui/proc-macro/multispan.stderr b/src/test/ui/proc-macro/multispan.stderr
index a0c1f9cd5c05f..e7f705c7feb67 100644
--- a/src/test/ui/proc-macro/multispan.stderr
+++ b/src/test/ui/proc-macro/multispan.stderr
@@ -1,8 +1,19 @@
 error: hello to you, too!
-  --> $DIR/multispan.rs:14:5
-   |
-LL |     hello!(hi);
-   |     ^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:14:5
+   |
+LL |       hello!(hi);
+   |       ----------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:14:12
@@ -11,10 +22,21 @@ LL |     hello!(hi);
    |            ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:17:5
-   |
-LL |     hello!(hi hi);
-   |     ^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:17:5
+   |
+LL |       hello!(hi hi);
+   |       -------------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:17:12
@@ -23,10 +45,21 @@ LL |     hello!(hi hi);
    |            ^^ ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:20:5
-   |
-LL |     hello!(hi hi hi);
-   |     ^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:20:5
+   |
+LL |       hello!(hi hi hi);
+   |       ----------------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:20:12
@@ -35,10 +68,21 @@ LL |     hello!(hi hi hi);
    |            ^^ ^^ ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:23:5
-   |
-LL |     hello!(hi hey hi yo hi beep beep hi hi);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:23:5
+   |
+LL |       hello!(hi hey hi yo hi beep beep hi hi);
+   |       ---------------------------------------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:23:12
@@ -47,10 +91,21 @@ LL |     hello!(hi hey hi yo hi beep beep hi hi);
    |            ^^     ^^    ^^           ^^ ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:24:5
-   |
-LL |     hello!(hi there, hi how are you? hi... hi.);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:24:5
+   |
+LL |       hello!(hi there, hi how are you? hi... hi.);
+   |       -------------------------------------------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:24:12
@@ -59,10 +114,21 @@ LL |     hello!(hi there, hi how are you? hi... hi.);
    |            ^^        ^^              ^^    ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:25:5
-   |
-LL |     hello!(whoah. hi di hi di ho);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:25:5
+   |
+LL |       hello!(whoah. hi di hi di ho);
+   |       ------------------------------ in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:25:19
@@ -71,10 +137,21 @@ LL |     hello!(whoah. hi di hi di ho);
    |                   ^^    ^^
 
 error: hello to you, too!
-  --> $DIR/multispan.rs:26:5
-   |
-LL |     hello!(hi good hi and good bye);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/multispan.rs:31:1
+   |
+LL | / pub fn hello(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |     }
+LL | |
+LL | |     TokenStream::new()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/multispan.rs:26:5
+   |
+LL |       hello!(hi good hi and good bye);
+   |       -------------------------------- in this macro invocation
    |
 note: found these 'hi's
   --> $DIR/multispan.rs:26:12
diff --git a/src/test/ui/proc-macro/three-equals.stderr b/src/test/ui/proc-macro/three-equals.stderr
index 0a6cbe13098a8..0698b0f475424 100644
--- a/src/test/ui/proc-macro/three-equals.stderr
+++ b/src/test/ui/proc-macro/three-equals.stderr
@@ -1,8 +1,19 @@
 error: found 2 equal signs, need exactly 3
-  --> $DIR/three-equals.rs:15:5
-   |
-LL |     three_equals!(==);
-   |     ^^^^^^^^^^^^^^^^^^ in this macro invocation
+  --> $DIR/auxiliary/three-equals.rs:42:1
+   |
+LL | / pub fn three_equals(input: TokenStream) -> TokenStream {
+LL | |     if let Err(diag) = parse(input) {
+LL | |         diag.emit();
+LL | |         return TokenStream::new();
+...  |
+LL | |     "3".parse().unwrap()
+LL | | }
+   | |_^
+   | 
+  ::: $DIR/three-equals.rs:15:5
+   |
+LL |       three_equals!(==);
+   |       ------------------ in this macro invocation
    |
    = help: input must be: `===`
 

From a77247acb1bbecff8acedefce3c6cc06d7787311 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sun, 11 Aug 2019 16:11:53 -0400
Subject: [PATCH 268/943] Move source HTML generation to own module

---
 src/librustdoc/html/render.rs  | 179 ++-----------------------------
 src/librustdoc/html/sources.rs | 187 +++++++++++++++++++++++++++++++++
 src/librustdoc/lib.rs          |   1 +
 3 files changed, 194 insertions(+), 173 deletions(-)
 create mode 100644 src/librustdoc/html/sources.rs

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index b64e74468e6e9..c8921a92d3382 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -72,6 +72,7 @@ use crate::html::format::fmt_impl_for_trait_page;
 use crate::html::item_type::ItemType;
 use crate::html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine, ErrorCodes, IdMap};
 use crate::html::{highlight, layout, static_files};
+use crate::html::sources;
 
 use minifier;
 
@@ -173,7 +174,7 @@ struct Context {
     playground: Option<markdown::Playground>,
 }
 
-struct SharedContext {
+crate struct SharedContext {
     /// The path to the crate root source minus the file name.
     /// Used for simplifying paths to the highlighted source code files.
     pub src_root: PathBuf,
@@ -218,7 +219,7 @@ struct SharedContext {
 }
 
 impl SharedContext {
-    fn ensure_dir(&self, dst: &Path) -> Result<(), Error> {
+    crate fn ensure_dir(&self, dst: &Path) -> Result<(), Error> {
         let mut dirs = self.created_dirs.borrow_mut();
         if !dirs.contains(dst) {
             try_err!(self.fs.create_dir_all(dst), dst);
@@ -389,18 +390,6 @@ pub struct RenderInfo {
     pub owned_box_did: Option<DefId>,
 }
 
-/// Helper struct to render all source code to HTML pages
-struct SourceCollector<'a> {
-    scx: &'a mut SharedContext,
-
-    /// Root destination to place all HTML output into
-    dst: PathBuf,
-}
-
-/// Wrapper struct to render the source code of a file. This will do things like
-/// adding line numbers to the left-hand side.
-struct Source<'a>(&'a str);
-
 // Helper structs for rendering items/sidebars and carrying along contextual
 // information
 
@@ -612,7 +601,7 @@ pub fn run(mut krate: clean::Crate,
     }
     let dst = output;
     scx.ensure_dir(&dst)?;
-    krate = render_sources(&dst, &mut scx, krate)?;
+    krate = sources::render(&dst, &mut scx, krate)?;
     let mut cx = Context {
         current: Vec::new(),
         dst,
@@ -1293,18 +1282,6 @@ themePicker.onblur = handleThemeButtonsBlur;
     Ok(())
 }
 
-fn render_sources(dst: &Path, scx: &mut SharedContext,
-                  krate: clean::Crate) -> Result<clean::Crate, Error> {
-    info!("emitting source files");
-    let dst = dst.join("src").join(&krate.name);
-    scx.ensure_dir(&dst)?;
-    let mut folder = SourceCollector {
-        dst,
-        scx,
-    };
-    Ok(folder.fold_crate(krate))
-}
-
 fn write_minify(fs:&DocFS, dst: PathBuf, contents: &str, enable_minification: bool
                 ) -> Result<(), Error> {
     if enable_minification {
@@ -1384,33 +1361,6 @@ fn write_minify_replacer<W: Write>(
     }
 }
 
-/// Takes a path to a source file and cleans the path to it. This canonicalizes
-/// things like ".." to components which preserve the "top down" hierarchy of a
-/// static HTML tree. Each component in the cleaned path will be passed as an
-/// argument to `f`. The very last component of the path (ie the file name) will
-/// be passed to `f` if `keep_filename` is true, and ignored otherwise.
-fn clean_srcpath<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F)
-where
-    F: FnMut(&OsStr),
-{
-    // make it relative, if possible
-    let p = p.strip_prefix(src_root).unwrap_or(p);
-
-    let mut iter = p.components().peekable();
-
-    while let Some(c) = iter.next() {
-        if !keep_filename && iter.peek().is_none() {
-            break;
-        }
-
-        match c {
-            Component::ParentDir => f("up".as_ref()),
-            Component::Normal(c) => f(c),
-            _ => continue,
-        }
-    }
-}
-
 /// Attempts to find where an external crate is located, given that we're
 /// rendering in to the specified source destination.
 fn extern_location(e: &clean::ExternalCrate, extern_url: Option<&str>, dst: &Path)
@@ -1444,102 +1394,6 @@ fn extern_location(e: &clean::ExternalCrate, extern_url: Option<&str>, dst: &Pat
     }).next().unwrap_or(Unknown) // Well, at least we tried.
 }
 
-impl<'a> DocFolder for SourceCollector<'a> {
-    fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
-        // If we're including source files, and we haven't seen this file yet,
-        // then we need to render it out to the filesystem.
-        if self.scx.include_sources
-            // skip all invalid or macro spans
-            && item.source.filename.is_real()
-            // skip non-local items
-            && item.def_id.is_local() {
-
-            // If it turns out that we couldn't read this file, then we probably
-            // can't read any of the files (generating html output from json or
-            // something like that), so just don't include sources for the
-            // entire crate. The other option is maintaining this mapping on a
-            // per-file basis, but that's probably not worth it...
-            self.scx
-                .include_sources = match self.emit_source(&item.source.filename) {
-                Ok(()) => true,
-                Err(e) => {
-                    println!("warning: source code was requested to be rendered, \
-                              but processing `{}` had an error: {}",
-                             item.source.filename, e);
-                    println!("         skipping rendering of source code");
-                    false
-                }
-            };
-        }
-        self.fold_item_recur(item)
-    }
-}
-
-impl<'a> SourceCollector<'a> {
-    /// Renders the given filename into its corresponding HTML source file.
-    fn emit_source(&mut self, filename: &FileName) -> Result<(), Error> {
-        let p = match *filename {
-            FileName::Real(ref file) => file,
-            _ => return Ok(()),
-        };
-        if self.scx.local_sources.contains_key(&**p) {
-            // We've already emitted this source
-            return Ok(());
-        }
-
-        let contents = try_err!(fs::read_to_string(&p), &p);
-
-        // Remove the utf-8 BOM if any
-        let contents = if contents.starts_with("\u{feff}") {
-            &contents[3..]
-        } else {
-            &contents[..]
-        };
-
-        // Create the intermediate directories
-        let mut cur = self.dst.clone();
-        let mut root_path = String::from("../../");
-        let mut href = String::new();
-        clean_srcpath(&self.scx.src_root, &p, false, |component| {
-            cur.push(component);
-            root_path.push_str("../");
-            href.push_str(&component.to_string_lossy());
-            href.push('/');
-        });
-        self.scx.ensure_dir(&cur)?;
-        let mut fname = p.file_name()
-                         .expect("source has no filename")
-                         .to_os_string();
-        fname.push(".html");
-        cur.push(&fname);
-        href.push_str(&fname.to_string_lossy());
-
-        let mut v = Vec::new();
-        let title = format!("{} -- source", cur.file_name().expect("failed to get file name")
-                                               .to_string_lossy());
-        let desc = format!("Source to the Rust file `{}`.", filename);
-        let page = layout::Page {
-            title: &title,
-            css_class: "source",
-            root_path: &root_path,
-            static_root_path: self.scx.static_root_path.as_deref(),
-            description: &desc,
-            keywords: BASIC_KEYWORDS,
-            resource_suffix: &self.scx.resource_suffix,
-            extra_scripts: &[&format!("source-files{}", self.scx.resource_suffix)],
-            static_extra_scripts: &[&format!("source-script{}", self.scx.resource_suffix)],
-        };
-        try_err!(layout::render(&mut v, &self.scx.layout,
-                       &page, &(""), &Source(contents),
-                       self.scx.css_file_extension.is_some(),
-                       &self.scx.themes,
-                       self.scx.generate_search_filter), &cur);
-        self.scx.fs.write(&cur, &v)?;
-        self.scx.local_sources.insert(p.clone(), href);
-        Ok(())
-    }
-}
-
 impl DocFolder for Cache {
     fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
         if item.def_id.is_local() {
@@ -2399,7 +2253,7 @@ impl<'a> Item<'a> {
                 (_, _, Unknown) => return None,
             };
 
-            clean_srcpath(&src_root, file, false, |component| {
+            sources::clean_path(&src_root, file, false, |component| {
                 path.push_str(&component.to_string_lossy());
                 path.push('/');
             });
@@ -5048,27 +4902,6 @@ fn sidebar_foreign_type(fmt: &mut fmt::Formatter<'_>, it: &clean::Item) -> fmt::
     Ok(())
 }
 
-impl<'a> fmt::Display for Source<'a> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let Source(s) = *self;
-        let lines = s.lines().count();
-        let mut cols = 0;
-        let mut tmp = lines;
-        while tmp > 0 {
-            cols += 1;
-            tmp /= 10;
-        }
-        write!(fmt, "<pre class=\"line-numbers\">")?;
-        for i in 1..=lines {
-            write!(fmt, "<span id=\"{0}\">{0:1$}</span>\n", i, cols)?;
-        }
-        write!(fmt, "</pre>")?;
-        write!(fmt, "{}",
-               highlight::render_with_highlighting(s, None, None, None))?;
-        Ok(())
-    }
-}
-
 fn item_macro(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
               t: &clean::Macro) -> fmt::Result {
     wrap_into_docblock(w, |w| {
@@ -5125,7 +4958,7 @@ fn item_keyword(w: &mut fmt::Formatter<'_>, cx: &Context,
     document(w, cx, it)
 }
 
-const BASIC_KEYWORDS: &'static str = "rust, rustlang, rust-lang";
+crate const BASIC_KEYWORDS: &'static str = "rust, rustlang, rust-lang";
 
 fn make_item_keywords(it: &clean::Item) -> String {
     format!("{}, {}", BASIC_KEYWORDS, it.name.as_ref().unwrap())
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
new file mode 100644
index 0000000000000..c1f1f59d9149a
--- /dev/null
+++ b/src/librustdoc/html/sources.rs
@@ -0,0 +1,187 @@
+use crate::clean;
+use crate::docfs::PathError;
+use crate::fold::DocFolder;
+use crate::html::layout;
+use crate::html::render::{Error, SharedContext, BASIC_KEYWORDS};
+use crate::html::highlight;
+use std::ffi::OsStr;
+use std::fs;
+use std::path::{Component, Path, PathBuf};
+use std::fmt;
+use syntax::source_map::FileName;
+
+crate fn render(dst: &Path, scx: &mut SharedContext,
+                  krate: clean::Crate) -> Result<clean::Crate, Error> {
+    info!("emitting source files");
+    let dst = dst.join("src").join(&krate.name);
+    scx.ensure_dir(&dst)?;
+    let mut folder = SourceCollector {
+        dst,
+        scx,
+    };
+    Ok(folder.fold_crate(krate))
+}
+
+/// Helper struct to render all source code to HTML pages
+struct SourceCollector<'a> {
+    scx: &'a mut SharedContext,
+
+    /// Root destination to place all HTML output into
+    dst: PathBuf,
+}
+
+impl<'a> DocFolder for SourceCollector<'a> {
+    fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
+        // If we're including source files, and we haven't seen this file yet,
+        // then we need to render it out to the filesystem.
+        if self.scx.include_sources
+            // skip all invalid or macro spans
+            && item.source.filename.is_real()
+            // skip non-local items
+            && item.def_id.is_local() {
+
+            // If it turns out that we couldn't read this file, then we probably
+            // can't read any of the files (generating html output from json or
+            // something like that), so just don't include sources for the
+            // entire crate. The other option is maintaining this mapping on a
+            // per-file basis, but that's probably not worth it...
+            self.scx
+                .include_sources = match self.emit_source(&item.source.filename) {
+                Ok(()) => true,
+                Err(e) => {
+                    println!("warning: source code was requested to be rendered, \
+                              but processing `{}` had an error: {}",
+                             item.source.filename, e);
+                    println!("         skipping rendering of source code");
+                    false
+                }
+            };
+        }
+        self.fold_item_recur(item)
+    }
+}
+
+impl<'a> SourceCollector<'a> {
+    /// Renders the given filename into its corresponding HTML source file.
+    fn emit_source(&mut self, filename: &FileName) -> Result<(), Error> {
+        let p = match *filename {
+            FileName::Real(ref file) => file,
+            _ => return Ok(()),
+        };
+        if self.scx.local_sources.contains_key(&**p) {
+            // We've already emitted this source
+            return Ok(());
+        }
+
+        let contents = match fs::read_to_string(&p) {
+            Ok(contents) => contents,
+            Err(e) => {
+                return Err(Error::new(e, &p));
+            }
+        };
+
+        // Remove the utf-8 BOM if any
+        let contents = if contents.starts_with("\u{feff}") {
+            &contents[3..]
+        } else {
+            &contents[..]
+        };
+
+        // Create the intermediate directories
+        let mut cur = self.dst.clone();
+        let mut root_path = String::from("../../");
+        let mut href = String::new();
+        clean_path(&self.scx.src_root, &p, false, |component| {
+            cur.push(component);
+            root_path.push_str("../");
+            href.push_str(&component.to_string_lossy());
+            href.push('/');
+        });
+        self.scx.ensure_dir(&cur)?;
+        let mut fname = p.file_name()
+                         .expect("source has no filename")
+                         .to_os_string();
+        fname.push(".html");
+        cur.push(&fname);
+        href.push_str(&fname.to_string_lossy());
+
+        let mut v = Vec::new();
+        let title = format!("{} -- source", cur.file_name().expect("failed to get file name")
+                                               .to_string_lossy());
+        let desc = format!("Source to the Rust file `{}`.", filename);
+        let page = layout::Page {
+            title: &title,
+            css_class: "source",
+            root_path: &root_path,
+            static_root_path: self.scx.static_root_path.as_deref(),
+            description: &desc,
+            keywords: BASIC_KEYWORDS,
+            resource_suffix: &self.scx.resource_suffix,
+            extra_scripts: &[&format!("source-files{}", self.scx.resource_suffix)],
+            static_extra_scripts: &[&format!("source-script{}", self.scx.resource_suffix)],
+        };
+        let result = layout::render(&mut v, &self.scx.layout,
+                       &page, &(""), &Source(contents),
+                       self.scx.css_file_extension.is_some(),
+                       &self.scx.themes,
+                       self.scx.generate_search_filter);
+        if let Err(e) = result {
+            return Err(Error::new(e, &cur));
+        }
+        self.scx.fs.write(&cur, &v)?;
+        self.scx.local_sources.insert(p.clone(), href);
+        Ok(())
+    }
+}
+
+/// Takes a path to a source file and cleans the path to it. This canonicalizes
+/// things like ".." to components which preserve the "top down" hierarchy of a
+/// static HTML tree. Each component in the cleaned path will be passed as an
+/// argument to `f`. The very last component of the path (ie the file name) will
+/// be passed to `f` if `keep_filename` is true, and ignored otherwise.
+pub fn clean_path<F>(src_root: &Path, p: &Path, keep_filename: bool, mut f: F)
+where
+    F: FnMut(&OsStr),
+{
+    // make it relative, if possible
+    let p = p.strip_prefix(src_root).unwrap_or(p);
+
+    let mut iter = p.components().peekable();
+
+    while let Some(c) = iter.next() {
+        if !keep_filename && iter.peek().is_none() {
+            break;
+        }
+
+        match c {
+            Component::ParentDir => f("up".as_ref()),
+            Component::Normal(c) => f(c),
+            _ => continue,
+        }
+    }
+}
+
+/// Wrapper struct to render the source code of a file. This will do things like
+/// adding line numbers to the left-hand side.
+struct Source<'a>(&'a str);
+
+impl<'a> fmt::Display for Source<'a> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Source(s) = *self;
+        let lines = s.lines().count();
+        let mut cols = 0;
+        let mut tmp = lines;
+        while tmp > 0 {
+            cols += 1;
+            tmp /= 10;
+        }
+        write!(fmt, "<pre class=\"line-numbers\">")?;
+        for i in 1..=lines {
+            write!(fmt, "<span id=\"{0}\">{0:1$}</span>\n", i, cols)?;
+        }
+        write!(fmt, "</pre>")?;
+        write!(fmt, "{}",
+               highlight::render_with_highlighting(s, None, None, None))?;
+        Ok(())
+    }
+}
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index e30b35937db9f..968578f957c5c 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -67,6 +67,7 @@ pub mod html {
     crate mod render;
     crate mod static_files;
     crate mod toc;
+    crate mod sources;
 }
 mod markdown;
 mod passes;

From e2b6f4c662ee2b57aeb0bdcd63356721cc6c4894 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 12 Aug 2019 07:10:55 -0400
Subject: [PATCH 269/943] Move top-level Clean impl to function

This allows us to pass it a `&mut DocContext` which will allow removal
of RefCells, etc. in the following commits. It's also somewhat a unique
Clean impl in that it previously ignored `self` (re-retriveing
hir::Crate), which it no longer needs to do.
---
 src/librustdoc/clean/mod.rs | 164 ++++++++++++++++++------------------
 src/librustdoc/core.rs      |   6 +-
 2 files changed, 83 insertions(+), 87 deletions(-)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ba792a413b3c4..19cb5ddb91e86 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -136,94 +136,90 @@ pub struct Crate {
     pub collapsed: bool,
 }
 
-impl Clean<Crate> for hir::Crate {
-    // note that self here is ignored in favor of `cx.tcx.hir().krate()` since
-    // that gets around tying self's lifetime to the '_ in cx.
-    fn clean(&self, cx: &DocContext<'_>) -> Crate {
-        use crate::visit_lib::LibEmbargoVisitor;
-
-        let v = crate::visit_ast::RustdocVisitor::new(&cx);
-        let module = v.visit(cx.tcx.hir().krate());
-
-        {
-            let mut r = cx.renderinfo.borrow_mut();
-            r.deref_trait_did = cx.tcx.lang_items().deref_trait();
-            r.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait();
-            r.owned_box_did = cx.tcx.lang_items().owned_box();
-        }
-
-        let mut externs = Vec::new();
-        for &cnum in cx.tcx.crates().iter() {
-            externs.push((cnum, cnum.clean(cx)));
-            // Analyze doc-reachability for extern items
-            LibEmbargoVisitor::new(cx).visit_lib(cnum);
-        }
-        externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
-
-        // Clean the crate, translating the entire libsyntax AST to one that is
-        // understood by rustdoc.
-        let mut module = module.clean(cx);
-        let mut masked_crates = FxHashSet::default();
-
-        match module.inner {
-            ModuleItem(ref module) => {
-                for it in &module.items {
-                    // `compiler_builtins` should be masked too, but we can't apply
-                    // `#[doc(masked)]` to the injected `extern crate` because it's unstable.
-                    if it.is_extern_crate()
-                        && (it.attrs.has_doc_flag(sym::masked)
-                            || cx.tcx.is_compiler_builtins(it.def_id.krate))
-                    {
-                        masked_crates.insert(it.def_id.krate);
-                    }
-                }
-            }
-            _ => unreachable!(),
-        }
+pub fn krate(cx: &mut DocContext<'a>) -> Crate {
+    use crate::visit_lib::LibEmbargoVisitor;
 
-        let ExternalCrate { name, src, primitives, keywords, .. } = LOCAL_CRATE.clean(cx);
-        {
-            let m = match module.inner {
-                ModuleItem(ref mut m) => m,
-                _ => unreachable!(),
-            };
-            m.items.extend(primitives.iter().map(|&(def_id, prim, ref attrs)| {
-                Item {
-                    source: Span::empty(),
-                    name: Some(prim.to_url_str().to_string()),
-                    attrs: attrs.clone(),
-                    visibility: Some(Public),
-                    stability: get_stability(cx, def_id),
-                    deprecation: get_deprecation(cx, def_id),
-                    def_id,
-                    inner: PrimitiveItem(prim),
-                }
-            }));
-            m.items.extend(keywords.into_iter().map(|(def_id, kw, attrs)| {
-                Item {
-                    source: Span::empty(),
-                    name: Some(kw.clone()),
-                    attrs: attrs,
-                    visibility: Some(Public),
-                    stability: get_stability(cx, def_id),
-                    deprecation: get_deprecation(cx, def_id),
-                    def_id,
-                    inner: KeywordItem(kw),
+    let v = crate::visit_ast::RustdocVisitor::new(&cx);
+    let module = v.visit(cx.tcx.hir().krate());
+
+    {
+        let mut r = cx.renderinfo.borrow_mut();
+        r.deref_trait_did = cx.tcx.lang_items().deref_trait();
+        r.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait();
+        r.owned_box_did = cx.tcx.lang_items().owned_box();
+    }
+
+    let mut externs = Vec::new();
+    for &cnum in cx.tcx.crates().iter() {
+        externs.push((cnum, cnum.clean(cx)));
+        // Analyze doc-reachability for extern items
+        LibEmbargoVisitor::new(cx).visit_lib(cnum);
+    }
+    externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
+
+    // Clean the crate, translating the entire libsyntax AST to one that is
+    // understood by rustdoc.
+    let mut module = module.clean(cx);
+    let mut masked_crates = FxHashSet::default();
+
+    match module.inner {
+        ModuleItem(ref module) => {
+            for it in &module.items {
+                // `compiler_builtins` should be masked too, but we can't apply
+                // `#[doc(masked)]` to the injected `extern crate` because it's unstable.
+                if it.is_extern_crate()
+                    && (it.attrs.has_doc_flag(sym::masked)
+                        || cx.tcx.is_compiler_builtins(it.def_id.krate))
+                {
+                    masked_crates.insert(it.def_id.krate);
                 }
-            }));
+            }
         }
+        _ => unreachable!(),
+    }
 
-        Crate {
-            name,
-            version: None,
-            src,
-            module: Some(module),
-            externs,
-            primitives,
-            external_traits: cx.external_traits.clone(),
-            masked_crates,
-            collapsed: false,
-        }
+    let ExternalCrate { name, src, primitives, keywords, .. } = LOCAL_CRATE.clean(cx);
+    {
+        let m = match module.inner {
+            ModuleItem(ref mut m) => m,
+            _ => unreachable!(),
+        };
+        m.items.extend(primitives.iter().map(|&(def_id, prim, ref attrs)| {
+            Item {
+                source: Span::empty(),
+                name: Some(prim.to_url_str().to_string()),
+                attrs: attrs.clone(),
+                visibility: Some(Public),
+                stability: get_stability(cx, def_id),
+                deprecation: get_deprecation(cx, def_id),
+                def_id,
+                inner: PrimitiveItem(prim),
+            }
+        }));
+        m.items.extend(keywords.into_iter().map(|(def_id, kw, attrs)| {
+            Item {
+                source: Span::empty(),
+                name: Some(kw.clone()),
+                attrs: attrs,
+                visibility: Some(Public),
+                stability: get_stability(cx, def_id),
+                deprecation: get_deprecation(cx, def_id),
+                def_id,
+                inner: KeywordItem(kw),
+            }
+        }));
+    }
+
+    Crate {
+        name,
+        version: None,
+        src,
+        module: Some(module),
+        externs,
+        primitives,
+        external_traits: cx.external_traits.clone(),
+        masked_crates,
+        collapsed: false,
     }
 }
 
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 04e69613d4b0f..45ebaa115063a 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -30,7 +30,7 @@ use std::rc::Rc;
 
 use crate::config::{Options as RustdocOptions, RenderOptions};
 use crate::clean;
-use crate::clean::{Clean, MAX_DEF_ID, AttributesExt};
+use crate::clean::{MAX_DEF_ID, AttributesExt};
 use crate::html::render::RenderInfo;
 
 use crate::passes;
@@ -363,7 +363,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
             let mut renderinfo = RenderInfo::default();
             renderinfo.access_levels = access_levels;
 
-            let ctxt = DocContext {
+            let mut ctxt = DocContext {
                 tcx,
                 resolver,
                 cstore: compiler.cstore().clone(),
@@ -383,7 +383,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
             };
             debug!("crate: {:?}", tcx.hir().krate());
 
-            let mut krate = tcx.hir().krate().clean(&ctxt);
+            let mut krate = clean::krate(&mut ctxt);
 
             fn report_deprecated_attr(name: &str, diag: &errors::Handler) {
                 let mut msg = diag.struct_warn(&format!("the `#![doc({})]` attribute is \

From 57d57c67843f05a40d11c7d442bd5b461da6ddee Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 12 Aug 2019 07:21:04 -0400
Subject: [PATCH 270/943] Mutate DocContext from LibEmbargoVisitor and
 RustdocVisitor

We have &mut access, so remove the RefCell borrowing
---
 src/librustdoc/clean/mod.rs | 18 ++++++++----------
 src/librustdoc/visit_ast.rs |  8 ++++----
 src/librustdoc/visit_lib.rs | 24 +++++++++++-------------
 3 files changed, 23 insertions(+), 27 deletions(-)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 19cb5ddb91e86..62900fa9fb15f 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -136,24 +136,22 @@ pub struct Crate {
     pub collapsed: bool,
 }
 
-pub fn krate(cx: &mut DocContext<'a>) -> Crate {
+pub fn krate(mut cx: &mut DocContext<'_>) -> Crate {
     use crate::visit_lib::LibEmbargoVisitor;
 
-    let v = crate::visit_ast::RustdocVisitor::new(&cx);
-    let module = v.visit(cx.tcx.hir().krate());
+    let krate = cx.tcx.hir().krate();
+    let module = crate::visit_ast::RustdocVisitor::new(&mut cx).visit(krate);
 
-    {
-        let mut r = cx.renderinfo.borrow_mut();
-        r.deref_trait_did = cx.tcx.lang_items().deref_trait();
-        r.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait();
-        r.owned_box_did = cx.tcx.lang_items().owned_box();
-    }
+    let mut r = cx.renderinfo.get_mut();
+    r.deref_trait_did = cx.tcx.lang_items().deref_trait();
+    r.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait();
+    r.owned_box_did = cx.tcx.lang_items().owned_box();
 
     let mut externs = Vec::new();
     for &cnum in cx.tcx.crates().iter() {
         externs.push((cnum, cnum.clean(cx)));
         // Analyze doc-reachability for extern items
-        LibEmbargoVisitor::new(cx).visit_lib(cnum);
+        LibEmbargoVisitor::new(&mut cx).visit_lib(cnum);
     }
     externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
 
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 903ed3aae1470..ee330cb32111e 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -41,7 +41,7 @@ fn def_id_to_path(
 // framework from syntax?.
 
 pub struct RustdocVisitor<'a, 'tcx> {
-    cx: &'a core::DocContext<'tcx>,
+    cx: &'a mut core::DocContext<'tcx>,
     view_item_stack: FxHashSet<hir::HirId>,
     inlining: bool,
     /// Are the current module and all of its parents public?
@@ -51,7 +51,7 @@ pub struct RustdocVisitor<'a, 'tcx> {
 
 impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
     pub fn new(
-        cx: &'a core::DocContext<'tcx>
+        cx: &'a mut core::DocContext<'tcx>
     ) -> RustdocVisitor<'a, 'tcx> {
         // If the root is re-exported, terminate all recursion.
         let mut stack = FxHashSet::default();
@@ -84,7 +84,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         );
         module.is_crate = true;
 
-        self.cx.renderinfo.borrow_mut().exact_paths = self.exact_paths;
+        self.cx.renderinfo.get_mut().exact_paths = self.exact_paths;
 
         module
     }
@@ -292,7 +292,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 Res::Def(DefKind::ForeignTy, did) |
                 Res::Def(DefKind::TyAlias, did) if !self_is_hidden => {
                     self.cx.renderinfo
-                        .borrow_mut()
+                        .get_mut()
                         .access_levels.map
                         .insert(did, AccessLevel::Public);
                 },
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 2547e3a06e9ef..b229b5f6884d8 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -1,12 +1,10 @@
 use rustc::middle::privacy::{AccessLevels, AccessLevel};
 use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId};
-use rustc::ty::Visibility;
+use rustc::ty::{TyCtxt, Visibility};
 use rustc::util::nodemap::FxHashSet;
 use syntax::symbol::sym;
 
-use std::cell::RefMut;
-
 use crate::clean::{AttributesExt, NestedAttributesExt};
 
 // FIXME: this may not be exhaustive, but is sufficient for rustdocs current uses
@@ -14,9 +12,9 @@ use crate::clean::{AttributesExt, NestedAttributesExt};
 /// Similar to `librustc_privacy::EmbargoVisitor`, but also takes
 /// specific rustdoc annotations into account (i.e., `doc(hidden)`)
 pub struct LibEmbargoVisitor<'a, 'tcx> {
-    cx: &'a crate::core::DocContext<'tcx>,
+    tcx: TyCtxt<'tcx>,
     // Accessibility levels for reachable nodes
-    access_levels: RefMut<'a, AccessLevels<DefId>>,
+    access_levels: &'a mut AccessLevels<DefId>,
     // Previous accessibility level, None means unreachable
     prev_level: Option<AccessLevel>,
     // Keeps track of already visited modules, in case a module re-exports its parent
@@ -25,13 +23,13 @@ pub struct LibEmbargoVisitor<'a, 'tcx> {
 
 impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
     pub fn new(
-        cx: &'a crate::core::DocContext<'tcx>
+        cx: &'a mut crate::core::DocContext<'tcx>
     ) -> LibEmbargoVisitor<'a, 'tcx> {
         LibEmbargoVisitor {
-            cx,
-            access_levels: RefMut::map(cx.renderinfo.borrow_mut(), |ri| &mut ri.access_levels),
+            tcx: cx.tcx,
+            access_levels: &mut cx.renderinfo.get_mut().access_levels,
             prev_level: Some(AccessLevel::Public),
-            visited_mods: FxHashSet::default()
+            visited_mods: FxHashSet::default(),
         }
     }
 
@@ -43,7 +41,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
 
     // Updates node level and returns the updated level
     fn update(&mut self, did: DefId, level: Option<AccessLevel>) -> Option<AccessLevel> {
-        let is_hidden = self.cx.tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden);
+        let is_hidden = self.tcx.get_attrs(did).lists(sym::doc).has_word(sym::hidden);
 
         let old_level = self.access_levels.map.get(&did).cloned();
         // Accessibility levels can only grow
@@ -60,9 +58,9 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
             return;
         }
 
-        for item in self.cx.tcx.item_children(def_id).iter() {
+        for item in self.tcx.item_children(def_id).iter() {
             if let Some(def_id) = item.res.opt_def_id() {
-                if self.cx.tcx.def_key(def_id).parent.map_or(false, |d| d == def_id.index) ||
+                if self.tcx.def_key(def_id).parent.map_or(false, |d| d == def_id.index) ||
                     item.vis == Visibility::Public {
                     self.visit_item(item.res);
                 }
@@ -72,7 +70,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
 
     fn visit_item(&mut self, res: Res) {
         let def_id = res.def_id();
-        let vis = self.cx.tcx.visibility(def_id);
+        let vis = self.tcx.visibility(def_id);
         let inherited_item_level = if vis == Visibility::Public {
             self.prev_level
         } else {

From 95f5698c10dbf92e444abc5334a3b1333b20cb0f Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 12 Aug 2019 07:32:38 -0400
Subject: [PATCH 271/943] Remove dead tracking of external param names

---
 src/librustdoc/clean/mod.rs   | 19 -------------------
 src/librustdoc/html/render.rs | 26 --------------------------
 2 files changed, 45 deletions(-)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 62900fa9fb15f..ed82c522779eb 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -566,23 +566,6 @@ pub enum ItemEnum {
 }
 
 impl ItemEnum {
-    pub fn generics(&self) -> Option<&Generics> {
-        Some(match *self {
-            ItemEnum::StructItem(ref s) => &s.generics,
-            ItemEnum::EnumItem(ref e) => &e.generics,
-            ItemEnum::FunctionItem(ref f) => &f.generics,
-            ItemEnum::TypedefItem(ref t, _) => &t.generics,
-            ItemEnum::OpaqueTyItem(ref t, _) => &t.generics,
-            ItemEnum::TraitItem(ref t) => &t.generics,
-            ItemEnum::ImplItem(ref i) => &i.generics,
-            ItemEnum::TyMethodItem(ref i) => &i.generics,
-            ItemEnum::MethodItem(ref i) => &i.generics,
-            ItemEnum::ForeignFunctionItem(ref f) => &f.generics,
-            ItemEnum::TraitAliasItem(ref ta) => &ta.generics,
-            _ => return None,
-        })
-    }
-
     pub fn is_associated(&self) -> bool {
         match *self {
             ItemEnum::TypedefItem(_, _) |
@@ -1535,8 +1518,6 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
                 (self.name.to_string(), GenericParamDefKind::Lifetime)
             }
             ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
-                cx.renderinfo.borrow_mut().external_param_names
-                             .insert(self.def_id, self.name.clean(cx));
                 let default = if has_default {
                     Some(cx.tcx.type_of(self.def_id).clean(cx))
                 } else {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c8921a92d3382..896246126d869 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -282,11 +282,6 @@ impl Impl {
 /// rendering threads.
 #[derive(Default)]
 pub struct Cache {
-    /// Mapping of typaram ids to the name of the type parameter. This is used
-    /// when pretty-printing a type (so pretty-printing doesn't have to
-    /// painfully maintain a context like this)
-    pub param_names: FxHashMap<DefId, String>,
-
     /// Maps a type ID to all known implementations for that type. This is only
     /// recognized for intra-crate `ResolvedPath` types, and is used to print
     /// out extra documentation on the page of an enum/struct.
@@ -382,7 +377,6 @@ pub struct Cache {
 pub struct RenderInfo {
     pub inlined: FxHashSet<DefId>,
     pub external_paths: crate::core::ExternalPaths,
-    pub external_param_names: FxHashMap<DefId, String>,
     pub exact_paths: FxHashMap<DefId, Vec<String>>,
     pub access_levels: AccessLevels<DefId>,
     pub deref_trait_did: Option<DefId>,
@@ -617,7 +611,6 @@ pub fn run(mut krate: clean::Crate,
     let RenderInfo {
         inlined: _,
         external_paths,
-        external_param_names,
         exact_paths,
         access_levels,
         deref_trait_did,
@@ -651,7 +644,6 @@ pub fn run(mut krate: clean::Crate,
         deref_mut_trait_did,
         owned_box_did,
         masked_crates: mem::take(&mut krate.masked_crates),
-        param_names: external_param_names,
         aliases: Default::default(),
     };
 
@@ -1419,12 +1411,6 @@ impl DocFolder for Cache {
             }
         }
 
-        // Register any generics to their corresponding string. This is used
-        // when pretty-printing types.
-        if let Some(generics) = item.inner.generics() {
-            self.generics(generics);
-        }
-
         // Propagate a trait method's documentation to all implementors of the
         // trait.
         if let clean::TraitItem(ref t) = item.inner {
@@ -1657,18 +1643,6 @@ impl DocFolder for Cache {
 }
 
 impl Cache {
-    fn generics(&mut self, generics: &clean::Generics) {
-        for param in &generics.params {
-            match param.kind {
-                clean::GenericParamDefKind::Lifetime => {}
-                clean::GenericParamDefKind::Type { did, .. } |
-                clean::GenericParamDefKind::Const { did, .. } => {
-                    self.param_names.insert(did, param.name.clone());
-                }
-            }
-        }
-    }
-
     fn add_aliases(&mut self, item: &clean::Item) {
         if item.def_id.index == CRATE_DEF_INDEX {
             return

From 0e079c2c689b6252154e9df04d067783bfc13224 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 12 Aug 2019 11:18:25 -0400
Subject: [PATCH 272/943] Remove support for printing HRef in alternate mode

The alternate mode merely prints out the passed in text which is largely
useless (as the text can simply be directly printed).
---
 src/librustdoc/html/format.rs | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 9c22837bdae87..182a72b6a4d88 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -72,8 +72,8 @@ pub struct WhereClause<'a>{
 }
 
 pub struct HRef<'a> {
-    pub did: DefId,
-    pub text: &'a str,
+    did: DefId,
+    text: &'a str,
 }
 
 impl<'a> VisSpace<'a> {
@@ -452,7 +452,7 @@ fn resolved_path(w: &mut fmt::Formatter<'_>, did: DefId, path: &clean::Path,
         }
     }
     if w.alternate() {
-        write!(w, "{:#}{:#}", HRef::new(did, &last.name), last.args)?;
+        write!(w, "{}{:#}", &last.name, last.args)?;
     } else {
         let path = if use_absolute {
             match href(did) {
@@ -538,14 +538,11 @@ impl<'a> HRef<'a> {
 
 impl<'a> fmt::Display for HRef<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match href(self.did) {
-            Some((url, shortty, fqp)) => if !f.alternate() {
-                write!(f, "<a class=\"{}\" href=\"{}\" title=\"{} {}\">{}</a>",
-                       shortty, url, shortty, fqp.join("::"), self.text)
-            } else {
-                write!(f, "{}", self.text)
-            },
-            _ => write!(f, "{}", self.text),
+        if let Some((url, short_ty, fqp)) = href(self.did) {
+            write!(f, r#"<a class="{}" href="{}" title="{} {}">{}</a>"#,
+                short_ty, url, short_ty, fqp.join("::"), self.text)
+        } else {
+            write!(f, "{}", self.text)
         }
     }
 }

From 6876f9bcdc94c5e0c8cde03040b428f24f19a051 Mon Sep 17 00:00:00 2001
From: Mark Mansi <markm@cs.wisc.edu>
Date: Mon, 26 Aug 2019 18:06:24 -0500
Subject: [PATCH 273/943] filter linkcheck spurious failure

---
 src/tools/rustbook/src/main.rs | 54 ++++++++++++++++++++++------------
 1 file changed, 35 insertions(+), 19 deletions(-)

diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs
index 95530b210afd6..0915600bb3875 100644
--- a/src/tools/rustbook/src/main.rs
+++ b/src/tools/rustbook/src/main.rs
@@ -1,18 +1,18 @@
-use clap::{crate_version};
+use clap::crate_version;
 
 use std::env;
 use std::path::{Path, PathBuf};
 
-use clap::{App, ArgMatches, SubCommand, AppSettings};
+use clap::{App, AppSettings, ArgMatches, SubCommand};
 
+use mdbook::errors::Result as Result3;
 use mdbook::MDBook;
-use mdbook::errors::{Result as Result3};
 
+use failure::Error;
 #[cfg(feature = "linkcheck")]
 use mdbook::renderer::RenderContext;
 #[cfg(feature = "linkcheck")]
 use mdbook_linkcheck::{self, errors::BrokenLinks};
-use failure::Error;
 
 fn main() {
     let d_message = "-d, --dest-dir=[dest-dir]
@@ -21,18 +21,22 @@ fn main() {
 'A directory for your book{n}(Defaults to Current Directory when omitted)'";
 
     let matches = App::new("rustbook")
-                    .about("Build a book with mdBook")
-                    .author("Steve Klabnik <steve@steveklabnik.com>")
-                    .version(&*format!("v{}", crate_version!()))
-                    .setting(AppSettings::SubcommandRequired)
-                    .subcommand(SubCommand::with_name("build")
-                        .about("Build the book from the markdown files")
-                        .arg_from_usage(d_message)
-                        .arg_from_usage(dir_message))
-                    .subcommand(SubCommand::with_name("linkcheck")
-                        .about("Run linkcheck with mdBook 3")
-                        .arg_from_usage(dir_message))
-                    .get_matches();
+        .about("Build a book with mdBook")
+        .author("Steve Klabnik <steve@steveklabnik.com>")
+        .version(&*format!("v{}", crate_version!()))
+        .setting(AppSettings::SubcommandRequired)
+        .subcommand(
+            SubCommand::with_name("build")
+                .about("Build the book from the markdown files")
+                .arg_from_usage(d_message)
+                .arg_from_usage(dir_message),
+        )
+        .subcommand(
+            SubCommand::with_name("linkcheck")
+                .about("Run linkcheck with mdBook 3")
+                .arg_from_usage(dir_message),
+        )
+        .get_matches();
 
     // Check which subcomamnd the user ran...
     match matches.subcommand() {
@@ -46,23 +50,35 @@ fn main() {
 
                 ::std::process::exit(101);
             }
-        },
+        }
         ("linkcheck", Some(sub_matches)) => {
             if let Err(err) = linkcheck(sub_matches) {
                 eprintln!("Error: {}", err);
 
+                // HACK: ignore timeouts
+                #[allow(unused_mut)]
+                let mut actually_broken = false;
+
                 #[cfg(feature = "linkcheck")]
                 {
                     if let Ok(broken_links) = err.downcast::<BrokenLinks>() {
                         for cause in broken_links.links().iter() {
                             eprintln!("\tCaused By: {}", cause);
+
+                            if cause.contains("timed out") {
+                                actually_broken = true;
+                            }
                         }
                     }
                 }
 
-                ::std::process::exit(101);
+                if actually_broken {
+                    std::process::exit(101);
+                } else {
+                    std::process::exit(0);
+                }
             }
-        },
+        }
         (_, _) => unreachable!(),
     };
 }

From 3307929a849592d8ea36b10f92192e31867f76e3 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 12 Aug 2019 12:53:45 -0400
Subject: [PATCH 274/943] Store only the current depth

Previously we stored the entire current path which is a bit expensive
and only ever accessed its length. This stores the length directly.
---
 src/librustdoc/html/format.rs | 12 ++++++------
 src/librustdoc/html/render.rs | 10 +++++-----
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 182a72b6a4d88..54c0120e398c3 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -15,7 +15,7 @@ use rustc::hir;
 
 use crate::clean::{self, PrimitiveType};
 use crate::html::item_type::ItemType;
-use crate::html::render::{self, cache, CURRENT_LOCATION_KEY};
+use crate::html::render::{self, cache, CURRENT_DEPTH};
 
 /// Helper to render an optional visibility with a space after it (if the
 /// visibility is preset)
@@ -407,16 +407,16 @@ pub fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
         return None
     }
 
-    let loc = CURRENT_LOCATION_KEY.with(|l| l.borrow().clone());
+    let depth = CURRENT_DEPTH.with(|l| l.get());
     let (fqp, shortty, mut url) = match cache.paths.get(&did) {
         Some(&(ref fqp, shortty)) => {
-            (fqp, shortty, "../".repeat(loc.len()))
+            (fqp, shortty, "../".repeat(depth))
         }
         None => {
             let &(ref fqp, shortty) = cache.external_paths.get(&did)?;
             (fqp, shortty, match cache.extern_locations[&did.krate] {
                 (.., render::Remote(ref s)) => s.to_string(),
-                (.., render::Local) => "../".repeat(loc.len()),
+                (.., render::Local) => "../".repeat(depth),
                 (.., render::Unknown) => return None,
             })
         }
@@ -479,7 +479,7 @@ fn primitive_link(f: &mut fmt::Formatter<'_>,
     if !f.alternate() {
         match m.primitive_locations.get(&prim) {
             Some(&def_id) if def_id.is_local() => {
-                let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len());
+                let len = CURRENT_DEPTH.with(|s| s.get());
                 let len = if len == 0 {0} else {len - 1};
                 write!(f, "<a class=\"primitive\" href=\"{}primitive.{}.html\">",
                        "../".repeat(len),
@@ -492,7 +492,7 @@ fn primitive_link(f: &mut fmt::Formatter<'_>,
                         Some((cname, s.to_string()))
                     }
                     (ref cname, _, render::Local) => {
-                        let len = CURRENT_LOCATION_KEY.with(|s| s.borrow().len());
+                        let len = CURRENT_DEPTH.with(|s| s.get());
                         Some((cname, "../".repeat(len)))
                     }
                     (.., render::Unknown) => None,
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 896246126d869..67084991276b8 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -28,7 +28,7 @@
 pub use self::ExternalLocation::*;
 
 use std::borrow::Cow;
-use std::cell::RefCell;
+use std::cell::{Cell, RefCell};
 use std::cmp::Ordering;
 use std::collections::{BTreeMap, VecDeque};
 use std::default::Default;
@@ -479,7 +479,7 @@ impl ToJson for IndexItemFunctionType {
 }
 
 thread_local!(static CACHE_KEY: RefCell<Arc<Cache>> = Default::default());
-thread_local!(pub static CURRENT_LOCATION_KEY: RefCell<Vec<String>> = RefCell::new(Vec::new()));
+thread_local!(pub static CURRENT_DEPTH: Cell<usize> = Cell::new(0));
 
 pub fn initial_ids() -> Vec<String> {
     [
@@ -695,7 +695,7 @@ pub fn run(mut krate: clean::Crate,
     // for future parallelization opportunities
     let cache = Arc::new(cache);
     CACHE_KEY.with(|v| *v.borrow_mut() = cache.clone());
-    CURRENT_LOCATION_KEY.with(|s| s.borrow_mut().clear());
+    CURRENT_DEPTH.with(|s| s.set(0));
 
     // Write shared runs within a flock; disable thread dispatching of IO temporarily.
     Arc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(true);
@@ -2003,8 +2003,8 @@ impl Context {
                    -> io::Result<()> {
         // A little unfortunate that this is done like this, but it sure
         // does make formatting *a lot* nicer.
-        CURRENT_LOCATION_KEY.with(|slot| {
-            *slot.borrow_mut() = self.current.clone();
+        CURRENT_DEPTH.with(|slot| {
+            slot.set(self.current.len());
         });
 
         let mut title = if it.is_primitive() || it.is_keyword() {

From dafdfee33e8e78c3f34dd5befb3581fff0041ebd Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 12 Aug 2019 12:57:48 -0400
Subject: [PATCH 275/943] Inline RawMutableSpace

---
 src/librustdoc/html/format.rs | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 54c0120e398c3..f232d4ca69ec8 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -36,9 +36,6 @@ pub struct AsyncSpace(pub hir::IsAsync);
 /// Similar to VisSpace, but used for mutability
 #[derive(Copy, Clone)]
 pub struct MutableSpace(pub clean::Mutability);
-/// Similar to VisSpace, but used for mutability
-#[derive(Copy, Clone)]
-pub struct RawMutableSpace(pub clean::Mutability);
 /// Wrapper struct for emitting type parameter bounds.
 pub struct GenericBounds<'a>(pub &'a [clean::GenericBound]);
 /// Wrapper struct for emitting a comma-separated list of items
@@ -604,19 +601,22 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
         clean::Never => primitive_link(f, PrimitiveType::Never, "!"),
         clean::CVarArgs => primitive_link(f, PrimitiveType::CVarArgs, "..."),
         clean::RawPointer(m, ref t) => {
+            let m = match m {
+                clean::Immutable => "const",
+                clean::Mutable => "mut",
+            };
             match **t {
                 clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => {
                     if f.alternate() {
                         primitive_link(f, clean::PrimitiveType::RawPointer,
-                                       &format!("*{}{:#}", RawMutableSpace(m), t))
+                                       &format!("*{} {:#}", m, t))
                     } else {
                         primitive_link(f, clean::PrimitiveType::RawPointer,
-                                       &format!("*{}{}", RawMutableSpace(m), t))
+                                       &format!("*{} {}", m, t))
                     }
                 }
                 _ => {
-                    primitive_link(f, clean::PrimitiveType::RawPointer,
-                                   &format!("*{}", RawMutableSpace(m)))?;
+                    primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{} ", m))?;
                     fmt::Display::fmt(t, f)
                 }
             }
@@ -1044,15 +1044,6 @@ impl fmt::Display for MutableSpace {
     }
 }
 
-impl fmt::Display for RawMutableSpace {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match *self {
-            RawMutableSpace(clean::Immutable) => write!(f, "const "),
-            RawMutableSpace(clean::Mutable) => write!(f, "mut "),
-        }
-    }
-}
-
 impl fmt::Display for AbiSpace {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let quot = if f.alternate() { "\"" } else { "&quot;" };

From edfd5556f1ddc44a9cf5a53db417330661d47053 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 12 Aug 2019 14:36:09 -0400
Subject: [PATCH 276/943] Transition a few fmt::Display impls to functions

This introduces a WithFormatter abstraction that permits one-time
fmt::Display on an arbitrary closure, created via `display_fn`. This
allows us to prevent allocation while still using functions instead of
structs, which are a bit unwieldy to thread arguments through as they
can't easily call each other (and are generally a bit opaque).

The eventual goal here is likely to move us off of the formatting
infrastructure entirely in favor of something more structured, but this
is a good step to move us in that direction as it makes, for example,
passing a context describing current state to the formatting impl much
easier.
---
 src/librustdoc/html/format.rs | 102 ++++++++++++++++++----------------
 src/librustdoc/html/render.rs |   6 +-
 2 files changed, 56 insertions(+), 52 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index f232d4ca69ec8..313734e3fdd6b 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -6,6 +6,7 @@
 //! them in the future to instead emit any format desired.
 
 use std::borrow::Cow;
+use std::cell::Cell;
 use std::fmt;
 
 use rustc::hir::def_id::DefId;
@@ -38,8 +39,6 @@ pub struct AsyncSpace(pub hir::IsAsync);
 pub struct MutableSpace(pub clean::Mutability);
 /// Wrapper struct for emitting type parameter bounds.
 pub struct GenericBounds<'a>(pub &'a [clean::GenericBound]);
-/// Wrapper struct for emitting a comma-separated list of items
-pub struct CommaSep<'a, T>(pub &'a [T]);
 pub struct AbiSpace(pub Abi);
 pub struct DefaultSpace(pub bool);
 
@@ -68,11 +67,6 @@ pub struct WhereClause<'a>{
     pub end_newline: bool,
 }
 
-pub struct HRef<'a> {
-    did: DefId,
-    text: &'a str,
-}
-
 impl<'a> VisSpace<'a> {
     pub fn get(self) -> &'a Option<clean::Visibility> {
         let VisSpace(v) = self; v
@@ -91,14 +85,14 @@ impl ConstnessSpace {
     }
 }
 
-impl<'a, T: fmt::Display> fmt::Display for CommaSep<'a, T> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        for (i, item) in self.0.iter().enumerate() {
+fn comma_sep<T: fmt::Display>(items: &[T]) -> impl fmt::Display + '_ {
+    display_fn(move |f| {
+        for (i, item) in items.iter().enumerate() {
             if i != 0 { write!(f, ", ")?; }
             fmt::Display::fmt(item, f)?;
         }
         Ok(())
-    }
+    })
 }
 
 impl<'a> fmt::Display for GenericBounds<'a> {
@@ -165,9 +159,9 @@ impl fmt::Display for clean::Generics {
             return Ok(());
         }
         if f.alternate() {
-            write!(f, "<{:#}>", CommaSep(&real_params))
+            write!(f, "<{:#}>", comma_sep(&real_params))
         } else {
-            write!(f, "&lt;{}&gt;", CommaSep(&real_params))
+            write!(f, "&lt;{}&gt;", comma_sep(&real_params))
         }
     }
 }
@@ -265,9 +259,9 @@ impl fmt::Display for clean::PolyTrait {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         if !self.generic_params.is_empty() {
             if f.alternate() {
-                write!(f, "for<{:#}> ", CommaSep(&self.generic_params))?;
+                write!(f, "for<{:#}> ", comma_sep(&self.generic_params))?;
             } else {
-                write!(f, "for&lt;{}&gt; ", CommaSep(&self.generic_params))?;
+                write!(f, "for&lt;{}&gt; ", comma_sep(&self.generic_params))?;
             }
         }
         if f.alternate() {
@@ -452,16 +446,15 @@ fn resolved_path(w: &mut fmt::Formatter<'_>, did: DefId, path: &clean::Path,
         write!(w, "{}{:#}", &last.name, last.args)?;
     } else {
         let path = if use_absolute {
-            match href(did) {
-                Some((_, _, fqp)) => {
-                    format!("{}::{}",
-                            fqp[..fqp.len() - 1].join("::"),
-                            HRef::new(did, fqp.last().unwrap()))
-                }
-                None => HRef::new(did, &last.name).to_string(),
+            if let Some((_, _, fqp)) = href(did) {
+                format!("{}::{}",
+                        fqp[..fqp.len() - 1].join("::"),
+                        anchor(did, fqp.last().unwrap()))
+            } else {
+                last.name.to_string()
             }
         } else {
-            HRef::new(did, &last.name).to_string()
+            anchor(did, &last.name).to_string()
         };
         write!(w, "{}{}", path, last.args)?;
     }
@@ -513,35 +506,30 @@ fn primitive_link(f: &mut fmt::Formatter<'_>,
 }
 
 /// Helper to render type parameters
-fn tybounds(w: &mut fmt::Formatter<'_>,
-            param_names: &Option<Vec<clean::GenericBound>>) -> fmt::Result {
-    match *param_names {
-        Some(ref params) => {
-            for param in params {
-                write!(w, " + ")?;
-                fmt::Display::fmt(param, w)?;
+fn tybounds(param_names: &Option<Vec<clean::GenericBound>>) -> impl fmt::Display + '_ {
+    display_fn(move |f| {
+        match *param_names {
+            Some(ref params) => {
+                for param in params {
+                    write!(f, " + ")?;
+                    fmt::Display::fmt(param, f)?;
+                }
+                Ok(())
             }
-            Ok(())
+            None => Ok(())
         }
-        None => Ok(())
-    }
-}
-
-impl<'a> HRef<'a> {
-    pub fn new(did: DefId, text: &'a str) -> HRef<'a> {
-        HRef { did: did, text: text }
-    }
+    })
 }
 
-impl<'a> fmt::Display for HRef<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        if let Some((url, short_ty, fqp)) = href(self.did) {
+pub fn anchor(did: DefId, text: &str) -> impl fmt::Display + '_ {
+    display_fn(move |f| {
+        if let Some((url, short_ty, fqp)) = href(did) {
             write!(f, r#"<a class="{}" href="{}" title="{} {}">{}</a>"#,
-                short_ty, url, short_ty, fqp.join("::"), self.text)
+                short_ty, url, short_ty, fqp.join("::"), text)
         } else {
-            write!(f, "{}", self.text)
+            write!(f, "{}", text)
         }
-    }
+    })
 }
 
 fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> fmt::Result {
@@ -555,7 +543,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
             }
             // Paths like `T::Output` and `Self::Output` should be rendered with all segments.
             resolved_path(f, did, path, is_generic, use_absolute)?;
-            tybounds(f, param_names)
+            fmt::Display::fmt(&tybounds(param_names), f)
         }
         clean::Infer => write!(f, "_"),
         clean::Primitive(prim) => primitive_link(f, prim, prim.as_str()),
@@ -564,12 +552,12 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
                 write!(f, "{}{:#}fn{:#}{:#}",
                        UnsafetySpace(decl.unsafety),
                        AbiSpace(decl.abi),
-                       CommaSep(&decl.generic_params),
+                       comma_sep(&decl.generic_params),
                        decl.decl)
             } else {
                 write!(f, "{}{}", UnsafetySpace(decl.unsafety), AbiSpace(decl.abi))?;
                 primitive_link(f, PrimitiveType::Fn, "fn")?;
-                write!(f, "{}{}", CommaSep(&decl.generic_params), decl.decl)
+                write!(f, "{}{}", comma_sep(&decl.generic_params), decl.decl)
             }
         }
         clean::Tuple(ref typs) => {
@@ -583,7 +571,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
                 }
                 many => {
                     primitive_link(f, PrimitiveType::Tuple, "(")?;
-                    fmt::Display::fmt(&CommaSep(many), f)?;
+                    fmt::Display::fmt(&comma_sep(many), f)?;
                     primitive_link(f, PrimitiveType::Tuple, ")")
                 }
             }
@@ -1063,3 +1051,19 @@ impl fmt::Display for DefaultSpace {
         }
     }
 }
+
+crate fn display_fn(
+    f: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
+) -> impl fmt::Display {
+    WithFormatter(Cell::new(Some(f)))
+}
+
+struct WithFormatter<F>(Cell<Option<F>>);
+
+impl<F> fmt::Display for WithFormatter<F>
+    where F: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        (self.0.take()).unwrap()(f)
+    }
+}
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 67084991276b8..c37c8ef9e6c34 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2644,19 +2644,19 @@ fn item_module(w: &mut fmt::Formatter<'_>, cx: &Context,
 
         match myitem.inner {
             clean::ExternCrateItem(ref name, ref src) => {
-                use crate::html::format::HRef;
+                use crate::html::format::anchor;
 
                 match *src {
                     Some(ref src) => {
                         write!(w, "<tr><td><code>{}extern crate {} as {};",
                                VisSpace(&myitem.visibility),
-                               HRef::new(myitem.def_id, src),
+                               anchor(myitem.def_id, src),
                                name)?
                     }
                     None => {
                         write!(w, "<tr><td><code>{}extern crate {};",
                                VisSpace(&myitem.visibility),
-                               HRef::new(myitem.def_id, name))?
+                               anchor(myitem.def_id, name))?
                     }
                 }
                 write!(w, "</code></td></tr>")?;

From b3f01753b0134af903eeeea4c177e2abf1eac26e Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 12 Aug 2019 16:43:26 -0400
Subject: [PATCH 277/943] Inline recurse into only callsite

---
 src/librustdoc/html/render.rs | 97 +++++++++++++++--------------------
 1 file changed, 40 insertions(+), 57 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c37c8ef9e6c34..faf4f46ca5495 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1885,31 +1885,6 @@ impl Context {
         "../".repeat(self.current.len())
     }
 
-    /// Recurse in the directory structure and change the "root path" to make
-    /// sure it always points to the top (relatively).
-    fn recurse<T, F>(&mut self, s: String, f: F) -> T where
-        F: FnOnce(&mut Context) -> T,
-    {
-        if s.is_empty() {
-            panic!("Unexpected empty destination: {:?}", self.current);
-        }
-        let prev = self.dst.clone();
-        self.dst.push(&s);
-        self.current.push(s);
-
-        info!("Recursing into {}", self.dst.display());
-
-        let ret = f(self);
-
-        info!("Recursed; leaving {}", self.dst.display());
-
-        // Go back to where we were at
-        self.dst = prev;
-        self.current.pop().unwrap();
-
-        ret
-    }
-
     /// Main method for rendering a crate.
     ///
     /// This currently isn't parallelized, but it'd be pretty easy to add
@@ -2090,42 +2065,50 @@ impl Context {
             // modules are special because they add a namespace. We also need to
             // recurse into the items of the module as well.
             let name = item.name.as_ref().unwrap().to_string();
-            let mut item = Some(item);
-            let scx = self.shared.clone();
-            self.recurse(name, |this| {
-                let item = item.take().unwrap();
-
-                let mut buf = Vec::new();
-                this.render_item(&mut buf, &item, false).unwrap();
-                // buf will be empty if the module is stripped and there is no redirect for it
-                if !buf.is_empty() {
-                    this.shared.ensure_dir(&this.dst)?;
-                    let joint_dst = this.dst.join("index.html");
-                    scx.fs.write(&joint_dst, buf)?;
-                }
+            let scx = &self.shared;
+            if name.is_empty() {
+                panic!("Unexpected empty destination: {:?}", self.current);
+            }
+            let prev = self.dst.clone();
+            self.dst.push(&name);
+            self.current.push(name);
 
-                let m = match item.inner {
-                    clean::StrippedItem(box clean::ModuleItem(m)) |
-                    clean::ModuleItem(m) => m,
-                    _ => unreachable!()
-                };
+            info!("Recursing into {}", self.dst.display());
 
-                // Render sidebar-items.js used throughout this module.
-                if !this.render_redirect_pages {
-                    let items = this.build_sidebar_items(&m);
-                    let js_dst = this.dst.join("sidebar-items.js");
-                    let mut v = Vec::new();
-                    try_err!(write!(&mut v, "initSidebarItems({});",
-                                    as_json(&items)), &js_dst);
-                    scx.fs.write(&js_dst, &v)?;
-                }
+            let mut buf = Vec::new();
+            self.render_item(&mut buf, &item, false).unwrap();
+            // buf will be empty if the module is stripped and there is no redirect for it
+            if !buf.is_empty() {
+                self.shared.ensure_dir(&self.dst)?;
+                let joint_dst = self.dst.join("index.html");
+                scx.fs.write(&joint_dst, buf)?;
+            }
 
-                for item in m.items {
-                    f(this, item);
-                }
+            let m = match item.inner {
+                clean::StrippedItem(box clean::ModuleItem(m)) |
+                clean::ModuleItem(m) => m,
+                _ => unreachable!()
+            };
+
+            // Render sidebar-items.js used throughout this module.
+            if !self.render_redirect_pages {
+                let items = self.build_sidebar_items(&m);
+                let js_dst = self.dst.join("sidebar-items.js");
+                let mut v = Vec::new();
+                try_err!(write!(&mut v, "initSidebarItems({});",
+                                as_json(&items)), &js_dst);
+                scx.fs.write(&js_dst, &v)?;
+            }
+
+            for item in m.items {
+                f(self, item);
+            }
+
+            info!("Recursed; leaving {}", self.dst.display());
 
-                Ok(())
-            })?;
+            // Go back to where we were at
+            self.dst = prev;
+            self.current.pop().unwrap();
         } else if item.name.is_some() {
             let mut buf = Vec::new();
             self.render_item(&mut buf, &item, true).unwrap();

From b0fab966fad61cac073d1494e0539961e1c442a0 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 12 Aug 2019 16:49:22 -0400
Subject: [PATCH 278/943] Shorten line during rendering instead of in markdown

---
 src/librustdoc/html/markdown.rs | 20 +----------
 src/librustdoc/html/render.rs   | 60 +++++++++++++++++++--------------
 2 files changed, 36 insertions(+), 44 deletions(-)

diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 5a7deb651b00d..74413a7f905d4 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -785,10 +785,6 @@ impl MarkdownSummaryLine<'_> {
 }
 
 pub fn plain_summary_line(md: &str) -> String {
-    plain_summary_line_full(md, false)
-}
-
-pub fn plain_summary_line_full(md: &str, limit_length: bool) -> String {
     struct ParserWrapper<'a> {
         inner: Parser<'a>,
         is_in: isize,
@@ -834,21 +830,7 @@ pub fn plain_summary_line_full(md: &str, limit_length: bool) -> String {
             s.push_str(&t);
         }
     }
-    if limit_length && s.chars().count() > 60 {
-        let mut len = 0;
-        let mut ret = s.split_whitespace()
-                       .take_while(|p| {
-                           // + 1 for the added character after the word.
-                           len += p.chars().count() + 1;
-                           len < 60
-                       })
-                       .collect::<Vec<_>>()
-                       .join(" ");
-        ret.push('…');
-        ret
-    } else {
-        s
-    }
+    s
 }
 
 pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index faf4f46ca5495..2a4a2fcea5838 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -732,7 +732,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
                 ty: item.type_(),
                 name: item.name.clone().unwrap(),
                 path: fqp[..fqp.len() - 1].join("::"),
-                desc: plain_summary_line_short(item.doc_value()),
+                desc: shorten(plain_summary_line(item.doc_value())),
                 parent: Some(did),
                 parent_idx: None,
                 search_type: get_index_search_type(&item),
@@ -770,7 +770,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
     }
 
     let crate_doc = krate.module.as_ref().map(|module| {
-        plain_summary_line_short(module.doc_value())
+        shorten(plain_summary_line(module.doc_value()))
     }).unwrap_or(String::new());
 
     let mut crate_data = BTreeMap::new();
@@ -1482,7 +1482,7 @@ impl DocFolder for Cache {
                             ty: item.type_(),
                             name: s.to_string(),
                             path: path.join("::"),
-                            desc: plain_summary_line_short(item.doc_value()),
+                            desc: shorten(plain_summary_line(item.doc_value())),
                             parent,
                             parent_idx: None,
                             search_type: get_index_search_type(&item),
@@ -1664,7 +1664,7 @@ impl Cache {
                                 ty: item.type_(),
                                 name: item_name.to_string(),
                                 path: path.clone(),
-                                desc: plain_summary_line_short(item.doc_value()),
+                                desc: shorten(plain_summary_line(item.doc_value())),
                                 parent: None,
                                 parent_idx: None,
                                 search_type: get_index_search_type(&item),
@@ -2360,29 +2360,39 @@ fn full_path(cx: &Context, item: &clean::Item) -> String {
     s
 }
 
-fn shorter(s: Option<&str>) -> String {
-    match s {
-        Some(s) => s.lines()
-            .skip_while(|s| s.chars().all(|c| c.is_whitespace()))
-            .take_while(|line|{
-            (*line).chars().any(|chr|{
-                !chr.is_whitespace()
-            })
-        }).collect::<Vec<_>>().join("\n"),
-        None => String::new()
-    }
-}
-
 #[inline]
 fn plain_summary_line(s: Option<&str>) -> String {
-    let line = shorter(s).replace("\n", " ");
-    markdown::plain_summary_line_full(&line[..], false)
-}
-
-#[inline]
-fn plain_summary_line_short(s: Option<&str>) -> String {
-    let line = shorter(s).replace("\n", " ");
-    markdown::plain_summary_line_full(&line[..], true)
+    let s = s.unwrap_or("");
+    // This essentially gets the first paragraph of text in one line.
+    let mut line = s.lines()
+        .skip_while(|line| line.chars().all(|c| c.is_whitespace()))
+        .take_while(|line| line.chars().any(|c| !c.is_whitespace()))
+        .fold(String::new(), |mut acc, line| {
+            acc.push_str(line);
+            acc.push(' ');
+            acc
+        });
+    // remove final whitespace
+    line.pop();
+    markdown::plain_summary_line(&line[..])
+}
+
+fn shorten(s: String) -> String {
+    if s.chars().count() > 60 {
+        let mut len = 0;
+        let mut ret = s.split_whitespace()
+                        .take_while(|p| {
+                            // + 1 for the added character after the word.
+                            len += p.chars().count() + 1;
+                            len < 60
+                        })
+                        .collect::<Vec<_>>()
+                        .join(" ");
+        ret.push('…');
+        ret
+    } else {
+        s
+    }
 }
 
 fn document(w: &mut fmt::Formatter<'_>, cx: &Context, item: &clean::Item) -> fmt::Result {

From 61ff27aa1cc71042a7f3699713d38b1d1ed2b4c5 Mon Sep 17 00:00:00 2001
From: Philip Craig <philipjcraig@gmail.com>
Date: Tue, 27 Aug 2019 10:34:28 +1000
Subject: [PATCH 279/943] debuginfo: always include disambiguator in type names

---
 .../debuginfo/type_names.rs                    | 18 ++++++++----------
 src/test/debuginfo/generator-objects.rs        | 16 ++++++++--------
 src/test/debuginfo/issue-57822.rs              |  4 ++--
 3 files changed, 18 insertions(+), 20 deletions(-)

diff --git a/src/librustc_codegen_ssa/debuginfo/type_names.rs b/src/librustc_codegen_ssa/debuginfo/type_names.rs
index b7c782528de0c..9b5ad94ecd7cb 100644
--- a/src/librustc_codegen_ssa/debuginfo/type_names.rs
+++ b/src/librustc_codegen_ssa/debuginfo/type_names.rs
@@ -191,18 +191,16 @@ pub fn push_debuginfo_type_name<'tcx>(
             visited.remove(t);
         },
         ty::Closure(def_id, ..) => {
-            output.push_str("closure");
-            let disambiguator = tcx.def_key(def_id).disambiguated_data.disambiguator;
-            if disambiguator != 0 {
-                output.push_str(&format!("-{}", disambiguator));
-            }
+            output.push_str(&format!(
+                "closure-{}",
+                tcx.def_key(def_id).disambiguated_data.disambiguator
+            ));
         }
         ty::Generator(def_id, ..) => {
-            output.push_str("generator");
-            let disambiguator = tcx.def_key(def_id).disambiguated_data.disambiguator;
-            if disambiguator != 0 {
-                output.push_str(&format!("-{}", disambiguator));
-            }
+            output.push_str(&format!(
+                "generator-{}",
+                tcx.def_key(def_id).disambiguated_data.disambiguator
+            ));
         }
         ty::Error |
         ty::Infer(_) |
diff --git a/src/test/debuginfo/generator-objects.rs b/src/test/debuginfo/generator-objects.rs
index c6f98e5782b1f..bfa7a05cad057 100644
--- a/src/test/debuginfo/generator-objects.rs
+++ b/src/test/debuginfo/generator-objects.rs
@@ -10,31 +10,31 @@
 
 // gdb-command:run
 // gdb-command:print b
-// gdb-check:$1 = generator_objects::main::generator {__0: 0x[...], <<variant>>: {__state: 0, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {[...]}, 4: generator_objects::main::generator::Suspend1 {[...]}}}
+// gdb-check:$1 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 0, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}}
 // gdb-command:continue
 // gdb-command:print b
-// gdb-check:$2 = generator_objects::main::generator {__0: 0x[...], <<variant>>: {__state: 3, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {c: 6, d: 7}, 4: generator_objects::main::generator::Suspend1 {[...]}}}
+// gdb-check:$2 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 3, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {c: 6, d: 7}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}}
 // gdb-command:continue
 // gdb-command:print b
-// gdb-check:$3 = generator_objects::main::generator {__0: 0x[...], <<variant>>: {__state: 4, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {[...]}, 4: generator_objects::main::generator::Suspend1 {c: 7, d: 8}}}
+// gdb-check:$3 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 4, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {c: 7, d: 8}}}
 // gdb-command:continue
 // gdb-command:print b
-// gdb-check:$4 = generator_objects::main::generator {__0: 0x[...], <<variant>>: {__state: 1, 0: generator_objects::main::generator::Unresumed, 1: generator_objects::main::generator::Returned, 2: generator_objects::main::generator::Panicked, 3: generator_objects::main::generator::Suspend0 {[...]}, 4: generator_objects::main::generator::Suspend1 {[...]}}}
+// gdb-check:$4 = generator_objects::main::generator-0 {__0: 0x[...], <<variant>>: {__state: 1, 0: generator_objects::main::generator-0::Unresumed, 1: generator_objects::main::generator-0::Returned, 2: generator_objects::main::generator-0::Panicked, 3: generator_objects::main::generator-0::Suspend0 {[...]}, 4: generator_objects::main::generator-0::Suspend1 {[...]}}}
 
 // === LLDB TESTS ==================================================================================
 
 // lldb-command:run
 // lldb-command:print b
-// lldbg-check:(generator_objects::main::generator) $0 = generator(&0x[...])
+// lldbg-check:(generator_objects::main::generator-0) $0 = generator-0(&0x[...])
 // lldb-command:continue
 // lldb-command:print b
-// lldbg-check:(generator_objects::main::generator) $1 = generator(&0x[...])
+// lldbg-check:(generator_objects::main::generator-0) $1 = generator-0(&0x[...])
 // lldb-command:continue
 // lldb-command:print b
-// lldbg-check:(generator_objects::main::generator) $2 = generator(&0x[...])
+// lldbg-check:(generator_objects::main::generator-0) $2 = generator-0(&0x[...])
 // lldb-command:continue
 // lldb-command:print b
-// lldbg-check:(generator_objects::main::generator) $3 = generator(&0x[...])
+// lldbg-check:(generator_objects::main::generator-0) $3 = generator-0(&0x[...])
 
 #![feature(omit_gdb_pretty_printer_section, generators, generator_trait)]
 #![omit_gdb_pretty_printer_section]
diff --git a/src/test/debuginfo/issue-57822.rs b/src/test/debuginfo/issue-57822.rs
index ba5e8e0f2192a..f18e41db0e6ba 100644
--- a/src/test/debuginfo/issue-57822.rs
+++ b/src/test/debuginfo/issue-57822.rs
@@ -13,7 +13,7 @@
 // gdb-command:run
 
 // gdb-command:print g
-// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure (1))
+// gdb-check:$1 = issue_57822::main::closure-1 (issue_57822::main::closure-0 (1))
 
 // gdb-command:print b
 // gdb-check:$2 = issue_57822::main::generator-3 {__0: issue_57822::main::generator-2 {__0: 2, <<variant>>: {[...]}}, <<variant>>: {[...]}}
@@ -23,7 +23,7 @@
 // lldb-command:run
 
 // lldb-command:print g
-// lldbg-check:(issue_57822::main::closure-1) $0 = closure-1(closure(1))
+// lldbg-check:(issue_57822::main::closure-1) $0 = closure-1(closure-0(1))
 
 // lldb-command:print b
 // lldbg-check:(issue_57822::main::generator-3) $1 = generator-3(generator-2(2))

From b2b9b81c9a69ba1bd35e042122b4b132dd6e1e6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 26 Aug 2019 17:46:14 -0700
Subject: [PATCH 280/943] Account for doc comments coming from proc macros
 without spans

---
 .../passes/check_code_block_syntax.rs         |  2 +-
 .../passes/collect_intra_doc_links.rs         |  4 ++--
 src/librustdoc/passes/mod.rs                  | 21 ++++++++++---------
 3 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 357e17d2d1bc4..67aa014a788f2 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -69,7 +69,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
                 // We couldn't calculate the span of the markdown block that had the error, so our
                 // diagnostics are going to be a bit lacking.
                 let mut diag = self.cx.sess().struct_span_warn(
-                    super::span_of_attrs(&item.attrs),
+                    super::span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
                     "doc comment contains an invalid Rust code block",
                 );
 
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index c73c46472d804..2951b2ccb2af9 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -465,7 +465,7 @@ fn resolution_failure(
         }
     };
     let attrs = &item.attrs;
-    let sp = span_of_attrs(attrs);
+    let sp = span_of_attrs(attrs).unwrap_or(item.source.span());
 
     let mut diag = cx.tcx.struct_span_lint_hir(
         lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
@@ -517,7 +517,7 @@ fn ambiguity_error(
         }
     };
     let attrs = &item.attrs;
-    let sp = span_of_attrs(attrs);
+    let sp = span_of_attrs(attrs).unwrap_or(item.source.span());
 
     let mut msg = format!("`{}` is ", path_str);
 
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 641a6df221446..49a34c7e46281 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -339,7 +339,7 @@ pub fn look_for_tests<'tcx>(
     find_testable_code(&dox, &mut tests, ErrorCodes::No);
 
     if check_missing_code == true && tests.found_tests == 0 {
-        let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span());
+        let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span());
         let mut diag = cx.tcx.struct_span_lint_hir(
             lint::builtin::MISSING_DOC_CODE_EXAMPLES,
             hir_id,
@@ -352,20 +352,23 @@ pub fn look_for_tests<'tcx>(
         let mut diag = cx.tcx.struct_span_lint_hir(
             lint::builtin::PRIVATE_DOC_TESTS,
             hir_id,
-            span_of_attrs(&item.attrs),
+            span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
             "Documentation test in private item");
         diag.emit();
     }
 }
 
 /// Returns a span encompassing all the given attributes.
-crate fn span_of_attrs(attrs: &clean::Attributes) -> Span {
+crate fn span_of_attrs(attrs: &clean::Attributes) -> Option<Span> {
     if attrs.doc_strings.is_empty() {
-        return DUMMY_SP;
+        return None;
     }
     let start = attrs.doc_strings[0].span();
+    if start == DUMMY_SP {
+        return None;
+    }
     let end = attrs.doc_strings.last().expect("No doc strings provided").span();
-    start.to(end)
+    Some(start.to(end))
 }
 
 /// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code.
@@ -391,7 +394,7 @@ crate fn source_span_for_markdown_range(
     let snippet = cx
         .sess()
         .source_map()
-        .span_to_snippet(span_of_attrs(attrs))
+        .span_to_snippet(span_of_attrs(attrs)?)
         .ok()?;
 
     let starting_line = markdown[..md_range.start].matches('\n').count();
@@ -441,10 +444,8 @@ crate fn source_span_for_markdown_range(
         }
     }
 
-    let sp = span_of_attrs(attrs).from_inner(InnerSpan::new(
+    Some(span_of_attrs(attrs)?.from_inner(InnerSpan::new(
         md_range.start + start_bytes,
         md_range.end + start_bytes + end_bytes,
-    ));
-
-    Some(sp)
+    )))
 }

From 7ed542da7815070b4fc7aa87d53e5b97aa2e8828 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 26 Aug 2019 21:12:59 -0700
Subject: [PATCH 281/943] add regression test

---
 .../auxiliary/through-proc-macro-aux.rs       | 20 +++++++++++++++++++
 src/test/rustdoc/through-proc-macro.rs        | 12 +++++++++++
 2 files changed, 32 insertions(+)
 create mode 100644 src/test/rustdoc/auxiliary/through-proc-macro-aux.rs
 create mode 100644 src/test/rustdoc/through-proc-macro.rs

diff --git a/src/test/rustdoc/auxiliary/through-proc-macro-aux.rs b/src/test/rustdoc/auxiliary/through-proc-macro-aux.rs
new file mode 100644
index 0000000000000..5c4a01ee3a74a
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/through-proc-macro-aux.rs
@@ -0,0 +1,20 @@
+// force-host
+// no-prefer-dynamic
+#![crate_type = "proc-macro"]
+#![crate_name="some_macros"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn first(_attr: TokenStream, item: TokenStream) -> TokenStream {
+    item // This doesn't erase the spans.
+}
+
+#[proc_macro_attribute]
+pub fn second(_attr: TokenStream, item: TokenStream) -> TokenStream {
+    // Make a new `TokenStream` to erase the spans:
+    let mut out: TokenStream = TokenStream::new();
+    out.extend(item);
+    out
+}
diff --git a/src/test/rustdoc/through-proc-macro.rs b/src/test/rustdoc/through-proc-macro.rs
new file mode 100644
index 0000000000000..348c9eea2dcbf
--- /dev/null
+++ b/src/test/rustdoc/through-proc-macro.rs
@@ -0,0 +1,12 @@
+// aux-build:through-proc-macro-aux.rs
+// build-aux-docs
+#![warn(intra_doc_link_resolution_failure)]
+extern crate some_macros;
+
+#[some_macros::second]
+pub enum Boom {
+    /// [Oooops]
+    Bam,
+}
+
+fn main() {}

From 5cc1559c600f34f534fa3e0328ca1c2659562229 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 27 Aug 2019 10:14:07 +0200
Subject: [PATCH 282/943] token: refactor with is_non_raw_ident_where.

---
 src/libsyntax/parse/token.rs | 32 +++++++++++++-------------------
 1 file changed, 13 insertions(+), 19 deletions(-)

diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 1865f925165bd..dfea34c331ad4 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -409,7 +409,7 @@ impl Token {
     crate fn expect_lit(&self) -> Lit {
         match self.kind {
             Literal(lit) => lit,
-            _=> panic!("`expect_lit` called on non-literal"),
+            _ => panic!("`expect_lit` called on non-literal"),
         }
     }
 
@@ -457,6 +457,7 @@ impl Token {
     pub fn is_ident(&self) -> bool {
         self.ident().is_some()
     }
+
     /// Returns `true` if the token is a lifetime.
     crate fn is_lifetime(&self) -> bool {
         self.lifetime().is_some()
@@ -508,45 +509,38 @@ impl Token {
 
     /// Returns `true` if the token is a given keyword, `kw`.
     pub fn is_keyword(&self, kw: Symbol) -> bool {
-        self.ident().map(|(id, is_raw)| id.name == kw && !is_raw).unwrap_or(false)
+        self.is_non_raw_ident_where(|id| id.name == kw)
     }
 
     crate fn is_path_segment_keyword(&self) -> bool {
-        match self.ident() {
-            Some((id, false)) => id.is_path_segment_keyword(),
-            _ => false,
-        }
+        self.is_non_raw_ident_where(ast::Ident::is_path_segment_keyword)
     }
 
     // Returns true for reserved identifiers used internally for elided lifetimes,
     // unnamed method parameters, crate root module, error recovery etc.
     crate fn is_special_ident(&self) -> bool {
-        match self.ident() {
-            Some((id, false)) => id.is_special(),
-            _ => false,
-        }
+        self.is_non_raw_ident_where(ast::Ident::is_special)
     }
 
     /// Returns `true` if the token is a keyword used in the language.
     crate fn is_used_keyword(&self) -> bool {
-        match self.ident() {
-            Some((id, false)) => id.is_used_keyword(),
-            _ => false,
-        }
+        self.is_non_raw_ident_where(ast::Ident::is_used_keyword)
     }
 
     /// Returns `true` if the token is a keyword reserved for possible future use.
     crate fn is_unused_keyword(&self) -> bool {
-        match self.ident() {
-            Some((id, false)) => id.is_unused_keyword(),
-            _ => false,
-        }
+        self.is_non_raw_ident_where(ast::Ident::is_unused_keyword)
     }
 
     /// Returns `true` if the token is either a special identifier or a keyword.
     pub fn is_reserved_ident(&self) -> bool {
+        self.is_non_raw_ident_where(ast::Ident::is_reserved)
+    }
+
+    /// Returns `true` if the token is a non-raw identifier for which `pred` holds.
+    fn is_non_raw_ident_where(&self, pred: impl FnOnce(ast::Ident) -> bool) -> bool {
         match self.ident() {
-            Some((id, false)) => id.is_reserved(),
+            Some((id, false)) => pred(id),
             _ => false,
         }
     }

From e49b9581baba9d89519d17ac0d8400b6ae77e754 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 27 Aug 2019 10:21:41 +0200
Subject: [PATCH 283/943] Simplify with Symbol/Token::is_book_lit.

---
 src/libsyntax/parse/literal.rs     |  4 ++--
 src/libsyntax/parse/parser/path.rs |  2 +-
 src/libsyntax/parse/token.rs       | 11 +++++++----
 src/libsyntax_pos/symbol.rs        |  5 +++++
 4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/libsyntax/parse/literal.rs b/src/libsyntax/parse/literal.rs
index 6409acba573ad..36233de3cfb57 100644
--- a/src/libsyntax/parse/literal.rs
+++ b/src/libsyntax/parse/literal.rs
@@ -104,7 +104,7 @@ impl LitKind {
 
         Ok(match kind {
             token::Bool => {
-                assert!(symbol == kw::True || symbol == kw::False);
+                assert!(symbol.is_bool_lit());
                 LitKind::Bool(symbol == kw::True)
             }
             token::Byte => return unescape_byte(&symbol.as_str())
@@ -261,7 +261,7 @@ impl Lit {
     /// Converts arbitrary token into an AST literal.
     crate fn from_token(token: &Token) -> Result<Lit, LitError> {
         let lit = match token.kind {
-            token::Ident(name, false) if name == kw::True || name == kw::False =>
+            token::Ident(name, false) if name.is_bool_lit() =>
                 token::Lit::new(token::Bool, name, None),
             token::Literal(lit) =>
                 lit,
diff --git a/src/libsyntax/parse/parser/path.rs b/src/libsyntax/parse/parser/path.rs
index 3eb4d45045a9e..d4b13cc2e0121 100644
--- a/src/libsyntax/parse/parser/path.rs
+++ b/src/libsyntax/parse/parser/path.rs
@@ -423,7 +423,7 @@ impl<'a> Parser<'a> {
                     // FIXME(const_generics): to distinguish between idents for types and consts,
                     // we should introduce a GenericArg::Ident in the AST and distinguish when
                     // lowering to the HIR. For now, idents for const args are not permitted.
-                    if self.token.is_keyword(kw::True) || self.token.is_keyword(kw::False) {
+                    if self.token.is_bool_lit() {
                         self.parse_literal_maybe_minus()?
                     } else {
                         return Err(
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index dfea34c331ad4..fe3b51aa246b8 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -417,10 +417,8 @@ impl Token {
     /// for example a '-42', or one of the boolean idents).
     crate fn can_begin_literal_or_bool(&self) -> bool {
         match self.kind {
-            Literal(..)  => true,
-            BinOp(Minus) => true,
-            Ident(name, false) if name == kw::True => true,
-            Ident(name, false) if name == kw::False => true,
+            Literal(..) | BinOp(Minus) => true,
+            Ident(name, false) if name.is_bool_lit() => true,
             Interpolated(ref nt) => match **nt {
                 NtLiteral(..) => true,
                 _             => false,
@@ -537,6 +535,11 @@ impl Token {
         self.is_non_raw_ident_where(ast::Ident::is_reserved)
     }
 
+    /// Returns `true` if the token is the identifier `true` or `false`.
+    crate fn is_bool_lit(&self) -> bool {
+        self.is_non_raw_ident_where(|id| id.name.is_bool_lit())
+    }
+
     /// Returns `true` if the token is a non-raw identifier for which `pred` holds.
     fn is_non_raw_ident_where(&self, pred: impl FnOnce(ast::Ident) -> bool) -> bool {
         match self.ident() {
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 0b8f16bbc3b99..856857f74e352 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -1063,6 +1063,11 @@ impl Symbol {
         self == kw::DollarCrate
     }
 
+    /// Returns `true` if the symbol is `true` or `false`.
+    pub fn is_bool_lit(self) -> bool {
+        self == kw::True || self == kw::False
+    }
+
     /// This symbol can be a raw identifier.
     pub fn can_be_raw(self) -> bool {
         self != kw::Invalid && self != kw::Underscore && !self.is_path_segment_keyword()

From f908aa9e8000dd7fd2c3de54fe1d914fddf4fe92 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 27 Aug 2019 13:04:48 +0200
Subject: [PATCH 284/943] recover on 'mut ' and improve recovery for keywords.

---
 src/libsyntax/parse/parser/pat.rs             | 136 ++++++++++++++----
 .../keyword-extern-as-identifier-pat.rs       |   2 +-
 .../keyword-extern-as-identifier-pat.stderr   |   8 +-
 src/test/ui/parser/issue-32501.rs             |   3 +-
 src/test/ui/parser/issue-32501.stderr         |   6 +-
 src/test/ui/parser/keyword-abstract.rs        |   2 +-
 src/test/ui/parser/keyword-abstract.stderr    |   8 +-
 .../ui/parser/keyword-as-as-identifier.rs     |   2 +-
 .../ui/parser/keyword-as-as-identifier.stderr |   8 +-
 .../ui/parser/keyword-break-as-identifier.rs  |   2 +-
 .../parser/keyword-break-as-identifier.stderr |   8 +-
 .../ui/parser/keyword-const-as-identifier.rs  |   2 +-
 .../parser/keyword-const-as-identifier.stderr |   8 +-
 .../parser/keyword-continue-as-identifier.rs  |   2 +-
 .../keyword-continue-as-identifier.stderr     |   8 +-
 .../ui/parser/keyword-else-as-identifier.rs   |   2 +-
 .../parser/keyword-else-as-identifier.stderr  |   8 +-
 .../ui/parser/keyword-enum-as-identifier.rs   |   2 +-
 .../parser/keyword-enum-as-identifier.stderr  |   8 +-
 src/test/ui/parser/keyword-final.rs           |   2 +-
 src/test/ui/parser/keyword-final.stderr       |   8 +-
 .../ui/parser/keyword-fn-as-identifier.rs     |   2 +-
 .../ui/parser/keyword-fn-as-identifier.stderr |   8 +-
 .../ui/parser/keyword-for-as-identifier.rs    |   2 +-
 .../parser/keyword-for-as-identifier.stderr   |   8 +-
 .../ui/parser/keyword-if-as-identifier.rs     |   2 +-
 .../ui/parser/keyword-if-as-identifier.stderr |   8 +-
 .../ui/parser/keyword-impl-as-identifier.rs   |   2 +-
 .../parser/keyword-impl-as-identifier.stderr  |   8 +-
 .../ui/parser/keyword-let-as-identifier.rs    |   2 +-
 .../parser/keyword-let-as-identifier.stderr   |   8 +-
 .../ui/parser/keyword-loop-as-identifier.rs   |   2 +-
 .../parser/keyword-loop-as-identifier.stderr  |   8 +-
 .../ui/parser/keyword-match-as-identifier.rs  |   2 +-
 .../parser/keyword-match-as-identifier.stderr |   8 +-
 .../ui/parser/keyword-mod-as-identifier.rs    |   2 +-
 .../parser/keyword-mod-as-identifier.stderr   |   8 +-
 .../ui/parser/keyword-move-as-identifier.rs   |   2 +-
 .../parser/keyword-move-as-identifier.stderr  |   8 +-
 src/test/ui/parser/keyword-override.rs        |   2 +-
 src/test/ui/parser/keyword-override.stderr    |   8 +-
 .../ui/parser/keyword-pub-as-identifier.rs    |   2 +-
 .../parser/keyword-pub-as-identifier.stderr   |   8 +-
 .../ui/parser/keyword-return-as-identifier.rs |   2 +-
 .../keyword-return-as-identifier.stderr       |   8 +-
 .../ui/parser/keyword-static-as-identifier.rs |   2 +-
 .../keyword-static-as-identifier.stderr       |   8 +-
 .../ui/parser/keyword-struct-as-identifier.rs |   2 +-
 .../keyword-struct-as-identifier.stderr       |   8 +-
 .../ui/parser/keyword-trait-as-identifier.rs  |   2 +-
 .../parser/keyword-trait-as-identifier.stderr |   8 +-
 .../keyword-try-as-identifier-edition2018.rs  |   2 +-
 ...yword-try-as-identifier-edition2018.stderr |   8 +-
 .../ui/parser/keyword-type-as-identifier.rs   |   2 +-
 .../parser/keyword-type-as-identifier.stderr  |   8 +-
 src/test/ui/parser/keyword-typeof.rs          |   2 +-
 src/test/ui/parser/keyword-typeof.stderr      |   8 +-
 .../ui/parser/keyword-unsafe-as-identifier.rs |   2 +-
 .../keyword-unsafe-as-identifier.stderr       |   8 +-
 .../ui/parser/keyword-use-as-identifier.rs    |   2 +-
 .../parser/keyword-use-as-identifier.stderr   |   8 +-
 .../ui/parser/keyword-where-as-identifier.rs  |   2 +-
 .../parser/keyword-where-as-identifier.stderr |   8 +-
 .../ui/parser/keyword-while-as-identifier.rs  |   2 +-
 .../parser/keyword-while-as-identifier.stderr |   8 +-
 src/test/ui/parser/mut-patterns.rs            |  30 +++-
 src/test/ui/parser/mut-patterns.stderr        |  68 ++++++++-
 src/test/ui/reserved/reserved-become.rs       |   2 +-
 src/test/ui/reserved/reserved-become.stderr   |   8 +-
 src/test/ui/self/self_type_keyword.rs         |   3 +-
 src/test/ui/self/self_type_keyword.stderr     |  30 ++--
 71 files changed, 449 insertions(+), 147 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 78c9a289b3702..7b228a700a748 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -4,6 +4,7 @@ use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
 use crate::ptr::P;
 use crate::ast::{self, Attribute, Pat, PatKind, FieldPat, RangeEnd, RangeSyntax, Mac};
 use crate::ast::{BindingMode, Ident, Mutability, Path, QSelf, Expr, ExprKind};
+use crate::mut_visit::{noop_visit_pat, MutVisitor};
 use crate::parse::token::{self};
 use crate::print::pprust;
 use crate::source_map::{respan, Span, Spanned};
@@ -273,7 +274,7 @@ impl<'a> Parser<'a> {
                 // Parse _
                 PatKind::Wild
             } else if self.eat_keyword(kw::Mut) {
-                self.recover_pat_ident_mut_first()?
+                self.parse_pat_ident_mut()?
             } else if self.eat_keyword(kw::Ref) {
                 // Parse ref ident @ pat / ref mut ident @ pat
                 let mutbl = self.parse_mutability();
@@ -281,13 +282,12 @@ impl<'a> Parser<'a> {
             } else if self.eat_keyword(kw::Box) {
                 // Parse `box pat`
                 PatKind::Box(self.parse_pat_with_range_pat(false, None)?)
-            } else if self.token.is_ident() && !self.token.is_reserved_ident() &&
-                      self.parse_as_ident() {
+            } else if self.can_be_ident_pat() {
                 // Parse `ident @ pat`
                 // This can give false positives and parse nullary enums,
                 // they are dealt with later in resolve.
                 self.parse_pat_ident(BindingMode::ByValue(Mutability::Immutable))?
-            } else if self.token.is_path_start() {
+            } else if self.is_start_of_pat_with_path() {
                 // Parse pattern starting with a path
                 let (qself, path) = if self.eat_lt() {
                     // Parse a qualified path
@@ -384,24 +384,85 @@ impl<'a> Parser<'a> {
         })
     }
 
+    fn parse_pat_ident_mut(&mut self) -> PResult<'a, PatKind> {
+        let mut_span = self.prev_span;
+
+        if self.eat_keyword(kw::Ref) {
+            return self.recover_mut_ref_ident(mut_span)
+        }
+
+        self.recover_additional_muts();
+
+        let mut pat = self.parse_pat(Some("identifier"))?;
+
+        // Add `mut` to any binding in the parsed pattern.
+        struct AddMut;
+        impl MutVisitor for AddMut {
+            fn visit_pat(&mut self, pat: &mut P<Pat>) {
+                if let PatKind::Ident(BindingMode::ByValue(ref mut m), ..) = pat.node {
+                    *m = Mutability::Mutable;
+                }
+                noop_visit_pat(pat, self);
+            }
+        }
+        AddMut.visit_pat(&mut pat);
+
+        // Unwrap; If we don't have `mut $ident`, error.
+        let pat = pat.into_inner();
+        match &pat.node {
+            PatKind::Ident(..) => {}
+            _ => self.ban_mut_general_pat(mut_span, &pat),
+        }
+
+        Ok(pat.node)
+    }
+
     /// Recover on `mut ref? ident @ pat` and suggest
     /// that the order of `mut` and `ref` is incorrect.
-    fn recover_pat_ident_mut_first(&mut self) -> PResult<'a, PatKind> {
-        let mutref_span = self.prev_span.to(self.token.span);
-        let binding_mode = if self.eat_keyword(kw::Ref) {
-            self.struct_span_err(mutref_span, "the order of `mut` and `ref` is incorrect")
-                .span_suggestion(
-                    mutref_span,
-                    "try switching the order",
-                    "ref mut".into(),
-                    Applicability::MachineApplicable
-                )
-                .emit();
-            BindingMode::ByRef(Mutability::Mutable)
-        } else {
-            BindingMode::ByValue(Mutability::Mutable)
-        };
-        self.parse_pat_ident(binding_mode)
+    fn recover_mut_ref_ident(&mut self, lo: Span) -> PResult<'a, PatKind> {
+        let mutref_span = lo.to(self.prev_span);
+        self.struct_span_err(mutref_span, "the order of `mut` and `ref` is incorrect")
+            .span_suggestion(
+                mutref_span,
+                "try switching the order",
+                "ref mut".into(),
+                Applicability::MachineApplicable
+            )
+            .emit();
+
+        self.parse_pat_ident(BindingMode::ByRef(Mutability::Mutable))
+    }
+
+    /// Error on `mut $pat` where `$pat` is not an ident.
+    fn ban_mut_general_pat(&self, lo: Span, pat: &Pat) {
+        let span = lo.to(pat.span);
+        self.struct_span_err(span, "`mut` must be attached to each individual binding")
+            .span_suggestion(
+                span,
+                "add `mut` to each binding",
+                pprust::pat_to_string(&pat),
+                Applicability::MachineApplicable,
+            )
+            .emit();
+    }
+
+    /// Eat any extraneous `mut`s and error + recover if we ate any.
+    fn recover_additional_muts(&mut self) {
+        let lo = self.token.span;
+        while self.eat_keyword(kw::Mut) {}
+        if lo == self.token.span {
+            return;
+        }
+
+        let span = lo.to(self.prev_span);
+        self.struct_span_err(span, "`mut` on a binding may not be repeated")
+            .span_suggestion(
+                span,
+                "remove the additional `mut`s",
+                String::new(),
+                Applicability::MachineApplicable,
+            )
+            .emit();
     }
 
     /// Parse macro invocation
@@ -479,17 +540,6 @@ impl<'a> Parser<'a> {
         Err(err)
     }
 
-    // Helper function to decide whether to parse as ident binding
-    // or to try to do something more complex like range patterns.
-    fn parse_as_ident(&mut self) -> bool {
-        self.look_ahead(1, |t| match t.kind {
-            token::OpenDelim(token::Paren) | token::OpenDelim(token::Brace) |
-            token::DotDotDot | token::DotDotEq | token::DotDot |
-            token::ModSep | token::Not => false,
-            _ => true,
-        })
-    }
-
     /// Is the current token suitable as the start of a range patterns end?
     fn is_pat_range_end_start(&self) -> bool {
         self.token.is_path_start() // e.g. `MY_CONST`;
@@ -563,6 +613,30 @@ impl<'a> Parser<'a> {
         }
     }
 
+    /// Is this the start of a pattern beginning with a path?
+    fn is_start_of_pat_with_path(&mut self) -> bool {
+        self.check_path()
+        // Just for recovery (see `can_be_ident`).
+        || self.token.is_ident() && !self.token.is_bool_lit() && !self.token.is_keyword(kw::In)
+    }
+
+    /// Would `parse_pat_ident` be appropriate here?
+    fn can_be_ident_pat(&mut self) -> bool {
+        self.check_ident()
+        && !self.token.is_bool_lit() // Avoid `true` or `false` as a binding as it is a literal.
+        && !self.token.is_path_segment_keyword() // Avoid e.g. `Self` as it is a path.
+        // Avoid `in`. Due to recovery in the list parser this messes with `for ( $pat in $expr )`.
+        && !self.token.is_keyword(kw::In)
+        && self.look_ahead(1, |t| match t.kind { // Try to do something more complex?
+            token::OpenDelim(token::Paren) // A tuple struct pattern.
+            | token::OpenDelim(token::Brace) // A struct pattern.
+            | token::DotDotDot | token::DotDotEq | token::DotDot // A range pattern.
+            | token::ModSep // A tuple / struct variant pattern.
+            | token::Not => false, // A macro expanding to a pattern.
+            _ => true,
+        })
+    }
+
     /// Parses `ident` or `ident @ pat`.
     /// Used by the copy foo and ref foo patterns to give a good
     /// error message when parsing mistakes like `ref foo(a, b)`.
diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.rs b/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.rs
index f9b6bad7c2552..8a420f7203cac 100644
--- a/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.rs
+++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.rs
@@ -1,3 +1,3 @@
 fn main() {
-    let extern = 0; //~ ERROR expected pattern, found keyword `extern`
+    let extern = 0; //~ ERROR expected identifier, found keyword `extern`
 }
diff --git a/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.stderr b/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.stderr
index d7b9ad2abe97a..73ac113f1b1e0 100644
--- a/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.stderr
+++ b/src/test/ui/keyword/extern/keyword-extern-as-identifier-pat.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `extern`
+error: expected identifier, found keyword `extern`
   --> $DIR/keyword-extern-as-identifier-pat.rs:2:9
    |
 LL |     let extern = 0;
-   |         ^^^^^^ expected pattern
+   |         ^^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#extern = 0;
+   |         ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/issue-32501.rs b/src/test/ui/parser/issue-32501.rs
index 9c01a5c6d20e3..695baf8187276 100644
--- a/src/test/ui/parser/issue-32501.rs
+++ b/src/test/ui/parser/issue-32501.rs
@@ -4,5 +4,6 @@ fn main() {
     let _ = 0;
     let mut b = 0;
     let mut _b = 0;
-    let mut _ = 0; //~ ERROR expected identifier, found reserved identifier `_`
+    let mut _ = 0;
+    //~^ ERROR `mut` must be attached to each individual binding
 }
diff --git a/src/test/ui/parser/issue-32501.stderr b/src/test/ui/parser/issue-32501.stderr
index 97efb89593579..f5d3300cf9c56 100644
--- a/src/test/ui/parser/issue-32501.stderr
+++ b/src/test/ui/parser/issue-32501.stderr
@@ -1,8 +1,8 @@
-error: expected identifier, found reserved identifier `_`
-  --> $DIR/issue-32501.rs:7:13
+error: `mut` must be attached to each individual binding
+  --> $DIR/issue-32501.rs:7:9
    |
 LL |     let mut _ = 0;
-   |             ^ expected identifier, found reserved identifier
+   |         ^^^^^ help: add `mut` to each binding: `_`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-abstract.rs b/src/test/ui/parser/keyword-abstract.rs
index 890802ac134a0..570206575ab07 100644
--- a/src/test/ui/parser/keyword-abstract.rs
+++ b/src/test/ui/parser/keyword-abstract.rs
@@ -1,3 +1,3 @@
 fn main() {
-    let abstract = (); //~ ERROR expected pattern, found reserved keyword `abstract`
+    let abstract = (); //~ ERROR expected identifier, found reserved keyword `abstract`
 }
diff --git a/src/test/ui/parser/keyword-abstract.stderr b/src/test/ui/parser/keyword-abstract.stderr
index 2c79598a81b18..eb2c810099e16 100644
--- a/src/test/ui/parser/keyword-abstract.stderr
+++ b/src/test/ui/parser/keyword-abstract.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found reserved keyword `abstract`
+error: expected identifier, found reserved keyword `abstract`
   --> $DIR/keyword-abstract.rs:2:9
    |
 LL |     let abstract = ();
-   |         ^^^^^^^^ expected pattern
+   |         ^^^^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#abstract = ();
+   |         ^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-as-as-identifier.rs b/src/test/ui/parser/keyword-as-as-identifier.rs
index 23ff259db3048..cd47c8a3907d9 100644
--- a/src/test/ui/parser/keyword-as-as-identifier.rs
+++ b/src/test/ui/parser/keyword-as-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py as'
 
 fn main() {
-    let as = "foo"; //~ error: expected pattern, found keyword `as`
+    let as = "foo"; //~ error: expected identifier, found keyword `as`
 }
diff --git a/src/test/ui/parser/keyword-as-as-identifier.stderr b/src/test/ui/parser/keyword-as-as-identifier.stderr
index ef466488ad061..5648652be9bca 100644
--- a/src/test/ui/parser/keyword-as-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-as-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `as`
+error: expected identifier, found keyword `as`
   --> $DIR/keyword-as-as-identifier.rs:4:9
    |
 LL |     let as = "foo";
-   |         ^^ expected pattern
+   |         ^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#as = "foo";
+   |         ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-break-as-identifier.rs b/src/test/ui/parser/keyword-break-as-identifier.rs
index 5ee111d38c9c3..04b25a7aaf613 100644
--- a/src/test/ui/parser/keyword-break-as-identifier.rs
+++ b/src/test/ui/parser/keyword-break-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py break'
 
 fn main() {
-    let break = "foo"; //~ error: expected pattern, found keyword `break`
+    let break = "foo"; //~ error: expected identifier, found keyword `break`
 }
diff --git a/src/test/ui/parser/keyword-break-as-identifier.stderr b/src/test/ui/parser/keyword-break-as-identifier.stderr
index 690bd84221a94..820193db70b0f 100644
--- a/src/test/ui/parser/keyword-break-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-break-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `break`
+error: expected identifier, found keyword `break`
   --> $DIR/keyword-break-as-identifier.rs:4:9
    |
 LL |     let break = "foo";
-   |         ^^^^^ expected pattern
+   |         ^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#break = "foo";
+   |         ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-const-as-identifier.rs b/src/test/ui/parser/keyword-const-as-identifier.rs
index 48fc142cf64b1..6a2d926bf5796 100644
--- a/src/test/ui/parser/keyword-const-as-identifier.rs
+++ b/src/test/ui/parser/keyword-const-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py const'
 
 fn main() {
-    let const = "foo"; //~ error: expected pattern, found keyword `const`
+    let const = "foo"; //~ error: expected identifier, found keyword `const`
 }
diff --git a/src/test/ui/parser/keyword-const-as-identifier.stderr b/src/test/ui/parser/keyword-const-as-identifier.stderr
index 6da47f88d04e3..95b536c99c75a 100644
--- a/src/test/ui/parser/keyword-const-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-const-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `const`
+error: expected identifier, found keyword `const`
   --> $DIR/keyword-const-as-identifier.rs:4:9
    |
 LL |     let const = "foo";
-   |         ^^^^^ expected pattern
+   |         ^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#const = "foo";
+   |         ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-continue-as-identifier.rs b/src/test/ui/parser/keyword-continue-as-identifier.rs
index 06315a48349ff..cfdd62a2d1bce 100644
--- a/src/test/ui/parser/keyword-continue-as-identifier.rs
+++ b/src/test/ui/parser/keyword-continue-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py continue'
 
 fn main() {
-    let continue = "foo"; //~ error: expected pattern, found keyword `continue`
+    let continue = "foo"; //~ error: expected identifier, found keyword `continue`
 }
diff --git a/src/test/ui/parser/keyword-continue-as-identifier.stderr b/src/test/ui/parser/keyword-continue-as-identifier.stderr
index 4b0a659f9ad7e..6b24422a5557e 100644
--- a/src/test/ui/parser/keyword-continue-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-continue-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `continue`
+error: expected identifier, found keyword `continue`
   --> $DIR/keyword-continue-as-identifier.rs:4:9
    |
 LL |     let continue = "foo";
-   |         ^^^^^^^^ expected pattern
+   |         ^^^^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#continue = "foo";
+   |         ^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-else-as-identifier.rs b/src/test/ui/parser/keyword-else-as-identifier.rs
index 0c69105cf9457..f12dac3ff75eb 100644
--- a/src/test/ui/parser/keyword-else-as-identifier.rs
+++ b/src/test/ui/parser/keyword-else-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py else'
 
 fn main() {
-    let else = "foo"; //~ error: expected pattern, found keyword `else`
+    let else = "foo"; //~ error: expected identifier, found keyword `else`
 }
diff --git a/src/test/ui/parser/keyword-else-as-identifier.stderr b/src/test/ui/parser/keyword-else-as-identifier.stderr
index bec7b7ba01e12..f28635cd08cd6 100644
--- a/src/test/ui/parser/keyword-else-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-else-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `else`
+error: expected identifier, found keyword `else`
   --> $DIR/keyword-else-as-identifier.rs:4:9
    |
 LL |     let else = "foo";
-   |         ^^^^ expected pattern
+   |         ^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#else = "foo";
+   |         ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-enum-as-identifier.rs b/src/test/ui/parser/keyword-enum-as-identifier.rs
index d1675800a2791..fe66230d02830 100644
--- a/src/test/ui/parser/keyword-enum-as-identifier.rs
+++ b/src/test/ui/parser/keyword-enum-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py enum'
 
 fn main() {
-    let enum = "foo"; //~ error: expected pattern, found keyword `enum`
+    let enum = "foo"; //~ error: expected identifier, found keyword `enum`
 }
diff --git a/src/test/ui/parser/keyword-enum-as-identifier.stderr b/src/test/ui/parser/keyword-enum-as-identifier.stderr
index 51a834f797c32..fc54dce1b68f4 100644
--- a/src/test/ui/parser/keyword-enum-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-enum-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `enum`
+error: expected identifier, found keyword `enum`
   --> $DIR/keyword-enum-as-identifier.rs:4:9
    |
 LL |     let enum = "foo";
-   |         ^^^^ expected pattern
+   |         ^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#enum = "foo";
+   |         ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-final.rs b/src/test/ui/parser/keyword-final.rs
index e1cecd0e8e07a..a79a11032a018 100644
--- a/src/test/ui/parser/keyword-final.rs
+++ b/src/test/ui/parser/keyword-final.rs
@@ -1,3 +1,3 @@
 fn main() {
-    let final = (); //~ ERROR expected pattern, found reserved keyword `final`
+    let final = (); //~ ERROR expected identifier, found reserved keyword `final`
 }
diff --git a/src/test/ui/parser/keyword-final.stderr b/src/test/ui/parser/keyword-final.stderr
index e8372643be6b7..291710d05cbfd 100644
--- a/src/test/ui/parser/keyword-final.stderr
+++ b/src/test/ui/parser/keyword-final.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found reserved keyword `final`
+error: expected identifier, found reserved keyword `final`
   --> $DIR/keyword-final.rs:2:9
    |
 LL |     let final = ();
-   |         ^^^^^ expected pattern
+   |         ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#final = ();
+   |         ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-fn-as-identifier.rs b/src/test/ui/parser/keyword-fn-as-identifier.rs
index bca2d5996a54b..f30e115f7947e 100644
--- a/src/test/ui/parser/keyword-fn-as-identifier.rs
+++ b/src/test/ui/parser/keyword-fn-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py fn'
 
 fn main() {
-    let fn = "foo"; //~ error: expected pattern, found keyword `fn`
+    let fn = "foo"; //~ error: expected identifier, found keyword `fn`
 }
diff --git a/src/test/ui/parser/keyword-fn-as-identifier.stderr b/src/test/ui/parser/keyword-fn-as-identifier.stderr
index a071a40a70e0d..692f195b2888d 100644
--- a/src/test/ui/parser/keyword-fn-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-fn-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `fn`
+error: expected identifier, found keyword `fn`
   --> $DIR/keyword-fn-as-identifier.rs:4:9
    |
 LL |     let fn = "foo";
-   |         ^^ expected pattern
+   |         ^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#fn = "foo";
+   |         ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-for-as-identifier.rs b/src/test/ui/parser/keyword-for-as-identifier.rs
index ce49fd90d9101..9e8a2ad53420c 100644
--- a/src/test/ui/parser/keyword-for-as-identifier.rs
+++ b/src/test/ui/parser/keyword-for-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py for'
 
 fn main() {
-    let for = "foo"; //~ error: expected pattern, found keyword `for`
+    let for = "foo"; //~ error: expected identifier, found keyword `for`
 }
diff --git a/src/test/ui/parser/keyword-for-as-identifier.stderr b/src/test/ui/parser/keyword-for-as-identifier.stderr
index 090046cebdc56..bcaf421286e76 100644
--- a/src/test/ui/parser/keyword-for-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-for-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `for`
+error: expected identifier, found keyword `for`
   --> $DIR/keyword-for-as-identifier.rs:4:9
    |
 LL |     let for = "foo";
-   |         ^^^ expected pattern
+   |         ^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#for = "foo";
+   |         ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-if-as-identifier.rs b/src/test/ui/parser/keyword-if-as-identifier.rs
index a1302970689c4..0bd5756afce7f 100644
--- a/src/test/ui/parser/keyword-if-as-identifier.rs
+++ b/src/test/ui/parser/keyword-if-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py if'
 
 fn main() {
-    let if = "foo"; //~ error: expected pattern, found keyword `if`
+    let if = "foo"; //~ error: expected identifier, found keyword `if`
 }
diff --git a/src/test/ui/parser/keyword-if-as-identifier.stderr b/src/test/ui/parser/keyword-if-as-identifier.stderr
index 98bfdb46e9770..43fbcd7148a1d 100644
--- a/src/test/ui/parser/keyword-if-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-if-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `if`
+error: expected identifier, found keyword `if`
   --> $DIR/keyword-if-as-identifier.rs:4:9
    |
 LL |     let if = "foo";
-   |         ^^ expected pattern
+   |         ^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#if = "foo";
+   |         ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-impl-as-identifier.rs b/src/test/ui/parser/keyword-impl-as-identifier.rs
index 95a34483ad21a..df529bae07214 100644
--- a/src/test/ui/parser/keyword-impl-as-identifier.rs
+++ b/src/test/ui/parser/keyword-impl-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py impl'
 
 fn main() {
-    let impl = "foo"; //~ error: expected pattern, found keyword `impl`
+    let impl = "foo"; //~ error: expected identifier, found keyword `impl`
 }
diff --git a/src/test/ui/parser/keyword-impl-as-identifier.stderr b/src/test/ui/parser/keyword-impl-as-identifier.stderr
index 2672959b7c68e..01886eb45cb6d 100644
--- a/src/test/ui/parser/keyword-impl-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-impl-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `impl`
+error: expected identifier, found keyword `impl`
   --> $DIR/keyword-impl-as-identifier.rs:4:9
    |
 LL |     let impl = "foo";
-   |         ^^^^ expected pattern
+   |         ^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#impl = "foo";
+   |         ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-let-as-identifier.rs b/src/test/ui/parser/keyword-let-as-identifier.rs
index 07c0ddf8ce573..9b1183501b28d 100644
--- a/src/test/ui/parser/keyword-let-as-identifier.rs
+++ b/src/test/ui/parser/keyword-let-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py let'
 
 fn main() {
-    let let = "foo"; //~ error: expected pattern, found keyword `let`
+    let let = "foo"; //~ error: expected identifier, found keyword `let`
 }
diff --git a/src/test/ui/parser/keyword-let-as-identifier.stderr b/src/test/ui/parser/keyword-let-as-identifier.stderr
index 99dbc0530f3fe..f6c39077be23b 100644
--- a/src/test/ui/parser/keyword-let-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-let-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `let`
+error: expected identifier, found keyword `let`
   --> $DIR/keyword-let-as-identifier.rs:4:9
    |
 LL |     let let = "foo";
-   |         ^^^ expected pattern
+   |         ^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#let = "foo";
+   |         ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-loop-as-identifier.rs b/src/test/ui/parser/keyword-loop-as-identifier.rs
index 8643ffe434505..46914a19be2bd 100644
--- a/src/test/ui/parser/keyword-loop-as-identifier.rs
+++ b/src/test/ui/parser/keyword-loop-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py loop'
 
 fn main() {
-    let loop = "foo"; //~ error: expected pattern, found keyword `loop`
+    let loop = "foo"; //~ error: expected identifier, found keyword `loop`
 }
diff --git a/src/test/ui/parser/keyword-loop-as-identifier.stderr b/src/test/ui/parser/keyword-loop-as-identifier.stderr
index 783507eb35cd7..f0c282faa29f1 100644
--- a/src/test/ui/parser/keyword-loop-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-loop-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `loop`
+error: expected identifier, found keyword `loop`
   --> $DIR/keyword-loop-as-identifier.rs:4:9
    |
 LL |     let loop = "foo";
-   |         ^^^^ expected pattern
+   |         ^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#loop = "foo";
+   |         ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-match-as-identifier.rs b/src/test/ui/parser/keyword-match-as-identifier.rs
index 8ef6b6810a56b..d3cecb991b8f9 100644
--- a/src/test/ui/parser/keyword-match-as-identifier.rs
+++ b/src/test/ui/parser/keyword-match-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py match'
 
 fn main() {
-    let match = "foo"; //~ error: expected pattern, found keyword `match`
+    let match = "foo"; //~ error: expected identifier, found keyword `match`
 }
diff --git a/src/test/ui/parser/keyword-match-as-identifier.stderr b/src/test/ui/parser/keyword-match-as-identifier.stderr
index e56a115c91636..f1f4397d194f0 100644
--- a/src/test/ui/parser/keyword-match-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-match-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `match`
+error: expected identifier, found keyword `match`
   --> $DIR/keyword-match-as-identifier.rs:4:9
    |
 LL |     let match = "foo";
-   |         ^^^^^ expected pattern
+   |         ^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#match = "foo";
+   |         ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-mod-as-identifier.rs b/src/test/ui/parser/keyword-mod-as-identifier.rs
index 96bcdccf0a096..b9c7b6c78ed6c 100644
--- a/src/test/ui/parser/keyword-mod-as-identifier.rs
+++ b/src/test/ui/parser/keyword-mod-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py mod'
 
 fn main() {
-    let mod = "foo"; //~ error: expected pattern, found keyword `mod`
+    let mod = "foo"; //~ error: expected identifier, found keyword `mod`
 }
diff --git a/src/test/ui/parser/keyword-mod-as-identifier.stderr b/src/test/ui/parser/keyword-mod-as-identifier.stderr
index a8be2ceb037d6..65ae3baa8c21d 100644
--- a/src/test/ui/parser/keyword-mod-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-mod-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `mod`
+error: expected identifier, found keyword `mod`
   --> $DIR/keyword-mod-as-identifier.rs:4:9
    |
 LL |     let mod = "foo";
-   |         ^^^ expected pattern
+   |         ^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#mod = "foo";
+   |         ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-move-as-identifier.rs b/src/test/ui/parser/keyword-move-as-identifier.rs
index 2193af530bd7a..65be02e3c70cf 100644
--- a/src/test/ui/parser/keyword-move-as-identifier.rs
+++ b/src/test/ui/parser/keyword-move-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py move'
 
 fn main() {
-    let move = "foo"; //~ error: expected pattern, found keyword `move`
+    let move = "foo"; //~ error: expected identifier, found keyword `move`
 }
diff --git a/src/test/ui/parser/keyword-move-as-identifier.stderr b/src/test/ui/parser/keyword-move-as-identifier.stderr
index e0687e27eb585..216f7c931eea7 100644
--- a/src/test/ui/parser/keyword-move-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-move-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `move`
+error: expected identifier, found keyword `move`
   --> $DIR/keyword-move-as-identifier.rs:4:9
    |
 LL |     let move = "foo";
-   |         ^^^^ expected pattern
+   |         ^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#move = "foo";
+   |         ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-override.rs b/src/test/ui/parser/keyword-override.rs
index 948a20095f1ea..009bebd7ddba8 100644
--- a/src/test/ui/parser/keyword-override.rs
+++ b/src/test/ui/parser/keyword-override.rs
@@ -1,3 +1,3 @@
 fn main() {
-    let override = (); //~ ERROR expected pattern, found reserved keyword `override`
+    let override = (); //~ ERROR expected identifier, found reserved keyword `override`
 }
diff --git a/src/test/ui/parser/keyword-override.stderr b/src/test/ui/parser/keyword-override.stderr
index 1bfc6c9b3858d..3183fa510c2d1 100644
--- a/src/test/ui/parser/keyword-override.stderr
+++ b/src/test/ui/parser/keyword-override.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found reserved keyword `override`
+error: expected identifier, found reserved keyword `override`
   --> $DIR/keyword-override.rs:2:9
    |
 LL |     let override = ();
-   |         ^^^^^^^^ expected pattern
+   |         ^^^^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#override = ();
+   |         ^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-pub-as-identifier.rs b/src/test/ui/parser/keyword-pub-as-identifier.rs
index 2ed8cc6b268ca..2b2bb14118d7d 100644
--- a/src/test/ui/parser/keyword-pub-as-identifier.rs
+++ b/src/test/ui/parser/keyword-pub-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py pub'
 
 fn main() {
-    let pub = "foo"; //~ error: expected pattern, found keyword `pub`
+    let pub = "foo"; //~ error: expected identifier, found keyword `pub`
 }
diff --git a/src/test/ui/parser/keyword-pub-as-identifier.stderr b/src/test/ui/parser/keyword-pub-as-identifier.stderr
index 526ddcd6ee0ff..f81078b12bd3c 100644
--- a/src/test/ui/parser/keyword-pub-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-pub-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `pub`
+error: expected identifier, found keyword `pub`
   --> $DIR/keyword-pub-as-identifier.rs:4:9
    |
 LL |     let pub = "foo";
-   |         ^^^ expected pattern
+   |         ^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#pub = "foo";
+   |         ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-return-as-identifier.rs b/src/test/ui/parser/keyword-return-as-identifier.rs
index 920931b00f954..e1a2db5e4d82d 100644
--- a/src/test/ui/parser/keyword-return-as-identifier.rs
+++ b/src/test/ui/parser/keyword-return-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py return'
 
 fn main() {
-    let return = "foo"; //~ error: expected pattern, found keyword `return`
+    let return = "foo"; //~ error: expected identifier, found keyword `return`
 }
diff --git a/src/test/ui/parser/keyword-return-as-identifier.stderr b/src/test/ui/parser/keyword-return-as-identifier.stderr
index c0156a63fa9d1..8cc4d12fbbb9a 100644
--- a/src/test/ui/parser/keyword-return-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-return-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `return`
+error: expected identifier, found keyword `return`
   --> $DIR/keyword-return-as-identifier.rs:4:9
    |
 LL |     let return = "foo";
-   |         ^^^^^^ expected pattern
+   |         ^^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#return = "foo";
+   |         ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-static-as-identifier.rs b/src/test/ui/parser/keyword-static-as-identifier.rs
index 3ccbfccfc9394..423b9854b8aa1 100644
--- a/src/test/ui/parser/keyword-static-as-identifier.rs
+++ b/src/test/ui/parser/keyword-static-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py static'
 
 fn main() {
-    let static = "foo"; //~ error: expected pattern, found keyword `static`
+    let static = "foo"; //~ error: expected identifier, found keyword `static`
 }
diff --git a/src/test/ui/parser/keyword-static-as-identifier.stderr b/src/test/ui/parser/keyword-static-as-identifier.stderr
index 00a65977732f8..7d22bc97d66ae 100644
--- a/src/test/ui/parser/keyword-static-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-static-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `static`
+error: expected identifier, found keyword `static`
   --> $DIR/keyword-static-as-identifier.rs:4:9
    |
 LL |     let static = "foo";
-   |         ^^^^^^ expected pattern
+   |         ^^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#static = "foo";
+   |         ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-struct-as-identifier.rs b/src/test/ui/parser/keyword-struct-as-identifier.rs
index 69d8f19065533..18cfe11592aed 100644
--- a/src/test/ui/parser/keyword-struct-as-identifier.rs
+++ b/src/test/ui/parser/keyword-struct-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py struct'
 
 fn main() {
-    let struct = "foo"; //~ error: expected pattern, found keyword `struct`
+    let struct = "foo"; //~ error: expected identifier, found keyword `struct`
 }
diff --git a/src/test/ui/parser/keyword-struct-as-identifier.stderr b/src/test/ui/parser/keyword-struct-as-identifier.stderr
index b2d6639e72ecb..b109fa6247dcd 100644
--- a/src/test/ui/parser/keyword-struct-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-struct-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `struct`
+error: expected identifier, found keyword `struct`
   --> $DIR/keyword-struct-as-identifier.rs:4:9
    |
 LL |     let struct = "foo";
-   |         ^^^^^^ expected pattern
+   |         ^^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#struct = "foo";
+   |         ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-trait-as-identifier.rs b/src/test/ui/parser/keyword-trait-as-identifier.rs
index f62858442d252..67f81167dbdd3 100644
--- a/src/test/ui/parser/keyword-trait-as-identifier.rs
+++ b/src/test/ui/parser/keyword-trait-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py trait'
 
 fn main() {
-    let trait = "foo"; //~ error: expected pattern, found keyword `trait`
+    let trait = "foo"; //~ error: expected identifier, found keyword `trait`
 }
diff --git a/src/test/ui/parser/keyword-trait-as-identifier.stderr b/src/test/ui/parser/keyword-trait-as-identifier.stderr
index b31c0df28c008..ccc675cdb3a7c 100644
--- a/src/test/ui/parser/keyword-trait-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-trait-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `trait`
+error: expected identifier, found keyword `trait`
   --> $DIR/keyword-trait-as-identifier.rs:4:9
    |
 LL |     let trait = "foo";
-   |         ^^^^^ expected pattern
+   |         ^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#trait = "foo";
+   |         ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-try-as-identifier-edition2018.rs b/src/test/ui/parser/keyword-try-as-identifier-edition2018.rs
index 13a938b2e0988..4fa37bdb057b7 100644
--- a/src/test/ui/parser/keyword-try-as-identifier-edition2018.rs
+++ b/src/test/ui/parser/keyword-try-as-identifier-edition2018.rs
@@ -1,5 +1,5 @@
 // compile-flags: --edition 2018
 
 fn main() {
-    let try = "foo"; //~ error: expected pattern, found reserved keyword `try`
+    let try = "foo"; //~ error: expected identifier, found reserved keyword `try`
 }
diff --git a/src/test/ui/parser/keyword-try-as-identifier-edition2018.stderr b/src/test/ui/parser/keyword-try-as-identifier-edition2018.stderr
index c342e3a76fbb4..f71b889a30db5 100644
--- a/src/test/ui/parser/keyword-try-as-identifier-edition2018.stderr
+++ b/src/test/ui/parser/keyword-try-as-identifier-edition2018.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found reserved keyword `try`
+error: expected identifier, found reserved keyword `try`
   --> $DIR/keyword-try-as-identifier-edition2018.rs:4:9
    |
 LL |     let try = "foo";
-   |         ^^^ expected pattern
+   |         ^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#try = "foo";
+   |         ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-type-as-identifier.rs b/src/test/ui/parser/keyword-type-as-identifier.rs
index 992547e6f59c0..04adddf72c6ff 100644
--- a/src/test/ui/parser/keyword-type-as-identifier.rs
+++ b/src/test/ui/parser/keyword-type-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py type'
 
 fn main() {
-    let type = "foo"; //~ error: expected pattern, found keyword `type`
+    let type = "foo"; //~ error: expected identifier, found keyword `type`
 }
diff --git a/src/test/ui/parser/keyword-type-as-identifier.stderr b/src/test/ui/parser/keyword-type-as-identifier.stderr
index b749c708d441d..88099d949a829 100644
--- a/src/test/ui/parser/keyword-type-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-type-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `type`
+error: expected identifier, found keyword `type`
   --> $DIR/keyword-type-as-identifier.rs:4:9
    |
 LL |     let type = "foo";
-   |         ^^^^ expected pattern
+   |         ^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#type = "foo";
+   |         ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-typeof.rs b/src/test/ui/parser/keyword-typeof.rs
index 4ef102646ef1c..29dc77d276cbd 100644
--- a/src/test/ui/parser/keyword-typeof.rs
+++ b/src/test/ui/parser/keyword-typeof.rs
@@ -1,3 +1,3 @@
 fn main() {
-    let typeof = (); //~ ERROR expected pattern, found reserved keyword `typeof`
+    let typeof = (); //~ ERROR expected identifier, found reserved keyword `typeof`
 }
diff --git a/src/test/ui/parser/keyword-typeof.stderr b/src/test/ui/parser/keyword-typeof.stderr
index e7b18023e61a9..4a1b63d5c9357 100644
--- a/src/test/ui/parser/keyword-typeof.stderr
+++ b/src/test/ui/parser/keyword-typeof.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found reserved keyword `typeof`
+error: expected identifier, found reserved keyword `typeof`
   --> $DIR/keyword-typeof.rs:2:9
    |
 LL |     let typeof = ();
-   |         ^^^^^^ expected pattern
+   |         ^^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#typeof = ();
+   |         ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-unsafe-as-identifier.rs b/src/test/ui/parser/keyword-unsafe-as-identifier.rs
index adb20ebe48c79..0ff6d188c6480 100644
--- a/src/test/ui/parser/keyword-unsafe-as-identifier.rs
+++ b/src/test/ui/parser/keyword-unsafe-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py unsafe'
 
 fn main() {
-    let unsafe = "foo"; //~ error: expected pattern, found keyword `unsafe`
+    let unsafe = "foo"; //~ error: expected identifier, found keyword `unsafe`
 }
diff --git a/src/test/ui/parser/keyword-unsafe-as-identifier.stderr b/src/test/ui/parser/keyword-unsafe-as-identifier.stderr
index 67935ce43ba04..205bb81df405b 100644
--- a/src/test/ui/parser/keyword-unsafe-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-unsafe-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `unsafe`
+error: expected identifier, found keyword `unsafe`
   --> $DIR/keyword-unsafe-as-identifier.rs:4:9
    |
 LL |     let unsafe = "foo";
-   |         ^^^^^^ expected pattern
+   |         ^^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#unsafe = "foo";
+   |         ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-use-as-identifier.rs b/src/test/ui/parser/keyword-use-as-identifier.rs
index 198444bafc5b8..821bedee08832 100644
--- a/src/test/ui/parser/keyword-use-as-identifier.rs
+++ b/src/test/ui/parser/keyword-use-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py use'
 
 fn main() {
-    let use = "foo"; //~ error: expected pattern, found keyword `use`
+    let use = "foo"; //~ error: expected identifier, found keyword `use`
 }
diff --git a/src/test/ui/parser/keyword-use-as-identifier.stderr b/src/test/ui/parser/keyword-use-as-identifier.stderr
index 2c69d0a8744a0..85a0492f5735f 100644
--- a/src/test/ui/parser/keyword-use-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-use-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `use`
+error: expected identifier, found keyword `use`
   --> $DIR/keyword-use-as-identifier.rs:4:9
    |
 LL |     let use = "foo";
-   |         ^^^ expected pattern
+   |         ^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#use = "foo";
+   |         ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-where-as-identifier.rs b/src/test/ui/parser/keyword-where-as-identifier.rs
index 5624a8fc46038..56301bd20adfd 100644
--- a/src/test/ui/parser/keyword-where-as-identifier.rs
+++ b/src/test/ui/parser/keyword-where-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py where'
 
 fn main() {
-    let where = "foo"; //~ error: expected pattern, found keyword `where`
+    let where = "foo"; //~ error: expected identifier, found keyword `where`
 }
diff --git a/src/test/ui/parser/keyword-where-as-identifier.stderr b/src/test/ui/parser/keyword-where-as-identifier.stderr
index fc01183ca046b..b8b8506907636 100644
--- a/src/test/ui/parser/keyword-where-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-where-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `where`
+error: expected identifier, found keyword `where`
   --> $DIR/keyword-where-as-identifier.rs:4:9
    |
 LL |     let where = "foo";
-   |         ^^^^^ expected pattern
+   |         ^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#where = "foo";
+   |         ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/keyword-while-as-identifier.rs b/src/test/ui/parser/keyword-while-as-identifier.rs
index c0a539d350764..22026d15dcbfb 100644
--- a/src/test/ui/parser/keyword-while-as-identifier.rs
+++ b/src/test/ui/parser/keyword-while-as-identifier.rs
@@ -1,5 +1,5 @@
 // This file was auto-generated using 'src/etc/generate-keyword-tests.py while'
 
 fn main() {
-    let while = "foo"; //~ error: expected pattern, found keyword `while`
+    let while = "foo"; //~ error: expected identifier, found keyword `while`
 }
diff --git a/src/test/ui/parser/keyword-while-as-identifier.stderr b/src/test/ui/parser/keyword-while-as-identifier.stderr
index f72ac87742099..bb0c0ac668a41 100644
--- a/src/test/ui/parser/keyword-while-as-identifier.stderr
+++ b/src/test/ui/parser/keyword-while-as-identifier.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found keyword `while`
+error: expected identifier, found keyword `while`
   --> $DIR/keyword-while-as-identifier.rs:4:9
    |
 LL |     let while = "foo";
-   |         ^^^^^ expected pattern
+   |         ^^^^^ expected identifier, found keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#while = "foo";
+   |         ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/mut-patterns.rs b/src/test/ui/parser/mut-patterns.rs
index bffeb1e2e7c40..87e127f9d364a 100644
--- a/src/test/ui/parser/mut-patterns.rs
+++ b/src/test/ui/parser/mut-patterns.rs
@@ -1,7 +1,35 @@
 // Can't put mut in non-ident pattern
 
+// edition:2018
+
+#![feature(box_patterns)]
+#![allow(warnings)]
+
 pub fn main() {
+    let mut mut x = 0;
+    //~^ ERROR `mut` on a binding may not be repeated
+    //~| remove the additional `mut`s
+
     struct Foo { x: isize }
     let mut Foo { x: x } = Foo { x: 3 };
-    //~^ ERROR: expected one of `:`, `;`, `=`, `@`, or `|`, found `{`
+    //~^ ERROR `mut` must be attached to each individual binding
+    //~| add `mut` to each binding
+
+    let mut Foo { x } = Foo { x: 3 };
+    //~^ ERROR `mut` must be attached to each individual binding
+    //~| add `mut` to each binding
+
+    struct r#yield(u8, u8);
+    let mut mut yield(become, await) = r#yield(0, 0);
+    //~^ ERROR `mut` on a binding may not be repeated
+    //~| ERROR `mut` must be attached to each individual binding
+    //~| ERROR expected identifier, found reserved keyword `yield`
+    //~| ERROR expected identifier, found reserved keyword `become`
+    //~| ERROR expected identifier, found reserved keyword `await`
+
+    struct W<T, U>(T, U);
+    struct B { f: Box<u8> }
+    let mut W(mut a, W(b, W(ref c, W(d, B { box f }))))
+    //~^ ERROR `mut` must be attached to each individual binding
+        = W(0, W(1, W(2, W(3, B { f: Box::new(4u8) }))));
 }
diff --git a/src/test/ui/parser/mut-patterns.stderr b/src/test/ui/parser/mut-patterns.stderr
index b39209afd4295..a251e2908f02c 100644
--- a/src/test/ui/parser/mut-patterns.stderr
+++ b/src/test/ui/parser/mut-patterns.stderr
@@ -1,8 +1,68 @@
-error: expected one of `:`, `;`, `=`, `@`, or `|`, found `{`
-  --> $DIR/mut-patterns.rs:5:17
+error: `mut` on a binding may not be repeated
+  --> $DIR/mut-patterns.rs:9:13
+   |
+LL |     let mut mut x = 0;
+   |             ^^^ help: remove the additional `mut`s
+
+error: `mut` must be attached to each individual binding
+  --> $DIR/mut-patterns.rs:14:9
    |
 LL |     let mut Foo { x: x } = Foo { x: 3 };
-   |                 ^ expected one of `:`, `;`, `=`, `@`, or `|` here
+   |         ^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { x: mut x }`
+
+error: `mut` must be attached to each individual binding
+  --> $DIR/mut-patterns.rs:18:9
+   |
+LL |     let mut Foo { x } = Foo { x: 3 };
+   |         ^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { mut x }`
+
+error: `mut` on a binding may not be repeated
+  --> $DIR/mut-patterns.rs:23:13
+   |
+LL |     let mut mut yield(become, await) = r#yield(0, 0);
+   |             ^^^ help: remove the additional `mut`s
+
+error: expected identifier, found reserved keyword `yield`
+  --> $DIR/mut-patterns.rs:23:17
+   |
+LL |     let mut mut yield(become, await) = r#yield(0, 0);
+   |                 ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let mut mut r#yield(become, await) = r#yield(0, 0);
+   |                 ^^^^^^^
+
+error: expected identifier, found reserved keyword `become`
+  --> $DIR/mut-patterns.rs:23:23
+   |
+LL |     let mut mut yield(become, await) = r#yield(0, 0);
+   |                       ^^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let mut mut yield(r#become, await) = r#yield(0, 0);
+   |                       ^^^^^^^^
+
+error: expected identifier, found reserved keyword `await`
+  --> $DIR/mut-patterns.rs:23:31
+   |
+LL |     let mut mut yield(become, await) = r#yield(0, 0);
+   |                               ^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let mut mut yield(become, r#await) = r#yield(0, 0);
+   |                               ^^^^^^^
+
+error: `mut` must be attached to each individual binding
+  --> $DIR/mut-patterns.rs:23:9
+   |
+LL |     let mut mut yield(become, await) = r#yield(0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `r#yield(mut r#become, mut r#await)`
+
+error: `mut` must be attached to each individual binding
+  --> $DIR/mut-patterns.rs:32:9
+   |
+LL |     let mut W(mut a, W(b, W(ref c, W(d, B { box f }))))
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `W(mut a, W(mut b, W(ref c, W(mut d, B { box mut f }))))`
 
-error: aborting due to previous error
+error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/reserved/reserved-become.rs b/src/test/ui/reserved/reserved-become.rs
index 2279a05e6b2db..56645255ee5f6 100644
--- a/src/test/ui/reserved/reserved-become.rs
+++ b/src/test/ui/reserved/reserved-become.rs
@@ -1,4 +1,4 @@
 fn main() {
     let become = 0;
-    //~^ ERROR expected pattern, found reserved keyword `become`
+    //~^ ERROR expected identifier, found reserved keyword `become`
 }
diff --git a/src/test/ui/reserved/reserved-become.stderr b/src/test/ui/reserved/reserved-become.stderr
index f9fe78e18b393..3ce9fb33c289e 100644
--- a/src/test/ui/reserved/reserved-become.stderr
+++ b/src/test/ui/reserved/reserved-become.stderr
@@ -1,8 +1,12 @@
-error: expected pattern, found reserved keyword `become`
+error: expected identifier, found reserved keyword `become`
   --> $DIR/reserved-become.rs:2:9
    |
 LL |     let become = 0;
-   |         ^^^^^^ expected pattern
+   |         ^^^^^^ expected identifier, found reserved keyword
+help: you can escape reserved keywords to use them as identifiers
+   |
+LL |     let r#become = 0;
+   |         ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/self/self_type_keyword.rs b/src/test/ui/self/self_type_keyword.rs
index 01b3309fcacb1..d479905932be0 100644
--- a/src/test/ui/self/self_type_keyword.rs
+++ b/src/test/ui/self/self_type_keyword.rs
@@ -14,7 +14,8 @@ pub fn main() {
         ref Self => (),
         //~^ ERROR expected identifier, found keyword `Self`
         mut Self => (),
-        //~^ ERROR expected identifier, found keyword `Self`
+        //~^ ERROR `mut` must be attached to each individual binding
+        //~| ERROR cannot find unit struct/variant or constant `Self`
         ref mut Self => (),
         //~^ ERROR expected identifier, found keyword `Self`
         Self!() => (),
diff --git a/src/test/ui/self/self_type_keyword.stderr b/src/test/ui/self/self_type_keyword.stderr
index b63de98b8e702..fdae06ccdd9f5 100644
--- a/src/test/ui/self/self_type_keyword.stderr
+++ b/src/test/ui/self/self_type_keyword.stderr
@@ -10,38 +10,38 @@ error: expected identifier, found keyword `Self`
 LL |         ref Self => (),
    |             ^^^^ expected identifier, found keyword
 
-error: expected identifier, found keyword `Self`
-  --> $DIR/self_type_keyword.rs:16:13
+error: `mut` must be attached to each individual binding
+  --> $DIR/self_type_keyword.rs:16:9
    |
 LL |         mut Self => (),
-   |             ^^^^ expected identifier, found keyword
+   |         ^^^^^^^^ help: add `mut` to each binding: `Self`
 
 error: expected identifier, found keyword `Self`
-  --> $DIR/self_type_keyword.rs:18:17
+  --> $DIR/self_type_keyword.rs:19:17
    |
 LL |         ref mut Self => (),
    |                 ^^^^ expected identifier, found keyword
 
 error: expected identifier, found keyword `Self`
-  --> $DIR/self_type_keyword.rs:22:15
+  --> $DIR/self_type_keyword.rs:23:15
    |
 LL |         Foo { Self } => (),
    |               ^^^^ expected identifier, found keyword
 
 error: expected identifier, found keyword `Self`
-  --> $DIR/self_type_keyword.rs:28:26
+  --> $DIR/self_type_keyword.rs:29:26
    |
 LL |     extern crate core as Self;
    |                          ^^^^ expected identifier, found keyword
 
 error: expected identifier, found keyword `Self`
-  --> $DIR/self_type_keyword.rs:33:32
+  --> $DIR/self_type_keyword.rs:34:32
    |
 LL |     use std::option::Option as Self;
    |                                ^^^^ expected identifier, found keyword
 
 error: expected identifier, found keyword `Self`
-  --> $DIR/self_type_keyword.rs:38:11
+  --> $DIR/self_type_keyword.rs:39:11
    |
 LL |     trait Self {}
    |           ^^^^ expected identifier, found keyword
@@ -53,11 +53,21 @@ LL | struct Bar<'Self>;
    |            ^^^^^
 
 error: cannot find macro `Self!` in this scope
-  --> $DIR/self_type_keyword.rs:20:9
+  --> $DIR/self_type_keyword.rs:21:9
    |
 LL |         Self!() => (),
    |         ^^^^
 
+error[E0531]: cannot find unit struct/variant or constant `Self` in this scope
+  --> $DIR/self_type_keyword.rs:16:13
+   |
+LL |         mut Self => (),
+   |             ^^^^ not found in this scope
+help: possible candidate is found in another module, you can import it into scope
+   |
+LL | use foo::Self;
+   |
+
 error[E0392]: parameter `'Self` is never used
   --> $DIR/self_type_keyword.rs:6:12
    |
@@ -66,6 +76,6 @@ LL | struct Bar<'Self>;
    |
    = help: consider removing `'Self` or using a marker such as `std::marker::PhantomData`
 
-error: aborting due to 11 previous errors
+error: aborting due to 12 previous errors
 
 For more information about this error, try `rustc --explain E0392`.

From e0ce9f8c0a97e5949c9cadd220279d6969289daa Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per@protonmail.com>
Date: Tue, 27 Aug 2019 13:24:32 +0200
Subject: [PATCH 285/943] Cleanup: Consistently use `Param` instead of `Arg`
 #62426

---
 src/librustc/hir/intravisit.rs                | 14 +--
 src/librustc/hir/lowering.rs                  | 28 +++---
 src/librustc/hir/lowering/item.rs             | 80 +++++++--------
 src/librustc/hir/map/collector.rs             | 10 +-
 src/librustc/hir/map/mod.rs                   | 14 +--
 src/librustc/hir/mod.rs                       | 20 ++--
 src/librustc/hir/print.rs                     | 16 +--
 src/librustc/ich/impls_hir.rs                 |  4 +-
 .../infer/error_reporting/need_type_info.rs   |  6 +-
 .../nice_region_error/different_lifetimes.rs  | 22 ++---
 .../nice_region_error/named_anon_conflict.rs  | 30 +++---
 .../error_reporting/nice_region_error/util.rs | 44 ++++-----
 src/librustc/lint/context.rs                  | 16 +--
 src/librustc/lint/mod.rs                      | 10 +-
 src/librustc/middle/expr_use_visitor.rs       | 18 ++--
 src/librustc/middle/liveness.rs               | 22 ++---
 src/librustc/middle/region.rs                 |  4 +-
 src/librustc/middle/resolve_lifetime.rs       |  2 +-
 src/librustc/traits/error_reporting.rs        |  3 +-
 src/librustc_ast_borrowck/dataflow.rs         |  4 +-
 src/librustc_metadata/cstore_impl.rs          |  2 +-
 src/librustc_metadata/decoder.rs              | 10 +-
 src/librustc_metadata/encoder.rs              | 24 ++---
 src/librustc_metadata/schema.rs               |  2 +-
 src/librustc_mir/build/mod.rs                 |  4 +-
 src/librustc_mir/hair/pattern/check_match.rs  |  6 +-
 src/librustc_passes/hir_stats.rs              |  6 +-
 src/librustc_save_analysis/dump_visitor.rs    |  2 +-
 src/librustc_save_analysis/lib.rs             |  4 +-
 src/librustc_typeck/check/demand.rs           | 14 +--
 src/librustc_typeck/check/mod.rs              | 18 ++--
 src/librustc_typeck/check/pat.rs              |  2 +-
 src/librustc_typeck/check/regionck.rs         | 20 ++--
 src/librustc_typeck/check/writeback.rs        |  8 +-
 src/librustdoc/clean/mod.rs                   |  4 +-
 src/libsyntax/ast.rs                          | 22 ++---
 src/libsyntax/attr/mod.rs                     |  2 +-
 src/libsyntax/ext/build.rs                    | 12 +--
 src/libsyntax/mut_visit.rs                    | 12 +--
 src/libsyntax/parse/attr.rs                   |  2 +-
 src/libsyntax/parse/diagnostics.rs            | 34 +++----
 src/libsyntax/parse/parser.rs                 | 98 ++++++++++---------
 src/libsyntax/parse/parser/expr.rs            | 12 +--
 src/libsyntax/parse/parser/item.rs            | 10 +-
 src/libsyntax/parse/parser/ty.rs              |  2 +-
 src/libsyntax/print/pprust.rs                 | 18 ++--
 src/libsyntax/visit.rs                        | 14 +--
 src/libsyntax_ext/deriving/generic/mod.rs     |  4 +-
 src/libsyntax_ext/global_allocator.rs         | 12 +--
 .../no-args-non-move-async-closure.rs         |  2 +-
 .../no-args-non-move-async-closure.stderr     |  2 +-
 .../generator/no-arguments-on-generators.rs   |  2 +-
 .../no-arguments-on-generators.stderr         |  2 +-
 53 files changed, 379 insertions(+), 376 deletions(-)

diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index fa274f831b795..bbde3510e29f9 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -210,8 +210,8 @@ pub trait Visitor<'v> : Sized {
         }
     }
 
-    fn visit_arg(&mut self, arg: &'v Arg) {
-        walk_arg(self, arg)
+    fn visit_param(&mut self, param: &'v Param) {
+        walk_param(self, param)
     }
 
     /// Visits the top-level item and (optionally) nested items / impl items. See
@@ -400,7 +400,7 @@ pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod, mod_hir_id
 }
 
 pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) {
-    walk_list!(visitor, visit_arg, &body.arguments);
+    walk_list!(visitor, visit_param, &body.params);
     visitor.visit_expr(&body.value);
 }
 
@@ -454,10 +454,10 @@ pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef)
     visitor.visit_path(&trait_ref.path, trait_ref.hir_ref_id)
 }
 
-pub fn walk_arg<'v, V: Visitor<'v>>(visitor: &mut V, arg: &'v Arg) {
-    visitor.visit_id(arg.hir_id);
-    visitor.visit_pat(&arg.pat);
-    walk_list!(visitor, visit_attribute, &arg.attrs);
+pub fn walk_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Param) {
+    visitor.visit_id(param.hir_id);
+    visitor.visit_pat(&param.pat);
+    walk_list!(visitor, visit_attribute, &param.attrs);
 }
 
 pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 7ec3210613727..5e2aebfd3187b 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -510,12 +510,12 @@ impl<'a> LoweringContext<'a> {
                             &f.generic_params
                         );
                         // Mirrors visit::walk_fn_decl
-                        for argument in &f.decl.inputs {
+                        for parameter in &f.decl.inputs {
                             // We don't lower the ids of argument patterns
                             self.with_hir_id_owner(None, |this| {
-                                this.visit_pat(&argument.pat);
+                                this.visit_pat(&parameter.pat);
                             });
-                            self.visit_ty(&argument.ty)
+                            self.visit_ty(&parameter.ty)
                         }
                         self.visit_fn_ret_ty(&f.decl.output)
                     }
@@ -735,7 +735,7 @@ impl<'a> LoweringContext<'a> {
     ///
     /// Presuming that in-band lifetimes are enabled, then
     /// `self.anonymous_lifetime_mode` will be updated to match the
-    /// argument while `f` is running (and restored afterwards).
+    /// parameter while `f` is running (and restored afterwards).
     fn collect_in_band_defs<T, F>(
         &mut self,
         parent_id: DefId,
@@ -880,7 +880,7 @@ impl<'a> LoweringContext<'a> {
     ///
     /// Presuming that in-band lifetimes are enabled, then
     /// `self.anonymous_lifetime_mode` will be updated to match the
-    /// argument while `f` is running (and restored afterwards).
+    /// parameter while `f` is running (and restored afterwards).
     fn add_in_band_defs<F, T>(
         &mut self,
         generics: &Generics,
@@ -1080,7 +1080,7 @@ impl<'a> LoweringContext<'a> {
                     ImplTraitContext::Disallowed(_) if self.is_in_dyn_type =>
                         (true, ImplTraitContext::OpaqueTy(None)),
 
-                    // We are in the argument position, but not within a dyn type:
+                    // We are in the parameter position, but not within a dyn type:
                     //
                     //     fn foo(x: impl Iterator<Item: Debug>)
                     //
@@ -1204,7 +1204,7 @@ impl<'a> LoweringContext<'a> {
                                 unsafety: this.lower_unsafety(f.unsafety),
                                 abi: f.abi,
                                 decl: this.lower_fn_decl(&f.decl, None, false, None),
-                                arg_names: this.lower_fn_args_to_names(&f.decl),
+                                param_names: this.lower_fn_params_to_names(&f.decl),
                             }))
                         },
                     )
@@ -2093,12 +2093,12 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn lower_fn_args_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Ident> {
+    fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> hir::HirVec<Ident> {
         decl.inputs
             .iter()
-            .map(|arg| match arg.pat.node {
+            .map(|param| match param.pat.node {
                 PatKind::Ident(_, ident, _) => ident,
-                _ => Ident::new(kw::Invalid, arg.pat.span),
+                _ => Ident::new(kw::Invalid, param.pat.span),
             })
             .collect()
     }
@@ -2136,11 +2136,11 @@ impl<'a> LoweringContext<'a> {
         let inputs = self.with_anonymous_lifetime_mode(lt_mode, |this| {
             decl.inputs
                 .iter()
-                .map(|arg| {
+                .map(|param| {
                     if let Some((_, ibty)) = &mut in_band_ty_params {
-                        this.lower_ty_direct(&arg.ty, ImplTraitContext::Universal(ibty))
+                        this.lower_ty_direct(&param.ty, ImplTraitContext::Universal(ibty))
                     } else {
-                        this.lower_ty_direct(&arg.ty, ImplTraitContext::disallowed())
+                        this.lower_ty_direct(&param.ty, ImplTraitContext::disallowed())
                     }
                 })
                 .collect::<HirVec<_>>()
@@ -2205,7 +2205,7 @@ impl<'a> LoweringContext<'a> {
     //
     //     type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
     //
-    // `inputs`: lowered types of arguments to the function (used to collect lifetimes)
+    // `inputs`: lowered types of parameters to the function (used to collect lifetimes)
     // `output`: unlowered output type (`T` in `-> T`)
     // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
     // `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 4f9a9ed5673c7..4e432f4981d23 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -720,7 +720,7 @@ impl LoweringContext<'_> {
                             (
                                 // Disallow impl Trait in foreign items
                                 this.lower_fn_decl(fdec, None, false, None),
-                                this.lower_fn_args_to_names(fdec),
+                                this.lower_fn_params_to_names(fdec),
                             )
                         },
                     );
@@ -827,7 +827,7 @@ impl LoweringContext<'_> {
                 ),
             ),
             TraitItemKind::Method(ref sig, None) => {
-                let names = self.lower_fn_args_to_names(&sig.decl);
+                let names = self.lower_fn_params_to_names(&sig.decl);
                 let (generics, sig) = self.lower_method_sig(
                     &i.generics,
                     sig,
@@ -1028,10 +1028,10 @@ impl LoweringContext<'_> {
         }
     }
 
-    fn record_body(&mut self, arguments: HirVec<hir::Arg>, value: hir::Expr) -> hir::BodyId {
+    fn record_body(&mut self, params: HirVec<hir::Param>, value: hir::Expr) -> hir::BodyId {
         let body = hir::Body {
             generator_kind: self.generator_kind,
-            arguments,
+            params,
             value,
         };
         let id = body.id();
@@ -1041,21 +1041,21 @@ impl LoweringContext<'_> {
 
     fn lower_body(
         &mut self,
-        f: impl FnOnce(&mut LoweringContext<'_>) -> (HirVec<hir::Arg>, hir::Expr),
+        f: impl FnOnce(&mut LoweringContext<'_>) -> (HirVec<hir::Param>, hir::Expr),
     ) -> hir::BodyId {
         let prev_gen_kind = self.generator_kind.take();
-        let (arguments, result) = f(self);
-        let body_id = self.record_body(arguments, result);
+        let (parameters, result) = f(self);
+        let body_id = self.record_body(parameters, result);
         self.generator_kind = prev_gen_kind;
         body_id
     }
 
-    fn lower_arg(&mut self, arg: &Arg) -> hir::Arg {
-        hir::Arg {
-            attrs: self.lower_attrs(&arg.attrs),
-            hir_id: self.lower_node_id(arg.id),
-            pat: self.lower_pat(&arg.pat),
-            span: arg.span,
+    fn lower_param(&mut self, param: &Param) -> hir::Param {
+        hir::Param {
+            attrs: self.lower_attrs(&param.attrs),
+            hir_id: self.lower_node_id(param.id),
+            pat: self.lower_pat(&param.pat),
+            span: param.span,
         }
     }
 
@@ -1065,7 +1065,7 @@ impl LoweringContext<'_> {
         body: impl FnOnce(&mut LoweringContext<'_>) -> hir::Expr,
     ) -> hir::BodyId {
         self.lower_body(|this| (
-            decl.inputs.iter().map(|x| this.lower_arg(x)).collect(),
+            decl.inputs.iter().map(|x| this.lower_param(x)).collect(),
             body(this),
         ))
     }
@@ -1093,10 +1093,10 @@ impl LoweringContext<'_> {
         };
 
         self.lower_body(|this| {
-            let mut arguments: Vec<hir::Arg> = Vec::new();
+            let mut parameters: Vec<hir::Param> = Vec::new();
             let mut statements: Vec<hir::Stmt> = Vec::new();
 
-            // Async function arguments are lowered into the closure body so that they are
+            // Async function parameters are lowered into the closure body so that they are
             // captured and so that the drop order matches the equivalent non-async functions.
             //
             // from:
@@ -1121,13 +1121,13 @@ impl LoweringContext<'_> {
             //
             // If `<pattern>` is a simple ident, then it is lowered to a single
             // `let <pattern> = <pattern>;` statement as an optimization.
-            for (index, argument) in decl.inputs.iter().enumerate() {
-                let argument = this.lower_arg(argument);
-                let span = argument.pat.span;
+            for (index, parameter) in decl.inputs.iter().enumerate() {
+                let parameter = this.lower_param(parameter);
+                let span = parameter.pat.span;
 
                 // Check if this is a binding pattern, if so, we can optimize and avoid adding a
-                // `let <pat> = __argN;` statement. In this case, we do not rename the argument.
-                let (ident, is_simple_argument) = match argument.pat.node {
+                // `let <pat> = __argN;` statement. In this case, we do not rename the parameter.
+                let (ident, is_simple_parameter) = match parameter.pat.node {
                     hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, ident, _) =>
                         (ident, true),
                     _ => {
@@ -1142,32 +1142,32 @@ impl LoweringContext<'_> {
                 let desugared_span =
                     this.mark_span_with_reason(DesugaringKind::Async, span, None);
 
-                // Construct an argument representing `__argN: <ty>` to replace the argument of the
+                // Construct a parameter representing `__argN: <ty>` to replace the parameter of the
                 // async function.
                 //
-                // If this is the simple case, this argument will end up being the same as the
-                // original argument, but with a different pattern id.
+                // If this is the simple case, this parameter will end up being the same as the
+                // original parameter, but with a different pattern id.
                 let mut stmt_attrs = ThinVec::new();
-                stmt_attrs.extend(argument.attrs.iter().cloned());
-                let (new_argument_pat, new_argument_id) = this.pat_ident(desugared_span, ident);
-                let new_argument = hir::Arg {
-                    attrs: argument.attrs,
-                    hir_id: argument.hir_id,
-                    pat: new_argument_pat,
-                    span: argument.span,
+                stmt_attrs.extend(parameter.attrs.iter().cloned());
+                let (new_parameter_pat, new_parameter_id) = this.pat_ident(desugared_span, ident);
+                let new_parameter = hir::Param {
+                    attrs: parameter.attrs,
+                    hir_id: parameter.hir_id,
+                    pat: new_parameter_pat,
+                    span: parameter.span,
                 };
 
 
-                if is_simple_argument {
+                if is_simple_parameter {
                     // If this is the simple case, then we only insert one statement that is
                     // `let <pat> = <pat>;`. We re-use the original argument's pattern so that
                     // `HirId`s are densely assigned.
-                    let expr = this.expr_ident(desugared_span, ident, new_argument_id);
+                    let expr = this.expr_ident(desugared_span, ident, new_parameter_id);
                     let stmt = this.stmt_let_pat(
                         stmt_attrs,
                         desugared_span,
                         Some(P(expr)),
-                        argument.pat,
+                        parameter.pat,
                         hir::LocalSource::AsyncFn
                     );
                     statements.push(stmt);
@@ -1179,7 +1179,7 @@ impl LoweringContext<'_> {
                     // let <pat> = __argN;
                     // ```
                     //
-                    // The first statement moves the argument into the closure and thus ensures
+                    // The first statement moves the parameter into the closure and thus ensures
                     // that the drop order is correct.
                     //
                     // The second statement creates the bindings that the user wrote.
@@ -1189,7 +1189,7 @@ impl LoweringContext<'_> {
                     // statement.
                     let (move_pat, move_id) = this.pat_ident_binding_mode(
                         desugared_span, ident, hir::BindingAnnotation::Mutable);
-                    let move_expr = this.expr_ident(desugared_span, ident, new_argument_id);
+                    let move_expr = this.expr_ident(desugared_span, ident, new_parameter_id);
                     let move_stmt = this.stmt_let_pat(
                         ThinVec::new(),
                         desugared_span,
@@ -1199,13 +1199,13 @@ impl LoweringContext<'_> {
                     );
 
                     // Construct the `let <pat> = __argN;` statement. We re-use the original
-                    // argument's pattern so that `HirId`s are densely assigned.
+                    // parameter's pattern so that `HirId`s are densely assigned.
                     let pattern_expr = this.expr_ident(desugared_span, ident, move_id);
                     let pattern_stmt = this.stmt_let_pat(
                         stmt_attrs,
                         desugared_span,
                         Some(P(pattern_expr)),
-                        argument.pat,
+                        parameter.pat,
                         hir::LocalSource::AsyncFn
                     );
 
@@ -1213,7 +1213,7 @@ impl LoweringContext<'_> {
                     statements.push(pattern_stmt);
                 };
 
-                arguments.push(new_argument);
+                parameters.push(new_parameter);
             }
 
             let async_expr = this.make_async_expr(
@@ -1222,7 +1222,7 @@ impl LoweringContext<'_> {
                     let body = this.lower_block_with_stmts(body, false, statements);
                     this.expr_block(body, ThinVec::new())
                 });
-            (HirVec::from(arguments), this.expr(body.span, async_expr, ThinVec::new()))
+            (HirVec::from(parameters), this.expr(body.span, async_expr, ThinVec::new()))
         })
     }
 
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index effe2c0cc6a76..773bb8dde0690 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -363,11 +363,11 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
         self.currently_in_body = prev_in_body;
     }
 
-    fn visit_arg(&mut self, arg: &'hir Arg) {
-        let node = Node::Arg(arg);
-        self.insert(arg.pat.span, arg.hir_id, node);
-        self.with_parent(arg.hir_id, |this| {
-            intravisit::walk_arg(this, arg);
+    fn visit_param(&mut self, param: &'hir Param) {
+        let node = Node::Param(param);
+        self.insert(param.pat.span, param.hir_id, node);
+        self.with_parent(param.hir_id, |this| {
+            intravisit::walk_param(this, param);
         });
     }
 
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index f80e527dfd9b7..eb8be6e6e3cbc 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -360,7 +360,7 @@ impl<'hir> Map<'hir> {
             Node::Pat(_) |
             Node::Binding(_) |
             Node::Local(_) |
-            Node::Arg(_) |
+            Node::Param(_) |
             Node::Arm(_) |
             Node::Lifetime(_) |
             Node::Visibility(_) |
@@ -964,7 +964,7 @@ impl<'hir> Map<'hir> {
     pub fn attrs(&self, id: HirId) -> &'hir [ast::Attribute] {
         self.read(id); // reveals attributes on the node
         let attrs = match self.find_entry(id).map(|entry| entry.node) {
-            Some(Node::Arg(a)) => Some(&a.attrs[..]),
+            Some(Node::Param(a)) => Some(&a.attrs[..]),
             Some(Node::Local(l)) => Some(&l.attrs[..]),
             Some(Node::Item(i)) => Some(&i.attrs[..]),
             Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]),
@@ -1028,7 +1028,7 @@ impl<'hir> Map<'hir> {
     pub fn span(&self, hir_id: HirId) -> Span {
         self.read(hir_id); // reveals span from node
         match self.find_entry(hir_id).map(|entry| entry.node) {
-            Some(Node::Arg(arg)) => arg.span,
+            Some(Node::Param(param)) => param.span,
             Some(Node::Item(item)) => item.span,
             Some(Node::ForeignItem(foreign_item)) => foreign_item.span,
             Some(Node::TraitItem(trait_method)) => trait_method.span,
@@ -1223,7 +1223,7 @@ impl<'hir> print::PpAnn for Map<'hir> {
             Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
             Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
             Nested::Body(id) => state.print_expr(&self.body(id).value),
-            Nested::BodyArgPat(id, i) => state.print_pat(&self.body(id).arguments[i].pat)
+            Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat)
         }
     }
 }
@@ -1231,7 +1231,7 @@ impl<'hir> print::PpAnn for Map<'hir> {
 impl<'a> print::State<'a> {
     pub fn print_node(&mut self, node: Node<'_>) {
         match node {
-            Node::Arg(a)          => self.print_arg(&a),
+            Node::Param(a)        => self.print_param(&a),
             Node::Item(a)         => self.print_item(&a),
             Node::ForeignItem(a)  => self.print_foreign_item(&a),
             Node::TraitItem(a)    => self.print_trait_item(a),
@@ -1373,8 +1373,8 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
         Some(Node::Pat(_)) => {
             format!("pat {}{}", map.hir_to_pretty_string(id), id_str)
         }
-        Some(Node::Arg(_)) => {
-            format!("arg {}{}", map.hir_to_pretty_string(id), id_str)
+        Some(Node::Param(_)) => {
+            format!("param {}{}", map.hir_to_pretty_string(id), id_str)
         }
         Some(Node::Arm(_)) => {
             format!("arm {}{}", map.hir_to_pretty_string(id), id_str)
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 983048188527f..d2c45a5af8598 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1030,7 +1030,7 @@ pub enum Mutability {
 }
 
 impl Mutability {
-    /// Returns `MutMutable` only if both arguments are mutable.
+    /// Returns `MutMutable` only if both `self` and `other` are mutable.
     pub fn and(self, other: Self) -> Self {
         match self {
             MutMutable => other,
@@ -1324,7 +1324,7 @@ pub struct BodyId {
 ///
 /// Here, the `Body` associated with `foo()` would contain:
 ///
-/// - an `arguments` array containing the `(x, y)` pattern
+/// - an `params` array containing the `(x, y)` pattern
 /// - a `value` containing the `x + y` expression (maybe wrapped in a block)
 /// - `generator_kind` would be `None`
 ///
@@ -1332,7 +1332,7 @@ pub struct BodyId {
 /// map using `body_owner_def_id()`.
 #[derive(RustcEncodable, RustcDecodable, Debug)]
 pub struct Body {
-    pub arguments: HirVec<Arg>,
+    pub params: HirVec<Param>,
     pub value: Expr,
     pub generator_kind: Option<GeneratorKind>,
 }
@@ -1644,7 +1644,7 @@ pub enum LocalSource {
     /// A desugared `for _ in _ { .. }` loop.
     ForLoopDesugar,
     /// When lowering async functions, we create locals within the `async move` so that
-    /// all arguments are dropped after the future is polled.
+    /// all parameters are dropped after the future is polled.
     ///
     /// ```ignore (pseudo-Rust)
     /// async fn foo(<pattern> @ x: Type) {
@@ -1940,7 +1940,7 @@ pub struct BareFnTy {
     pub abi: Abi,
     pub generic_params: HirVec<GenericParam>,
     pub decl: P<FnDecl>,
-    pub arg_names: HirVec<Ident>,
+    pub param_names: HirVec<Ident>,
 }
 
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
@@ -2027,9 +2027,9 @@ pub struct InlineAsm {
     pub dialect: AsmDialect,
 }
 
-/// Represents an argument in a function header.
+/// Represents a parameter in a function header.
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
-pub struct Arg {
+pub struct Param {
     pub attrs: HirVec<Attribute>,
     pub hir_id: HirId,
     pub pat: P<Pat>,
@@ -2039,9 +2039,9 @@ pub struct Arg {
 /// Represents the header (not the body) of a function declaration.
 #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct FnDecl {
-    /// The types of the function's arguments.
+    /// The types of the function's parameters.
     ///
-    /// Additional argument data is stored in the function's [body](Body::arguments).
+    /// Additional argument data is stored in the function's [body](Body::parameters).
     pub inputs: HirVec<Ty>,
     pub output: FunctionRetTy,
     pub c_variadic: bool,
@@ -2721,7 +2721,7 @@ impl CodegenFnAttrs {
 
 #[derive(Copy, Clone, Debug)]
 pub enum Node<'hir> {
-    Arg(&'hir Arg),
+    Param(&'hir Param),
     Item(&'hir Item),
     ForeignItem(&'hir ForeignItem),
     TraitItem(&'hir TraitItem),
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 632a13f9183b2..21cc72efee4a3 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -33,7 +33,7 @@ pub enum Nested {
     TraitItem(hir::TraitItemId),
     ImplItem(hir::ImplItemId),
     Body(hir::BodyId),
-    BodyArgPat(hir::BodyId, usize)
+    BodyParamPat(hir::BodyId, usize)
 }
 
 pub trait PpAnn {
@@ -62,7 +62,7 @@ impl PpAnn for hir::Crate {
             Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
             Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
             Nested::Body(id) => state.print_expr(&self.body(id).value),
-            Nested::BodyArgPat(id, i) => state.print_pat(&self.body(id).arguments[i].pat)
+            Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat)
         }
     }
 }
@@ -318,7 +318,7 @@ impl<'a> State<'a> {
             }
             hir::TyKind::BareFn(ref f) => {
                 self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &f.generic_params,
-                                 &f.arg_names[..]);
+                                 &f.param_names[..]);
             }
             hir::TyKind::Def(..) => {},
             hir::TyKind::Path(ref qpath) => {
@@ -1290,7 +1290,7 @@ impl<'a> State<'a> {
             hir::ExprKind::Closure(capture_clause, ref decl, body, _fn_decl_span, _gen) => {
                 self.print_capture_clause(capture_clause);
 
-                self.print_closure_args(&decl, body);
+                self.print_closure_params(&decl, body);
                 self.s.space();
 
                 // this is a bare expression
@@ -1775,7 +1775,7 @@ impl<'a> State<'a> {
         self.ann.post(self, AnnNode::Pat(pat))
     }
 
-    pub fn print_arg(&mut self, arg: &hir::Arg) {
+    pub fn print_param(&mut self, arg: &hir::Param) {
         self.print_outer_attributes(&arg.attrs);
         self.print_pat(&arg.pat);
     }
@@ -1864,7 +1864,7 @@ impl<'a> State<'a> {
                 s.s.word(":");
                 s.s.space();
             } else if let Some(body_id) = body_id {
-                s.ann.nested(s, Nested::BodyArgPat(body_id, i));
+                s.ann.nested(s, Nested::BodyParamPat(body_id, i));
                 s.s.word(":");
                 s.s.space();
             }
@@ -1881,13 +1881,13 @@ impl<'a> State<'a> {
         self.print_where_clause(&generics.where_clause)
     }
 
-    fn print_closure_args(&mut self, decl: &hir::FnDecl, body_id: hir::BodyId) {
+    fn print_closure_params(&mut self, decl: &hir::FnDecl, body_id: hir::BodyId) {
         self.s.word("|");
         let mut i = 0;
         self.commasep(Inconsistent, &decl.inputs, |s, ty| {
             s.ibox(INDENT_UNIT);
 
-            s.ann.nested(s, Nested::BodyArgPat(body_id, i));
+            s.ann.nested(s, Nested::BodyParamPat(body_id, i));
             i += 1;
 
             if let hir::TyKind::Infer = ty.node {
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 60b338010b0db..fb981d961129f 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -331,13 +331,13 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::Body {
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
         let hir::Body {
-            arguments,
+            params,
             value,
             generator_kind,
         } = self;
 
         hcx.with_node_id_hashing_mode(NodeIdHashingMode::Ignore, |hcx| {
-            arguments.hash_stable(hcx, hasher);
+            params.hash_stable(hcx, hasher);
             value.hash_stable(hcx, hasher);
             generator_kind.hash_stable(hcx, hasher);
         });
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index 5e0f973fdd310..7068fe3601a62 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -78,12 +78,12 @@ impl<'a, 'tcx> Visitor<'tcx> for FindLocalByTypeVisitor<'a, 'tcx> {
     }
 
     fn visit_body(&mut self, body: &'tcx Body) {
-        for argument in &body.arguments {
+        for param in &body.params {
             if let (None, Some(ty)) = (
                 self.found_arg_pattern,
-                self.node_matches_type(argument.hir_id),
+                self.node_matches_type(param.hir_id),
             ) {
-                self.found_arg_pattern = Some(&*argument.pat);
+                self.found_arg_pattern = Some(&*param.pat);
                 self.found_ty = Some(ty);
             }
         }
diff --git a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs
index 6bd2c04d51281..979815fa7f184 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/different_lifetimes.rs
@@ -2,7 +2,7 @@
 //! where both the regions are anonymous.
 
 use crate::infer::error_reporting::nice_region_error::NiceRegionError;
-use crate::infer::error_reporting::nice_region_error::util::AnonymousArgInfo;
+use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
 use crate::util::common::ErrorReported;
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
@@ -59,13 +59,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         let ty_sub = self.find_anon_type(sub, &bregion_sub)?;
 
         debug!(
-            "try_report_anon_anon_conflict: found_arg1={:?} sup={:?} br1={:?}",
+            "try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}",
             ty_sub,
             sup,
             bregion_sup
         );
         debug!(
-            "try_report_anon_anon_conflict: found_arg2={:?} sub={:?} br2={:?}",
+            "try_report_anon_anon_conflict: found_param2={:?} sub={:?} br2={:?}",
             ty_sup,
             sub,
             bregion_sub
@@ -74,24 +74,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         let (ty_sup, ty_fndecl_sup) = ty_sup;
         let (ty_sub, ty_fndecl_sub) = ty_sub;
 
-        let AnonymousArgInfo {
-            arg: anon_arg_sup, ..
-        } = self.find_arg_with_region(sup, sup)?;
-        let AnonymousArgInfo {
-            arg: anon_arg_sub, ..
-        } = self.find_arg_with_region(sub, sub)?;
+        let AnonymousParamInfo {
+            param: anon_param_sup, ..
+        } = self.find_param_with_region(sup, sup)?;
+        let AnonymousParamInfo {
+            param: anon_param_sub, ..
+        } = self.find_param_with_region(sub, sub)?;
 
         let sup_is_ret_type =
             self.is_return_type_anon(scope_def_id_sup, bregion_sup, ty_fndecl_sup);
         let sub_is_ret_type =
             self.is_return_type_anon(scope_def_id_sub, bregion_sub, ty_fndecl_sub);
 
-        let span_label_var1 = match anon_arg_sup.pat.simple_ident() {
+        let span_label_var1 = match anon_param_sup.pat.simple_ident() {
             Some(simple_ident) => format!(" from `{}`", simple_ident),
             None => String::new(),
         };
 
-        let span_label_var2 = match anon_arg_sub.pat.simple_ident() {
+        let span_label_var2 = match anon_param_sub.pat.simple_ident() {
             Some(simple_ident) => format!(" into `{}`", simple_ident),
             None => String::new(),
         };
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 51bee49b70fc0..604115cfc3711 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
@@ -6,7 +6,7 @@ use crate::ty;
 use errors::{Applicability, DiagnosticBuilder};
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
-    /// When given a `ConcreteFailure` for a function with arguments containing a named region and
+    /// When given a `ConcreteFailure` for a function with parameters containing a named region and
     /// an anonymous region, emit an descriptive diagnostic error.
     pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<'a>> {
         let (span, sub, sup) = self.get_regions();
@@ -24,23 +24,23 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         // only introduced anonymous regions in parameters) as well as a
         // version new_ty of its type where the anonymous region is replaced
         // with the named one.//scope_def_id
-        let (named, anon, anon_arg_info, region_info) = if self.is_named_region(sub)
+        let (named, anon, anon_param_info, region_info) = if self.is_named_region(sub)
             && self.tcx().is_suitable_region(sup).is_some()
-            && self.find_arg_with_region(sup, sub).is_some()
+            && self.find_param_with_region(sup, sub).is_some()
         {
             (
                 sub,
                 sup,
-                self.find_arg_with_region(sup, sub).unwrap(),
+                self.find_param_with_region(sup, sub).unwrap(),
                 self.tcx().is_suitable_region(sup).unwrap(),
             )
         } else if self.is_named_region(sup) && self.tcx().is_suitable_region(sub).is_some()
-            && self.find_arg_with_region(sub, sup).is_some()
+            && self.find_param_with_region(sub, sup).is_some()
         {
             (
                 sup,
                 sub,
-                self.find_arg_with_region(sub, sup).unwrap(),
+                self.find_param_with_region(sub, sup).unwrap(),
                 self.tcx().is_suitable_region(sub).unwrap(),
             )
         } else {
@@ -49,20 +49,20 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
 
         debug!("try_report_named_anon_conflict: named = {:?}", named);
         debug!(
-            "try_report_named_anon_conflict: anon_arg_info = {:?}",
-            anon_arg_info
+            "try_report_named_anon_conflict: anon_param_info = {:?}",
+            anon_param_info
         );
         debug!(
             "try_report_named_anon_conflict: region_info = {:?}",
             region_info
         );
 
-        let (arg, new_ty, new_ty_span, br, is_first, scope_def_id, is_impl_item) = (
-            anon_arg_info.arg,
-            anon_arg_info.arg_ty,
-            anon_arg_info.arg_ty_span,
-            anon_arg_info.bound_region,
-            anon_arg_info.is_first,
+        let (param, new_ty, new_ty_span, br, is_first, scope_def_id, is_impl_item) = (
+            anon_param_info.param,
+            anon_param_info.param_ty,
+            anon_param_info.param_ty_span,
+            anon_param_info.bound_region,
+            anon_param_info.is_first,
             region_info.def_id,
             region_info.is_impl_item,
         );
@@ -95,7 +95,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             }
         }
 
-        let (error_var, span_label_var) = match arg.pat.simple_ident() {
+        let (error_var, span_label_var) = match param.pat.simple_ident() {
             Some(simple_ident) => (
                 format!("the type of `{}`", simple_ident),
                 format!("the type of `{}`", simple_ident),
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 f33f917392653..668c99da0034f 100644
--- a/src/librustc/infer/error_reporting/nice_region_error/util.rs
+++ b/src/librustc/infer/error_reporting/nice_region_error/util.rs
@@ -10,37 +10,37 @@ use syntax_pos::Span;
 // The struct contains the information about the anonymous region
 // we are searching for.
 #[derive(Debug)]
-pub(super) struct AnonymousArgInfo<'tcx> {
-    // the argument corresponding to the anonymous region
-    pub arg: &'tcx hir::Arg,
-    // the type corresponding to the anonymopus region argument
-    pub arg_ty: Ty<'tcx>,
+pub(super) struct AnonymousParamInfo<'tcx> {
+    // the parameter corresponding to the anonymous region
+    pub param: &'tcx hir::Param,
+    // the type corresponding to the anonymopus region parameter
+    pub param_ty: Ty<'tcx>,
     // the ty::BoundRegion corresponding to the anonymous region
     pub bound_region: ty::BoundRegion,
-    // arg_ty_span contains span of argument type
-    pub arg_ty_span : Span,
+    // param_ty_span contains span of parameter type
+    pub param_ty_span : Span,
     // corresponds to id the argument is the first parameter
     // in the declaration
     pub is_first: bool,
 }
 
 impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
-    // This method walks the Type of the function body arguments using
+    // This method walks the Type of the function body parameters using
     // `fold_regions()` function and returns the
-    // &hir::Arg of the function argument corresponding to the anonymous
+    // &hir::Param of the function parameter corresponding to the anonymous
     // region and the Ty corresponding to the named region.
     // Currently only the case where the function declaration consists of
     // one named region and one anonymous region is handled.
     // Consider the example `fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32`
-    // Here, we would return the hir::Arg for y, we return the type &'a
+    // Here, we would return the hir::Param for y, we return the type &'a
     // i32, which is the type of y but with the anonymous region replaced
     // with 'a, the corresponding bound region and is_first which is true if
-    // the hir::Arg is the first argument in the function declaration.
-    pub(super) fn find_arg_with_region(
+    // the hir::Param is the first parameter in the function declaration.
+    pub(super) fn find_param_with_region(
         &self,
         anon_region: Region<'tcx>,
         replace_region: Region<'tcx>,
-    ) -> Option<AnonymousArgInfo<'_>> {
+    ) -> Option<AnonymousParamInfo<'_>> {
         let (id, bound_region) = match *anon_region {
             ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region),
             ty::ReEarlyBound(ebr) => (
@@ -57,16 +57,16 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                 let owner_id = hir.body_owner(body_id);
                 let fn_decl = hir.fn_decl_by_hir_id(owner_id).unwrap();
                 if let Some(tables) = self.tables {
-                    body.arguments
+                    body.params
                         .iter()
                         .enumerate()
-                        .filter_map(|(index, arg)| {
+                        .filter_map(|(index, param)| {
                             // 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(ty_hir_id);
-                            let ty = tables.node_type_opt(arg.hir_id)?;
+                            let param_ty_span = hir.span(ty_hir_id);
+                            let ty = tables.node_type_opt(param.hir_id)?;
                             let mut found_anon_region = false;
-                            let new_arg_ty = self.tcx().fold_regions(&ty, &mut false, |r, _| {
+                            let new_param_ty = self.tcx().fold_regions(&ty, &mut false, |r, _| {
                                 if *r == *anon_region {
                                     found_anon_region = true;
                                     replace_region
@@ -76,10 +76,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
                             });
                             if found_anon_region {
                                 let is_first = index == 0;
-                                Some(AnonymousArgInfo {
-                                    arg: arg,
-                                    arg_ty: new_arg_ty,
-                                    arg_ty_span : arg_ty_span,
+                                Some(AnonymousParamInfo {
+                                    param: param,
+                                    param_ty: new_param_ty,
+                                    param_ty_span : param_ty_span,
                                     bound_region: bound_region,
                                     is_first: is_first,
                                 })
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 8126db1429247..affda256322a4 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -966,10 +966,10 @@ for LateContextAndPass<'a, 'tcx, T> {
         self.context.tables = old_tables;
     }
 
-    fn visit_arg(&mut self, arg: &'tcx hir::Arg) {
-        self.with_lint_attrs(arg.hir_id, &arg.attrs, |cx| {
-            lint_callback!(cx, check_arg, arg);
-            hir_visit::walk_arg(cx, arg);
+    fn visit_param(&mut self, param: &'tcx hir::Param) {
+        self.with_lint_attrs(param.hir_id, &param.attrs, |cx| {
+            lint_callback!(cx, check_param, param);
+            hir_visit::walk_param(cx, param);
         });
     }
 
@@ -1163,10 +1163,10 @@ for LateContextAndPass<'a, 'tcx, T> {
 }
 
 impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> {
-    fn visit_arg(&mut self, arg: &'a ast::Arg) {
-        self.with_lint_attrs(arg.id, &arg.attrs, |cx| {
-            run_early_pass!(cx, check_arg, arg);
-            ast_visit::walk_arg(cx, arg);
+    fn visit_param(&mut self, param: &'a ast::Param) {
+        self.with_lint_attrs(param.id, &param.attrs, |cx| {
+            run_early_pass!(cx, check_param, param);
+            ast_visit::walk_param(cx, param);
         });
     }
 
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 7e2707b98d50a..a3518b2b478ad 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -206,7 +206,7 @@ macro_rules! declare_lint_pass {
 macro_rules! late_lint_methods {
     ($macro:path, $args:tt, [$hir:tt]) => (
         $macro!($args, [$hir], [
-            fn check_arg(a: &$hir hir::Arg);
+            fn check_param(a: &$hir hir::Param);
             fn check_body(a: &$hir hir::Body);
             fn check_body_post(a: &$hir hir::Body);
             fn check_name(a: Span, b: ast::Name);
@@ -349,7 +349,7 @@ macro_rules! declare_combined_late_lint_pass {
 macro_rules! early_lint_methods {
     ($macro:path, $args:tt) => (
         $macro!($args, [
-            fn check_arg(a: &ast::Arg);
+            fn check_param(a: &ast::Param);
             fn check_ident(a: ast::Ident);
             fn check_crate(a: &ast::Crate);
             fn check_crate_post(a: &ast::Crate);
@@ -792,9 +792,9 @@ impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> {
         intravisit::NestedVisitorMap::All(&self.tcx.hir())
     }
 
-    fn visit_arg(&mut self, arg: &'tcx hir::Arg) {
-        self.with_lint_attrs(arg.hir_id, &arg.attrs, |builder| {
-            intravisit::walk_arg(builder, arg);
+    fn visit_param(&mut self, param: &'tcx hir::Param) {
+        self.with_lint_attrs(param.hir_id, &param.attrs, |builder| {
+            intravisit::walk_param(builder, param);
         });
     }
 
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index a274d7bbee5f7..222c2a405d65b 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -313,9 +313,9 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
     pub fn consume_body(&mut self, body: &hir::Body) {
         debug!("consume_body(body={:?})", body);
 
-        for arg in &body.arguments {
-            let arg_ty = return_if_err!(self.mc.pat_ty_adjusted(&arg.pat));
-            debug!("consume_body: arg_ty = {:?}", arg_ty);
+        for param in &body.params {
+            let param_ty = return_if_err!(self.mc.pat_ty_adjusted(&param.pat));
+            debug!("consume_body: param_ty = {:?}", param_ty);
 
             let fn_body_scope_r =
                 self.tcx().mk_region(ty::ReScope(
@@ -323,13 +323,13 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                         id: body.value.hir_id.local_id,
                         data: region::ScopeData::Node
                 }));
-            let arg_cmt = Rc::new(self.mc.cat_rvalue(
-                arg.hir_id,
-                arg.pat.span,
-                fn_body_scope_r, // Args live only as long as the fn body.
-                arg_ty));
+            let param_cmt = Rc::new(self.mc.cat_rvalue(
+                param.hir_id,
+                param.pat.span,
+                fn_body_scope_r, // Parameters live only as long as the fn body.
+                param_ty));
 
-            self.walk_irrefutable_pat(arg_cmt, &arg.pat);
+            self.walk_irrefutable_pat(param_cmt, &param.pat);
         }
 
         self.consume_expr(&body.value);
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 9c9e8c0bca3b8..00013bfc574f4 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -242,7 +242,7 @@ struct LocalInfo {
 
 #[derive(Copy, Clone, Debug)]
 enum VarKind {
-    Arg(HirId, ast::Name),
+    Param(HirId, ast::Name),
     Local(LocalInfo),
     CleanExit
 }
@@ -298,7 +298,7 @@ impl IrMaps<'tcx> {
         self.num_vars += 1;
 
         match vk {
-            Local(LocalInfo { id: node_id, .. }) | Arg(node_id, _) => {
+            Local(LocalInfo { id: node_id, .. }) | Param(node_id, _) => {
                 self.variable_map.insert(node_id, v);
             },
             CleanExit => {}
@@ -320,7 +320,7 @@ impl IrMaps<'tcx> {
 
     fn variable_name(&self, var: Variable) -> String {
         match self.var_kinds[var.get()] {
-            Local(LocalInfo { name, .. }) | Arg(_, name) => {
+            Local(LocalInfo { name, .. }) | Param(_, name) => {
                 name.to_string()
             },
             CleanExit => "<clean-exit>".to_owned()
@@ -330,7 +330,7 @@ impl IrMaps<'tcx> {
     fn variable_is_shorthand(&self, var: Variable) -> bool {
         match self.var_kinds[var.get()] {
             Local(LocalInfo { is_shorthand, .. }) => is_shorthand,
-            Arg(..) | CleanExit => false
+            Param(..) | CleanExit => false
         }
     }
 
@@ -371,13 +371,13 @@ fn visit_fn<'tcx>(
 
     let body = ir.tcx.hir().body(body_id);
 
-    for arg in &body.arguments {
-        let is_shorthand = match arg.pat.node {
+    for param in &body.params {
+        let is_shorthand = match param.pat.node {
             crate::hir::PatKind::Struct(..) => true,
             _ => false,
         };
-        arg.pat.each_binding(|_bm, hir_id, _x, ident| {
-            debug!("adding argument {:?}", hir_id);
+        param.pat.each_binding(|_bm, hir_id, _x, ident| {
+            debug!("adding parameters {:?}", hir_id);
             let var = if is_shorthand {
                 Local(LocalInfo {
                     id: hir_id,
@@ -385,7 +385,7 @@ fn visit_fn<'tcx>(
                     is_shorthand: true,
                 })
             } else {
-                Arg(hir_id, ident.name)
+                Param(hir_id, ident.name)
             };
             fn_maps.add_variable(var);
         })
@@ -1525,8 +1525,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     }
 
     fn warn_about_unused_args(&self, body: &hir::Body, entry_ln: LiveNode) {
-        for arg in &body.arguments {
-            arg.pat.each_binding(|_bm, hir_id, _, ident| {
+        for param in &body.params {
+            param.pat.each_binding(|_bm, hir_id, _, ident| {
                 let sp = ident.span;
                 let var = self.variable(hir_id, sp);
                 // Ignore unused self.
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 3d100d2fbf833..28aa86ef9afb2 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -1383,8 +1383,8 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
 
         // The arguments and `self` are parented to the fn.
         self.cx.var_parent = self.cx.parent.take();
-        for argument in &body.arguments {
-            self.visit_pat(&argument.pat);
+        for param in &body.params {
+            self.visit_pat(&param.pat);
         }
 
         // The body of the every fn is a root scope.
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index f5b0af61693be..8836a632a7ca8 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -2557,7 +2557,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             } = info;
 
             let help_name = if let Some(ident) = parent.and_then(|body| {
-                self.tcx.hir().body(body).arguments[index].pat.simple_ident()
+                self.tcx.hir().body(body).params[index].pat.simple_ident()
             }) {
                 format!("`{}`", ident)
             } else {
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index ba92e851141a6..93742c83be440 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1044,7 +1044,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 node: hir::ExprKind::Closure(_, ref _decl, id, span, _),
                 ..
             }) => {
-                (self.tcx.sess.source_map().def_span(span), self.tcx.hir().body(id).arguments.iter()
+                (self.tcx.sess.source_map().def_span(span),
+                 self.tcx.hir().body(id).params.iter()
                     .map(|arg| {
                         if let hir::Pat {
                             node: hir::PatKind::Tuple(ref args, _),
diff --git a/src/librustc_ast_borrowck/dataflow.rs b/src/librustc_ast_borrowck/dataflow.rs
index 94849728a9319..3a4c8c924764e 100644
--- a/src/librustc_ast_borrowck/dataflow.rs
+++ b/src/librustc_ast_borrowck/dataflow.rs
@@ -186,8 +186,8 @@ fn build_local_id_to_index(body: Option<&hir::Body>,
             index: &'a mut FxHashMap<hir::ItemLocalId, Vec<CFGIndex>>,
         }
         let mut formals = Formals { entry: entry, index: index };
-        for arg in &body.arguments {
-            formals.visit_pat(&arg.pat);
+        for param in &body.params {
+            formals.visit_pat(&param.pat);
         }
         impl<'a, 'v> Visitor<'v> for Formals<'a> {
             fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'v> {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 7aeeef00ea934..3fbd11bd22a7c 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -166,7 +166,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     // a `fn` when encoding, so the dep-tracking wouldn't work.
     // This is only used by rustdoc anyway, which shouldn't have
     // incremental recompilation ever enabled.
-    fn_arg_names => { cdata.get_fn_arg_names(def_id.index) }
+    fn_arg_names => { cdata.get_fn_param_names(def_id.index) }
     rendered_const => { cdata.get_rendered_const(def_id.index) }
     impl_parent => { cdata.get_parent_impl(def_id.index) }
     trait_of_item => { cdata.get_trait_of_item(def_id.index) }
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 5b9cb966af235..ede31fe69b6ff 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1150,14 +1150,14 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    pub fn get_fn_arg_names(&self, id: DefIndex) -> Vec<ast::Name> {
-        let arg_names = match self.entry(id).kind {
+    pub fn get_fn_param_names(&self, id: DefIndex) -> Vec<ast::Name> {
+        let param_names = match self.entry(id).kind {
             EntryKind::Fn(data) |
-            EntryKind::ForeignFn(data) => data.decode(self).arg_names,
-            EntryKind::Method(data) => data.decode(self).fn_data.arg_names,
+            EntryKind::ForeignFn(data) => data.decode(self).param_names,
+            EntryKind::Method(data) => data.decode(self).fn_data.param_names,
             _ => Lazy::empty(),
         };
-        arg_names.decode(self).collect()
+        param_names.decode(self).collect()
     }
 
     pub fn exported_symbols(
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 1797d77461567..0eafcebefd745 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -869,18 +869,18 @@ impl EncodeContext<'tcx> {
             }
             ty::AssocKind::Method => {
                 let fn_data = if let hir::TraitItemKind::Method(_, ref m) = ast_item.node {
-                    let arg_names = match *m {
+                    let param_names = match *m {
                         hir::TraitMethod::Required(ref names) => {
-                            self.encode_fn_arg_names(names)
+                            self.encode_fn_param_names(names)
                         }
                         hir::TraitMethod::Provided(body) => {
-                            self.encode_fn_arg_names_for_body(body)
+                            self.encode_fn_param_names_for_body(body)
                         }
                     };
                     FnData {
                         constness: hir::Constness::NotConst,
-                        arg_names,
-                        sig: self.lazy(tcx.fn_sig(def_id)),
+                        param_names,
+                        sig: self.lazy(&tcx.fn_sig(def_id)),
                     }
                 } else {
                     bug!()
@@ -976,8 +976,8 @@ impl EncodeContext<'tcx> {
                 let fn_data = if let hir::ImplItemKind::Method(ref sig, body) = ast_item.node {
                     FnData {
                         constness: sig.header.constness,
-                        arg_names: self.encode_fn_arg_names_for_body(body),
-                        sig: self.lazy(tcx.fn_sig(def_id)),
+                        param_names: self.encode_fn_param_names_for_body(body),
+                        sig: self.lazy(&tcx.fn_sig(def_id)),
                     }
                 } else {
                     bug!()
@@ -1033,11 +1033,11 @@ impl EncodeContext<'tcx> {
         }
     }
 
-    fn encode_fn_arg_names_for_body(&mut self, body_id: hir::BodyId)
+    fn encode_fn_param_names_for_body(&mut self, body_id: hir::BodyId)
                                     -> Lazy<[ast::Name]> {
         self.tcx.dep_graph.with_ignore(|| {
             let body = self.tcx.hir().body(body_id);
-            self.lazy(body.arguments.iter().map(|arg| {
+            self.lazy(body.params.iter().map(|arg| {
                 match arg.pat.node {
                     PatKind::Binding(_, _, ident, _) => ident.name,
                     _ => kw::Invalid,
@@ -1046,7 +1046,7 @@ impl EncodeContext<'tcx> {
         })
     }
 
-    fn encode_fn_arg_names(&mut self, param_names: &[ast::Ident]) -> Lazy<[ast::Name]> {
+    fn encode_fn_param_names(&mut self, param_names: &[ast::Ident]) -> Lazy<[ast::Name]> {
         self.lazy(param_names.iter().map(|ident| ident.name))
     }
 
@@ -1122,7 +1122,7 @@ impl EncodeContext<'tcx> {
             hir::ItemKind::Fn(_, header, .., body) => {
                 let data = FnData {
                     constness: header.constness,
-                    arg_names: self.encode_fn_arg_names_for_body(body),
+                    param_names: self.encode_fn_param_names_for_body(body),
                     sig: self.lazy(tcx.fn_sig(def_id)),
                 };
 
@@ -1663,7 +1663,7 @@ impl EncodeContext<'tcx> {
             hir::ForeignItemKind::Fn(_, ref names, _) => {
                 let data = FnData {
                     constness: hir::Constness::NotConst,
-                    arg_names: self.encode_fn_arg_names(names),
+                    param_names: self.encode_fn_param_names(names),
                     sig: self.lazy(tcx.fn_sig(def_id)),
                 };
                 EntryKind::ForeignFn(self.lazy(data))
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 72a4b527c93d0..1a5887bbf4ed8 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -295,7 +295,7 @@ pub struct MacroDef {
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct FnData<'tcx> {
     pub constness: hir::Constness,
-    pub arg_names: Lazy<[ast::Name]>,
+    pub param_names: Lazy<[ast::Name]>,
     pub sig: Lazy<ty::PolyFnSig<'tcx>>,
 }
 
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 61be17327ffda..7ab0bf7d66a64 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -94,7 +94,7 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
 
             let body = tcx.hir().body(body_id);
             let explicit_arguments =
-                body.arguments
+                body.params
                     .iter()
                     .enumerate()
                     .map(|(index, arg)| {
@@ -511,7 +511,7 @@ fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool {
 ///////////////////////////////////////////////////////////////////////////
 /// the main entry point for building MIR for a function
 
-struct ArgInfo<'tcx>(Ty<'tcx>, Option<Span>, Option<&'tcx hir::Arg>, Option<ImplicitSelfKind>);
+struct ArgInfo<'tcx>(Ty<'tcx>, Option<Span>, Option<&'tcx hir::Param>, Option<ImplicitSelfKind>);
 
 fn construct_fn<'a, 'tcx, A>(
     hir: Cx<'a, 'tcx>,
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 17fd9377a1629..5352888006c30 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -91,9 +91,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
     fn visit_body(&mut self, body: &'tcx hir::Body) {
         intravisit::walk_body(self, body);
 
-        for arg in &body.arguments {
-            self.check_irrefutable(&arg.pat, "function argument");
-            self.check_patterns(false, slice::from_ref(&arg.pat));
+        for param in &body.params {
+            self.check_irrefutable(&param.pat, "function argument");
+            self.check_patterns(false, slice::from_ref(&param.pat));
         }
     }
 }
diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs
index 7e03df5b75bdc..a5924efefc2af 100644
--- a/src/librustc_passes/hir_stats.rs
+++ b/src/librustc_passes/hir_stats.rs
@@ -94,9 +94,9 @@ impl<'k> StatCollector<'k> {
 }
 
 impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
-    fn visit_arg(&mut self, arg: &'v hir::Arg) {
-        self.record("Arg", Id::Node(arg.hir_id), arg);
-        hir_visit::walk_arg(self, arg)
+    fn visit_param(&mut self, param: &'v hir::Param) {
+        self.record("Param", Id::Node(param.hir_id), param);
+        hir_visit::walk_param(self, param)
     }
 
     fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'v> {
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 9068605b0753c..d1fd51a97f683 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -230,7 +230,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         }
     }
 
-    fn process_formals(&mut self, formals: &'l [ast::Arg], qualname: &str) {
+    fn process_formals(&mut self, formals: &'l [ast::Param], qualname: &str) {
         for arg in formals {
             self.visit_pat(&arg.pat);
             let mut collector = PathCollector::new();
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 0bbbbb8249c20..92ccd4f49f6b9 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -32,7 +32,7 @@ use syntax::source_map::Spanned;
 use syntax::parse::lexer::comments::strip_doc_comment_decoration;
 use syntax::print::pprust;
 use syntax::visit::{self, Visitor};
-use syntax::print::pprust::{arg_to_string, ty_to_string};
+use syntax::print::pprust::{param_to_string, ty_to_string};
 use syntax_pos::*;
 
 use dump_visitor::DumpVisitor;
@@ -934,7 +934,7 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String {
     sig.push('(');
     sig.push_str(&decl.inputs
         .iter()
-        .map(arg_to_string)
+        .map(param_to_string)
         .collect::<Vec<_>>()
         .join(", "));
     sig.push(')');
diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 0efc433341c1f..63137bad52ff8 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -224,13 +224,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// fn takes_ref(_: &Foo) {}
     /// let ref opt = Some(Foo);
     ///
-    /// opt.map(|arg| takes_ref(arg));
+    /// opt.map(|param| takes_ref(param));
     /// ```
-    /// Suggest using `opt.as_ref().map(|arg| takes_ref(arg));` instead.
+    /// Suggest using `opt.as_ref().map(|param| takes_ref(param));` instead.
     ///
     /// It only checks for `Option` and `Result` and won't work with
     /// ```
-    /// opt.map(|arg| { takes_ref(arg) });
+    /// opt.map(|param| { takes_ref(param) });
     /// ```
     fn can_use_as_ref(
         &self,
@@ -247,13 +247,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         let local_parent = self.tcx.hir().get_parent_node(local_id);
-        let arg_hir_id = match self.tcx.hir().find(local_parent) {
-            Some(Node::Arg(hir::Arg { hir_id, .. })) => hir_id,
+        let param_hir_id = match self.tcx.hir().find(local_parent) {
+            Some(Node::Param(hir::Param { hir_id, .. })) => hir_id,
             _ => return None
         };
 
-        let arg_parent = self.tcx.hir().get_parent_node(*arg_hir_id);
-        let (expr_hir_id, closure_fn_decl) = match self.tcx.hir().find(arg_parent) {
+        let param_parent = self.tcx.hir().get_parent_node(*param_hir_id);
+        let (expr_hir_id, closure_fn_decl) = match self.tcx.hir().find(param_parent) {
             Some(Node::Expr(
                 hir::Expr { hir_id, node: hir::ExprKind::Closure(_, decl, ..), .. }
             )) => (hir_id, decl),
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c4dbe97a7bd96..2a3c422fe0438 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1102,19 +1102,19 @@ fn check_fn<'a, 'tcx>(
     GatherLocalsVisitor { fcx: &fcx, parent_id: outer_hir_id, }.visit_body(body);
 
     // Add formal parameters.
-    for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
+    for (param_ty, param) in fn_sig.inputs().iter().zip(&body.params) {
         // Check the pattern.
-        fcx.check_pat_top(&arg.pat, arg_ty, None);
+        fcx.check_pat_top(&param.pat, param_ty, None);
 
         // Check that argument is Sized.
         // The check for a non-trivial pattern is a hack to avoid duplicate warnings
         // for simple cases like `fn foo(x: Trait)`,
         // where we would error once on the parameter as a whole, and once on the binding `x`.
-        if arg.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
-            fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::SizedArgumentType);
+        if param.pat.simple_ident().is_none() && !fcx.tcx.features().unsized_locals {
+            fcx.require_type_is_sized(param_ty, decl.output.span(), traits::SizedArgumentType);
         }
 
-        fcx.write_ty(arg.hir_id, arg_ty);
+        fcx.write_ty(param.hir_id, param_ty);
     }
 
     inherited.tables.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
@@ -3952,8 +3952,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     ..
                 })) => {
                     let body = hir.body(*body_id);
-                    sugg_call = body.arguments.iter()
-                        .map(|arg| match &arg.pat.node {
+                    sugg_call = body.params.iter()
+                        .map(|param| match &param.pat.node {
                             hir::PatKind::Binding(_, _, ident, None)
                             if ident.name != kw::SelfLower => ident.to_string(),
                             _ => "_".to_string(),
@@ -3970,8 +3970,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     err.span_label(*closure_span, "closure defined here");
                     msg = "call this closure";
                     let body = hir.body(*body_id);
-                    sugg_call = body.arguments.iter()
-                        .map(|arg| match &arg.pat.node {
+                    sugg_call = body.params.iter()
+                        .map(|param| match &param.pat.node {
                             hir::PatKind::Binding(_, _, ident, None)
                             if ident.name != kw::SelfLower => ident.to_string(),
                             _ => "_".to_string(),
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 3f6fc95360a5e..4cf0df308fb4c 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -468,7 +468,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let binding_parent = tcx.hir().get(binding_parent_id);
             debug!("inner {:?} pat {:?} parent {:?}", inner, pat, binding_parent);
             match binding_parent {
-                hir::Node::Arg(hir::Arg { span, .. }) => {
+                hir::Node::Param(hir::Param { span, .. }) => {
                     if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(inner.span) {
                         err.span_suggestion(
                             *span,
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 3f9e662c6f412..fc01a820e2359 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -347,12 +347,12 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         );
         self.outlives_environment
             .save_implied_bounds(body_id.hir_id);
-        self.link_fn_args(
+        self.link_fn_params(
             region::Scope {
                 id: body.value.hir_id.local_id,
                 data: region::ScopeData::Node,
             },
-            &body.arguments,
+            &body.params,
         );
         self.visit_body(body);
         self.visit_region_obligations(body_id.hir_id);
@@ -1078,16 +1078,16 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     /// Computes the guarantors for any ref bindings in a match and
     /// then ensures that the lifetime of the resulting pointer is
     /// linked to the lifetime of its guarantor (if any).
-    fn link_fn_args(&self, body_scope: region::Scope, args: &[hir::Arg]) {
-        debug!("regionck::link_fn_args(body_scope={:?})", body_scope);
-        for arg in args {
-            let arg_ty = self.node_ty(arg.hir_id);
+    fn link_fn_params(&self, body_scope: region::Scope, params: &[hir::Param]) {
+        debug!("regionck::link_fn_params(body_scope={:?})", body_scope);
+        for param in params {
+            let param_ty = self.node_ty(param.hir_id);
             let re_scope = self.tcx.mk_region(ty::ReScope(body_scope));
-            let arg_cmt = self.with_mc(|mc| {
-                Rc::new(mc.cat_rvalue(arg.hir_id, arg.pat.span, re_scope, arg_ty))
+            let param_cmt = self.with_mc(|mc| {
+                Rc::new(mc.cat_rvalue(param.hir_id, param.pat.span, re_scope, param_ty))
             });
-            debug!("arg_ty={:?} arg_cmt={:?} arg={:?}", arg_ty, arg_cmt, arg);
-            self.link_pattern(arg_cmt, &arg.pat);
+            debug!("param_ty={:?} param_cmt={:?} param={:?}", param_ty, param_cmt, param);
+            self.link_pattern(param_cmt, &param.pat);
         }
     }
 
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index a88e32eb34dcd..487dc8ec2ae0c 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -39,8 +39,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let rustc_dump_user_substs = self.tcx.has_attr(item_def_id, sym::rustc_dump_user_substs);
 
         let mut wbcx = WritebackCx::new(self, body, rustc_dump_user_substs);
-        for arg in &body.arguments {
-            wbcx.visit_node_id(arg.pat.span, arg.hir_id);
+        for param in &body.params {
+            wbcx.visit_node_id(param.pat.span, param.hir_id);
         }
         // Type only exists for constants and statics, not functions.
         match self.tcx.hir().body_owner_kind(item_id) {
@@ -245,8 +245,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
         match e.node {
             hir::ExprKind::Closure(_, _, body, _, _) => {
                 let body = self.fcx.tcx.hir().body(body);
-                for arg in &body.arguments {
-                    self.visit_node_id(e.span, arg.hir_id);
+                for param in &body.params {
+                    self.visit_node_id(e.span, param.hir_id);
                 }
 
                 self.visit_body(body);
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ba792a413b3c4..629892e60727b 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2120,7 +2120,7 @@ impl<'a> Clean<Arguments> for (&'a [hir::Ty], hir::BodyId) {
         Arguments {
             values: self.0.iter().enumerate().map(|(i, ty)| {
                 Argument {
-                    name: name_from_pat(&body.arguments[i].pat),
+                    name: name_from_pat(&body.params[i].pat),
                     type_: ty.clean(cx),
                 }
             }).collect()
@@ -3804,7 +3804,7 @@ pub struct BareFunctionDecl {
 impl Clean<BareFunctionDecl> for hir::BareFnTy {
     fn clean(&self, cx: &DocContext<'_>) -> BareFunctionDecl {
         let (generic_params, decl) = enter_impl_trait(cx, || {
-            (self.generic_params.clean(cx), (&*self.decl, &self.arg_names[..]).clean(cx))
+            (self.generic_params.clean(cx), (&*self.decl, &self.param_names[..]).clean(cx))
         });
         BareFunctionDecl {
             unsafety: self.unsafety,
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 50e428ea0cca6..6be00bcef45c0 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1789,11 +1789,11 @@ pub struct InlineAsm {
     pub dialect: AsmDialect,
 }
 
-/// An argument in a function header.
+/// A parameter in a function header.
 ///
 /// E.g., `bar: usize` as in `fn foo(bar: usize)`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
-pub struct Arg {
+pub struct Param {
     pub attrs: ThinVec<Attribute>,
     pub ty: P<Ty>,
     pub pat: P<Pat>,
@@ -1816,7 +1816,7 @@ pub enum SelfKind {
 
 pub type ExplicitSelf = Spanned<SelfKind>;
 
-impl Arg {
+impl Param {
     pub fn to_self(&self) -> Option<ExplicitSelf> {
         if let PatKind::Ident(BindingMode::ByValue(mutbl), ident, _) = self.pat.node {
             if ident.name == kw::SelfLower {
@@ -1843,14 +1843,14 @@ impl Arg {
         }
     }
 
-    pub fn from_self(attrs: ThinVec<Attribute>, eself: ExplicitSelf, eself_ident: Ident) -> Arg {
+    pub fn from_self(attrs: ThinVec<Attribute>, eself: ExplicitSelf, eself_ident: Ident) -> Param {
         let span = eself.span.to(eself_ident.span);
         let infer_ty = P(Ty {
             id: DUMMY_NODE_ID,
             node: TyKind::ImplicitSelf,
             span,
         });
-        let arg = |mutbl, ty| Arg {
+        let param = |mutbl, ty| Param {
             attrs,
             pat: P(Pat {
                 id: DUMMY_NODE_ID,
@@ -1862,9 +1862,9 @@ impl Arg {
             id: DUMMY_NODE_ID,
         };
         match eself.node {
-            SelfKind::Explicit(ty, mutbl) => arg(mutbl, ty),
-            SelfKind::Value(mutbl) => arg(mutbl, infer_ty),
-            SelfKind::Region(lt, mutbl) => arg(
+            SelfKind::Explicit(ty, mutbl) => param(mutbl, ty),
+            SelfKind::Value(mutbl) => param(mutbl, infer_ty),
+            SelfKind::Region(lt, mutbl) => param(
                 Mutability::Immutable,
                 P(Ty {
                     id: DUMMY_NODE_ID,
@@ -1887,17 +1887,17 @@ impl Arg {
 /// E.g., `fn foo(bar: baz)`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct FnDecl {
-    pub inputs: Vec<Arg>,
+    pub inputs: Vec<Param>,
     pub output: FunctionRetTy,
     pub c_variadic: bool,
 }
 
 impl FnDecl {
     pub fn get_self(&self) -> Option<ExplicitSelf> {
-        self.inputs.get(0).and_then(Arg::to_self)
+        self.inputs.get(0).and_then(Param::to_self)
     }
     pub fn has_self(&self) -> bool {
-        self.inputs.get(0).map(Arg::is_self).unwrap_or(false)
+        self.inputs.get(0).map(Param::is_self).unwrap_or(false)
     }
 }
 
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index bcf03b5237a8d..0e5cfa73a9e3a 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -714,7 +714,7 @@ macro_rules! derive_has_attrs {
 
 derive_has_attrs! {
     Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm,
-    ast::Field, ast::FieldPat, ast::Variant, ast::Arg
+    ast::Field, ast::FieldPat, ast::Variant, ast::Param
 }
 
 pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate {
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index e2ac4d573a1e0..e894fd17ff587 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -655,7 +655,7 @@ impl<'a> ExtCtxt<'a> {
               body: P<ast::Expr>)
               -> P<ast::Expr> {
         let fn_decl = self.fn_decl(
-            ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(),
+            ids.iter().map(|id| self.param(span, *id, self.ty_infer(span))).collect(),
             ast::FunctionRetTy::Default(span));
 
         // FIXME -- We are using `span` as the span of the `|...|`
@@ -693,9 +693,9 @@ impl<'a> ExtCtxt<'a> {
         self.lambda1(span, self.expr_block(self.block(span, stmts)), ident)
     }
 
-    pub fn arg(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Arg {
+    pub fn param(&self, span: Span, ident: ast::Ident, ty: P<ast::Ty>) -> ast::Param {
         let arg_pat = self.pat_ident(span, ident);
-        ast::Arg {
+        ast::Param {
             attrs: ThinVec::default(),
             id: ast::DUMMY_NODE_ID,
             pat: arg_pat,
@@ -705,7 +705,7 @@ impl<'a> ExtCtxt<'a> {
     }
 
     // FIXME: unused `self`
-    pub fn fn_decl(&self, inputs: Vec<ast::Arg>, output: ast::FunctionRetTy) -> P<ast::FnDecl> {
+    pub fn fn_decl(&self, inputs: Vec<ast::Param>, output: ast::FunctionRetTy) -> P<ast::FnDecl> {
         P(ast::FnDecl {
             inputs,
             output,
@@ -731,7 +731,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn item_fn_poly(&self,
                     span: Span,
                     name: Ident,
-                    inputs: Vec<ast::Arg> ,
+                    inputs: Vec<ast::Param> ,
                     output: P<ast::Ty>,
                     generics: Generics,
                     body: P<ast::Block>) -> P<ast::Item> {
@@ -752,7 +752,7 @@ impl<'a> ExtCtxt<'a> {
     pub fn item_fn(&self,
                span: Span,
                name: Ident,
-               inputs: Vec<ast::Arg> ,
+               inputs: Vec<ast::Param> ,
                output: P<ast::Ty>,
                body: P<ast::Block>
               ) -> P<ast::Item> {
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 414d234e43419..e14ca4b06a09e 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -225,8 +225,8 @@ pub trait MutVisitor: Sized {
         noop_visit_attribute(at, self);
     }
 
-    fn flat_map_arg(&mut self, arg: Arg) -> SmallVec<[Arg; 1]> {
-        noop_flat_map_arg(arg, self)
+    fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> {
+        noop_flat_map_param(param, self)
     }
 
     fn visit_generics(&mut self, generics: &mut Generics) {
@@ -587,14 +587,14 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
     vis.visit_span(span);
 }
 
-pub fn noop_flat_map_arg<T: MutVisitor>(mut arg: Arg, vis: &mut T) -> SmallVec<[Arg; 1]> {
-    let Arg { attrs, id, pat, span, ty } = &mut arg;
+pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> SmallVec<[Param; 1]> {
+    let Param { attrs, id, pat, span, ty } = &mut param;
     vis.visit_id(id);
     visit_thin_attrs(attrs, vis);
     vis.visit_pat(pat);
     vis.visit_span(span);
     vis.visit_ty(ty);
-    smallvec![arg]
+    smallvec![param]
 }
 
 pub fn noop_visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) {
@@ -720,7 +720,7 @@ pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut IsAsync, vis: &mut T)
 
 pub fn noop_visit_fn_decl<T: MutVisitor>(decl: &mut P<FnDecl>, vis: &mut T) {
     let FnDecl { inputs, output, c_variadic: _ } = decl.deref_mut();
-    inputs.flat_map_in_place(|arg| vis.flat_map_arg(arg));
+    inputs.flat_map_in_place(|param| vis.flat_map_param(param));
     match output {
         FunctionRetTy::Default(span) => vis.visit_span(span),
         FunctionRetTy::Ty(ty) => vis.visit_ty(ty),
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index c703058e7952d..671178223f503 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -19,7 +19,7 @@ const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
                                                      permitted in this context";
 
 impl<'a> Parser<'a> {
-    crate fn parse_arg_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
+    crate fn parse_param_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let attrs = self.parse_outer_attributes()?;
         self.sess.gated_spans.param_attrs.borrow_mut()
             .extend(attrs.iter().map(|a| a.span));
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index 1fbf28fb83016..d4e661d1a38b7 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -1,5 +1,5 @@
 use crate::ast::{
-    self, Arg, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind,
+    self, Param, BinOpKind, BindingMode, BlockCheckMode, Expr, ExprKind, Ident, Item, ItemKind,
     Mutability, Pat, PatKind, PathSegment, QSelf, Ty, TyKind, VariantData,
 };
 use crate::feature_gate::{feature_err, UnstableFeatures};
@@ -18,7 +18,7 @@ use log::{debug, trace};
 use std::mem;
 
 /// Creates a placeholder argument.
-crate fn dummy_arg(ident: Ident) -> Arg {
+crate fn dummy_arg(ident: Ident) -> Param {
     let pat = P(Pat {
         id: ast::DUMMY_NODE_ID,
         node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), ident, None),
@@ -29,7 +29,7 @@ crate fn dummy_arg(ident: Ident) -> Arg {
         span: ident.span,
         id: ast::DUMMY_NODE_ID
     };
-    Arg { attrs: ThinVec::default(), id: ast::DUMMY_NODE_ID, pat, span: ident.span, ty: P(ty) }
+    Param { attrs: ThinVec::default(), id: ast::DUMMY_NODE_ID, pat, span: ident.span, ty: P(ty) }
 }
 
 pub enum Error {
@@ -1183,7 +1183,7 @@ impl<'a> Parser<'a> {
         Err(err)
     }
 
-    crate fn eat_incorrect_doc_comment_for_arg_type(&mut self) {
+    crate fn eat_incorrect_doc_comment_for_param_type(&mut self) {
         if let token::DocComment(_) = self.token.kind {
             self.struct_span_err(
                 self.token.span,
@@ -1211,7 +1211,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    crate fn argument_without_type(
+    crate fn parameter_without_type(
         &mut self,
         err: &mut DiagnosticBuilder<'_>,
         pat: P<ast::Pat>,
@@ -1286,13 +1286,13 @@ impl<'a> Parser<'a> {
         Ok((pat, ty))
     }
 
-    crate fn recover_bad_self_arg(
+    crate fn recover_bad_self_param(
         &mut self,
-        mut arg: ast::Arg,
+        mut param: ast::Param,
         is_trait_item: bool,
-    ) -> PResult<'a, ast::Arg> {
-        let sp = arg.pat.span;
-        arg.ty.node = TyKind::Err;
+    ) -> PResult<'a, ast::Param> {
+        let sp = param.pat.span;
+        param.ty.node = TyKind::Err;
         let mut err = self.struct_span_err(sp, "unexpected `self` parameter in function");
         if is_trait_item {
             err.span_label(sp, "must be the first associated function parameter");
@@ -1301,7 +1301,7 @@ impl<'a> Parser<'a> {
             err.note("`self` is only valid as the first parameter of an associated function");
         }
         err.emit();
-        Ok(arg)
+        Ok(param)
     }
 
     crate fn consume_block(&mut self, delim: token::DelimToken) {
@@ -1344,15 +1344,15 @@ impl<'a> Parser<'a> {
         err
     }
 
-    /// Replace duplicated recovered arguments with `_` pattern to avoid unecessary errors.
+    /// Replace duplicated recovered parameters with `_` pattern to avoid unecessary errors.
     ///
     /// This is necessary because at this point we don't know whether we parsed a function with
-    /// anonymous arguments or a function with names but no types. In order to minimize
-    /// unecessary errors, we assume the arguments are in the shape of `fn foo(a, b, c)` where
-    /// the arguments are *names* (so we don't emit errors about not being able to find `b` in
+    /// anonymous parameters or a function with names but no types. In order to minimize
+    /// unecessary errors, we assume the parameters are in the shape of `fn foo(a, b, c)` where
+    /// the parameters are *names* (so we don't emit errors about not being able to find `b` in
     /// the local scope), but if we find the same name multiple times, like in `fn foo(i8, i8)`,
-    /// we deduplicate them to not complain about duplicated argument names.
-    crate fn deduplicate_recovered_arg_names(&self, fn_inputs: &mut Vec<Arg>) {
+    /// we deduplicate them to not complain about duplicated parameter names.
+    crate fn deduplicate_recovered_params_names(&self, fn_inputs: &mut Vec<Param>) {
         let mut seen_inputs = FxHashSet::default();
         for input in fn_inputs.iter_mut() {
             let opt_ident = if let (PatKind::Ident(_, ident, _), TyKind::Err) = (
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 25ad2d4404cac..bee47df942ae9 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -10,7 +10,7 @@ pub use path::PathStyle;
 mod stmt;
 mod generics;
 
-use crate::ast::{self, AttrStyle, Attribute, Arg, BindingMode, StrStyle, SelfKind};
+use crate::ast::{self, AttrStyle, Attribute, Param, BindingMode, StrStyle, SelfKind};
 use crate::ast::{FnDecl, Ident, IsAsync, MacDelimiter, Mutability, TyKind};
 use crate::ast::{Visibility, VisibilityKind, Unsafety, CrateSugar};
 use crate::source_map::{self, respan};
@@ -970,27 +970,27 @@ impl<'a> Parser<'a> {
 
     /// Skips unexpected attributes and doc comments in this position and emits an appropriate
     /// error.
-    /// This version of parse arg doesn't necessarily require identifier names.
-    fn parse_arg_general(
+    /// This version of parse param doesn't necessarily require identifier names.
+    fn parse_param_general(
         &mut self,
         is_trait_item: bool,
         allow_c_variadic: bool,
         is_name_required: impl Fn(&token::Token) -> bool,
-    ) -> PResult<'a, Arg> {
+    ) -> PResult<'a, Param> {
         let lo = self.token.span;
-        let attrs = self.parse_arg_attributes()?;
-        if let Some(mut arg) = self.parse_self_arg()? {
-            arg.attrs = attrs.into();
-            return self.recover_bad_self_arg(arg, is_trait_item);
+        let attrs = self.parse_param_attributes()?;
+        if let Some(mut param) = self.parse_self_param()? {
+            param.attrs = attrs.into();
+            return self.recover_bad_self_param(param, is_trait_item);
         }
 
         let is_name_required = is_name_required(&self.token);
         let (pat, ty) = if is_name_required || self.is_named_argument() {
-            debug!("parse_arg_general parse_pat (is_name_required:{})", is_name_required);
+            debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
 
             let pat = self.parse_fn_param_pat()?;
             if let Err(mut err) = self.expect(&token::Colon) {
-                if let Some(ident) = self.argument_without_type(
+                if let Some(ident) = self.parameter_without_type(
                     &mut err,
                     pat,
                     is_name_required,
@@ -1003,12 +1003,12 @@ impl<'a> Parser<'a> {
                 }
             }
 
-            self.eat_incorrect_doc_comment_for_arg_type();
+            self.eat_incorrect_doc_comment_for_param_type();
             (pat, self.parse_ty_common(true, true, allow_c_variadic)?)
         } else {
-            debug!("parse_arg_general ident_to_pat");
+            debug!("parse_param_general ident_to_pat");
             let parser_snapshot_before_ty = self.clone();
-            self.eat_incorrect_doc_comment_for_arg_type();
+            self.eat_incorrect_doc_comment_for_param_type();
             let mut ty = self.parse_ty_common(true, true, allow_c_variadic);
             if ty.is_ok() && self.token != token::Comma &&
                self.token != token::CloseDelim(token::Paren) {
@@ -1039,7 +1039,7 @@ impl<'a> Parser<'a> {
 
         let span = lo.to(self.token.span);
 
-        Ok(Arg { attrs: attrs.into(), id: ast::DUMMY_NODE_ID, pat, span, ty })
+        Ok(Param { attrs: attrs.into(), id: ast::DUMMY_NODE_ID, pat, span, ty })
     }
 
     /// Parses mutability (`mut` or nothing).
@@ -1185,26 +1185,26 @@ impl<'a> Parser<'a> {
 
     }
 
-    fn parse_fn_args(&mut self, named_args: bool, allow_c_variadic: bool)
-                     -> PResult<'a, (Vec<Arg> , bool)> {
+    fn parse_fn_params(&mut self, named_params: bool, allow_c_variadic: bool)
+                     -> PResult<'a, (Vec<Param> , bool)> {
         let sp = self.token.span;
         let mut c_variadic = false;
-        let (args, _): (Vec<Option<Arg>>, _) = self.parse_paren_comma_seq(|p| {
+        let (params, _): (Vec<Option<Param>>, _) = self.parse_paren_comma_seq(|p| {
             let do_not_enforce_named_arguments_for_c_variadic =
                 |token: &token::Token| -> bool {
                     if token == &token::DotDotDot {
                         false
                     } else {
-                        named_args
+                        named_params
                     }
                 };
-            match p.parse_arg_general(
+            match p.parse_param_general(
                 false,
                 allow_c_variadic,
                 do_not_enforce_named_arguments_for_c_variadic
             ) {
-                Ok(arg) => {
-                    if let TyKind::CVarArgs = arg.ty.node {
+                Ok(param) => {
+                    if let TyKind::CVarArgs = param.ty.node {
                         c_variadic = true;
                         if p.token != token::CloseDelim(token::Paren) {
                             let span = p.token.span;
@@ -1212,10 +1212,10 @@ impl<'a> Parser<'a> {
                                 "`...` must be the last argument of a C-variadic function");
                             Ok(None)
                         } else {
-                            Ok(Some(arg))
+                            Ok(Some(param))
                         }
                     } else {
-                        Ok(Some(arg))
+                        Ok(Some(param))
                     }
                 },
                 Err(mut e) => {
@@ -1230,20 +1230,20 @@ impl<'a> Parser<'a> {
             }
         })?;
 
-        let args: Vec<_> = args.into_iter().filter_map(|x| x).collect();
+        let params: Vec<_> = params.into_iter().filter_map(|x| x).collect();
 
-        if c_variadic && args.len() <= 1 {
+        if c_variadic && params.len() <= 1 {
             self.span_err(sp,
                           "C-variadic function must be declared with at least one named argument");
         }
 
-        Ok((args, c_variadic))
+        Ok((params, c_variadic))
     }
 
-    /// Returns the parsed optional self argument and whether a self shortcut was used.
+    /// Returns the parsed optional self parameter and whether a self shortcut was used.
     ///
-    /// See `parse_self_arg_with_attrs` to collect attributes.
-    fn parse_self_arg(&mut self) -> PResult<'a, Option<Arg>> {
+    /// See `parse_self_param_with_attrs` to collect attributes.
+    fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
         let expect_ident = |this: &mut Self| match this.token.kind {
             // Preserve hygienic context.
             token::Ident(name, _) =>
@@ -1348,49 +1348,51 @@ impl<'a> Parser<'a> {
         };
 
         let eself = source_map::respan(eself_lo.to(eself_hi), eself);
-        Ok(Some(Arg::from_self(ThinVec::default(), eself, eself_ident)))
+        Ok(Some(Param::from_self(ThinVec::default(), eself, eself_ident)))
     }
 
-    /// Returns the parsed optional self argument with attributes and whether a self
+    /// Returns the parsed optional self parameter with attributes and whether a self
     /// shortcut was used.
-    fn parse_self_arg_with_attrs(&mut self) -> PResult<'a, Option<Arg>> {
-        let attrs = self.parse_arg_attributes()?;
-        let arg_opt = self.parse_self_arg()?;
-        Ok(arg_opt.map(|mut arg| {
-            arg.attrs = attrs.into();
-            arg
+    fn parse_self_parameter_with_attrs(&mut self) -> PResult<'a, Option<Param>> {
+        let attrs = self.parse_param_attributes()?;
+        let param_opt = self.parse_self_param()?;
+        Ok(param_opt.map(|mut param| {
+            param.attrs = attrs.into();
+            param
         }))
     }
 
     /// Parses the parameter list and result type of a function that may have a `self` parameter.
-    fn parse_fn_decl_with_self<F>(&mut self, parse_arg_fn: F) -> PResult<'a, P<FnDecl>>
-        where F: FnMut(&mut Parser<'a>) -> PResult<'a,  Arg>,
+    fn parse_fn_decl_with_self<F>(&mut self, parse_param_fn: F) -> PResult<'a, P<FnDecl>>
+        where F: FnMut(&mut Parser<'a>) -> PResult<'a,  Param>,
     {
         self.expect(&token::OpenDelim(token::Paren))?;
 
         // Parse optional self argument.
-        let self_arg = self.parse_self_arg_with_attrs()?;
+        let self_param = self.parse_self_parameter_with_attrs()?;
 
         // Parse the rest of the function parameter list.
         let sep = SeqSep::trailing_allowed(token::Comma);
-        let (mut fn_inputs, recovered) = if let Some(self_arg) = self_arg {
+        let (mut fn_inputs, recovered) = if let Some(self_param) = self_param {
             if self.check(&token::CloseDelim(token::Paren)) {
-                (vec![self_arg], false)
+                (vec![self_param], false)
             } else if self.eat(&token::Comma) {
-                let mut fn_inputs = vec![self_arg];
+                let mut fn_inputs = vec![self_param];
                 let (mut input, _, recovered) = self.parse_seq_to_before_end(
-                    &token::CloseDelim(token::Paren), sep, parse_arg_fn)?;
+                    &token::CloseDelim(token::Paren), sep, parse_param_fn)?;
                 fn_inputs.append(&mut input);
                 (fn_inputs, recovered)
             } else {
                 match self.expect_one_of(&[], &[]) {
                     Err(err) => return Err(err),
-                    Ok(recovered) => (vec![self_arg], recovered),
+                    Ok(recovered) => (vec![self_param], recovered),
                 }
             }
         } else {
             let (input, _, recovered) =
-                self.parse_seq_to_before_end(&token::CloseDelim(token::Paren), sep, parse_arg_fn)?;
+                self.parse_seq_to_before_end(&token::CloseDelim(token::Paren),
+                                             sep,
+                                             parse_param_fn)?;
             (input, recovered)
         };
 
@@ -1398,8 +1400,8 @@ impl<'a> Parser<'a> {
             // Parse closing paren and return type.
             self.expect(&token::CloseDelim(token::Paren))?;
         }
-        // Replace duplicated recovered arguments with `_` pattern to avoid unecessary errors.
-        self.deduplicate_recovered_arg_names(&mut fn_inputs);
+        // Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
+        self.deduplicate_recovered_params_names(&mut fn_inputs);
 
         Ok(P(FnDecl {
             inputs: fn_inputs,
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index f7c090b5135e9..5b9f0f1df6718 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -7,7 +7,7 @@ use crate::maybe_recover_from_interpolated_ty_qpath;
 use crate::ptr::P;
 use crate::ast::{self, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode};
 use crate::ast::{Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm};
-use crate::ast::{Ty, TyKind, FunctionRetTy, Arg, FnDecl};
+use crate::ast::{Ty, TyKind, FunctionRetTy, Param, FnDecl};
 use crate::ast::{BinOpKind, BinOp, UnOp};
 use crate::ast::{Mac, AnonConst, Field};
 
@@ -1157,7 +1157,7 @@ impl<'a> Parser<'a> {
                     &[&token::BinOp(token::Or), &token::OrOr],
                     SeqSep::trailing_allowed(token::Comma),
                     TokenExpectType::NoExpect,
-                    |p| p.parse_fn_block_arg()
+                    |p| p.parse_fn_block_param()
                 )?.0;
                 self.expect_or()?;
                 args
@@ -1172,10 +1172,10 @@ impl<'a> Parser<'a> {
         }))
     }
 
-    /// Parses an argument in a lambda header (e.g., `|arg, arg|`).
-    fn parse_fn_block_arg(&mut self) -> PResult<'a, Arg> {
+    /// Parses a parameter in a lambda header (e.g., `|arg, arg|`).
+    fn parse_fn_block_param(&mut self) -> PResult<'a, Param> {
         let lo = self.token.span;
-        let attrs = self.parse_arg_attributes()?;
+        let attrs = self.parse_param_attributes()?;
         let pat = self.parse_pat(PARAM_EXPECTED)?;
         let t = if self.eat(&token::Colon) {
             self.parse_ty()?
@@ -1187,7 +1187,7 @@ impl<'a> Parser<'a> {
             })
         };
         let span = lo.to(self.token.span);
-        Ok(Arg {
+        Ok(Param {
             attrs: attrs.into(),
             ty: t,
             pat,
diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index 03d7e92212382..59a3ade9c30e5 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -422,7 +422,7 @@ impl<'a> Parser<'a> {
             } else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
                 let ident = self.parse_ident().unwrap();
                 self.bump();  // `(`
-                let kw_name = if let Ok(Some(_)) = self.parse_self_arg_with_attrs()
+                let kw_name = if let Ok(Some(_)) = self.parse_self_parameter_with_attrs()
                     .map_err(|mut e| e.cancel())
                 {
                     "method"
@@ -475,7 +475,7 @@ impl<'a> Parser<'a> {
                 self.eat_to_tokens(&[&token::Gt]);
                 self.bump();  // `>`
                 let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
-                    if let Ok(Some(_)) = self.parse_self_arg_with_attrs()
+                    if let Ok(Some(_)) = self.parse_self_parameter_with_attrs()
                         .map_err(|mut e| e.cancel())
                     {
                         ("fn", "method", false)
@@ -861,7 +861,7 @@ impl<'a> Parser<'a> {
             let ident = self.parse_ident()?;
             let mut generics = self.parse_generics()?;
             let decl = self.parse_fn_decl_with_self(|p| {
-                p.parse_arg_general(true, false, |_| true)
+                p.parse_param_general(true, false, |_| true)
             })?;
             generics.where_clause = self.parse_where_clause()?;
             *at_end = true;
@@ -1040,7 +1040,7 @@ impl<'a> Parser<'a> {
 
                 // We don't allow argument names to be left off in edition 2018.
                 let is_name_required = p.token.span.rust_2018();
-                p.parse_arg_general(true, false, |_| is_name_required)
+                p.parse_param_general(true, false, |_| is_name_required)
             })?;
             generics.where_clause = self.parse_where_clause()?;
 
@@ -1291,7 +1291,7 @@ impl<'a> Parser<'a> {
 
     /// Parses the argument list and result type of a function declaration.
     fn parse_fn_decl(&mut self, allow_c_variadic: bool) -> PResult<'a, P<FnDecl>> {
-        let (args, c_variadic) = self.parse_fn_args(true, allow_c_variadic)?;
+        let (args, c_variadic) = self.parse_fn_params(true, allow_c_variadic)?;
         let ret_ty = self.parse_ret_ty(true)?;
 
         Ok(P(FnDecl {
diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs
index 337702b8d30c5..465e31ac57e64 100644
--- a/src/libsyntax/parse/parser/ty.rs
+++ b/src/libsyntax/parse/parser/ty.rs
@@ -292,7 +292,7 @@ impl<'a> Parser<'a> {
         };
 
         self.expect_keyword(kw::Fn)?;
-        let (inputs, c_variadic) = self.parse_fn_args(false, true)?;
+        let (inputs, c_variadic) = self.parse_fn_params(false, true)?;
         let ret_ty = self.parse_ret_ty(false)?;
         let decl = P(FnDecl {
             inputs,
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 83a926a6217e7..bead941b20d5a 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -418,8 +418,8 @@ pub fn attribute_to_string(attr: &ast::Attribute) -> String {
     to_string(|s| s.print_attribute(attr))
 }
 
-pub fn arg_to_string(arg: &ast::Arg) -> String {
-    to_string(|s| s.print_arg(arg, false))
+pub fn param_to_string(arg: &ast::Param) -> String {
+    to_string(|s| s.print_param(arg, false))
 }
 
 fn foreign_item_to_string(arg: &ast::ForeignItem) -> String {
@@ -2101,7 +2101,7 @@ impl<'a> State<'a> {
                 self.print_asyncness(asyncness);
                 self.print_capture_clause(capture_clause);
 
-                self.print_fn_block_args(decl);
+                self.print_fn_block_params(decl);
                 self.s.space();
                 self.print_expr(body);
                 self.end(); // need to close a box
@@ -2536,21 +2536,21 @@ impl<'a> State<'a> {
             self.print_ident(name);
         }
         self.print_generic_params(&generics.params);
-        self.print_fn_args_and_ret(decl);
+        self.print_fn_params_and_ret(decl);
         self.print_where_clause(&generics.where_clause)
     }
 
-    crate fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl) {
+    crate fn print_fn_params_and_ret(&mut self, decl: &ast::FnDecl) {
         self.popen();
-        self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, false));
+        self.commasep(Inconsistent, &decl.inputs, |s, param| s.print_param(param, false));
         self.pclose();
 
         self.print_fn_output(decl)
     }
 
-    crate fn print_fn_block_args(&mut self, decl: &ast::FnDecl) {
+    crate fn print_fn_block_params(&mut self, decl: &ast::FnDecl) {
         self.s.word("|");
-        self.commasep(Inconsistent, &decl.inputs, |s, arg| s.print_arg(arg, true));
+        self.commasep(Inconsistent, &decl.inputs, |s, param| s.print_param(param, true));
         self.s.word("|");
 
         if let ast::FunctionRetTy::Default(..) = decl.output {
@@ -2759,7 +2759,7 @@ impl<'a> State<'a> {
         self.print_type(&mt.ty)
     }
 
-    crate fn print_arg(&mut self, input: &ast::Arg, is_closure: bool) {
+    crate fn print_param(&mut self, input: &ast::Param, is_closure: bool) {
         self.ibox(INDENT_UNIT);
 
         self.print_outer_attributes_inline(&input.attrs);
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 86f6d36c3c6ba..ce1568316f8d4 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -66,7 +66,7 @@ pub trait Visitor<'ast>: Sized {
     fn visit_local(&mut self, l: &'ast Local) { walk_local(self, l) }
     fn visit_block(&mut self, b: &'ast Block) { walk_block(self, b) }
     fn visit_stmt(&mut self, s: &'ast Stmt) { walk_stmt(self, s) }
-    fn visit_arg(&mut self, arg: &'ast Arg) { walk_arg(self, arg) }
+    fn visit_param(&mut self, param: &'ast Param) { walk_param(self, param) }
     fn visit_arm(&mut self, a: &'ast Arm) { walk_arm(self, a) }
     fn visit_pat(&mut self, p: &'ast Pat) { walk_pat(self, p) }
     fn visit_anon_const(&mut self, c: &'ast AnonConst) { walk_anon_const(self, c) }
@@ -555,8 +555,8 @@ pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FunctionR
 }
 
 pub fn walk_fn_decl<'a, V: Visitor<'a>>(visitor: &mut V, function_declaration: &'a FnDecl) {
-    for arg in &function_declaration.inputs {
-        visitor.visit_arg(arg);
+    for param in &function_declaration.inputs {
+        visitor.visit_param(param);
     }
     visitor.visit_fn_ret_ty(&function_declaration.output);
 }
@@ -824,10 +824,10 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
     visitor.visit_expr_post(expression)
 }
 
-pub fn walk_arg<'a, V: Visitor<'a>>(visitor: &mut V, arg: &'a Arg) {
-    walk_list!(visitor, visit_attribute, arg.attrs.iter());
-    visitor.visit_pat(&arg.pat);
-    visitor.visit_ty(&arg.ty);
+pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) {
+    walk_list!(visitor, visit_attribute, param.attrs.iter());
+    visitor.visit_pat(&param.pat);
+    visitor.visit_ty(&param.ty);
 }
 
 pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) {
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 1475bac068846..6fd763f5a9100 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -929,10 +929,10 @@ impl<'a> MethodDef<'a> {
         let args = {
             let self_args = explicit_self.map(|explicit_self| {
                 let ident = Ident::with_dummy_span(kw::SelfLower).with_span_pos(trait_.span);
-                ast::Arg::from_self(ThinVec::default(), explicit_self, ident)
+                ast::Param::from_self(ThinVec::default(), explicit_self, ident)
             });
             let nonself_args = arg_types.into_iter()
-                .map(|(name, ty)| cx.arg(trait_.span, name, ty));
+                .map(|(name, ty)| cx.param(trait_.span, name, ty));
             self_args.into_iter().chain(nonself_args).collect()
         };
 
diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs
index 97b8087ad1581..f4af1699cd683 100644
--- a/src/libsyntax_ext/global_allocator.rs
+++ b/src/libsyntax_ext/global_allocator.rs
@@ -1,5 +1,5 @@
 use syntax::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafety};
-use syntax::ast::{self, Arg, Attribute, Expr, FnHeader, Generics, Ident};
+use syntax::ast::{self, Param, Attribute, Expr, FnHeader, Generics, Ident};
 use syntax::attr::check_builtin_macro_attribute;
 use syntax::ext::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
 use syntax::ext::base::{Annotatable, ExtCtxt};
@@ -114,7 +114,7 @@ impl AllocFnFactory<'_, '_> {
     fn arg_ty(
         &self,
         ty: &AllocatorTy,
-        args: &mut Vec<Arg>,
+        args: &mut Vec<Param>,
         ident: &mut dyn FnMut() -> Ident,
     ) -> P<Expr> {
         match *ty {
@@ -123,8 +123,8 @@ impl AllocFnFactory<'_, '_> {
                 let ty_usize = self.cx.ty_path(usize);
                 let size = ident();
                 let align = ident();
-                args.push(self.cx.arg(self.span, size, ty_usize.clone()));
-                args.push(self.cx.arg(self.span, align, ty_usize));
+                args.push(self.cx.param(self.span, size, ty_usize.clone()));
+                args.push(self.cx.param(self.span, align, ty_usize));
 
                 let layout_new = self.cx.std_path(&[
                     Symbol::intern("alloc"),
@@ -140,14 +140,14 @@ impl AllocFnFactory<'_, '_> {
 
             AllocatorTy::Ptr => {
                 let ident = ident();
-                args.push(self.cx.arg(self.span, ident, self.ptr_u8()));
+                args.push(self.cx.param(self.span, ident, self.ptr_u8()));
                 let arg = self.cx.expr_ident(self.span, ident);
                 self.cx.expr_cast(self.span, arg, self.ptr_u8())
             }
 
             AllocatorTy::Usize => {
                 let ident = ident();
-                args.push(self.cx.arg(self.span, ident, self.usize()));
+                args.push(self.cx.param(self.span, ident, self.usize()));
                 self.cx.expr_ident(self.span, ident)
             }
 
diff --git a/src/test/ui/async-await/no-args-non-move-async-closure.rs b/src/test/ui/async-await/no-args-non-move-async-closure.rs
index 0ca50807f2626..3b15f35c260dc 100644
--- a/src/test/ui/async-await/no-args-non-move-async-closure.rs
+++ b/src/test/ui/async-await/no-args-non-move-async-closure.rs
@@ -4,5 +4,5 @@
 
 fn main() {
     let _ = async |x: u8| {};
-    //~^ ERROR `async` non-`move` closures with arguments are not currently supported
+    //~^ ERROR `async` non-`move` closures with parameters are not currently supported
 }
diff --git a/src/test/ui/async-await/no-args-non-move-async-closure.stderr b/src/test/ui/async-await/no-args-non-move-async-closure.stderr
index 1b4b86210f840..c58210b997b66 100644
--- a/src/test/ui/async-await/no-args-non-move-async-closure.stderr
+++ b/src/test/ui/async-await/no-args-non-move-async-closure.stderr
@@ -1,4 +1,4 @@
-error[E0708]: `async` non-`move` closures with arguments are not currently supported
+error[E0708]: `async` non-`move` closures with parameters are not currently supported
   --> $DIR/no-args-non-move-async-closure.rs:6:13
    |
 LL |     let _ = async |x: u8| {};
diff --git a/src/test/ui/generator/no-arguments-on-generators.rs b/src/test/ui/generator/no-arguments-on-generators.rs
index 344c1179be90e..a2632a4bd7d84 100644
--- a/src/test/ui/generator/no-arguments-on-generators.rs
+++ b/src/test/ui/generator/no-arguments-on-generators.rs
@@ -1,7 +1,7 @@
 #![feature(generators)]
 
 fn main() {
-    let gen = |start| { //~ ERROR generators cannot have explicit arguments
+    let gen = |start| { //~ ERROR generators cannot have explicit parameters
         yield;
     };
 }
diff --git a/src/test/ui/generator/no-arguments-on-generators.stderr b/src/test/ui/generator/no-arguments-on-generators.stderr
index 23ae21585fd38..8f993b27ce236 100644
--- a/src/test/ui/generator/no-arguments-on-generators.stderr
+++ b/src/test/ui/generator/no-arguments-on-generators.stderr
@@ -1,4 +1,4 @@
-error[E0628]: generators cannot have explicit arguments
+error[E0628]: generators cannot have explicit parameters
   --> $DIR/no-arguments-on-generators.rs:4:15
    |
 LL |     let gen = |start| {

From 98ad4ac2506e543111559ec5064cc1bd58349342 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Aug 2019 15:49:47 +0200
Subject: [PATCH 286/943] update miri

---
 Cargo.lock     | 1 +
 src/tools/miri | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/Cargo.lock b/Cargo.lock
index 8ae21c8663706..dffd496c7d9e7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1992,6 +1992,7 @@ dependencies = [
  "compiletest_rs",
  "directories",
  "env_logger 0.6.0",
+ "getrandom",
  "hex",
  "log",
  "num-traits",
diff --git a/src/tools/miri b/src/tools/miri
index d77fe6c63ca4c..69268fb75fdb4 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit d77fe6c63ca4c50b207a1161def90c9e57368d5b
+Subproject commit 69268fb75fdb452296caa9bc4aaeff1674279de2

From 935c1c86070dfac3515a4296bf991cdf544bae27 Mon Sep 17 00:00:00 2001
From: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
Date: Tue, 27 Aug 2019 09:37:51 +0200
Subject: [PATCH 287/943] rustbuild: allow disabling deny(warnings) for
 bootstrap

When deny-warnings is not specified or set to true, the behaviour is the same as before.
When deny-warnings is set to false, warnings are now allowed

Fixes #63911

Signed-off-by: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
---
 src/bootstrap/bin/main.rs    | 3 ---
 src/bootstrap/bin/rustc.rs   | 8 +++-----
 src/bootstrap/bin/rustdoc.rs | 3 ---
 src/bootstrap/bootstrap.py   | 2 ++
 src/bootstrap/lib.rs         | 3 ---
 src/build_helper/lib.rs      | 3 ---
 6 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs
index bd1a87c5744d3..138b7f4b26104 100644
--- a/src/bootstrap/bin/main.rs
+++ b/src/bootstrap/bin/main.rs
@@ -5,9 +5,6 @@
 //! parent directory, and otherwise documentation can be found throughout the `build`
 //! directory in each respective module.
 
-// NO-RUSTC-WRAPPER
-#![deny(warnings, rust_2018_idioms, unused_lifetimes)]
-
 use std::env;
 
 use bootstrap::{Config, Build};
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index ce92ce0269671..8cb48df14bfef 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -15,9 +15,6 @@
 //! switching compilers for the bootstrap and for build scripts will probably
 //! never get replaced.
 
-// NO-RUSTC-WRAPPER
-#![deny(warnings, rust_2018_idioms, unused_lifetimes)]
-
 use std::env;
 use std::ffi::OsString;
 use std::io;
@@ -124,8 +121,9 @@ fn main() {
 
     if env::var_os("RUSTC_DENY_WARNINGS").is_some() &&
        env::var_os("RUSTC_EXTERNAL_TOOL").is_none() {
-        // When extending this list, search for `NO-RUSTC-WRAPPER` and add the new lints
-        // there as well, some code doesn't go through this `rustc` wrapper.
+        // When extending this list, add the new lints to the RUSTFLAGS of the
+        // build_bootstrap function of src/bootstrap/bootstrap.py as well as
+        // some code doesn't go through this `rustc` wrapper.
         cmd.arg("-Dwarnings");
         cmd.arg("-Drust_2018_idioms");
         cmd.arg("-Dunused_lifetimes");
diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index ff38ee8788f56..766a3463ecd8b 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -2,9 +2,6 @@
 //!
 //! See comments in `src/bootstrap/rustc.rs` for more information.
 
-// NO-RUSTC-WRAPPER
-#![deny(warnings, rust_2018_idioms, unused_lifetimes)]
-
 use std::env;
 use std::process::Command;
 use std::path::PathBuf;
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 86901792d7974..3c56131396f29 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -631,6 +631,8 @@ def build_bootstrap(self):
         target_linker = self.get_toml("linker", build_section)
         if target_linker is not None:
             env["RUSTFLAGS"] += "-C linker=" + target_linker + " "
+        if self.get_toml("deny-warnings", "rust") != "false":
+            env["RUSTFLAGS"] += "-Dwarnings -Drust_2018_idioms -Dunused_lifetimes "
 
         env["PATH"] = os.path.join(self.bin_root(), "bin") + \
             os.pathsep + env["PATH"]
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index c0e0ad1a857b9..575844028d562 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -103,9 +103,6 @@
 //! More documentation can be found in each respective module below, and you can
 //! also check out the `src/bootstrap/README.md` file for more information.
 
-// NO-RUSTC-WRAPPER
-#![deny(warnings, rust_2018_idioms, unused_lifetimes)]
-
 #![feature(core_intrinsics)]
 #![feature(drain_filter)]
 
diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs
index 131d2034675e3..f035a7119188a 100644
--- a/src/build_helper/lib.rs
+++ b/src/build_helper/lib.rs
@@ -1,6 +1,3 @@
-// NO-RUSTC-WRAPPER
-#![deny(warnings, rust_2018_idioms, unused_lifetimes)]
-
 use std::fs::File;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};

From 97319b2b952c32ac1f0b36a834615b60b0376797 Mon Sep 17 00:00:00 2001
From: Kevin Per <kevin.per@protonmail.com>
Date: Tue, 27 Aug 2019 15:47:41 +0200
Subject: [PATCH 288/943] Changing error messages and renaming tests #63127

`async-await/no-args-non-move-async-closure`
`generator/no-arguments-on-generators`
---
 src/librustc/error_codes.rs                                   | 4 ++--
 src/librustc/hir/lowering/expr.rs                             | 4 ++--
 ...e-async-closure.rs => no-params-non-move-async-closure.rs} | 0
 ...closure.stderr => no-params-non-move-async-closure.stderr} | 2 +-
 ...uments-on-generators.rs => no-parameters-on-generators.rs} | 0
 ...n-generators.stderr => no-parameters-on-generators.stderr} | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)
 rename src/test/ui/async-await/{no-args-non-move-async-closure.rs => no-params-non-move-async-closure.rs} (100%)
 rename src/test/ui/async-await/{no-args-non-move-async-closure.stderr => no-params-non-move-async-closure.stderr} (86%)
 rename src/test/ui/generator/{no-arguments-on-generators.rs => no-parameters-on-generators.rs} (100%)
 rename src/test/ui/generator/{no-arguments-on-generators.stderr => no-parameters-on-generators.stderr} (77%)

diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index a200a058f4f99..2d09013f675a7 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -2231,7 +2231,7 @@ register_diagnostics! {
     E0495, // cannot infer an appropriate lifetime due to conflicting requirements
     E0566, // conflicting representation hints
     E0623, // lifetime mismatch where both parameters are anonymous regions
-    E0628, // generators cannot have explicit arguments
+    E0628, // generators cannot have explicit parameters
     E0631, // type mismatch in closure arguments
     E0637, // "'_" is not a valid lifetime bound
     E0657, // `impl Trait` can only capture lifetimes bound at the fn level
@@ -2239,7 +2239,7 @@ register_diagnostics! {
     E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
     E0697, // closures cannot be static
     E0707, // multiple elided lifetimes used in arguments of `async fn`
-    E0708, // `async` non-`move` closures with arguments are not currently supported
+    E0708, // `async` non-`move` closures with parameters are not currently supported
     E0709, // multiple different lifetimes used in arguments of `async fn`
     E0710, // an unknown tool name found in scoped lint
     E0711, // a feature has been declared with conflicting stability attributes
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index ff0c44a23874b..bd217831faabf 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -724,7 +724,7 @@ impl LoweringContext<'_> {
                         self.sess,
                         fn_decl_span,
                         E0628,
-                        "generators cannot have explicit arguments"
+                        "generators cannot have explicit parameters"
                     );
                     self.sess.abort_if_errors();
                 }
@@ -775,7 +775,7 @@ impl LoweringContext<'_> {
                     this.sess,
                     fn_decl_span,
                     E0708,
-                    "`async` non-`move` closures with arguments are not currently supported",
+                    "`async` non-`move` closures with parameters are not currently supported",
                 )
                 .help(
                     "consider using `let` statements to manually capture \
diff --git a/src/test/ui/async-await/no-args-non-move-async-closure.rs b/src/test/ui/async-await/no-params-non-move-async-closure.rs
similarity index 100%
rename from src/test/ui/async-await/no-args-non-move-async-closure.rs
rename to src/test/ui/async-await/no-params-non-move-async-closure.rs
diff --git a/src/test/ui/async-await/no-args-non-move-async-closure.stderr b/src/test/ui/async-await/no-params-non-move-async-closure.stderr
similarity index 86%
rename from src/test/ui/async-await/no-args-non-move-async-closure.stderr
rename to src/test/ui/async-await/no-params-non-move-async-closure.stderr
index c58210b997b66..04c8c325fe7da 100644
--- a/src/test/ui/async-await/no-args-non-move-async-closure.stderr
+++ b/src/test/ui/async-await/no-params-non-move-async-closure.stderr
@@ -1,5 +1,5 @@
 error[E0708]: `async` non-`move` closures with parameters are not currently supported
-  --> $DIR/no-args-non-move-async-closure.rs:6:13
+  --> $DIR/no-params-non-move-async-closure.rs:6:13
    |
 LL |     let _ = async |x: u8| {};
    |             ^^^^^^^^^^^^^
diff --git a/src/test/ui/generator/no-arguments-on-generators.rs b/src/test/ui/generator/no-parameters-on-generators.rs
similarity index 100%
rename from src/test/ui/generator/no-arguments-on-generators.rs
rename to src/test/ui/generator/no-parameters-on-generators.rs
diff --git a/src/test/ui/generator/no-arguments-on-generators.stderr b/src/test/ui/generator/no-parameters-on-generators.stderr
similarity index 77%
rename from src/test/ui/generator/no-arguments-on-generators.stderr
rename to src/test/ui/generator/no-parameters-on-generators.stderr
index 8f993b27ce236..41862f2b0704b 100644
--- a/src/test/ui/generator/no-arguments-on-generators.stderr
+++ b/src/test/ui/generator/no-parameters-on-generators.stderr
@@ -1,5 +1,5 @@
 error[E0628]: generators cannot have explicit parameters
-  --> $DIR/no-arguments-on-generators.rs:4:15
+  --> $DIR/no-parameters-on-generators.rs:4:15
    |
 LL |     let gen = |start| {
    |               ^^^^^^^

From 661141f8082f4ecde1e391799523ad3c566754b5 Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Wed, 28 Aug 2019 00:32:21 +0900
Subject: [PATCH 289/943] Fix build src/libtest

---
 src/bootstrap/check.rs   | 2 +-
 src/bootstrap/compile.rs | 2 +-
 src/bootstrap/doc.rs     | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index e9a9b7881a068..205a80c3a3a9e 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -34,7 +34,7 @@ impl Step for Std {
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.all_krates("std")
+        run.all_krates("test")
     }
 
     fn make_run(run: RunConfig<'_>) {
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 7dad146b48d83..9d57a4f00d780 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -39,7 +39,7 @@ impl Step for Std {
     const DEFAULT: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.all_krates("std")
+        run.all_krates("test")
     }
 
     fn make_run(run: RunConfig<'_>) {
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 6805474aa049f..3d0a175e8206c 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -413,7 +413,7 @@ impl Step for Std {
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
         let builder = run.builder;
-        run.all_krates("std").default_condition(builder.config.docs)
+        run.all_krates("test").default_condition(builder.config.docs)
     }
 
     fn make_run(run: RunConfig<'_>) {

From c9bf5c0bffef595136b484b0282ade18894cf5af Mon Sep 17 00:00:00 2001
From: Charles Lew <crlf0710@gmail.com>
Date: Wed, 28 Aug 2019 00:45:29 +0800
Subject: [PATCH 290/943] bootstrap: allow specifying mirror for bootstrap
 compiler download.

---
 src/bootstrap/bootstrap.py | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 86901792d7974..c9f5d299a61c9 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -320,7 +320,7 @@ class RustBuild(object):
     def __init__(self):
         self.cargo_channel = ''
         self.date = ''
-        self._download_url = 'https://static.rust-lang.org'
+        self._download_url = ''
         self.rustc_channel = ''
         self.build = ''
         self.build_dir = os.path.join(os.getcwd(), "build")
@@ -731,9 +731,19 @@ def update_submodules(self):
             self.update_submodule(module[0], module[1], recorded_submodules)
         print("Submodules updated in %.2f seconds" % (time() - start_time))
 
+    def set_normal_environment(self):
+        """Set download URL for normal environment"""
+        if 'RUSTUP_DIST_SERVER' in os.environ:
+            self._download_url = os.environ['RUSTUP_DIST_SERVER']
+        else:
+            self._download_url = 'https://static.rust-lang.org'
+
     def set_dev_environment(self):
         """Set download URL for development environment"""
-        self._download_url = 'https://dev-static.rust-lang.org'
+        if 'RUSTUP_DEV_DIST_SERVER' in os.environ:
+            self._download_url = os.environ['RUSTUP_DEV_DIST_SERVER']
+        else:
+            self._download_url = 'https://dev-static.rust-lang.org'
 
     def check_vendored_status(self):
         """Check that vendoring is configured properly"""
@@ -826,6 +836,8 @@ def bootstrap(help_triggered):
 
     if 'dev' in data:
         build.set_dev_environment()
+    else:
+        build.set_normal_environment()
 
     build.update_submodules()
 

From 3b2c14736d6d8fc44cf60588ed41a67eaf9459ad Mon Sep 17 00:00:00 2001
From: Baoshan Pang <baoshan.pang@windriver.com>
Date: Tue, 27 Aug 2019 10:13:59 -0700
Subject: [PATCH 291/943] remove the reference to __cxa_thread_atexit_impl

---
 src/libstd/sys/vxworks/fast_thread_local.rs | 27 ++-------------------
 1 file changed, 2 insertions(+), 25 deletions(-)

diff --git a/src/libstd/sys/vxworks/fast_thread_local.rs b/src/libstd/sys/vxworks/fast_thread_local.rs
index f5a2e263d25e7..2e021980778e5 100644
--- a/src/libstd/sys/vxworks/fast_thread_local.rs
+++ b/src/libstd/sys/vxworks/fast_thread_local.rs
@@ -1,33 +1,10 @@
+// Copyright (c) 2019 Wind River Systems, Inc.
+
 #![cfg(target_thread_local)]
 #![unstable(feature = "thread_local_internals", issue = "0")]
 
-// Since what appears to be glibc 2.18 this symbol has been shipped which
-// GCC and clang both use to invoke destructors in thread_local globals, so
-// let's do the same!
-//
-// Note, however, that we run on lots older linuxes, as well as cross
-// compiling from a newer linux to an older linux, so we also have a
-// fallback implementation to use as well.
-//
-// Due to rust-lang/rust#18804, make sure this is not generic!
 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
-    use crate::mem;
     use crate::sys_common::thread_local::register_dtor_fallback;
-
-    extern {
-        #[linkage = "extern_weak"]
-        static __dso_handle: *mut u8;
-        #[linkage = "extern_weak"]
-        static __cxa_thread_atexit_impl: *const libc::c_void;
-    }
-    if !__cxa_thread_atexit_impl.is_null() {
-        type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8),
-                                  arg: *mut u8,
-                                  dso_handle: *mut u8) -> libc::c_int;
-        mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)
-            (dtor, t, &__dso_handle as *const _ as *mut _);
-        return
-    }
     register_dtor_fallback(t, dtor);
 }
 

From dbbe3363c94b120d1eba9cba01dadddd862716b8 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 27 Aug 2019 19:51:21 +0200
Subject: [PATCH 292/943] Ensure 'let mut ;' where ':pat' is banned.

---
 src/libsyntax/parse/parser/pat.rs      |  9 +++++++++
 src/test/ui/parser/mut-patterns.rs     |  8 ++++++++
 src/test/ui/parser/mut-patterns.stderr | 11 ++++++++++-
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 7b228a700a748..08934e8533049 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -384,6 +384,7 @@ impl<'a> Parser<'a> {
         })
     }
 
+    /// Parse a mutable binding with the `mut` token already eaten.
     fn parse_pat_ident_mut(&mut self) -> PResult<'a, PatKind> {
         let mut_span = self.prev_span;
 
@@ -393,6 +394,14 @@ impl<'a> Parser<'a> {
 
         self.recover_additional_muts();
 
+        // Make sure we don't allow e.g. `let mut $p;` where `$p:pat`.
+        if let token::Interpolated(ref nt) = self.token.kind {
+             if let token::NtPat(_) = **nt {
+                 self.expected_ident_found().emit();
+             }
+        }
+
+        // Parse the pattern we hope to be an identifier.
         let mut pat = self.parse_pat(Some("identifier"))?;
 
         // Add `mut` to any binding in the parsed pattern.
diff --git a/src/test/ui/parser/mut-patterns.rs b/src/test/ui/parser/mut-patterns.rs
index 87e127f9d364a..0c78ca726e003 100644
--- a/src/test/ui/parser/mut-patterns.rs
+++ b/src/test/ui/parser/mut-patterns.rs
@@ -32,4 +32,12 @@ pub fn main() {
     let mut W(mut a, W(b, W(ref c, W(d, B { box f }))))
     //~^ ERROR `mut` must be attached to each individual binding
         = W(0, W(1, W(2, W(3, B { f: Box::new(4u8) }))));
+
+    // Make sure we don't accidentally allow `mut $p` where `$p:pat`.
+    macro_rules! foo {
+        ($p:pat) => {
+            let mut $p = 0; //~ ERROR expected identifier, found `x`
+        }
+    }
+    foo!(x);
 }
diff --git a/src/test/ui/parser/mut-patterns.stderr b/src/test/ui/parser/mut-patterns.stderr
index a251e2908f02c..a1293129e2eaf 100644
--- a/src/test/ui/parser/mut-patterns.stderr
+++ b/src/test/ui/parser/mut-patterns.stderr
@@ -64,5 +64,14 @@ error: `mut` must be attached to each individual binding
 LL |     let mut W(mut a, W(b, W(ref c, W(d, B { box f }))))
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `W(mut a, W(mut b, W(ref c, W(mut d, B { box mut f }))))`
 
-error: aborting due to 9 previous errors
+error: expected identifier, found `x`
+  --> $DIR/mut-patterns.rs:39:21
+   |
+LL |             let mut $p = 0;
+   |                     ^^ expected identifier
+...
+LL |     foo!(x);
+   |     -------- in this macro invocation
+
+error: aborting due to 10 previous errors
 

From 7677d1f771525606af256e2972cb7116d8fde99f Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Aug 2019 22:18:25 +0200
Subject: [PATCH 293/943] const_prop: only call error_to_const_error if we are
 actually showing something

---
 src/librustc_mir/const_eval.rs           | 3 +++
 src/librustc_mir/transform/const_prop.rs | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 67d63e52b2bfa..5aa487d901663 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -519,6 +519,9 @@ pub fn const_variant_index<'tcx>(
     ecx.read_discriminant(op).unwrap().1
 }
 
+/// Turn an interpreter error into something to report to the user.
+/// As a side-effect, if RUSTC_CTFE_BACKTRACE is set, this prints the backtrace.
+/// Should be called only if the error is actually going to to be reported!
 pub fn error_to_const_error<'mir, 'tcx>(
     ecx: &InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
     mut error: InterpErrorInfo<'tcx>,
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index b6146b6b7227d..f261fdc268b5b 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -237,9 +237,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
         let r = match f(self) {
             Ok(val) => Some(val),
             Err(error) => {
-                let diagnostic = error_to_const_error(&self.ecx, error);
                 use rustc::mir::interpret::InterpError::*;
-                match diagnostic.error {
+                match error.kind {
                     Exit(_) => bug!("the CTFE program cannot exit"),
                     Unsupported(_)
                     | UndefinedBehavior(_)
@@ -248,6 +247,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                         // Ignore these errors.
                     }
                     Panic(_) => {
+                        let diagnostic = error_to_const_error(&self.ecx, error);
                         diagnostic.report_as_lint(
                             self.ecx.tcx,
                             "this expression will panic at runtime",

From 1a4330d2a23f8b9912cb4ca54d259333b0133b76 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Tue, 27 Aug 2019 12:25:35 -0700
Subject: [PATCH 294/943] rustc: Handle modules in "fat" LTO more robustly

When performing a "fat" LTO the compiler has a whole mess of codegen
units that it links together. To do this it needs to select one module
as a "base" module and then link everything else into this module.
Previously LTO passes assume that there's at least one module in-memory
to link into, but nowadays that's not always true! With incremental
compilation modules may actually largely be cached and it may be
possible that there's no in-memory modules to work with.

This commit updates the logic of the LTO backend to handle modules a bit
more uniformly during a fat LTO. This commit immediately splits them
into two lists, one serialized and one in-memory. The in-memory list is
then searched for the largest module and failing that we simply
deserialize the first serialized module and link into that. This
refactoring avoids juggling three lists, two of which are serialized
modules and one of which is half serialized and half in-memory.

Closes #63349
---
 src/librustc_codegen_llvm/back/lto.rs         | 86 +++++++++----------
 src/librustc_codegen_llvm/lib.rs              |  7 +-
 src/test/run-make-fulldeps/lto-empty/Makefile | 12 +++
 src/test/run-make-fulldeps/lto-empty/lib.rs   |  1 +
 src/test/ui/lto-duplicate-symbols.stderr      |  2 +-
 5 files changed, 59 insertions(+), 49 deletions(-)
 create mode 100644 src/test/run-make-fulldeps/lto-empty/Makefile
 create mode 100644 src/test/run-make-fulldeps/lto-empty/lib.rs

diff --git a/src/librustc_codegen_llvm/back/lto.rs b/src/librustc_codegen_llvm/back/lto.rs
index 5ed08943fe6fd..a43fbb68dbaed 100644
--- a/src/librustc_codegen_llvm/back/lto.rs
+++ b/src/librustc_codegen_llvm/back/lto.rs
@@ -183,7 +183,7 @@ pub(crate) fn prepare_thin(
 
 fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
            diag_handler: &Handler,
-           mut modules: Vec<FatLTOInput<LlvmCodegenBackend>>,
+           modules: Vec<FatLTOInput<LlvmCodegenBackend>>,
            cached_modules: Vec<(SerializedModule<ModuleBuffer>, WorkProduct)>,
            mut serialized_modules: Vec<(SerializedModule<ModuleBuffer>, CString)>,
            symbol_white_list: &[*const libc::c_char])
@@ -191,6 +191,32 @@ fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
 {
     info!("going for a fat lto");
 
+    // Sort out all our lists of incoming modules into two lists.
+    //
+    // * `serialized_modules` (also and argument to this function) contains all
+    //   modules that are serialized in-memory.
+    // * `in_memory` contains modules which are already parsed and in-memory,
+    //   such as from multi-CGU builds.
+    //
+    // All of `cached_modules` (cached from previous incremental builds) can
+    // immediately go onto the `serialized_modules` modules list and then we can
+    // split the `modules` array into these two lists.
+    let mut in_memory = Vec::new();
+    serialized_modules.extend(cached_modules.into_iter().map(|(buffer, wp)| {
+        info!("pushing cached module {:?}", wp.cgu_name);
+        (buffer, CString::new(wp.cgu_name).unwrap())
+    }));
+    for module in modules {
+        match module {
+            FatLTOInput::InMemory(m) => in_memory.push(m),
+            FatLTOInput::Serialized { name, buffer } => {
+                info!("pushing serialized module {:?}", name);
+                let buffer = SerializedModule::Local(buffer);
+                serialized_modules.push((buffer, CString::new(name).unwrap()));
+            }
+        }
+    }
+
     // Find the "costliest" module and merge everything into that codegen unit.
     // All the other modules will be serialized and reparsed into the new
     // context, so this hopefully avoids serializing and parsing the largest
@@ -200,14 +226,8 @@ fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
     // file copy operations in the backend work correctly. The only other kind
     // of module here should be an allocator one, and if your crate is smaller
     // than the allocator module then the size doesn't really matter anyway.
-    let costliest_module = modules.iter()
+    let costliest_module = in_memory.iter()
         .enumerate()
-        .filter_map(|(i, module)| {
-            match module {
-                FatLTOInput::InMemory(m) => Some((i, m)),
-                FatLTOInput::Serialized { .. } => None,
-            }
-        })
         .filter(|&(_, module)| module.kind == ModuleKind::Regular)
         .map(|(i, module)| {
             let cost = unsafe {
@@ -223,26 +243,14 @@ fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
     // re-executing the LTO passes. If that's the case deserialize the first
     // module and create a linker with it.
     let module: ModuleCodegen<ModuleLlvm> = match costliest_module {
-        Some((_cost, i)) => {
-            match modules.remove(i) {
-                FatLTOInput::InMemory(m) => m,
-                FatLTOInput::Serialized { .. } => unreachable!(),
-            }
-        }
+        Some((_cost, i)) => in_memory.remove(i),
         None => {
-            let pos = modules.iter().position(|m| {
-                match m {
-                    FatLTOInput::InMemory(_) => false,
-                    FatLTOInput::Serialized { .. } => true,
-                }
-            }).expect("must have at least one serialized module");
-            let (name, buffer) = match modules.remove(pos) {
-                FatLTOInput::Serialized { name, buffer } => (name, buffer),
-                FatLTOInput::InMemory(_) => unreachable!(),
-            };
+            assert!(serialized_modules.len() > 0, "must have at least one serialized module");
+            let (buffer, name) = serialized_modules.remove(0);
+            info!("no in-memory regular modules to choose from, parsing {:?}", name);
             ModuleCodegen {
-                module_llvm: ModuleLlvm::parse(cgcx, &name, &buffer, diag_handler)?,
-                name,
+                module_llvm: ModuleLlvm::parse(cgcx, &name, buffer.data(), diag_handler)?,
+                name: name.into_string().unwrap(),
                 kind: ModuleKind::Regular,
             }
         }
@@ -265,25 +273,13 @@ fn fat_lto(cgcx: &CodegenContext<LlvmCodegenBackend>,
         // and we want to move everything to the same LLVM context. Currently the
         // way we know of to do that is to serialize them to a string and them parse
         // them later. Not great but hey, that's why it's "fat" LTO, right?
-        let mut new_modules = modules.into_iter().map(|module| {
-            match module {
-                FatLTOInput::InMemory(module) => {
-                    let buffer = ModuleBuffer::new(module.module_llvm.llmod());
-                    let llmod_id = CString::new(&module.name[..]).unwrap();
-                    (SerializedModule::Local(buffer), llmod_id)
-                }
-                FatLTOInput::Serialized { name, buffer } => {
-                    let llmod_id = CString::new(name).unwrap();
-                    (SerializedModule::Local(buffer), llmod_id)
-                }
-            }
-        }).collect::<Vec<_>>();
+        for module in in_memory {
+            let buffer = ModuleBuffer::new(module.module_llvm.llmod());
+            let llmod_id = CString::new(&module.name[..]).unwrap();
+            serialized_modules.push((SerializedModule::Local(buffer), llmod_id));
+        }
         // Sort the modules to ensure we produce deterministic results.
-        new_modules.sort_by(|module1, module2| module1.1.partial_cmp(&module2.1).unwrap());
-        serialized_modules.extend(new_modules);
-        serialized_modules.extend(cached_modules.into_iter().map(|(buffer, wp)| {
-            (buffer, CString::new(wp.cgu_name).unwrap())
-        }));
+        serialized_modules.sort_by(|module1, module2| module1.1.cmp(&module2.1));
 
         // For all serialized bitcode files we parse them and link them in as we did
         // above, this is all mostly handled in C++. Like above, though, we don't
@@ -850,7 +846,7 @@ fn module_name_to_str(c_str: &CStr) -> &str {
         bug!("Encountered non-utf8 LLVM module name `{}`: {}", c_str.to_string_lossy(), e))
 }
 
-fn parse_module<'a>(
+pub fn parse_module<'a>(
     cx: &'a llvm::Context,
     name: &CStr,
     data: &[u8],
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 653dd8868f479..2fd78885bd01e 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -54,6 +54,7 @@ use syntax_pos::symbol::InternedString;
 pub use llvm_util::target_features;
 use std::any::Any;
 use std::sync::{mpsc, Arc};
+use std::ffi::CStr;
 
 use rustc::dep_graph::DepGraph;
 use rustc::middle::cstore::{EncodedMetadata, MetadataLoader};
@@ -386,13 +387,13 @@ impl ModuleLlvm {
 
     fn parse(
         cgcx: &CodegenContext<LlvmCodegenBackend>,
-        name: &str,
-        buffer: &back::lto::ModuleBuffer,
+        name: &CStr,
+        buffer: &[u8],
         handler: &Handler,
     ) -> Result<Self, FatalError> {
         unsafe {
             let llcx = llvm::LLVMRustContextCreate(cgcx.fewer_names);
-            let llmod_raw = buffer.parse(name, llcx, handler)?;
+            let llmod_raw = back::lto::parse_module(llcx, name, buffer, handler)?;
             let tm = match (cgcx.tm_factory.0)() {
                 Ok(m) => m,
                 Err(e) => {
diff --git a/src/test/run-make-fulldeps/lto-empty/Makefile b/src/test/run-make-fulldeps/lto-empty/Makefile
new file mode 100644
index 0000000000000..345d10bc4b9ea
--- /dev/null
+++ b/src/test/run-make-fulldeps/lto-empty/Makefile
@@ -0,0 +1,12 @@
+-include ../tools.mk
+
+all: cdylib-fat cdylib-thin
+
+cdylib-fat:
+	$(RUSTC) lib.rs -C lto=fat -C opt-level=3 -C incremental=$(TMPDIR)/inc-fat
+	$(RUSTC) lib.rs -C lto=fat -C opt-level=3 -C incremental=$(TMPDIR)/inc-fat
+
+cdylib-thin:
+	$(RUSTC) lib.rs -C lto=thin -C opt-level=3 -C incremental=$(TMPDIR)/inc-thin
+	$(RUSTC) lib.rs -C lto=thin -C opt-level=3 -C incremental=$(TMPDIR)/inc-thin
+
diff --git a/src/test/run-make-fulldeps/lto-empty/lib.rs b/src/test/run-make-fulldeps/lto-empty/lib.rs
new file mode 100644
index 0000000000000..e3663c79078f4
--- /dev/null
+++ b/src/test/run-make-fulldeps/lto-empty/lib.rs
@@ -0,0 +1 @@
+#![crate_type = "cdylib"]
diff --git a/src/test/ui/lto-duplicate-symbols.stderr b/src/test/ui/lto-duplicate-symbols.stderr
index 5760cb9a8fdb6..b7a930b61cc96 100644
--- a/src/test/ui/lto-duplicate-symbols.stderr
+++ b/src/test/ui/lto-duplicate-symbols.stderr
@@ -1,6 +1,6 @@
 warning: Linking globals named 'foo': symbol multiply defined!
 
-error: failed to load bc of "lto_duplicate_symbols1.3a1fbbbh-cgu.0": 
+error: failed to load bc of "lto_duplicate_symbols2.3a1fbbbh-cgu.0": 
 
 error: aborting due to previous error
 

From 85a4d6f522d733871c1dc94e008f4ff2ac548db0 Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Tue, 27 Aug 2019 14:03:32 -0700
Subject: [PATCH 295/943] Update cargo

---
 Cargo.lock      | 22 +++++++++++-----------
 src/tools/cargo |  2 +-
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 8ae21c8663706..c758ef177d691 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -287,7 +287,7 @@ dependencies = [
  "git2-curl",
  "glob",
  "hex",
- "home 0.4.2",
+ "home 0.5.0",
  "ignore",
  "im-rc",
  "jobserver",
@@ -1160,9 +1160,9 @@ dependencies = [
 
 [[package]]
 name = "git2"
-version = "0.9.2"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cb400360e8a4d61b10e648285bbfa919bbf9519d0d5d5720354456f44349226"
+checksum = "327d698f86a7ebdfeb86a4238ccdb004828939d3a3555b6ead679541d14e36c0"
 dependencies = [
  "bitflags",
  "libc",
@@ -1175,9 +1175,9 @@ dependencies = [
 
 [[package]]
 name = "git2-curl"
-version = "0.10.1"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2293de73491c3dc4174c5949ef53d2cc037b27613f88d72032e3f5237247a7dd"
+checksum = "cd6527e480187ce19aaf4fa6acfb7657b25628ce31cb8ffabdfca3bf731524c5"
 dependencies = [
  "curl",
  "git2",
@@ -1282,9 +1282,9 @@ dependencies = [
 
 [[package]]
 name = "home"
-version = "0.4.2"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "013e4e6e9134211bb4d6bf53dd8cfb75d9e2715cc33614b9c0827718c6fbe0b8"
+checksum = "c07c315e106bd6f83f026a20ddaeef2706782e490db1dcdd37caad38a0e895b3"
 dependencies = [
  "scopeguard 1.0.0",
  "winapi 0.3.6",
@@ -1604,9 +1604,9 @@ dependencies = [
 
 [[package]]
 name = "libgit2-sys"
-version = "0.8.2"
+version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c179ed6d19cd3a051e68c177fbbc214e79ac4724fac3a850ec9f3d3eb8a5578"
+checksum = "8c2078aec6f4b16d1b89f6a72e4f6eb1e75ffa85312023291e89c6d3087bc8fb"
 dependencies = [
  "cc",
  "libc",
@@ -1668,9 +1668,9 @@ dependencies = [
 
 [[package]]
 name = "log"
-version = "0.4.6"
+version = "0.4.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
+checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
 dependencies = [
  "cfg-if",
 ]
diff --git a/src/tools/cargo b/src/tools/cargo
index 3f700ec43ce72..22f7dd0495cd7 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 3f700ec43ce72305eb5315cfc710681f3469d4b4
+Subproject commit 22f7dd0495cd72ce2082d318d5a9b4dccb9c5b8c

From 42e895d4d99ec7724f3efd632f52170f3f99a5aa Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 27 Aug 2019 23:44:44 +0200
Subject: [PATCH 296/943] Improve 'mut ' diagnostic.

---
 src/libsyntax/parse/parser/pat.rs         | 54 ++++++++++++++---------
 src/test/ui/parser/issue-32501.rs         |  2 +-
 src/test/ui/parser/issue-32501.stderr     |  6 ++-
 src/test/ui/parser/mut-patterns.rs        |  3 ++
 src/test/ui/parser/mut-patterns.stderr    | 46 ++++++++++++++-----
 src/test/ui/self/self_type_keyword.rs     |  2 +-
 src/test/ui/self/self_type_keyword.stderr |  6 ++-
 7 files changed, 82 insertions(+), 37 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 08934e8533049..1ffb112a5e87e 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -405,22 +405,13 @@ impl<'a> Parser<'a> {
         let mut pat = self.parse_pat(Some("identifier"))?;
 
         // Add `mut` to any binding in the parsed pattern.
-        struct AddMut;
-        impl MutVisitor for AddMut {
-            fn visit_pat(&mut self, pat: &mut P<Pat>) {
-                if let PatKind::Ident(BindingMode::ByValue(ref mut m), ..) = pat.node {
-                    *m = Mutability::Mutable;
-                }
-                noop_visit_pat(pat, self);
-            }
-        }
-        AddMut.visit_pat(&mut pat);
+        let changed_any_binding = Self::make_all_value_bindings_mutable(&mut pat);
 
         // Unwrap; If we don't have `mut $ident`, error.
         let pat = pat.into_inner();
         match &pat.node {
             PatKind::Ident(..) => {}
-            _ => self.ban_mut_general_pat(mut_span, &pat),
+            _ => self.ban_mut_general_pat(mut_span, &pat, changed_any_binding),
         }
 
         Ok(pat.node)
@@ -442,17 +433,40 @@ impl<'a> Parser<'a> {
         self.parse_pat_ident(BindingMode::ByRef(Mutability::Mutable))
     }
 
+    /// Turn all by-value immutable bindings in a pattern into mutable bindings.
+    /// Returns `true` if any change was made.
+    fn make_all_value_bindings_mutable(pat: &mut P<Pat>) -> bool {
+        struct AddMut(bool);
+        impl MutVisitor for AddMut {
+            fn visit_pat(&mut self, pat: &mut P<Pat>) {
+                if let PatKind::Ident(BindingMode::ByValue(ref mut m @ Mutability::Immutable), ..)
+                    = pat.node
+                {
+                    *m = Mutability::Mutable;
+                    self.0 = true;
+                }
+                noop_visit_pat(pat, self);
+            }
+        }
+
+        let mut add_mut = AddMut(false);
+        add_mut.visit_pat(pat);
+        add_mut.0
+    }
+
     /// Error on `mut $pat` where `$pat` is not an ident.
-    fn ban_mut_general_pat(&self, lo: Span, pat: &Pat) {
+    fn ban_mut_general_pat(&self, lo: Span, pat: &Pat, changed_any_binding: bool) {
         let span = lo.to(pat.span);
-        self.struct_span_err(span, "`mut` must be attached to each individual binding")
-            .span_suggestion(
-                span,
-                "add `mut` to each binding",
-                pprust::pat_to_string(&pat),
-                Applicability::MachineApplicable,
-            )
-            .emit();
+        let fix = pprust::pat_to_string(&pat);
+        let (problem, suggestion) = if changed_any_binding {
+            ("`mut` must be attached to each individual binding", "add `mut` to each binding")
+        } else {
+            ("`mut` must be followed by a named binding", "remove the `mut` prefix")
+        };
+        self.struct_span_err(span, problem)
+            .span_suggestion(span, suggestion, fix, Applicability::MachineApplicable)
+            .note("`mut` may be followed by `variable` and `variable @ pattern`")
+            .emit()
     }
 
     /// Eat any extraneous `mut`s and error + recover if we ate any.
diff --git a/src/test/ui/parser/issue-32501.rs b/src/test/ui/parser/issue-32501.rs
index 695baf8187276..500242030c655 100644
--- a/src/test/ui/parser/issue-32501.rs
+++ b/src/test/ui/parser/issue-32501.rs
@@ -5,5 +5,5 @@ fn main() {
     let mut b = 0;
     let mut _b = 0;
     let mut _ = 0;
-    //~^ ERROR `mut` must be attached to each individual binding
+    //~^ ERROR `mut` must be followed by a named binding
 }
diff --git a/src/test/ui/parser/issue-32501.stderr b/src/test/ui/parser/issue-32501.stderr
index f5d3300cf9c56..d53302449a806 100644
--- a/src/test/ui/parser/issue-32501.stderr
+++ b/src/test/ui/parser/issue-32501.stderr
@@ -1,8 +1,10 @@
-error: `mut` must be attached to each individual binding
+error: `mut` must be followed by a named binding
   --> $DIR/issue-32501.rs:7:9
    |
 LL |     let mut _ = 0;
-   |         ^^^^^ help: add `mut` to each binding: `_`
+   |         ^^^^^ help: remove the `mut` prefix: `_`
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/mut-patterns.rs b/src/test/ui/parser/mut-patterns.rs
index 0c78ca726e003..d46186a0fea0e 100644
--- a/src/test/ui/parser/mut-patterns.rs
+++ b/src/test/ui/parser/mut-patterns.rs
@@ -6,6 +6,9 @@
 #![allow(warnings)]
 
 pub fn main() {
+    let mut _ = 0; //~ ERROR `mut` must be followed by a named binding
+    let mut (_, _) = (0, 0); //~ ERROR `mut` must be followed by a named binding
+
     let mut mut x = 0;
     //~^ ERROR `mut` on a binding may not be repeated
     //~| remove the additional `mut`s
diff --git a/src/test/ui/parser/mut-patterns.stderr b/src/test/ui/parser/mut-patterns.stderr
index a1293129e2eaf..18ffaa5255870 100644
--- a/src/test/ui/parser/mut-patterns.stderr
+++ b/src/test/ui/parser/mut-patterns.stderr
@@ -1,29 +1,49 @@
+error: `mut` must be followed by a named binding
+  --> $DIR/mut-patterns.rs:9:9
+   |
+LL |     let mut _ = 0;
+   |         ^^^^^ help: remove the `mut` prefix: `_`
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: `mut` must be followed by a named binding
+  --> $DIR/mut-patterns.rs:10:9
+   |
+LL |     let mut (_, _) = (0, 0);
+   |         ^^^^^^^^^^ help: remove the `mut` prefix: `(_, _)`
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
+
 error: `mut` on a binding may not be repeated
-  --> $DIR/mut-patterns.rs:9:13
+  --> $DIR/mut-patterns.rs:12:13
    |
 LL |     let mut mut x = 0;
    |             ^^^ help: remove the additional `mut`s
 
 error: `mut` must be attached to each individual binding
-  --> $DIR/mut-patterns.rs:14:9
+  --> $DIR/mut-patterns.rs:17:9
    |
 LL |     let mut Foo { x: x } = Foo { x: 3 };
    |         ^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { x: mut x }`
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
 
 error: `mut` must be attached to each individual binding
-  --> $DIR/mut-patterns.rs:18:9
+  --> $DIR/mut-patterns.rs:21:9
    |
 LL |     let mut Foo { x } = Foo { x: 3 };
    |         ^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { mut x }`
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
 
 error: `mut` on a binding may not be repeated
-  --> $DIR/mut-patterns.rs:23:13
+  --> $DIR/mut-patterns.rs:26:13
    |
 LL |     let mut mut yield(become, await) = r#yield(0, 0);
    |             ^^^ help: remove the additional `mut`s
 
 error: expected identifier, found reserved keyword `yield`
-  --> $DIR/mut-patterns.rs:23:17
+  --> $DIR/mut-patterns.rs:26:17
    |
 LL |     let mut mut yield(become, await) = r#yield(0, 0);
    |                 ^^^^^ expected identifier, found reserved keyword
@@ -33,7 +53,7 @@ LL |     let mut mut r#yield(become, await) = r#yield(0, 0);
    |                 ^^^^^^^
 
 error: expected identifier, found reserved keyword `become`
-  --> $DIR/mut-patterns.rs:23:23
+  --> $DIR/mut-patterns.rs:26:23
    |
 LL |     let mut mut yield(become, await) = r#yield(0, 0);
    |                       ^^^^^^ expected identifier, found reserved keyword
@@ -43,7 +63,7 @@ LL |     let mut mut yield(r#become, await) = r#yield(0, 0);
    |                       ^^^^^^^^
 
 error: expected identifier, found reserved keyword `await`
-  --> $DIR/mut-patterns.rs:23:31
+  --> $DIR/mut-patterns.rs:26:31
    |
 LL |     let mut mut yield(become, await) = r#yield(0, 0);
    |                               ^^^^^ expected identifier, found reserved keyword
@@ -53,19 +73,23 @@ LL |     let mut mut yield(become, r#await) = r#yield(0, 0);
    |                               ^^^^^^^
 
 error: `mut` must be attached to each individual binding
-  --> $DIR/mut-patterns.rs:23:9
+  --> $DIR/mut-patterns.rs:26:9
    |
 LL |     let mut mut yield(become, await) = r#yield(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `r#yield(mut r#become, mut r#await)`
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
 
 error: `mut` must be attached to each individual binding
-  --> $DIR/mut-patterns.rs:32:9
+  --> $DIR/mut-patterns.rs:35:9
    |
 LL |     let mut W(mut a, W(b, W(ref c, W(d, B { box f }))))
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `W(mut a, W(mut b, W(ref c, W(mut d, B { box mut f }))))`
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
 
 error: expected identifier, found `x`
-  --> $DIR/mut-patterns.rs:39:21
+  --> $DIR/mut-patterns.rs:42:21
    |
 LL |             let mut $p = 0;
    |                     ^^ expected identifier
@@ -73,5 +97,5 @@ LL |             let mut $p = 0;
 LL |     foo!(x);
    |     -------- in this macro invocation
 
-error: aborting due to 10 previous errors
+error: aborting due to 12 previous errors
 
diff --git a/src/test/ui/self/self_type_keyword.rs b/src/test/ui/self/self_type_keyword.rs
index d479905932be0..844f13c2f896a 100644
--- a/src/test/ui/self/self_type_keyword.rs
+++ b/src/test/ui/self/self_type_keyword.rs
@@ -14,7 +14,7 @@ pub fn main() {
         ref Self => (),
         //~^ ERROR expected identifier, found keyword `Self`
         mut Self => (),
-        //~^ ERROR `mut` must be attached to each individual binding
+        //~^ ERROR `mut` must be followed by a named binding
         //~| ERROR cannot find unit struct/variant or constant `Self`
         ref mut Self => (),
         //~^ ERROR expected identifier, found keyword `Self`
diff --git a/src/test/ui/self/self_type_keyword.stderr b/src/test/ui/self/self_type_keyword.stderr
index fdae06ccdd9f5..bb631194bf3df 100644
--- a/src/test/ui/self/self_type_keyword.stderr
+++ b/src/test/ui/self/self_type_keyword.stderr
@@ -10,11 +10,13 @@ error: expected identifier, found keyword `Self`
 LL |         ref Self => (),
    |             ^^^^ expected identifier, found keyword
 
-error: `mut` must be attached to each individual binding
+error: `mut` must be followed by a named binding
   --> $DIR/self_type_keyword.rs:16:9
    |
 LL |         mut Self => (),
-   |         ^^^^^^^^ help: add `mut` to each binding: `Self`
+   |         ^^^^^^^^ help: remove the `mut` prefix: `Self`
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
 
 error: expected identifier, found keyword `Self`
   --> $DIR/self_type_keyword.rs:19:17

From 3d718037dcddd2aa56bd2727dee074ac9b6a6f0e Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sat, 24 Aug 2019 16:25:55 +0100
Subject: [PATCH 297/943] Add default serialization for `Ident`s

Add tests for -Zast-json and -Zast-json-noexpand, which need this impl.
---
 src/librustc/ty/query/on_disk_cache.rs      | 25 ++++++++++++-
 src/libsyntax_pos/symbol.rs                 | 24 +++++++++++-
 src/test/ui/ast-json/ast-json-ice.rs        | 41 +++++++++++++++++++++
 src/test/ui/ast-json/ast-json-output.rs     |  9 +++++
 src/test/ui/ast-json/ast-json-output.stdout |  1 +
 5 files changed, 96 insertions(+), 4 deletions(-)
 create mode 100644 src/test/ui/ast-json/ast-json-ice.rs
 create mode 100644 src/test/ui/ast-json/ast-json-output.rs
 create mode 100644 src/test/ui/ast-json/ast-json-output.stdout

diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index c21639d0dcaee..674f8944f261a 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -20,7 +20,7 @@ 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::ast::{Ident, NodeId};
 use syntax::source_map::{SourceMap, StableSourceFileId};
 use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile};
 use syntax_pos::hygiene::{ExpnId, SyntaxContext};
@@ -591,7 +591,8 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
         // FIXME(mw): This method does not restore `ExpnData::parent` or
         // `SyntaxContextData::prev_ctxt` or `SyntaxContextData::opaque`. These things
         // don't seem to be used after HIR lowering, so everything should be fine
-        // as long as incremental compilation does not kick in before that.
+        // until we want incremental compilation to serialize Spans that we need
+        // full hygiene information for.
         let location = || Span::with_root_ctxt(lo, hi);
         let recover_from_expn_data = |this: &Self, expn_data, transparency, pos| {
             let span = location().fresh_expansion_with_transparency(expn_data, transparency);
@@ -626,6 +627,13 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> {
     }
 }
 
+impl<'a, 'tcx> SpecializedDecoder<Ident> for CacheDecoder<'a, 'tcx> {
+    fn specialized_decode(&mut self) -> Result<Ident, Self::Error> {
+        // FIXME: Handle hygiene in incremental
+        bug!("Trying to decode Ident for incremental");
+    }
+}
+
 // This impl makes sure that we get a runtime error when we try decode a
 // DefIndex that is not contained in a DefId. Such a case would be problematic
 // because we would not know how to transform the DefIndex to the current
@@ -833,6 +841,19 @@ where
     }
 }
 
+impl<'a, 'tcx, E> SpecializedEncoder<Ident> for CacheEncoder<'a, 'tcx, E>
+where
+    E: 'a + ty_codec::TyEncoder,
+{
+    fn specialized_encode(&mut self, _: &Ident) -> Result<(), Self::Error> {
+        // We don't currently encode enough information to ensure hygiene works
+        // with incremental, so panic rather than risk incremental bugs.
+
+        // FIXME: Handle hygiene in incremental
+        bug!("Trying to encode Ident for incremental")
+    }
+}
+
 impl<'a, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'a, 'tcx, E>
 where
     E: 'a + ty_codec::TyEncoder,
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 0b8f16bbc3b99..2d8e97c1800f7 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -849,9 +849,29 @@ impl fmt::Display for Ident {
     }
 }
 
-impl UseSpecializedEncodable for Ident {}
+impl UseSpecializedEncodable for Ident {
+    fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+        s.emit_struct("Ident", 2, |s| {
+            s.emit_struct_field("name", 0, |s| {
+                self.name.encode(s)
+            })?;
+            s.emit_struct_field("span", 1, |s| {
+                self.span.encode(s)
+            })
+        })
+    }
+}
 
-impl UseSpecializedDecodable for Ident {}
+impl UseSpecializedDecodable for Ident {
+    fn default_decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
+        d.read_struct("Ident", 2, |d| {
+            Ok(Ident {
+                name: d.read_struct_field("name", 0, Decodable::decode)?,
+                span: d.read_struct_field("span", 1, Decodable::decode)?,
+            })
+        })
+    }
+}
 
 /// A symbol is an interned or gensymed string. A gensym is a symbol that is
 /// never equal to any other symbol.
diff --git a/src/test/ui/ast-json/ast-json-ice.rs b/src/test/ui/ast-json/ast-json-ice.rs
new file mode 100644
index 0000000000000..e8a622e1b8772
--- /dev/null
+++ b/src/test/ui/ast-json/ast-json-ice.rs
@@ -0,0 +1,41 @@
+// Test that AST json serialization doesn't ICE (#63728).
+
+// revisions: expand noexpand
+
+//[expand] compile-flags: -Zast-json
+//[noexpand] compile-flags: -Zast-json-noexpand
+
+// check-pass
+// dont-check-compiler-stdout - don't check for any AST change.
+
+#![feature(asm)]
+
+enum V {
+    A(i32),
+    B { f: [i64; 3 + 4] }
+}
+
+trait X {
+    type Output;
+    fn read(&self) -> Self::Output;
+    fn write(&mut self, _: Self::Output);
+}
+
+macro_rules! call_println {
+    ($y:ident) => { println!("{}", $y) }
+}
+
+fn main() {
+    #[cfg(any(target_arch = "x86",
+        target_arch = "x86_64",
+        target_arch = "arm",
+        target_arch = "aarch64"))]
+    unsafe { asm!(""::::); }
+
+    let x: (i32) = 35;
+    let y = x as i64<> + 5;
+
+    call_println!(y);
+
+    struct A;
+}
diff --git a/src/test/ui/ast-json/ast-json-output.rs b/src/test/ui/ast-json/ast-json-output.rs
new file mode 100644
index 0000000000000..e444a07460248
--- /dev/null
+++ b/src/test/ui/ast-json/ast-json-output.rs
@@ -0,0 +1,9 @@
+// Check that AST json printing works.
+
+// check-pass
+// compile-flags: -Zast-json-noexpand
+// normalize-stdout-test ":\d+" -> ":0"
+
+// Only include a single item to reduce how often the test output needs
+// updating.
+extern crate core;
diff --git a/src/test/ui/ast-json/ast-json-output.stdout b/src/test/ui/ast-json/ast-json-output.stdout
new file mode 100644
index 0000000000000..d23cbe0240ee1
--- /dev/null
+++ b/src/test/ui/ast-json/ast-json-output.stdout
@@ -0,0 +1 @@
+{"module":{"inner":{"lo":0,"hi":0},"items":[{"ident":{"name":"core","span":{"lo":0,"hi":0}},"attrs":[],"id":0,"node":{"variant":"ExternCrate","fields":[null]},"vis":{"node":"Inherited","span":{"lo":0,"hi":0}},"span":{"lo":0,"hi":0},"tokens":[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["extern",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["core",false]},"span":{"lo":0,"hi":0}}]},{"variant":"Token","fields":[{"kind":"Semi","span":{"lo":0,"hi":0}}]}]}],"inline":true},"attrs":[],"span":{"lo":0,"hi":0}}

From 82f2b376357e68cdde86d75259fed39ea4df79e3 Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Wed, 28 Aug 2019 06:17:58 +0900
Subject: [PATCH 298/943] Add Option<Span> to `require_lang_item`

---
 src/librustc/infer/mod.rs                      | 2 +-
 src/librustc/middle/lang_items.rs              | 8 ++++++--
 src/librustc/traits/select.rs                  | 2 +-
 src/librustc/ty/context.rs                     | 4 ++--
 src/librustc/ty/instance.rs                    | 2 +-
 src/librustc/ty/mod.rs                         | 6 +++---
 src/librustc/ty/util.rs                        | 6 +++---
 src/librustc/ty/wf.rs                          | 2 +-
 src/librustc_codegen_ssa/base.rs               | 2 +-
 src/librustc_mir/build/matches/test.rs         | 2 +-
 src/librustc_mir/transform/qualify_consts.rs   | 5 ++++-
 src/librustc_mir/util/elaborate_drops.rs       | 2 +-
 src/librustc_typeck/check/cast.rs              | 2 +-
 src/librustc_typeck/check/closure.rs           | 2 +-
 src/librustc_typeck/check/mod.rs               | 2 +-
 src/librustc_typeck/check/wfcheck.rs           | 4 ++--
 src/librustdoc/clean/auto_trait.rs             | 8 ++++----
 src/librustdoc/clean/mod.rs                    | 2 +-
 src/test/ui/lang-item-missing-generator.stderr | 4 ++++
 19 files changed, 39 insertions(+), 28 deletions(-)

diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index e1d77a97c1160..cc28567e2fc9e 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -1460,7 +1460,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             }
         }
 
-        let copy_def_id = self.tcx.require_lang_item(lang_items::CopyTraitLangItem);
+        let copy_def_id = self.tcx.require_lang_item(lang_items::CopyTraitLangItem, None);
 
         // this can get called from typeck (by euv), and moves_by_default
         // rightly refuses to work with inference variables, but
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index c5c8639324358..334c06618bb28 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -381,9 +381,13 @@ language_item_table! {
 impl<'tcx> TyCtxt<'tcx> {
     /// Returns the `DefId` for a given `LangItem`.
     /// If not found, fatally abort compilation.
-    pub fn require_lang_item(&self, lang_item: LangItem) -> DefId {
+    pub fn require_lang_item(&self, lang_item: LangItem, span: Option<Span>) -> DefId {
         self.lang_items().require(lang_item).unwrap_or_else(|msg| {
-            self.sess.fatal(&msg)
+            if let Some(span) = span {
+                self.sess.span_fatal(span, &msg)
+            } else {
+                self.sess.fatal(&msg)
+            }
         })
     }
 }
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index d4ae366262cbf..217c887d5254e 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -3513,7 +3513,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
                 // We can only make objects from sized types.
                 let tr = ty::TraitRef {
-                    def_id: tcx.require_lang_item(lang_items::SizedTraitLangItem),
+                    def_id: tcx.require_lang_item(lang_items::SizedTraitLangItem, None),
                     substs: tcx.mk_substs_trait(source, &[]),
                 };
                 nested.push(predicate_to_obligation(tr.to_predicate()));
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 9f316e93111a3..c0d86a79882ef 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2385,13 +2385,13 @@ impl<'tcx> TyCtxt<'tcx> {
 
     #[inline]
     pub fn mk_box(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem);
+        let def_id = self.require_lang_item(lang_items::OwnedBoxLangItem, None);
         self.mk_generic_adt(def_id, ty)
     }
 
     #[inline]
     pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let def_id = self.require_lang_item(lang_items::MaybeUninitLangItem);
+        let def_id = self.require_lang_item(lang_items::MaybeUninitLangItem, None);
         self.mk_generic_adt(def_id, ty)
     }
 
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index c71e1ea4e5859..a26fa72f33041 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -327,7 +327,7 @@ impl<'tcx> Instance<'tcx> {
     }
 
     pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
-        let def_id = tcx.require_lang_item(DropInPlaceFnLangItem);
+        let def_id = tcx.require_lang_item(DropInPlaceFnLangItem, None);
         let substs = tcx.intern_substs(&[ty.into()]);
         Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs).unwrap()
     }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 0b81f193df409..90b3b7ebb0635 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2588,12 +2588,12 @@ impl<'tcx> ClosureKind {
 
     pub fn trait_did(&self, tcx: TyCtxt<'tcx>) -> DefId {
         match *self {
-            ClosureKind::Fn => tcx.require_lang_item(FnTraitLangItem),
+            ClosureKind::Fn => tcx.require_lang_item(FnTraitLangItem, None),
             ClosureKind::FnMut => {
-                tcx.require_lang_item(FnMutTraitLangItem)
+                tcx.require_lang_item(FnMutTraitLangItem, None)
             }
             ClosureKind::FnOnce => {
-                tcx.require_lang_item(FnOnceTraitLangItem)
+                tcx.require_lang_item(FnOnceTraitLangItem, None)
             }
         }
     }
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 96e16efd1300a..7a77418050cdb 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -998,7 +998,7 @@ impl<'tcx> ty::TyS<'tcx> {
 
 fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
     let (param_env, ty) = query.into_parts();
-    let trait_def_id = tcx.require_lang_item(lang_items::CopyTraitLangItem);
+    let trait_def_id = tcx.require_lang_item(lang_items::CopyTraitLangItem, None);
     tcx.infer_ctxt()
         .enter(|infcx| traits::type_known_to_meet_bound_modulo_regions(
             &infcx,
@@ -1011,7 +1011,7 @@ fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
 
 fn is_sized_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
     let (param_env, ty) = query.into_parts();
-    let trait_def_id = tcx.require_lang_item(lang_items::SizedTraitLangItem);
+    let trait_def_id = tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
     tcx.infer_ctxt()
         .enter(|infcx| traits::type_known_to_meet_bound_modulo_regions(
             &infcx,
@@ -1024,7 +1024,7 @@ fn is_sized_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
 
 fn is_freeze_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
     let (param_env, ty) = query.into_parts();
-    let trait_def_id = tcx.require_lang_item(lang_items::FreezeTraitLangItem);
+    let trait_def_id = tcx.require_lang_item(lang_items::FreezeTraitLangItem, None);
     tcx.infer_ctxt()
         .enter(|infcx| traits::type_known_to_meet_bound_modulo_regions(
             &infcx,
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs
index d32c32af29e0d..d6de217f79c29 100644
--- a/src/librustc/ty/wf.rs
+++ b/src/librustc/ty/wf.rs
@@ -221,7 +221,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
         if !subty.has_escaping_bound_vars() {
             let cause = self.cause(cause);
             let trait_ref = ty::TraitRef {
-                def_id: self.infcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
+                def_id: self.infcx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None),
                 substs: self.infcx.tcx.mk_substs_trait(subty, &[]),
             };
             self.out.push(traits::Obligation::new(cause, self.param_env, trait_ref.to_predicate()));
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index cdc54bb179ebf..4acbe0356b47c 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -456,7 +456,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
         let arg_argv = param_argv;
 
         let (start_fn, args) = if use_start_lang_item {
-            let start_def_id = cx.tcx().require_lang_item(StartFnLangItem);
+            let start_def_id = cx.tcx().require_lang_item(StartFnLangItem, None);
             let start_fn = callee::resolve_and_get_fn(
                 cx,
                 start_def_id,
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index ec85daccd476e..d5890d00ea80f 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -443,7 +443,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             _ => bug!("non_scalar_compare called on non-reference type: {}", ty),
         };
 
-        let eq_def_id = self.hir.tcx().require_lang_item(EqTraitLangItem);
+        let eq_def_id = self.hir.tcx().require_lang_item(EqTraitLangItem, None);
         let method = self.hir.trait_method(eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]);
 
         let bool_ty = self.hir.bool_ty();
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 7f8ae88342934..a59bd6677cb51 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1752,7 +1752,10 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
                 fulfillment_cx.register_bound(&infcx,
                                               param_env,
                                               ty,
-                                              tcx.require_lang_item(lang_items::SyncTraitLangItem),
+                                              tcx.require_lang_item(
+                                                  lang_items::SyncTraitLangItem,
+                                                  None
+                                              ),
                                               cause);
                 if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
                     infcx.report_fulfillment_errors(&err, None, false);
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index c5561a1ae0d15..3e9e4b7767f1e 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -897,7 +897,7 @@ where
     ) -> BasicBlock {
         let tcx = self.tcx();
         let unit_temp = Place::from(self.new_temp(tcx.mk_unit()));
-        let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem);
+        let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem, None);
         let args = adt.variants[VariantIdx::new(0)].fields.iter().enumerate().map(|(i, f)| {
             let field = Field::new(i);
             let field_ty = f.ty(self.tcx(), substs);
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 53101499af1dc..55e7a10f1aaa4 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -649,7 +649,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn type_is_known_to_be_sized_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool {
-        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
+        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
         traits::type_known_to_meet_bound_modulo_regions(self, self.param_env, ty, lang_item, span)
     }
 }
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 06b1e7bfd4eaf..e9370429f3f55 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -266,7 +266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let trait_ref = projection.to_poly_trait_ref(tcx);
 
         let is_fn = tcx.lang_items().fn_trait_kind(trait_ref.def_id()).is_some();
-        let gen_trait = tcx.require_lang_item(lang_items::GeneratorTraitLangItem);
+        let gen_trait = tcx.require_lang_item(lang_items::GeneratorTraitLangItem, cause_span);
         let is_gen = gen_trait == trait_ref.def_id();
         if !is_fn && !is_gen {
             debug!("deduce_sig_from_projection: not fn or generator");
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c4dbe97a7bd96..29fae13e6a866 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2622,7 +2622,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                  span: Span,
                                  code: traits::ObligationCauseCode<'tcx>)
     {
-        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem);
+        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
         self.require_type_meets(ty, span, code, lang_item);
     }
 
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 9c6ea7d30ccf9..f95b3e44bf0f7 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -287,7 +287,7 @@ fn check_type_defn<'tcx, F>(
                 let last = idx == variant.fields.len() - 1;
                 fcx.register_bound(
                     field.ty,
-                    fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
+                    fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None),
                     traits::ObligationCause::new(
                         field.span,
                         fcx.body_id,
@@ -375,7 +375,7 @@ fn check_item_type(
         if forbid_unsized {
             fcx.register_bound(
                 item_ty,
-                fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
+                fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None),
                 traits::ObligationCause::new(ty_span, fcx.body_id, traits::MiscObligation),
             );
         }
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 5a4dc7be326d2..516be99ed6aad 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -464,7 +464,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
         // it is *not* required (i.e., '?Sized')
         let sized_trait = self.cx
             .tcx
-            .require_lang_item(lang_items::SizedTraitLangItem);
+            .require_lang_item(lang_items::SizedTraitLangItem, None);
 
         let mut replacer = RegionReplacer {
             vid_to_region: &vid_to_region,
@@ -777,9 +777,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
     fn is_fn_ty(&self, tcx: TyCtxt<'_>, ty: &Type) -> bool {
         match &ty {
             &&Type::ResolvedPath { ref did, .. } => {
-                *did == tcx.require_lang_item(lang_items::FnTraitLangItem)
-                    || *did == tcx.require_lang_item(lang_items::FnMutTraitLangItem)
-                    || *did == tcx.require_lang_item(lang_items::FnOnceTraitLangItem)
+                *did == tcx.require_lang_item(lang_items::FnTraitLangItem, None)
+                    || *did == tcx.require_lang_item(lang_items::FnMutTraitLangItem, None)
+                    || *did == tcx.require_lang_item(lang_items::FnOnceTraitLangItem, None)
             }
             _ => false,
         }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ba792a413b3c4..ad1fa96cd3557 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1060,7 +1060,7 @@ pub enum GenericBound {
 
 impl GenericBound {
     fn maybe_sized(cx: &DocContext<'_>) -> GenericBound {
-        let did = cx.tcx.require_lang_item(lang_items::SizedTraitLangItem);
+        let did = cx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
         let empty = cx.tcx.intern_substs(&[]);
         let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
             Some(did), false, vec![], empty);
diff --git a/src/test/ui/lang-item-missing-generator.stderr b/src/test/ui/lang-item-missing-generator.stderr
index d0cc4b81be685..fa13bf0b12719 100644
--- a/src/test/ui/lang-item-missing-generator.stderr
+++ b/src/test/ui/lang-item-missing-generator.stderr
@@ -1,4 +1,8 @@
 error: requires `generator` lang_item
+  --> $DIR/lang-item-missing-generator.rs:15:17
+   |
+LL | pub fn abc() -> impl FnOnce(f32) {
+   |                 ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 

From 8c921beebbc4501f301cd1830b7c2528368e517a Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Wed, 28 Aug 2019 07:10:47 +0900
Subject: [PATCH 299/943] Apply review comments

---
 src/librustc_mir/transform/qualify_consts.rs | 2 +-
 src/librustc_mir/util/elaborate_drops.rs     | 5 ++++-
 src/librustc_typeck/check/cast.rs            | 2 +-
 src/librustc_typeck/check/mod.rs             | 2 +-
 src/test/ui/lang-item-missing.stderr         | 4 ++++
 src/test/ui/privacy/privacy2.rs              | 2 +-
 src/test/ui/privacy/privacy2.stderr          | 4 ++++
 src/test/ui/privacy/privacy3.rs              | 2 +-
 src/test/ui/privacy/privacy3.stderr          | 4 ++++
 9 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index a59bd6677cb51..a77421ce15008 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1754,7 +1754,7 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
                                               ty,
                                               tcx.require_lang_item(
                                                   lang_items::SyncTraitLangItem,
-                                                  None
+                                                  Some(body.span)
                                               ),
                                               cause);
                 if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 3e9e4b7767f1e..f3e03e7f81daa 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -897,7 +897,10 @@ where
     ) -> BasicBlock {
         let tcx = self.tcx();
         let unit_temp = Place::from(self.new_temp(tcx.mk_unit()));
-        let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem, None);
+        let free_func = tcx.require_lang_item(
+            lang_items::BoxFreeFnLangItem,
+            Some(self.source_info.span)
+        );
         let args = adt.variants[VariantIdx::new(0)].fields.iter().enumerate().map(|(i, f)| {
             let field = Field::new(i);
             let field_ty = f.ty(self.tcx(), substs);
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 55e7a10f1aaa4..6b88144d1fc10 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -649,7 +649,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn type_is_known_to_be_sized_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool {
-        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
+        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, Some(span));
         traits::type_known_to_meet_bound_modulo_regions(self, self.param_env, ty, lang_item, span)
     }
 }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 29fae13e6a866..62e11fb421ee7 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2622,7 +2622,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                  span: Span,
                                  code: traits::ObligationCauseCode<'tcx>)
     {
-        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
+        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, Some(span));
         self.require_type_meets(ty, span, code, lang_item);
     }
 
diff --git a/src/test/ui/lang-item-missing.stderr b/src/test/ui/lang-item-missing.stderr
index f7516c7d377da..94d62023f3562 100644
--- a/src/test/ui/lang-item-missing.stderr
+++ b/src/test/ui/lang-item-missing.stderr
@@ -1,4 +1,8 @@
 error: requires `sized` lang_item
+  --> $DIR/lang-item-missing.rs:10:50
+   |
+LL | fn start(argc: isize, argv: *const *const u8) -> isize {
+   |                                                  ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/privacy/privacy2.rs b/src/test/ui/privacy/privacy2.rs
index c8fa436bd14fc..07634d9132e78 100644
--- a/src/test/ui/privacy/privacy2.rs
+++ b/src/test/ui/privacy/privacy2.rs
@@ -11,7 +11,7 @@ mod bar {
     }
 }
 
-pub fn foo() {}
+pub fn foo() {} //~ ERROR: requires `sized` lang_item
 
 fn test1() {
     use bar::foo;
diff --git a/src/test/ui/privacy/privacy2.stderr b/src/test/ui/privacy/privacy2.stderr
index 9f2359657bd7c..eaa9f1ad6528e 100644
--- a/src/test/ui/privacy/privacy2.stderr
+++ b/src/test/ui/privacy/privacy2.stderr
@@ -11,6 +11,10 @@ LL |     use bar::glob::foo;
    |                    ^^^
 
 error: requires `sized` lang_item
+  --> $DIR/privacy2.rs:14:14
+   |
+LL | pub fn foo() {}
+   |              ^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/privacy/privacy3.rs b/src/test/ui/privacy/privacy3.rs
index 5a7cd76a98f6e..8853700180dbc 100644
--- a/src/test/ui/privacy/privacy3.rs
+++ b/src/test/ui/privacy/privacy3.rs
@@ -8,7 +8,7 @@ mod bar {
     pub use self::glob::*;
 
     mod glob {
-        fn gpriv() {}
+        fn gpriv() {} //~ ERROR: requires `sized` lang_item
     }
 }
 
diff --git a/src/test/ui/privacy/privacy3.stderr b/src/test/ui/privacy/privacy3.stderr
index 22c1e48b07d94..6826fbf9df290 100644
--- a/src/test/ui/privacy/privacy3.stderr
+++ b/src/test/ui/privacy/privacy3.stderr
@@ -5,6 +5,10 @@ LL |     use bar::gpriv;
    |         ^^^^^^^^^^ no `gpriv` in `bar`
 
 error: requires `sized` lang_item
+  --> $DIR/privacy3.rs:11:20
+   |
+LL |         fn gpriv() {}
+   |                    ^
 
 error: aborting due to 2 previous errors
 

From ede7a777c08658ec54abea504da0e46cd0fb5e5b Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Wed, 28 Aug 2019 07:32:25 +0900
Subject: [PATCH 300/943] Remove `sized` spans

---
 src/librustc_typeck/check/cast.rs    | 2 +-
 src/librustc_typeck/check/mod.rs     | 2 +-
 src/test/ui/lang-item-missing.stderr | 4 ----
 src/test/ui/privacy/privacy2.rs      | 2 +-
 src/test/ui/privacy/privacy2.stderr  | 4 ----
 src/test/ui/privacy/privacy3.rs      | 2 +-
 src/test/ui/privacy/privacy3.stderr  | 4 ----
 7 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 6b88144d1fc10..55e7a10f1aaa4 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -649,7 +649,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn type_is_known_to_be_sized_modulo_regions(&self, ty: Ty<'tcx>, span: Span) -> bool {
-        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, Some(span));
+        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
         traits::type_known_to_meet_bound_modulo_regions(self, self.param_env, ty, lang_item, span)
     }
 }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 62e11fb421ee7..29fae13e6a866 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2622,7 +2622,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                  span: Span,
                                  code: traits::ObligationCauseCode<'tcx>)
     {
-        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, Some(span));
+        let lang_item = self.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
         self.require_type_meets(ty, span, code, lang_item);
     }
 
diff --git a/src/test/ui/lang-item-missing.stderr b/src/test/ui/lang-item-missing.stderr
index 94d62023f3562..f7516c7d377da 100644
--- a/src/test/ui/lang-item-missing.stderr
+++ b/src/test/ui/lang-item-missing.stderr
@@ -1,8 +1,4 @@
 error: requires `sized` lang_item
-  --> $DIR/lang-item-missing.rs:10:50
-   |
-LL | fn start(argc: isize, argv: *const *const u8) -> isize {
-   |                                                  ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/privacy/privacy2.rs b/src/test/ui/privacy/privacy2.rs
index 07634d9132e78..c8fa436bd14fc 100644
--- a/src/test/ui/privacy/privacy2.rs
+++ b/src/test/ui/privacy/privacy2.rs
@@ -11,7 +11,7 @@ mod bar {
     }
 }
 
-pub fn foo() {} //~ ERROR: requires `sized` lang_item
+pub fn foo() {}
 
 fn test1() {
     use bar::foo;
diff --git a/src/test/ui/privacy/privacy2.stderr b/src/test/ui/privacy/privacy2.stderr
index eaa9f1ad6528e..9f2359657bd7c 100644
--- a/src/test/ui/privacy/privacy2.stderr
+++ b/src/test/ui/privacy/privacy2.stderr
@@ -11,10 +11,6 @@ LL |     use bar::glob::foo;
    |                    ^^^
 
 error: requires `sized` lang_item
-  --> $DIR/privacy2.rs:14:14
-   |
-LL | pub fn foo() {}
-   |              ^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/privacy/privacy3.rs b/src/test/ui/privacy/privacy3.rs
index 8853700180dbc..5a7cd76a98f6e 100644
--- a/src/test/ui/privacy/privacy3.rs
+++ b/src/test/ui/privacy/privacy3.rs
@@ -8,7 +8,7 @@ mod bar {
     pub use self::glob::*;
 
     mod glob {
-        fn gpriv() {} //~ ERROR: requires `sized` lang_item
+        fn gpriv() {}
     }
 }
 
diff --git a/src/test/ui/privacy/privacy3.stderr b/src/test/ui/privacy/privacy3.stderr
index 6826fbf9df290..22c1e48b07d94 100644
--- a/src/test/ui/privacy/privacy3.stderr
+++ b/src/test/ui/privacy/privacy3.stderr
@@ -5,10 +5,6 @@ LL |     use bar::gpriv;
    |         ^^^^^^^^^^ no `gpriv` in `bar`
 
 error: requires `sized` lang_item
-  --> $DIR/privacy3.rs:11:20
-   |
-LL |         fn gpriv() {}
-   |                    ^
 
 error: aborting due to 2 previous errors
 

From 6f67bbc445e5c2b426abc4ac0db4c1dcffd48452 Mon Sep 17 00:00:00 2001
From: Tshepang Lekhonkhobe <tshepang@gmail.com>
Date: Wed, 28 Aug 2019 02:23:58 +0200
Subject: [PATCH 301/943] or-pattern: fix typo in error message

---
 src/libsyntax/parse/parser/pat.rs                            | 2 +-
 src/test/ui/or-patterns/while-parsing-this-or-pattern.rs     | 2 +-
 src/test/ui/or-patterns/while-parsing-this-or-pattern.stderr | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 78c9a289b3702..4c6b6ce38f66b 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -113,7 +113,7 @@ impl<'a> Parser<'a> {
         let mut pats = vec![first_pat];
         while self.eat_or_separator() {
             let pat = self.parse_pat(expected).map_err(|mut err| {
-                err.span_label(lo, "while parsing this or-pattern staring here");
+                err.span_label(lo, "while parsing this or-pattern starting here");
                 err
             })?;
             self.maybe_recover_unexpected_comma(pat.span, rc)?;
diff --git a/src/test/ui/or-patterns/while-parsing-this-or-pattern.rs b/src/test/ui/or-patterns/while-parsing-this-or-pattern.rs
index 4a9fae1406af7..b9bfb8638b2ce 100644
--- a/src/test/ui/or-patterns/while-parsing-this-or-pattern.rs
+++ b/src/test/ui/or-patterns/while-parsing-this-or-pattern.rs
@@ -3,7 +3,7 @@
 fn main() {
     match Some(42) {
         Some(42) | .=. => {} //~ ERROR expected pattern, found `.`
-        //~^ while parsing this or-pattern staring here
+        //~^ while parsing this or-pattern starting here
         //~| NOTE expected pattern
     }
 }
diff --git a/src/test/ui/or-patterns/while-parsing-this-or-pattern.stderr b/src/test/ui/or-patterns/while-parsing-this-or-pattern.stderr
index 21fece6c64fe5..7ad62ff99ee73 100644
--- a/src/test/ui/or-patterns/while-parsing-this-or-pattern.stderr
+++ b/src/test/ui/or-patterns/while-parsing-this-or-pattern.stderr
@@ -4,7 +4,7 @@ error: expected pattern, found `.`
 LL |         Some(42) | .=. => {}
    |         --------   ^ expected pattern
    |         |
-   |         while parsing this or-pattern staring here
+   |         while parsing this or-pattern starting here
 
 error: aborting due to previous error
 

From 42bd6fa22b753858bd57aec5e987247fd6a00897 Mon Sep 17 00:00:00 2001
From: Logan Wendholt <lwendholt@gmail.com>
Date: Tue, 27 Aug 2019 20:35:33 -0400
Subject: [PATCH 302/943] Prevent syntax error in ld linker version script

---
 src/librustc_codegen_ssa/back/linker.rs | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index 26091005f25aa..de481d2262478 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -430,10 +430,13 @@ impl<'a> Linker for GccLinker<'a> {
             // Write an LD version script
             let res: io::Result<()> = try {
                 let mut f = BufWriter::new(File::create(&path)?);
-                writeln!(f, "{{\n  global:")?;
-                for sym in self.info.exports[&crate_type].iter() {
-                    debug!("    {};", sym);
-                    writeln!(f, "    {};", sym)?;
+                writeln!(f, "{{")?;
+                if !self.info.exports[&crate_type].is_empty() {
+                    writeln!(f, "  global:")?;
+                    for sym in self.info.exports[&crate_type].iter() {
+                        debug!("    {};", sym);
+                        writeln!(f, "    {};", sym)?;
+                    }
                 }
                 writeln!(f, "\n  local:\n    *;\n}};")?;
             };

From 85d6b7b9d3d946b35826298e3d04381f96427433 Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Wed, 28 Aug 2019 03:58:42 +0200
Subject: [PATCH 303/943] Address naming and comments from reviews

---
 src/librustc/mir/interpret/allocation.rs | 8 ++++----
 src/librustc_codegen_llvm/consts.rs      | 6 +++---
 src/librustc_mir/interpret/memory.rs     | 4 ++--
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index d3f87f16313d0..dcfa2e5cb4691 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -136,7 +136,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
         self.size.bytes() as usize
     }
 
-    /// Look at a slice which may describe undefined bytes or describe a relocation. This differs
+    /// Looks at a slice which may describe undefined bytes or describe a relocation. This differs
     /// from `get_bytes_with_undef_and_ptr` in that it does no relocation checks (even on the
     /// edges) at all. It further ignores `AllocationExtra` callbacks.
     /// This must not be used for reads affecting the interpreter execution.
@@ -144,7 +144,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
         &self.bytes[range]
     }
 
-    /// View the undef mask.
+    /// Returns the undef mask.
     pub fn undef_mask(&self) -> &UndefMask {
         &self.undef_mask
     }
@@ -583,7 +583,7 @@ pub struct AllocationDefinedness {
 /// Transferring the definedness mask to other allocations.
 impl<Tag, Extra> Allocation<Tag, Extra> {
     /// Creates a run-length encoding of the undef_mask.
-    pub fn compress_defined_range(
+    pub fn compress_undef_range(
         &self,
         src: Pointer<Tag>,
         size: Size,
@@ -622,7 +622,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
     }
 
     /// Apply multiple instances of the run-length encoding to the undef_mask.
-    pub fn mark_compressed_range(
+    pub fn mark_compressed_undef_range(
         &mut self,
         defined: &AllocationDefinedness,
         dest: Pointer<Tag>,
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 26eb870cfc0d4..8725e69b11270 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -35,9 +35,9 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll
         assert_eq!(offset as usize as u64, offset);
         let offset = offset as usize;
         if offset > next_offset {
-            // This `inspect` is okay since we have check that it is not within a relocation, it is
-            // within the bounds of the allocation, and it doesn't affect interpreter execution (we
-            // inspect the result after interpreter execution). Any undef byte is replaced with
+            // This `inspect` is okay since we have checked that it is not within a relocation, it
+            // is within the bounds of the allocation, and it doesn't affect interpreter execution
+            // (we inspect the result after interpreter execution). Any undef byte is replaced with
             // some arbitrary byte value.
             //
             // FIXME: relay undef bytes to codegen as undef const bytes
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index f7576a41e0f00..7f7729ae5e0f4 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -900,11 +900,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         assert_eq!(size.bytes() as usize as u64, size.bytes());
 
         let src_alloc = self.get(src.alloc_id)?;
-        let compressed = src_alloc.compress_defined_range(src, size);
+        let compressed = src_alloc.compress_undef_range(src, size);
 
         // now fill in all the data
         let dest_allocation = self.get_mut(dest.alloc_id)?;
-        dest_allocation.mark_compressed_range(&compressed, dest, size, repeat);
+        dest_allocation.mark_compressed_undef_range(&compressed, dest, size, repeat);
 
         Ok(())
     }

From 0006216c9d83dabed3f13f5ed231c152561ceb6a Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Wed, 28 Aug 2019 11:23:41 +0300
Subject: [PATCH 304/943] rustc_apfloat: make the crate #![no_std] explicitly.

---
 src/librustc_apfloat/ieee.rs | 16 ++++++++--------
 src/librustc_apfloat/lib.rs  | 36 ++++++++++++++++++++----------------
 src/librustc_apfloat/ppc.rs  |  6 +++---
 3 files changed, 31 insertions(+), 27 deletions(-)

diff --git a/src/librustc_apfloat/ieee.rs b/src/librustc_apfloat/ieee.rs
index 9f68d770b9e87..18d968fbddd9b 100644
--- a/src/librustc_apfloat/ieee.rs
+++ b/src/librustc_apfloat/ieee.rs
@@ -1,13 +1,13 @@
 use crate::{Category, ExpInt, IEK_INF, IEK_NAN, IEK_ZERO};
 use crate::{Float, FloatConvert, ParseError, Round, Status, StatusAnd};
 
+use core::cmp::{self, Ordering};
+use core::convert::TryFrom;
+use core::fmt::{self, Write};
+use core::marker::PhantomData;
+use core::mem;
+use core::ops::Neg;
 use smallvec::{SmallVec, smallvec};
-use std::cmp::{self, Ordering};
-use std::convert::TryFrom;
-use std::fmt::{self, Write};
-use std::marker::PhantomData;
-use std::mem;
-use std::ops::Neg;
 
 #[must_use]
 pub struct IeeeFloat<S> {
@@ -2287,8 +2287,8 @@ impl Loss {
 /// Implementation details of IeeeFloat significands, such as big integer arithmetic.
 /// As a rule of thumb, no functions in this module should dynamically allocate.
 mod sig {
-    use std::cmp::Ordering;
-    use std::mem;
+    use core::cmp::Ordering;
+    use core::mem;
     use super::{ExpInt, Limb, LIMB_BITS, limbs_for_bits, Loss};
 
     pub(super) fn is_all_zeros(limbs: &[Limb]) -> bool {
diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs
index 9e6d5a6f62434..1190cea21acc3 100644
--- a/src/librustc_apfloat/lib.rs
+++ b/src/librustc_apfloat/lib.rs
@@ -31,15 +31,19 @@
 //! This API is completely unstable and subject to change.
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
+#![no_std]
 #![forbid(unsafe_code)]
 
 #![feature(nll)]
 
-use std::cmp::Ordering;
-use std::fmt;
-use std::ops::{Neg, Add, Sub, Mul, Div, Rem};
-use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
-use std::str::FromStr;
+#[macro_use]
+extern crate alloc;
+
+use core::cmp::Ordering;
+use core::fmt;
+use core::ops::{Neg, Add, Sub, Mul, Div, Rem};
+use core::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
+use core::str::FromStr;
 
 bitflags::bitflags! {
     /// IEEE-754R 7: Default exception handling.
@@ -587,7 +591,7 @@ macro_rules! float_common_impls {
             }
         }
 
-        impl<$t> ::std::str::FromStr for $ty<$t> where Self: Float {
+        impl<$t> ::core::str::FromStr for $ty<$t> where Self: Float {
             type Err = ParseError;
             fn from_str(s: &str) -> Result<Self, ParseError> {
                 Self::from_str_r(s, Round::NearestTiesToEven).map(|x| x.value)
@@ -596,66 +600,66 @@ macro_rules! float_common_impls {
 
         // Rounding ties to the nearest even, by default.
 
-        impl<$t> ::std::ops::Add for $ty<$t> where Self: Float {
+        impl<$t> ::core::ops::Add for $ty<$t> where Self: Float {
             type Output = StatusAnd<Self>;
             fn add(self, rhs: Self) -> StatusAnd<Self> {
                 self.add_r(rhs, Round::NearestTiesToEven)
             }
         }
 
-        impl<$t> ::std::ops::Sub for $ty<$t> where Self: Float {
+        impl<$t> ::core::ops::Sub for $ty<$t> where Self: Float {
             type Output = StatusAnd<Self>;
             fn sub(self, rhs: Self) -> StatusAnd<Self> {
                 self.sub_r(rhs, Round::NearestTiesToEven)
             }
         }
 
-        impl<$t> ::std::ops::Mul for $ty<$t> where Self: Float {
+        impl<$t> ::core::ops::Mul for $ty<$t> where Self: Float {
             type Output = StatusAnd<Self>;
             fn mul(self, rhs: Self) -> StatusAnd<Self> {
                 self.mul_r(rhs, Round::NearestTiesToEven)
             }
         }
 
-        impl<$t> ::std::ops::Div for $ty<$t> where Self: Float {
+        impl<$t> ::core::ops::Div for $ty<$t> where Self: Float {
             type Output = StatusAnd<Self>;
             fn div(self, rhs: Self) -> StatusAnd<Self> {
                 self.div_r(rhs, Round::NearestTiesToEven)
             }
         }
 
-        impl<$t> ::std::ops::Rem for $ty<$t> where Self: Float {
+        impl<$t> ::core::ops::Rem for $ty<$t> where Self: Float {
             type Output = StatusAnd<Self>;
             fn rem(self, rhs: Self) -> StatusAnd<Self> {
                 self.c_fmod(rhs)
             }
         }
 
-        impl<$t> ::std::ops::AddAssign for $ty<$t> where Self: Float {
+        impl<$t> ::core::ops::AddAssign for $ty<$t> where Self: Float {
             fn add_assign(&mut self, rhs: Self) {
                 *self = (*self + rhs).value;
             }
         }
 
-        impl<$t> ::std::ops::SubAssign for $ty<$t> where Self: Float {
+        impl<$t> ::core::ops::SubAssign for $ty<$t> where Self: Float {
             fn sub_assign(&mut self, rhs: Self) {
                 *self = (*self - rhs).value;
             }
         }
 
-        impl<$t> ::std::ops::MulAssign for $ty<$t> where Self: Float {
+        impl<$t> ::core::ops::MulAssign for $ty<$t> where Self: Float {
             fn mul_assign(&mut self, rhs: Self) {
                 *self = (*self * rhs).value;
             }
         }
 
-        impl<$t> ::std::ops::DivAssign for $ty<$t> where Self: Float {
+        impl<$t> ::core::ops::DivAssign for $ty<$t> where Self: Float {
             fn div_assign(&mut self, rhs: Self) {
                 *self = (*self / rhs).value;
             }
         }
 
-        impl<$t> ::std::ops::RemAssign for $ty<$t> where Self: Float {
+        impl<$t> ::core::ops::RemAssign for $ty<$t> where Self: Float {
             fn rem_assign(&mut self, rhs: Self) {
                 *self = (*self % rhs).value;
             }
diff --git a/src/librustc_apfloat/ppc.rs b/src/librustc_apfloat/ppc.rs
index ddccfd6ca623b..8e2e390568e48 100644
--- a/src/librustc_apfloat/ppc.rs
+++ b/src/librustc_apfloat/ppc.rs
@@ -1,9 +1,9 @@
 use crate::{Category, ExpInt, Float, FloatConvert, Round, ParseError, Status, StatusAnd};
 use crate::ieee;
 
-use std::cmp::Ordering;
-use std::fmt;
-use std::ops::Neg;
+use core::cmp::Ordering;
+use core::fmt;
+use core::ops::Neg;
 
 #[must_use]
 #[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]

From 06228d33cac6770653d6798cf5f80d1269e5482d Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Wed, 24 Jul 2019 17:50:48 +0200
Subject: [PATCH 305/943] Save crate filtering on rustdoc

---
 src/librustdoc/html/static/main.js    | 20 ++++++++++++++++++--
 src/librustdoc/html/static/storage.js |  2 +-
 2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 82d2c11b2497b..1dd8b0ad686f5 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -445,6 +445,21 @@ if (!DOMTokenList.prototype.remove) {
         var OUTPUT_DATA = 1;
         var params = getQueryStringParams();
 
+        // Set the crate filter from saved storage, if the current page has the saved crate filter.
+        //
+        // If not, ignore the crate filter -- we want to support filtering for crates on sites like
+        // doc.rust-lang.org where the crates may differ from page to page while on the same domain.
+        var savedCrate = getCurrentValue("rustdoc-saved-filter-crate");
+        if (savedCrate !== null) {
+            onEachLazy(document.getElementById("crate-search").getElementsByTagName("option"),
+                       function(e) {
+                if (e.value === savedCrate) {
+                    document.getElementById("crate-search").value = e.value;
+                    return true;
+                }
+            });
+        }
+
         // Populate search bar with query string search term when provided,
         // but only if the input bar is empty. This avoid the obnoxious issue
         // where you start trying to do a search, and the index loads, and
@@ -1658,9 +1673,10 @@ if (!DOMTokenList.prototype.remove) {
             };
             search_input.onpaste = search_input.onchange;
 
-            var selectCrate = document.getElementById('crate-search');
+            var selectCrate = document.getElementById("crate-search");
             if (selectCrate) {
                 selectCrate.onchange = function() {
+                    updateLocalStorage("rustdoc-saved-filter-crate", selectCrate.value);
                     search(undefined, true);
                 };
             }
@@ -2496,7 +2512,7 @@ if (!DOMTokenList.prototype.remove) {
     }
 
     function addSearchOptions(crates) {
-        var elem = document.getElementById('crate-search');
+        var elem = document.getElementById("crate-search");
 
         if (!elem) {
             return;
diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index e3927350d1104..dd16664395bb2 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -57,7 +57,7 @@ function onEachLazy(lazyArray, func, reversed) {
 
 function usableLocalStorage() {
     // Check if the browser supports localStorage at all:
-    if (typeof(Storage) === "undefined") {
+    if (typeof Storage === "undefined") {
         return false;
     }
     // Check if we can access it; this access will fail if the browser

From cca64e73399c02b2f964e3b34f969e826d061eed Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Mon, 26 Aug 2019 21:07:58 -0400
Subject: [PATCH 306/943] Add some comments to `mir::Static` and
 `mir::StaticKind`

---
 src/librustc/mir/mod.rs | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 60efeaab97602..a5ef3792c6b96 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1733,6 +1733,10 @@ pub enum PlaceBase<'tcx> {
 pub struct Static<'tcx> {
     pub ty: Ty<'tcx>,
     pub kind: StaticKind<'tcx>,
+    /// The `DefId` of the item this static was declared in. For promoted values, usually, this is
+    /// the same as the `DefId` of the `mir::Body` containing the `Place` this promoted appears in.
+    /// However, after inlining, that might no longer be the case as inlined `Place`s are copied
+    /// into the calling frame.
     pub def_id: DefId,
 }
 
@@ -1740,6 +1744,9 @@ pub struct Static<'tcx> {
     Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, RustcEncodable, RustcDecodable,
 )]
 pub enum StaticKind<'tcx> {
+    /// Promoted references consist of an id (`Promoted`) and the substs necessary to monomorphize
+    /// it. Usually, these substs are just the identity substs for the item. However, the inliner
+    /// will adjust these substs when it inlines a function based on the substs at the callsite.
     Promoted(Promoted, SubstsRef<'tcx>),
     Static,
 }

From 30b29ab0f7c54a2ca74de5117395371101fa9518 Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Mon, 26 Aug 2019 21:58:16 -0400
Subject: [PATCH 307/943] Simplify `maybe_get_optimized_mir` and
 `maybe_get_promoted_mir`

Since both functions are always unwrapped, don't wrap the return value
in an `Option`.
---
 src/librustc_metadata/cstore_impl.rs | 20 ++---------------
 src/librustc_metadata/decoder.rs     | 32 ++++++++++++++++++----------
 2 files changed, 23 insertions(+), 29 deletions(-)

diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 7aeeef00ea934..81e0cd7a4c4dd 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -127,24 +127,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
             bug!("coerce_unsized_info: `{:?}` is missing its info", def_id);
         })
     }
-    optimized_mir => {
-        let mir = cdata.maybe_get_optimized_mir(tcx, def_id.index).unwrap_or_else(|| {
-            bug!("get_optimized_mir: missing MIR for `{:?}`", def_id)
-        });
-
-        let mir = tcx.arena.alloc(mir);
-
-        mir
-    }
-    promoted_mir => {
-        let promoted = cdata.maybe_get_promoted_mir(tcx, def_id.index).unwrap_or_else(|| {
-            bug!("get_promoted_mir: missing promoted MIR for `{:?}`", def_id)
-        });
-
-        let promoted = tcx.arena.alloc(promoted);
-
-        promoted
-    }
+    optimized_mir => { tcx.arena.alloc(cdata.get_optimized_mir(tcx, def_id.index)) }
+    promoted_mir => { tcx.arena.alloc(cdata.get_promoted_mir(tcx, def_id.index)) }
     mir_const_qualif => {
         (cdata.mir_const_qualif(def_id.index), tcx.arena.alloc(BitSet::new_empty(0)))
     }
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 5b9cb966af235..10b165c906625 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -917,22 +917,32 @@ impl<'a, 'tcx> CrateMetadata {
         self.maybe_entry(id).and_then(|item| item.decode(self).mir).is_some()
     }
 
-    pub fn maybe_get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Option<Body<'tcx>> {
-        match self.is_proc_macro(id) {
-            true => None,
-            false => self.entry(id).mir.map(|mir| mir.decode((self, tcx))),
-        }
+    pub fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
+        let mir =
+            match self.is_proc_macro(id) {
+                true => None,
+                false => self.entry(id).mir.map(|mir| mir.decode((self, tcx))),
+            };
+
+        mir.unwrap_or_else(|| {
+            bug!("get_optimized_mir: missing MIR for `{:?}`", self.local_def_id(id))
+        })
     }
 
-    pub fn maybe_get_promoted_mir(
+    pub fn get_promoted_mir(
         &self,
         tcx: TyCtxt<'tcx>,
         id: DefIndex,
-    ) -> Option<IndexVec<Promoted, Body<'tcx>>> {
-        match self.is_proc_macro(id) {
-            true => None,
-            false => self.entry(id).promoted_mir.map(|promoted| promoted.decode((self, tcx)),)
-        }
+    ) -> IndexVec<Promoted, Body<'tcx>> {
+        let promoted =
+            match self.is_proc_macro(id) {
+                true => None,
+                false => self.entry(id).promoted_mir.map(|promoted| promoted.decode((self, tcx)))
+            };
+
+        promoted.unwrap_or_else(|| {
+            bug!("get_promoted_mir: missing MIR for `{:?}`", self.local_def_id(id))
+        })
     }
 
     pub fn mir_const_qualif(&self, id: DefIndex) -> u8 {

From 009cce88ebcbdb5825c86fd7f3ff84216a2d3fec Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Tue, 27 Aug 2019 21:24:57 -0400
Subject: [PATCH 308/943] Extract `Decoder::entry_unless_proc_macro()`

---
 src/librustc_metadata/decoder.rs | 42 +++++++++++++++-----------------
 1 file changed, 20 insertions(+), 22 deletions(-)

diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 10b165c906625..4d2f9f58226d7 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -450,11 +450,19 @@ impl<'a, 'tcx> CrateMetadata {
     pub fn is_proc_macro_crate(&self) -> bool {
         self.root.proc_macro_decls_static.is_some()
     }
+
     fn is_proc_macro(&self, id: DefIndex) -> bool {
         self.is_proc_macro_crate() &&
             self.root.proc_macro_data.unwrap().decode(self).find(|x| *x == id).is_some()
     }
 
+    fn entry_unless_proc_macro(&self, id: DefIndex) -> Option<Entry<'tcx>> {
+        match self.is_proc_macro(id) {
+            true => None,
+            false => Some(self.entry(id)),
+        }
+    }
+
     fn maybe_entry(&self, item_id: DefIndex) -> Option<Lazy<Entry<'tcx>>> {
         self.root.entries_index.lookup(self.blob.raw_bytes(), item_id)
     }
@@ -704,10 +712,8 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     pub fn get_deprecation(&self, id: DefIndex) -> Option<attr::Deprecation> {
-        match self.is_proc_macro(id) {
-            true => None,
-            false => self.entry(id).deprecation.map(|depr| depr.decode(self)),
-        }
+        self.entry_unless_proc_macro(id)
+            .and_then(|entry| entry.deprecation.map(|depr| depr.decode(self)))
     }
 
     pub fn get_visibility(&self, id: DefIndex) -> ty::Visibility {
@@ -918,15 +924,11 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     pub fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
-        let mir =
-            match self.is_proc_macro(id) {
-                true => None,
-                false => self.entry(id).mir.map(|mir| mir.decode((self, tcx))),
-            };
-
-        mir.unwrap_or_else(|| {
-            bug!("get_optimized_mir: missing MIR for `{:?}`", self.local_def_id(id))
-        })
+        self.entry_unless_proc_macro(id)
+            .and_then(|entry| entry.mir.map(|mir| mir.decode((self, tcx))))
+            .unwrap_or_else(|| {
+                bug!("get_optimized_mir: missing MIR for `{:?}", self.local_def_id(id))
+            })
     }
 
     pub fn get_promoted_mir(
@@ -934,15 +936,11 @@ impl<'a, 'tcx> CrateMetadata {
         tcx: TyCtxt<'tcx>,
         id: DefIndex,
     ) -> IndexVec<Promoted, Body<'tcx>> {
-        let promoted =
-            match self.is_proc_macro(id) {
-                true => None,
-                false => self.entry(id).promoted_mir.map(|promoted| promoted.decode((self, tcx)))
-            };
-
-        promoted.unwrap_or_else(|| {
-            bug!("get_promoted_mir: missing MIR for `{:?}`", self.local_def_id(id))
-        })
+        self.entry_unless_proc_macro(id)
+            .and_then(|entry| entry.promoted_mir.map(|promoted| promoted.decode((self, tcx))))
+            .unwrap_or_else(|| {
+                bug!("get_promoted_mir: missing MIR for `{:?}`", self.local_def_id(id))
+            })
     }
 
     pub fn mir_const_qualif(&self, id: DefIndex) -> u8 {

From 8cf392114da9deb8bdf160b196b8fd1503fb395e Mon Sep 17 00:00:00 2001
From: flip1995 <hello@philkrones.com>
Date: Wed, 28 Aug 2019 13:23:00 +0200
Subject: [PATCH 309/943] Notify me (flip1995) when Clippy toolstate changes

---
 src/tools/publish_toolstate.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 648838d26efe9..1411f4c0b05a2 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -22,7 +22,7 @@
 # List of people to ping when the status of a tool or a book changed.
 MAINTAINERS = {
     'miri': '@oli-obk @RalfJung @eddyb',
-    'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk @phansch',
+    'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk @phansch @flip1995',
     'rls': '@Xanewok',
     'rustfmt': '@topecongiro',
     'book': '@carols10cents @steveklabnik',

From bc91706a84bcbcf2bcbbf4b38196a219f2cf62ee Mon Sep 17 00:00:00 2001
From: flip1995 <hello@philkrones.com>
Date: Wed, 28 Aug 2019 13:25:04 +0200
Subject: [PATCH 310/943] Update Clippy

---
 src/tools/clippy | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/clippy b/src/tools/clippy
index 05f603e6cec63..a939d61cf7fea 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit 05f603e6cec63d0b2681a84d4a64a51bccac1624
+Subproject commit a939d61cf7feac0f328aec07f050c4ac96c51d2c

From 8e10725317f9d55f41a881cfadd8cfa2e3f8c59e Mon Sep 17 00:00:00 2001
From: topecongiro <seuchida@gmail.com>
Date: Wed, 28 Aug 2019 22:36:56 +0900
Subject: [PATCH 311/943] Update rustfmt to 1.4.6

---
 Cargo.lock        | 2 +-
 src/tools/rustfmt | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 1b294b22026ed..7749979430514 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3578,7 +3578,7 @@ dependencies = [
 
 [[package]]
 name = "rustfmt-nightly"
-version = "1.4.5"
+version = "1.4.6"
 dependencies = [
  "annotate-snippets",
  "atty",
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
index 9792ff05297c0..f800ce47d1da2 160000
--- a/src/tools/rustfmt
+++ b/src/tools/rustfmt
@@ -1 +1 @@
-Subproject commit 9792ff05297c0a5c40942b346c9b0341b9e7c0ee
+Subproject commit f800ce47d1da2a1c02ffd260deca8b7445f7facf

From 8fe65da935d7e01dbac897dcfbb4fb0f9f24e442 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Tue, 23 Jul 2019 07:25:34 -0700
Subject: [PATCH 312/943] std: Remove the `wasm_syscall` feature

This commit removes the `wasm_syscall` feature from the
wasm32-unknown-unknown build of the standard library. This feature was
originally intended to allow an opt-in way to interact with the
operating system in a posix-like way but it was never stabilized.
Nowadays with the advent of the `wasm32-wasi` target that should
entirely replace the intentions of the `wasm_syscall` feature.
---
 config.toml.example          |   5 -
 src/bootstrap/config.rs      |   3 -
 src/bootstrap/lib.rs         |   3 -
 src/bootstrap/test.rs        |  10 --
 src/etc/wasm32-shim.js       | 108 +----------------
 src/libstd/Cargo.toml        |   5 -
 src/libstd/sys/wasm/args.rs  |   4 +-
 src/libstd/sys/wasm/mod.rs   | 222 +----------------------------------
 src/libstd/sys/wasm/os.rs    |  18 +--
 src/libstd/sys/wasm/stdio.rs |  15 +--
 src/libstd/sys/wasm/time.rs  |   5 +-
 11 files changed, 19 insertions(+), 379 deletions(-)

diff --git a/config.toml.example b/config.toml.example
index a3ec4f2044cbd..30e2ee1b9babf 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -382,11 +382,6 @@
 # This is the name of the directory in which codegen backends will get installed
 #codegen-backends-dir = "codegen-backends"
 
-# Flag indicating whether `libstd` calls an imported function to handle basic IO
-# when targeting WebAssembly. Enable this to debug tests for the `wasm32-unknown-unknown`
-# target, as without this option the test output will not be captured.
-#wasm-syscall = false
-
 # Indicates whether LLD will be compiled and made available in the sysroot for
 # rustc to execute.
 #lld = false
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index a5bfafdfdb4dc..43d9264eaca92 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -122,7 +122,6 @@ pub struct Config {
 
     // libstd features
     pub backtrace: bool, // support for RUST_BACKTRACE
-    pub wasm_syscall: bool,
 
     // misc
     pub low_priority: bool,
@@ -318,7 +317,6 @@ struct Rust {
     save_toolstates: Option<String>,
     codegen_backends: Option<Vec<String>>,
     codegen_backends_dir: Option<String>,
-    wasm_syscall: Option<bool>,
     lld: Option<bool>,
     lldb: Option<bool>,
     llvm_tools: Option<bool>,
@@ -558,7 +556,6 @@ impl Config {
             if let Some(true) = rust.incremental {
                 config.incremental = true;
             }
-            set(&mut config.wasm_syscall, rust.wasm_syscall);
             set(&mut config.lld_enabled, rust.lld);
             set(&mut config.lldb_enabled, rust.lldb);
             set(&mut config.llvm_tools_enabled, rust.llvm_tools);
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index c0e0ad1a857b9..0982f22473392 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -498,9 +498,6 @@ impl Build {
         if self.config.profiler {
             features.push_str(" profiler");
         }
-        if self.config.wasm_syscall {
-            features.push_str(" wasm_syscall");
-        }
         features
     }
 
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 2bb053cc2b002..97b28ed9e96c8 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1811,16 +1811,6 @@ impl Step for Crate {
                     .expect("nodejs not configured"),
             );
         } else if target.starts_with("wasm32") {
-            // Warn about running tests without the `wasm_syscall` feature enabled.
-            // The javascript shim implements the syscall interface so that test
-            // output can be correctly reported.
-            if !builder.config.wasm_syscall {
-                builder.info(
-                    "Libstd was built without `wasm_syscall` feature enabled: \
-                     test output may not be visible."
-                );
-            }
-
             // On the wasm32-unknown-unknown target we're using LTO which is
             // incompatible with `-C prefer-dynamic`, so disable that here
             cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
diff --git a/src/etc/wasm32-shim.js b/src/etc/wasm32-shim.js
index 2a89c0d321d6a..262a53eabe3c7 100644
--- a/src/etc/wasm32-shim.js
+++ b/src/etc/wasm32-shim.js
@@ -15,113 +15,7 @@ const buffer = fs.readFileSync(process.argv[2]);
 Error.stackTraceLimit = 20;
 
 let m = new WebAssembly.Module(buffer);
-
-let memory = null;
-
-function viewstruct(data, fields) {
-  return new Uint32Array(memory.buffer).subarray(data/4, data/4 + fields);
-}
-
-function copystr(a, b) {
-  let view = new Uint8Array(memory.buffer).subarray(a, a + b);
-  return String.fromCharCode.apply(null, view);
-}
-
-function syscall_write([fd, ptr, len]) {
-  let s = copystr(ptr, len);
-  switch (fd) {
-    case 1: process.stdout.write(s); break;
-    case 2: process.stderr.write(s); break;
-  }
-}
-
-function syscall_exit([code]) {
-  process.exit(code);
-}
-
-function syscall_args(params) {
-  let [ptr, len] = params;
-
-  // Calculate total required buffer size
-  let totalLen = -1;
-  for (let i = 2; i < process.argv.length; ++i) {
-    totalLen += Buffer.byteLength(process.argv[i]) + 1;
-  }
-  if (totalLen < 0) { totalLen = 0; }
-  params[2] = totalLen;
-
-  // If buffer is large enough, copy data
-  if (len >= totalLen) {
-    let view = new Uint8Array(memory.buffer);
-    for (let i = 2; i < process.argv.length; ++i) {
-      let value = process.argv[i];
-      Buffer.from(value).copy(view, ptr);
-      ptr += Buffer.byteLength(process.argv[i]) + 1;
-    }
-  }
-}
-
-function syscall_getenv(params) {
-  let [keyPtr, keyLen, valuePtr, valueLen] = params;
-
-  let key = copystr(keyPtr, keyLen);
-  let value = process.env[key];
-
-  if (value == null) {
-    params[4] = 0xFFFFFFFF;
-  } else {
-    let view = new Uint8Array(memory.buffer);
-    let totalLen = Buffer.byteLength(value);
-    params[4] = totalLen;
-    if (valueLen >= totalLen) {
-      Buffer.from(value).copy(view, valuePtr);
-    }
-  }
-}
-
-function syscall_time(params) {
-  let t = Date.now();
-  let secs = Math.floor(t / 1000);
-  let millis = t % 1000;
-  params[1] = Math.floor(secs / 0x100000000);
-  params[2] = secs % 0x100000000;
-  params[3] = Math.floor(millis * 1000000);
-}
-
-let imports = {};
-imports.env = {
-  // These are generated by LLVM itself for various intrinsic calls. Hopefully
-  // one day this is not necessary and something will automatically do this.
-  fmod: function(x, y) { return x % y; },
-  exp2: function(x) { return Math.pow(2, x); },
-  exp2f: function(x) { return Math.pow(2, x); },
-  ldexp: function(x, y) { return x * Math.pow(2, y); },
-  ldexpf: function(x, y) { return x * Math.pow(2, y); },
-  sin: Math.sin,
-  sinf: Math.sin,
-  cos: Math.cos,
-  cosf: Math.cos,
-  log: Math.log,
-  log2: Math.log2,
-  log10: Math.log10,
-  log10f: Math.log10,
-
-  rust_wasm_syscall: function(index, data) {
-    switch (index) {
-      case 1: syscall_write(viewstruct(data, 3)); return true;
-      case 2: syscall_exit(viewstruct(data, 1)); return true;
-      case 3: syscall_args(viewstruct(data, 3)); return true;
-      case 4: syscall_getenv(viewstruct(data, 5)); return true;
-      case 6: syscall_time(viewstruct(data, 4)); return true;
-      default:
-        console.log("Unsupported syscall: " + index);
-        return false;
-    }
-  }
-};
-
-let instance = new WebAssembly.Instance(m, imports);
-memory = instance.exports.memory;
+let instance = new WebAssembly.Instance(m, {});
 try {
   instance.exports.main();
 } catch (e) {
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index bb77a5bdea493..157faa0af9bca 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -70,11 +70,6 @@ llvm-libunwind = ["unwind/llvm-libunwind"]
 # Make panics and failed asserts immediately abort without formatting any message
 panic_immediate_abort = ["core/panic_immediate_abort"]
 
-# An off-by-default feature which enables a linux-syscall-like ABI for libstd to
-# interoperate with the host environment. Currently not well documented and
-# requires rebuilding the standard library to use it.
-wasm_syscall = []
-
 # Enable std_detect default features for stdarch/crates/std_detect:
 # https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml
 std_detect_file_io = []
diff --git a/src/libstd/sys/wasm/args.rs b/src/libstd/sys/wasm/args.rs
index b3c77b8699563..8279e5280e924 100644
--- a/src/libstd/sys/wasm/args.rs
+++ b/src/libstd/sys/wasm/args.rs
@@ -1,7 +1,6 @@
 use crate::ffi::OsString;
 use crate::marker::PhantomData;
 use crate::vec;
-use crate::sys::ArgsSysCall;
 
 pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
     // On wasm these should always be null, so there's nothing for us to do here
@@ -11,9 +10,8 @@ pub unsafe fn cleanup() {
 }
 
 pub fn args() -> Args {
-    let v = ArgsSysCall::perform();
     Args {
-        iter: v.into_iter(),
+        iter: Vec::new().into_iter(),
         _dont_send_or_sync_me: PhantomData,
     }
 }
diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs
index 56cbafcfdb8a2..de0bb38dc319e 100644
--- a/src/libstd/sys/wasm/mod.rs
+++ b/src/libstd/sys/wasm/mod.rs
@@ -15,11 +15,6 @@
 //! guaranteed to be a runtime error!
 
 use crate::os::raw::c_char;
-use crate::ptr;
-use crate::sys::os_str::Buf;
-use crate::sys_common::{AsInner, FromInner};
-use crate::ffi::{OsString, OsStr};
-use crate::time::Duration;
 
 pub mod alloc;
 pub mod args;
@@ -89,7 +84,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize {
 }
 
 pub unsafe fn abort_internal() -> ! {
-    ExitSysCall::perform(1)
+    crate::arch::wasm32::unreachable()
 }
 
 // We don't have randomness yet, but I totally used a random number generator to
@@ -100,218 +95,3 @@ pub unsafe fn abort_internal() -> ! {
 pub fn hashmap_random_keys() -> (u64, u64) {
     (1, 2)
 }
-
-// Implement a minimal set of system calls to enable basic IO
-pub enum SysCallIndex {
-    Read = 0,
-    Write = 1,
-    Exit = 2,
-    Args = 3,
-    GetEnv = 4,
-    SetEnv = 5,
-    Time = 6,
-}
-
-#[repr(C)]
-pub struct ReadSysCall {
-    fd: usize,
-    ptr: *mut u8,
-    len: usize,
-    result: usize,
-}
-
-impl ReadSysCall {
-    pub fn perform(fd: usize, buffer: &mut [u8]) -> usize {
-        let mut call_record = ReadSysCall {
-            fd,
-            len: buffer.len(),
-            ptr: buffer.as_mut_ptr(),
-            result: 0
-        };
-        if unsafe { syscall(SysCallIndex::Read, &mut call_record) } {
-            call_record.result
-        } else {
-            0
-        }
-    }
-}
-
-#[repr(C)]
-pub struct WriteSysCall {
-    fd: usize,
-    ptr: *const u8,
-    len: usize,
-}
-
-impl WriteSysCall {
-    pub fn perform(fd: usize, buffer: &[u8]) {
-        let mut call_record = WriteSysCall {
-            fd,
-            len: buffer.len(),
-            ptr: buffer.as_ptr()
-        };
-        unsafe { syscall(SysCallIndex::Write, &mut call_record); }
-    }
-}
-
-#[repr(C)]
-pub struct ExitSysCall {
-    code: usize,
-}
-
-impl ExitSysCall {
-    pub fn perform(code: usize) -> ! {
-        let mut call_record = ExitSysCall {
-            code
-        };
-        unsafe {
-            syscall(SysCallIndex::Exit, &mut call_record);
-            crate::intrinsics::abort();
-        }
-    }
-}
-
-fn receive_buffer<E, F: FnMut(&mut [u8]) -> Result<usize, E>>(estimate: usize, mut f: F)
-    -> Result<Vec<u8>, E>
-{
-    let mut buffer = vec![0; estimate];
-    loop {
-        let result = f(&mut buffer)?;
-        if result <= buffer.len() {
-            buffer.truncate(result);
-            break;
-        }
-        buffer.resize(result, 0);
-    }
-    Ok(buffer)
-}
-
-#[repr(C)]
-pub struct ArgsSysCall {
-    ptr: *mut u8,
-    len: usize,
-    result: usize
-}
-
-impl ArgsSysCall {
-    pub fn perform() -> Vec<OsString> {
-        receive_buffer(1024, |buffer| -> Result<usize, !> {
-            let mut call_record = ArgsSysCall {
-                len: buffer.len(),
-                ptr: buffer.as_mut_ptr(),
-                result: 0
-            };
-            if unsafe { syscall(SysCallIndex::Args, &mut call_record) } {
-                Ok(call_record.result)
-            } else {
-                Ok(0)
-            }
-        })
-            .unwrap()
-            .split(|b| *b == 0)
-            .map(|s| FromInner::from_inner(Buf { inner: s.to_owned() }))
-            .collect()
-    }
-}
-
-#[repr(C)]
-pub struct GetEnvSysCall {
-    key_ptr: *const u8,
-    key_len: usize,
-    value_ptr: *mut u8,
-    value_len: usize,
-    result: usize
-}
-
-impl GetEnvSysCall {
-    pub fn perform(key: &OsStr) -> Option<OsString> {
-        let key_buf = &AsInner::as_inner(key).inner;
-        receive_buffer(64, |buffer| {
-            let mut call_record = GetEnvSysCall {
-                key_len: key_buf.len(),
-                key_ptr: key_buf.as_ptr(),
-                value_len: buffer.len(),
-                value_ptr: buffer.as_mut_ptr(),
-                result: !0usize
-            };
-            if unsafe { syscall(SysCallIndex::GetEnv, &mut call_record) } {
-                if call_record.result == !0usize {
-                    Err(())
-                } else {
-                    Ok(call_record.result)
-                }
-            } else {
-                Err(())
-            }
-        }).ok().map(|s| {
-            FromInner::from_inner(Buf { inner: s })
-        })
-    }
-}
-
-#[repr(C)]
-pub struct SetEnvSysCall {
-    key_ptr: *const u8,
-    key_len: usize,
-    value_ptr: *const u8,
-    value_len: usize
-}
-
-impl SetEnvSysCall {
-    pub fn perform(key: &OsStr, value: Option<&OsStr>) {
-        let key_buf = &AsInner::as_inner(key).inner;
-        let value_buf = value.map(|v| &AsInner::as_inner(v).inner);
-        let mut call_record = SetEnvSysCall {
-            key_len: key_buf.len(),
-            key_ptr: key_buf.as_ptr(),
-            value_len: value_buf.map(|v| v.len()).unwrap_or(!0usize),
-            value_ptr: value_buf.map(|v| v.as_ptr()).unwrap_or(ptr::null())
-        };
-        unsafe { syscall(SysCallIndex::SetEnv, &mut call_record); }
-    }
-}
-
-pub enum TimeClock {
-    Monotonic = 0,
-    System = 1,
-}
-
-#[repr(C)]
-pub struct TimeSysCall {
-    clock: usize,
-    secs_hi: usize,
-    secs_lo: usize,
-    nanos: usize
-}
-
-impl TimeSysCall {
-    pub fn perform(clock: TimeClock) -> Duration {
-        let mut call_record = TimeSysCall {
-            clock: clock as usize,
-            secs_hi: 0,
-            secs_lo: 0,
-            nanos: 0
-        };
-        if unsafe { syscall(SysCallIndex::Time, &mut call_record) } {
-            Duration::new(
-                ((call_record.secs_hi as u64) << 32) | (call_record.secs_lo as u64),
-                call_record.nanos as u32
-            )
-        } else {
-            panic!("Time system call is not implemented by WebAssembly host");
-        }
-    }
-}
-
-unsafe fn syscall<T>(index: SysCallIndex, data: &mut T) -> bool {
-    #[cfg(feature = "wasm_syscall")]
-    extern {
-        #[no_mangle]
-        fn rust_wasm_syscall(index: usize, data: *mut Void) -> usize;
-    }
-
-    #[cfg(not(feature = "wasm_syscall"))]
-    unsafe fn rust_wasm_syscall(_index: usize, _data: *mut Void) -> usize { 0 }
-
-    rust_wasm_syscall(index as usize, data as *mut T as *mut Void) != 0
-}
diff --git a/src/libstd/sys/wasm/os.rs b/src/libstd/sys/wasm/os.rs
index 5d21999a991e1..890049e8bfae5 100644
--- a/src/libstd/sys/wasm/os.rs
+++ b/src/libstd/sys/wasm/os.rs
@@ -4,7 +4,7 @@ use crate::fmt;
 use crate::io;
 use crate::path::{self, PathBuf};
 use crate::str;
-use crate::sys::{unsupported, Void, ExitSysCall, GetEnvSysCall, SetEnvSysCall};
+use crate::sys::{unsupported, Void};
 
 pub fn errno() -> i32 {
     0
@@ -73,16 +73,16 @@ pub fn env() -> Env {
     panic!("not supported on web assembly")
 }
 
-pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
-    Ok(GetEnvSysCall::perform(k))
+pub fn getenv(_: &OsStr) -> io::Result<Option<OsString>> {
+    Ok(None)
 }
 
-pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
-    Ok(SetEnvSysCall::perform(k, Some(v)))
+pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
+    Err(io::Error::new(io::ErrorKind::Other, "cannot set env vars on wasm32-unknown-unknown"))
 }
 
-pub fn unsetenv(k: &OsStr) -> io::Result<()> {
-    Ok(SetEnvSysCall::perform(k, None))
+pub fn unsetenv(_: &OsStr) -> io::Result<()> {
+    Err(io::Error::new(io::ErrorKind::Other, "cannot unset env vars on wasm32-unknown-unknown"))
 }
 
 pub fn temp_dir() -> PathBuf {
@@ -94,7 +94,9 @@ pub fn home_dir() -> Option<PathBuf> {
 }
 
 pub fn exit(_code: i32) -> ! {
-    ExitSysCall::perform(_code as isize as usize)
+    unsafe {
+        crate::arch::wasm32::unreachable();
+    }
 }
 
 pub fn getpid() -> u32 {
diff --git a/src/libstd/sys/wasm/stdio.rs b/src/libstd/sys/wasm/stdio.rs
index b8899a9c84746..5a4e4505e93bd 100644
--- a/src/libstd/sys/wasm/stdio.rs
+++ b/src/libstd/sys/wasm/stdio.rs
@@ -1,5 +1,4 @@
 use crate::io;
-use crate::sys::{ReadSysCall, WriteSysCall};
 
 pub struct Stdin;
 pub struct Stdout;
@@ -12,8 +11,8 @@ impl Stdin {
 }
 
 impl io::Read for Stdin {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        Ok(ReadSysCall::perform(0, buf))
+    fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
+        Ok(0)
     }
 }
 
@@ -25,7 +24,6 @@ impl Stdout {
 
 impl io::Write for Stdout {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        WriteSysCall::perform(1, buf);
         Ok(buf.len())
     }
 
@@ -42,7 +40,6 @@ impl Stderr {
 
 impl io::Write for Stderr {
     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
-        WriteSysCall::perform(2, buf);
         Ok(buf.len())
     }
 
@@ -57,10 +54,6 @@ pub fn is_ebadf(_err: &io::Error) -> bool {
     true
 }
 
-pub fn panic_output() -> Option<impl io::Write> {
-    if cfg!(feature = "wasm_syscall") {
-        Stderr::new().ok()
-    } else {
-        None
-    }
+pub fn panic_output() -> Option<Vec<u8>> {
+    None
 }
diff --git a/src/libstd/sys/wasm/time.rs b/src/libstd/sys/wasm/time.rs
index 3f71461eea487..dd9ad3760b050 100644
--- a/src/libstd/sys/wasm/time.rs
+++ b/src/libstd/sys/wasm/time.rs
@@ -1,5 +1,4 @@
 use crate::time::Duration;
-use crate::sys::{TimeSysCall, TimeClock};
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
 pub struct Instant(Duration);
@@ -11,7 +10,7 @@ pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));
 
 impl Instant {
     pub fn now() -> Instant {
-        Instant(TimeSysCall::perform(TimeClock::Monotonic))
+        panic!("time not implemented on wasm32-unknown-unknown")
     }
 
     pub const fn zero() -> Instant {
@@ -37,7 +36,7 @@ impl Instant {
 
 impl SystemTime {
     pub fn now() -> SystemTime {
-        SystemTime(TimeSysCall::perform(TimeClock::System))
+        panic!("time not implemented on wasm32-unknown-unknown")
     }
 
     pub fn sub_time(&self, other: &SystemTime)

From 080fdb8184cea898f48818312a7645007c8b7594 Mon Sep 17 00:00:00 2001
From: Dodo <kasper199914@gmail.com>
Date: Wed, 28 Aug 2019 17:38:24 +0200
Subject: [PATCH 313/943] add missing `#[repr(C)]` on a union

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

diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index f20cb7bfbc3bd..752c372e93e3a 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -2170,6 +2170,7 @@ impl str {
     #[inline(always)]
     #[rustc_const_unstable(feature="const_str_as_bytes")]
     pub const fn as_bytes(&self) -> &[u8] {
+        #[repr(C)]
         union Slices<'a> {
             str: &'a str,
             slice: &'a [u8],

From 12e0420268a3855eea981bb8907a8bbfb1cb9d9a Mon Sep 17 00:00:00 2001
From: Nathan <nathan.whitaker01@gmail.com>
Date: Sun, 25 Aug 2019 21:10:33 -0400
Subject: [PATCH 314/943] Update dbg macro test to use `check-run-results` flag
 for run-pass test

Updates the dbg-macro-expected behavior test to remove the workaround and use the `check-run-result` flag/feature in compiletest. This serves to test the feature on a real use-case (as mentioned in #63751)
---
 .../dbg-macro-expected-behavior.rs            | 84 +------------------
 .../dbg-macro-expected-behavior.run.stderr    | 28 +++++++
 2 files changed, 30 insertions(+), 82 deletions(-)
 create mode 100644 src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr

diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
index e885263aa8084..04d924a9aed20 100644
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
@@ -1,7 +1,5 @@
 // run-pass
-// ignore-cloudabi no processes
-// ignore-emscripten no processes
-// ignore-sgx no processes
+// check-run-results
 
 // Tests ensuring that `dbg!(expr)` has the expected run-time behavior.
 // as well as some compile time properties we expect.
@@ -18,7 +16,7 @@ struct Point<T> {
 #[derive(Debug, PartialEq)]
 struct NoCopy(usize);
 
-fn test() {
+fn main() {
     let a: Unit = dbg!(Unit);
     let _: Unit = dbg!(a);
     // We can move `a` because it's Copy.
@@ -67,81 +65,3 @@ fn test() {
     assert_eq!((1u8, 2u32, "Yeah"), dbg!(1u8, 2u32,
                                          "Yeah",));
 }
-
-fn validate_stderr(stderr: Vec<String>) {
-    assert_eq!(stderr, &[
-        ":22] Unit = Unit",
-
-        ":23] a = Unit",
-
-        ":29] Point{x: 42, y: 24,} = Point {",
-        "    x: 42,",
-        "    y: 24,",
-        "}",
-
-        ":30] b = Point {",
-        "    x: 42,",
-        "    y: 24,",
-        "}",
-
-        ":38]",
-
-        ":42] &a = NoCopy(",
-        "    1337,",
-        ")",
-
-        ":42] dbg!(& a) = NoCopy(",
-        "    1337,",
-        ")",
-        ":47] f(&42) = 42",
-
-        "before",
-        ":52] { foo += 1; eprintln!(\"before\"); 7331 } = 7331",
-
-        ":60] (\"Yeah\",) = (",
-        "    \"Yeah\",",
-        ")",
-
-        ":63] 1 = 1",
-        ":63] 2 = 2",
-
-        ":67] 1u8 = 1",
-        ":67] 2u32 = 2",
-        ":67] \"Yeah\" = \"Yeah\"",
-    ]);
-}
-
-fn main() {
-    // The following is a hack to deal with compiletest's inability
-    // to check the output (to stdout) of run-pass tests.
-    use std::env;
-    use std::process::Command;
-
-    let mut args = env::args();
-    let prog = args.next().unwrap();
-    let child = args.next();
-    if let Some("child") = child.as_ref().map(|s| &**s) {
-        // Only run the test if we've been spawned as 'child'
-        test()
-    } else {
-        // This essentially spawns as 'child' to run the tests
-        // and then it collects output of stderr and checks the output
-        // against what we expect.
-        let out = Command::new(&prog).arg("child").output().unwrap();
-        assert!(out.status.success());
-        assert!(out.stdout.is_empty());
-
-        let stderr = String::from_utf8(out.stderr).unwrap();
-        let stderr = stderr.lines().map(|mut s| {
-            if s.starts_with("[") {
-                // Strip `[` and file path:
-                s = s.trim_start_matches("[");
-                assert!(s.starts_with(file!()));
-                s = s.trim_start_matches(file!());
-            }
-            s.to_owned()
-        }).collect();
-
-        validate_stderr(stderr);
-    }
-}
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
new file mode 100644
index 0000000000000..707b38cf37af0
--- /dev/null
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
@@ -0,0 +1,28 @@
+[$DIR/dbg-macro-expected-behavior.rs:20] Unit = Unit
+[$DIR/dbg-macro-expected-behavior.rs:21] a = Unit
+[$DIR/dbg-macro-expected-behavior.rs:27] Point{x: 42, y: 24,} = Point {
+    x: 42,
+    y: 24,
+}
+[$DIR/dbg-macro-expected-behavior.rs:28] b = Point {
+    x: 42,
+    y: 24,
+}
+[$DIR/dbg-macro-expected-behavior.rs:36]
+[$DIR/dbg-macro-expected-behavior.rs:40] &a = NoCopy(
+    1337,
+)
+[$DIR/dbg-macro-expected-behavior.rs:40] dbg!(& a) = NoCopy(
+    1337,
+)
+[$DIR/dbg-macro-expected-behavior.rs:45] f(&42) = 42
+before
+[$DIR/dbg-macro-expected-behavior.rs:50] { foo += 1; eprintln!("before"); 7331 } = 7331
+[$DIR/dbg-macro-expected-behavior.rs:58] ("Yeah",) = (
+    "Yeah",
+)
+[$DIR/dbg-macro-expected-behavior.rs:61] 1 = 1
+[$DIR/dbg-macro-expected-behavior.rs:61] 2 = 2
+[$DIR/dbg-macro-expected-behavior.rs:65] 1u8 = 1
+[$DIR/dbg-macro-expected-behavior.rs:65] 2u32 = 2
+[$DIR/dbg-macro-expected-behavior.rs:65] "Yeah" = "Yeah"

From fdd8b967c180192fb74bf17f07e2fda040bb9865 Mon Sep 17 00:00:00 2001
From: Sam Radhakrishan <sk09idm@gmail.com>
Date: Thu, 29 Aug 2019 02:43:09 +0530
Subject: [PATCH 315/943] Fixes #63976. Incorrect error message.

Fix incorrect error message when accessing
private field of union
---
 src/librustc_typeck/check/expr.rs | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index d139cd4264c86..4943270e193ec 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1396,8 +1396,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.tcx().sess,
             expr.span,
             E0616,
-            "field `{}` of struct `{}` is private",
+            "field `{}` of `{}` `{}` is private",
             field,
+            if let Some(def_kind) = self.tcx().def_kind(base_did){ def_kind.descr(base_did) }
+            else { " " },
             struct_path
         );
         // Also check if an accessible method exists, which is often what is meant.

From 35717892b9c399d7c984d7098a341db8c48d93a5 Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Wed, 28 Aug 2019 14:48:02 -0700
Subject: [PATCH 316/943] Update rust-installer to limit memory use

---
 src/tools/rust-installer | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/rust-installer b/src/tools/rust-installer
index 85958b001dbff..9f66c14c3f91a 160000
--- a/src/tools/rust-installer
+++ b/src/tools/rust-installer
@@ -1 +1 @@
-Subproject commit 85958b001dbff8523396809bfa844fc34a7869a8
+Subproject commit 9f66c14c3f91a48a118c7817f434167b311c3515

From 4c3e386bd7ee9020407cee4ba120eebfb6373549 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Wed, 28 Aug 2019 18:00:36 -0400
Subject: [PATCH 317/943] Allow running rustdoc on proc-macro crates without
 specifying '--crate-type proc-macro'

Add a test to make sure that this works
---
 src/librustc_interface/passes.rs | 48 +++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 16 deletions(-)

diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 856690903c659..24b44964e4fd2 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -473,22 +473,38 @@ fn configure_and_expand_inner<'a>(
         ast_validation::check_crate(sess, &krate)
     });
 
-    krate = time(sess, "maybe creating a macro crate", || {
-        let crate_types = sess.crate_types.borrow();
-        let num_crate_types = crate_types.len();
-        let is_proc_macro_crate = crate_types.contains(&config::CrateType::ProcMacro);
-        let is_test_crate = sess.opts.test;
-        syntax_ext::proc_macro_harness::inject(
-            &sess.parse_sess,
-            &mut resolver,
-            krate,
-            is_proc_macro_crate,
-            has_proc_macro_decls,
-            is_test_crate,
-            num_crate_types,
-            sess.diagnostic(),
-        )
-    });
+
+    let crate_types = sess.crate_types.borrow();
+    let is_proc_macro_crate = crate_types.contains(&config::CrateType::ProcMacro);
+
+    // For backwards compatibility, we don't try to run proc macro injection
+    // if rustdoc is run on a proc macro crate without '--crate-type proc-macro' being
+    // specified. This should only affect users who manually invoke 'rustdoc', as
+    // 'cargo doc' will automatically pass the proper '--crate-type' flags.
+    // However, we do emit a warning, to let such users know that they should
+    // start passing '--crate-type proc-macro'
+    if has_proc_macro_decls && sess.opts.actually_rustdoc && !is_proc_macro_crate {
+        let mut msg = sess.diagnostic().struct_warn(&"Trying to document proc macro crate \
+            without passing '--crate-type proc-macro to rustdoc");
+
+        msg.warn("The generated documentation may be incorrect");
+        msg.emit()
+    } else {
+        krate = time(sess, "maybe creating a macro crate", || {
+            let num_crate_types = crate_types.len();
+            let is_test_crate = sess.opts.test;
+            syntax_ext::proc_macro_harness::inject(
+                &sess.parse_sess,
+                &mut resolver,
+                krate,
+                is_proc_macro_crate,
+                has_proc_macro_decls,
+                is_test_crate,
+                num_crate_types,
+                sess.diagnostic(),
+            )
+        });
+    }
 
     // Done with macro expansion!
 

From 820aa5b2ef9b527a67b46ef70f001151f5d66441 Mon Sep 17 00:00:00 2001
From: Alessandro Ghedini <alessandro@ghedini.me>
Date: Wed, 28 Aug 2019 23:55:28 +0100
Subject: [PATCH 318/943] Stabilize pin_into_inner in 1.39.0

FCP: https://github.com/rust-lang/rust/issues/60245#issuecomment-522258129

Closes #60245
---
 src/libcore/pin.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index 6efeaf9ee7d2e..1080fd32a8862 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -462,7 +462,7 @@ impl<P: Deref<Target: Unpin>> Pin<P> {
     /// can ignore the pinning invariants when unwrapping it.
     ///
     /// [`Unpin`]: ../../std/marker/trait.Unpin.html
-    #[unstable(feature = "pin_into_inner", issue = "60245")]
+    #[stable(feature = "pin_into_inner", since = "1.39.0")]
     #[inline(always)]
     pub fn into_inner(pin: Pin<P>) -> P {
         pin.pointer
@@ -569,7 +569,7 @@ impl<P: Deref> Pin<P> {
     ///
     /// [`Unpin`]: ../../std/marker/trait.Unpin.html
     /// [`Pin::into_inner`]: #method.into_inner
-    #[unstable(feature = "pin_into_inner", issue = "60245")]
+    #[stable(feature = "pin_into_inner", since = "1.39.0")]
     #[inline(always)]
     pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
         pin.pointer

From ade191c70a51f6699b64423e0bc8e0f307de9ecd Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Thu, 29 Aug 2019 03:52:18 +0000
Subject: [PATCH 319/943] Small improvement for Ord implementation of integers

---
 src/libcore/cmp.rs              | 4 ++--
 src/test/codegen/integer-cmp.rs | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 167a9dd1c3620..607427a85d67a 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -1015,8 +1015,8 @@ mod impls {
                     // The order here is important to generate more optimal assembly.
                     // See <https://github.com/rust-lang/rust/issues/63758> for more info.
                     if *self < *other { Less }
-                    else if *self > *other { Greater }
-                    else { Equal }
+                    else if *self == *other { Equal }
+                    else { Greater }
                 }
             }
         )*)
diff --git a/src/test/codegen/integer-cmp.rs b/src/test/codegen/integer-cmp.rs
index 1373b12e3721c..8ada3cf09d073 100644
--- a/src/test/codegen/integer-cmp.rs
+++ b/src/test/codegen/integer-cmp.rs
@@ -11,7 +11,7 @@ use std::cmp::Ordering;
 #[no_mangle]
 pub fn cmp_signed(a: i64, b: i64) -> Ordering {
 // CHECK: icmp slt
-// CHECK: icmp sgt
+// CHECK: icmp ne
 // CHECK: zext i1
 // CHECK: select i1
     a.cmp(&b)
@@ -21,7 +21,7 @@ pub fn cmp_signed(a: i64, b: i64) -> Ordering {
 #[no_mangle]
 pub fn cmp_unsigned(a: u32, b: u32) -> Ordering {
 // CHECK: icmp ult
-// CHECK: icmp ugt
+// CHECK: icmp ne
 // CHECK: zext i1
 // CHECK: select i1
     a.cmp(&b)

From 0e7424653e82187bd6b17bf90239247d92bb5753 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Thu, 29 Aug 2019 16:04:13 +0200
Subject: [PATCH 320/943] Add missing links on AsRef trait

---
 src/libcore/convert.rs | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index 641621f492baf..402a7b2c95a46 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -104,22 +104,17 @@ pub const fn identity<T>(x: T) -> T { x }
 /// If you need to do a costly conversion it is better to implement [`From`] with type
 /// `&T` or write a custom function.
 ///
-/// `AsRef` has the same signature as [`Borrow`], but `Borrow` is different in few aspects:
+/// `AsRef` has the same signature as [`Borrow`], but [`Borrow`] is different in few aspects:
 ///
-/// - Unlike `AsRef`, `Borrow` has a blanket impl for any `T`, and can be used to accept either
+/// - Unlike `AsRef`, [`Borrow`] has a blanket impl for any `T`, and can be used to accept either
 ///   a reference or a value.
-/// - `Borrow` also requires that `Hash`, `Eq` and `Ord` for borrowed value are
+/// - [`Borrow`] also requires that [`Hash`], [`Eq`] and [`Ord`] for borrowed value are
 ///   equivalent to those of the owned value. For this reason, if you want to
-///   borrow only a single field of a struct you can implement `AsRef`, but not `Borrow`.
-///
-/// [`Borrow`]: ../../std/borrow/trait.Borrow.html
+///   borrow only a single field of a struct you can implement `AsRef`, but not [`Borrow`].
 ///
 /// **Note: This trait must not fail**. If the conversion can fail, use a
 /// dedicated method which returns an [`Option<T>`] or a [`Result<T, E>`].
 ///
-/// [`Option<T>`]: ../../std/option/enum.Option.html
-/// [`Result<T, E>`]: ../../std/result/enum.Result.html
-///
 /// # Generic Implementations
 ///
 /// - `AsRef` auto-dereferences if the inner type is a reference or a mutable
@@ -132,9 +127,16 @@ pub const fn identity<T>(x: T) -> T { x }
 /// converted to the specified type `T`.
 ///
 /// For example: By creating a generic function that takes an `AsRef<str>` we express that we
-/// want to accept all references that can be converted to `&str` as an argument.
-/// Since both [`String`] and `&str` implement `AsRef<str>` we can accept both as input argument.
+/// want to accept all references that can be converted to [`&str`] as an argument.
+/// Since both [`String`] and [`&str`] implement `AsRef<str>` we can accept both as input argument.
 ///
+/// [`Option<T>`]: ../../std/option/enum.Option.html
+/// [`Result<T, E>`]: ../../std/result/enum.Result.html
+/// [`Borrow`]: ../../std/borrow/trait.Borrow.html
+/// [`Hash`]: ../../std/hash/trait.Hash.html
+/// [`Eq`]: ../../std/cmp/trait.Eq.html
+/// [`Ord`]: ../../std/cmp/trait.Ord.html
+/// [`&str`]: ../../std/primitive.str.html
 /// [`String`]: ../../std/string/struct.String.html
 ///
 /// ```

From 6374b8458f0796a1ff3ee2caec41321e801c35d1 Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Thu, 29 Aug 2019 20:13:15 +0300
Subject: [PATCH 321/943] update to wasi v0.7

---
 Cargo.lock                    |  12 ++++
 src/libstd/Cargo.toml         |   2 +-
 src/libstd/sys/wasi/fd.rs     | 104 ++++++++++++++++++----------------
 src/libstd/sys/wasi/mod.rs    |  13 ++++-
 src/libstd/sys/wasi/thread.rs |   2 +-
 5 files changed, 80 insertions(+), 53 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 8ae21c8663706..3719b36236797 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3866,6 +3866,7 @@ dependencies = [
  "rustc_msan",
  "rustc_tsan",
  "unwind",
+ "wasi",
 ]
 
 [[package]]
@@ -4664,6 +4665,17 @@ dependencies = [
  "try-lock",
 ]
 
+[[package]]
+name = "wasi"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
+dependencies = [
+ "compiler_builtins",
+ "rustc-std-workspace-alloc",
+ "rustc-std-workspace-core",
+]
+
 [[package]]
 name = "winapi"
 version = "0.2.8"
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index d801b051357a4..0d04b7a274037 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -24,7 +24,7 @@ compiler_builtins = { version = "0.1.16" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] }
-wasi = { git = "https://github.com/newpavlov/rust-wasi", branch = "safe_rework", features = ['rustc-dep-of-std', 'alloc'] }
+wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] }
 
 [dependencies.backtrace]
 version = "0.3.35"
diff --git a/src/libstd/sys/wasi/fd.rs b/src/libstd/sys/wasi/fd.rs
index 275e1319be6ad..5b7a8678b66ea 100644
--- a/src/libstd/sys/wasi/fd.rs
+++ b/src/libstd/sys/wasi/fd.rs
@@ -53,23 +53,23 @@ impl WasiFd {
     }
 
     pub fn datasync(&self) -> io::Result<()> {
-        wasi::fd_datasync(self.fd).map_err(err2io)
+        unsafe { wasi::fd_datasync(self.fd).map_err(err2io) }
     }
 
     pub fn pread(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
-        wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io)
+        unsafe { wasi::fd_pread(self.fd, iovec(bufs), offset).map_err(err2io) }
     }
 
     pub fn pwrite(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result<usize> {
-        wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io)
+        unsafe { wasi::fd_pwrite(self.fd, ciovec(bufs), offset).map_err(err2io) }
     }
 
     pub fn read(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
-        wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io)
+        unsafe { wasi::fd_read(self.fd, iovec(bufs)).map_err(err2io) }
     }
 
     pub fn write(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
-        wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io)
+        unsafe { wasi::fd_write(self.fd, ciovec(bufs)).map_err(err2io) }
     }
 
     pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
@@ -78,37 +78,37 @@ impl WasiFd {
             SeekFrom::End(pos) => (wasi::WHENCE_END, pos),
             SeekFrom::Current(pos) => (wasi::WHENCE_CUR, pos),
         };
-        wasi::fd_seek(self.fd, offset, whence).map_err(err2io)
+        unsafe { wasi::fd_seek(self.fd, offset, whence).map_err(err2io) }
     }
 
     pub fn tell(&self) -> io::Result<u64> {
-        wasi::fd_tell(self.fd).map_err(err2io)
+        unsafe { wasi::fd_tell(self.fd).map_err(err2io) }
     }
 
     // FIXME: __wasi_fd_fdstat_get
 
     pub fn set_flags(&self, flags: wasi::FdFlags) -> io::Result<()> {
-        wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io)
+        unsafe { wasi::fd_fdstat_set_flags(self.fd, flags).map_err(err2io) }
     }
 
     pub fn set_rights(&self, base: wasi::Rights, inheriting: wasi::Rights) -> io::Result<()> {
-        wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io)
+        unsafe { wasi::fd_fdstat_set_rights(self.fd, base, inheriting).map_err(err2io) }
     }
 
     pub fn sync(&self) -> io::Result<()> {
-        wasi::fd_sync(self.fd).map_err(err2io)
+        unsafe { wasi::fd_sync(self.fd).map_err(err2io) }
     }
 
     pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
-        wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io)
+        unsafe { wasi::fd_advise(self.fd, offset, len, advice).map_err(err2io) }
     }
 
     pub fn allocate(&self, offset: u64, len: u64) -> io::Result<()> {
-        wasi::fd_allocate(self.fd, offset, len).map_err(err2io)
+        unsafe { wasi::fd_allocate(self.fd, offset, len).map_err(err2io) }
     }
 
     pub fn create_directory(&self, path: &[u8]) -> io::Result<()> {
-        wasi::path_create_directory(self.fd, path).map_err(err2io)
+        unsafe { wasi::path_create_directory(self.fd, path).map_err(err2io) }
     }
 
     pub fn link(
@@ -118,8 +118,10 @@ impl WasiFd {
         new_fd: &WasiFd,
         new_path: &[u8],
     ) -> io::Result<()> {
-        wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path)
-            .map_err(err2io)
+        unsafe {
+            wasi::path_link(self.fd, old_flags, old_path, new_fd.fd, new_path)
+                .map_err(err2io)
+        }
     }
 
     pub fn open(
@@ -131,32 +133,35 @@ impl WasiFd {
         fs_rights_inheriting: wasi::Rights,
         fs_flags: wasi::FdFlags,
     ) -> io::Result<WasiFd> {
-        wasi::path_open(
-            self.fd,
-            dirflags,
-            path,
-            oflags,
-            fs_rights_base,
-            fs_rights_inheriting,
-            fs_flags,
-        ).map(|fd| unsafe { WasiFd::from_raw(fd) }).map_err(err2io)
+        unsafe {
+            wasi::path_open(
+                self.fd,
+                dirflags,
+                path,
+                oflags,
+                fs_rights_base,
+                fs_rights_inheriting,
+                fs_flags,
+            ).map(|fd| WasiFd::from_raw(fd)).map_err(err2io)
+        }
     }
 
     pub fn readdir(&self, buf: &mut [u8], cookie: wasi::DirCookie) -> io::Result<usize> {
-        wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io)
+        unsafe { wasi::fd_readdir(self.fd, buf, cookie).map_err(err2io) }
     }
 
     pub fn readlink(&self, path: &[u8], buf: &mut [u8]) -> io::Result<usize> {
-        wasi::path_readlink(self.fd, path, buf).map_err(err2io)
+        unsafe { wasi::path_readlink(self.fd, path, buf).map_err(err2io) }
     }
 
     pub fn rename(&self, old_path: &[u8], new_fd: &WasiFd, new_path: &[u8]) -> io::Result<()> {
-        wasi::path_rename(self.fd, old_path, new_fd.fd, new_path)
-            .map_err(err2io)
+        unsafe {
+            wasi::path_rename(self.fd, old_path, new_fd.fd, new_path).map_err(err2io)
+        }
     }
 
     pub fn filestat_get(&self) -> io::Result<wasi::FileStat> {
-        wasi::fd_filestat_get(self.fd).map_err(err2io)
+        unsafe { wasi::fd_filestat_get(self.fd).map_err(err2io) }
     }
 
     pub fn filestat_set_times(
@@ -165,12 +170,13 @@ impl WasiFd {
         mtim: wasi::Timestamp,
         fstflags: wasi::FstFlags,
     ) -> io::Result<()> {
-        wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags)
-            .map_err(err2io)
+        unsafe {
+            wasi::fd_filestat_set_times(self.fd, atim, mtim, fstflags).map_err(err2io)
+        }
     }
 
     pub fn filestat_set_size(&self, size: u64) -> io::Result<()> {
-        wasi::fd_filestat_set_size(self.fd, size).map_err(err2io)
+        unsafe { wasi::fd_filestat_set_size(self.fd, size).map_err(err2io) }
     }
 
     pub fn path_filestat_get(
@@ -178,7 +184,7 @@ impl WasiFd {
         flags: wasi::LookupFlags,
         path: &[u8],
     ) -> io::Result<wasi::FileStat> {
-        wasi::path_filestat_get(self.fd, flags, path).map_err(err2io)
+        unsafe { wasi::path_filestat_get(self.fd, flags, path).map_err(err2io) }
     }
 
     pub fn path_filestat_set_times(
@@ -189,26 +195,28 @@ impl WasiFd {
         mtim: wasi::Timestamp,
         fstflags: wasi::FstFlags,
     ) -> io::Result<()> {
-        wasi::path_filestat_set_times(
-            self.fd,
-            flags,
-            path,
-            atim,
-            mtim,
-            fstflags,
-        ).map_err(err2io)
+        unsafe {
+            wasi::path_filestat_set_times(
+                self.fd,
+                flags,
+                path,
+                atim,
+                mtim,
+                fstflags,
+            ).map_err(err2io)
+        }
     }
 
     pub fn symlink(&self, old_path: &[u8], new_path: &[u8]) -> io::Result<()> {
-        wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io)
+        unsafe { wasi::path_symlink(old_path, self.fd, new_path).map_err(err2io) }
     }
 
     pub fn unlink_file(&self, path: &[u8]) -> io::Result<()> {
-        wasi::path_unlink_file(self.fd, path).map_err(err2io)
+        unsafe { wasi::path_unlink_file(self.fd, path).map_err(err2io) }
     }
 
     pub fn remove_directory(&self, path: &[u8]) -> io::Result<()> {
-        wasi::path_remove_directory(self.fd, path).map_err(err2io)
+        unsafe { wasi::path_remove_directory(self.fd, path).map_err(err2io) }
     }
 
     pub fn sock_recv(
@@ -216,11 +224,11 @@ impl WasiFd {
         ri_data: &mut [IoSliceMut<'_>],
         ri_flags: wasi::RiFlags,
     ) -> io::Result<(usize, wasi::RoFlags)> {
-        wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io)
+        unsafe { wasi::sock_recv(self.fd, iovec(ri_data), ri_flags).map_err(err2io) }
     }
 
     pub fn sock_send(&self, si_data: &[IoSlice<'_>], si_flags: wasi::SiFlags) -> io::Result<usize> {
-        wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io)
+        unsafe { wasi::sock_send(self.fd, ciovec(si_data), si_flags).map_err(err2io) }
     }
 
     pub fn sock_shutdown(&self, how: Shutdown) -> io::Result<()> {
@@ -229,7 +237,7 @@ impl WasiFd {
             Shutdown::Write => wasi::SHUT_WR,
             Shutdown::Both => wasi::SHUT_WR | wasi::SHUT_RD,
         };
-        wasi::sock_shutdown(self.fd, how).map_err(err2io)
+        unsafe { wasi::sock_shutdown(self.fd, how).map_err(err2io) }
     }
 }
 
@@ -237,6 +245,6 @@ impl Drop for WasiFd {
     fn drop(&mut self) {
         // FIXME: can we handle the return code here even though we can't on
         // unix?
-        let _ = wasi::fd_close(self.fd);
+        let _ = unsafe { wasi::fd_close(self.fd) };
     }
 }
diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs
index 4007b7ac0ec5f..517e3be9cb58c 100644
--- a/src/libstd/sys/wasi/mod.rs
+++ b/src/libstd/sys/wasi/mod.rs
@@ -69,10 +69,17 @@ pub fn unsupported_err() -> std_io::Error {
 
 pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
     use std_io::ErrorKind::*;
-    match errno as libc::c_int {
+    if errno > u16::max_value() as i32 || errno < 0 {
+        return Other;
+    }
+    let code = match wasi::Error::new(errno as u16) {
+        Some(code) => code,
+        None => return Other,
+    };
+    match code {
         wasi::ECONNREFUSED => ConnectionRefused,
         wasi::ECONNRESET => ConnectionReset,
-        wasi::EPERM | libc::EACCES => PermissionDenied,
+        wasi::EPERM | wasi::EACCES => PermissionDenied,
         wasi::EPIPE => BrokenPipe,
         wasi::ENOTCONN => NotConnected,
         wasi::ECONNABORTED => ConnectionAborted,
@@ -84,7 +91,7 @@ pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind {
         wasi::ETIMEDOUT => TimedOut,
         wasi::EEXIST => AlreadyExists,
         wasi::EAGAIN => WouldBlock,
-        _ => ErrorKind::Other,
+        _ => Other,
     }
 }
 
diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs
index dc5a72e82a354..987bf7580838b 100644
--- a/src/libstd/sys/wasi/thread.rs
+++ b/src/libstd/sys/wasi/thread.rs
@@ -47,7 +47,7 @@ impl Thread {
             u: wasi::raw::__wasi_subscription_u { clock: clock },
         }];
         let mut out: [wasi::Event; 1] = [unsafe { mem::zeroed() }];
-        let n = wasi::poll_oneoff(&in_, &mut out).unwrap();
+        let n = unsafe { wasi::poll_oneoff(&in_, &mut out).unwrap() };
         let wasi::Event { userdata, error, type_, .. } = out[0];
         match (n, userdata, error) {
             (1, CLOCK_ID, 0) if type_ == wasi::EVENTTYPE_CLOCK => {}

From 06acfb22e03ff482275e1ffd78f691b0e5d88ffb Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Thu, 29 Aug 2019 20:22:24 +0300
Subject: [PATCH 322/943] add wasi license to the licenses whitelist

---
 src/tools/tidy/src/deps.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index e07a07234c71e..6ca912db5930d 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -15,6 +15,7 @@ const LICENSES: &[&str] = &[
     "Apache-2.0 / MIT",
     "MIT OR Apache-2.0",
     "Apache-2.0 OR MIT",
+    "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", // wasi license
     "MIT",
     "Unlicense/MIT",
     "Unlicense OR MIT",

From 6fe31fefd80cd1c4300b03b1e55c63de12134eed Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Thu, 29 Aug 2019 18:02:51 +0200
Subject: [PATCH 323/943] Make allocation relocation field private

---
 src/librustc/mir/interpret/allocation.rs   | 13 +++++++++----
 src/librustc_mir/interpret/intern.rs       |  4 ++--
 src/librustc_mir/interpret/memory.rs       |  4 ++--
 src/librustc_mir/monomorphize/collector.rs |  4 ++--
 src/librustc_typeck/check/mod.rs           |  2 +-
 5 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index dcfa2e5cb4691..75319a6783167 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -35,7 +35,7 @@ pub struct Allocation<Tag=(),Extra=()> {
     /// Only the first byte of a pointer is inserted into the map; i.e.,
     /// every entry in this map applies to `pointer_size` consecutive bytes starting
     /// at the given offset.
-    pub relocations: Relocations<Tag>,
+    relocations: Relocations<Tag>,
     /// Denotes which part of this allocation is initialized.
     undef_mask: UndefMask,
     /// The size of the allocation. Currently, must always equal `bytes.len()`.
@@ -148,6 +148,11 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
     pub fn undef_mask(&self) -> &UndefMask {
         &self.undef_mask
     }
+
+    /// Returns the relocation list.
+    pub fn relocations(&self) -> &Relocations<Tag> {
+        &self.relocations
+    }
 }
 
 impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Allocation {}
@@ -459,7 +464,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
 /// Relocations
 impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
     /// Returns all relocations overlapping with the given ptr-offset pair.
-    pub fn relocations(
+    pub fn get_relocations(
         &self,
         cx: &impl HasDataLayout,
         ptr: Pointer<Tag>,
@@ -480,7 +485,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
         ptr: Pointer<Tag>,
         size: Size,
     ) -> InterpResult<'tcx> {
-        if self.relocations(cx, ptr, size).is_empty() {
+        if self.get_relocations(cx, ptr, size).is_empty() {
             Ok(())
         } else {
             throw_unsup!(ReadPointerAsBytes)
@@ -502,7 +507,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
         // Find the start and end of the given range and its outermost relocations.
         let (first, last) = {
             // Find all relocations overlapping the given range.
-            let relocations = self.relocations(cx, ptr, size);
+            let relocations = self.get_relocations(cx, ptr, size);
             if relocations.is_empty() {
                 return Ok(());
             }
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 32ba70a81c997..4cbbc0ffe17cc 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -94,7 +94,7 @@ impl<'rt, 'mir, 'tcx> InternVisitor<'rt, 'mir, 'tcx> {
         alloc.mutability = mutability;
         // link the alloc id to the actual allocation
         let alloc = tcx.intern_const_alloc(alloc);
-        self.leftover_relocations.extend(alloc.relocations.iter().map(|&(_, ((), reloc))| reloc));
+        self.leftover_relocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc));
         tcx.alloc_map.lock().set_alloc_id_memory(ptr.alloc_id, alloc);
         Ok(None)
     }
@@ -316,7 +316,7 @@ pub fn intern_const_alloc_recursive(
             // So we hand-roll the interning logic here again
             let alloc = tcx.intern_const_alloc(alloc);
             tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
-            for &(_, ((), reloc)) in alloc.relocations.iter() {
+            for &(_, ((), reloc)) in alloc.relocations().iter() {
                 if leftover_relocations.insert(reloc) {
                     todo.push(reloc);
                 }
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 7f7729ae5e0f4..26b3f0be8c2b8 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -647,7 +647,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
 
         for i in 0..alloc.size.bytes() {
             let i = Size::from_bytes(i);
-            if let Some(&(_, target_id)) = alloc.relocations.get(&i) {
+            if let Some(&(_, target_id)) = alloc.relocations().get(&i) {
                 if allocs_seen.insert(target_id) {
                     allocs_to_print.push_back(target_id);
                 }
@@ -809,7 +809,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // (`get_bytes_with_undef_and_ptr` below checks that there are no
         // relocations overlapping the edges; those would not be handled correctly).
         let relocations = {
-            let relocations = self.get(src.alloc_id)?.relocations(self, src, size);
+            let relocations = self.get(src.alloc_id)?.get_relocations(self, src, size);
             if relocations.is_empty() {
                 // nothing to copy, ignore even the `length` loop
                 Vec::new()
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 12d763bb7910a..a9403502f64d3 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -1202,7 +1202,7 @@ fn collect_miri<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut Vec<Mon
         }
         Some(GlobalAlloc::Memory(alloc)) => {
             trace!("collecting {:?} with {:#?}", alloc_id, alloc);
-            for &((), inner) in alloc.relocations.values() {
+            for &((), inner) in alloc.relocations().values() {
                 collect_miri(tcx, inner, output);
             }
         },
@@ -1268,7 +1268,7 @@ fn collect_const<'tcx>(
             collect_miri(tcx, ptr.alloc_id, output),
         ConstValue::Slice { data: alloc, start: _, end: _ } |
         ConstValue::ByRef { alloc, .. } => {
-            for &((), id) in alloc.relocations.values() {
+            for &((), id) in alloc.relocations().values() {
                 collect_miri(tcx, id, output);
             }
         }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 14fc0d6347e4b..e68104c6df808 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1570,7 +1570,7 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span)
         } else {
             bug!("Matching on non-ByRef static")
         };
-        if alloc.relocations.len() != 0 {
+        if alloc.relocations().len() != 0 {
             let msg = "statics with a custom `#[link_section]` must be a \
                        simple list of bytes on the wasm target with no \
                        extra levels of indirection such as references";

From 2e59c4afd16ea7b887f3d81b5aeea8669b843afe Mon Sep 17 00:00:00 2001
From: Mark Mansi <markm@cs.wisc.edu>
Date: Thu, 29 Aug 2019 13:03:22 -0500
Subject: [PATCH 324/943] fix bugs + review comments

---
 src/tools/rustbook/src/main.rs | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs
index 0915600bb3875..e155f3f7607f3 100644
--- a/src/tools/rustbook/src/main.rs
+++ b/src/tools/rustbook/src/main.rs
@@ -56,21 +56,22 @@ fn main() {
                 eprintln!("Error: {}", err);
 
                 // HACK: ignore timeouts
-                #[allow(unused_mut)]
-                let mut actually_broken = false;
-
-                #[cfg(feature = "linkcheck")]
-                {
-                    if let Ok(broken_links) = err.downcast::<BrokenLinks>() {
-                        for cause in broken_links.links().iter() {
-                            eprintln!("\tCaused By: {}", cause);
-
-                            if cause.contains("timed out") {
-                                actually_broken = true;
-                            }
-                        }
+                let actually_broken = {
+                    #[cfg(feature = "linkcheck")]
+                    {
+                        err.downcast::<BrokenLinks>()
+                            .unwrap_or(false)
+                            .links()
+                            .iter()
+                            .inspect(|cause| eprintln!("\tCaused By: {}", cause))
+                            .any(|cause| !cause.contains("timed out"));
                     }
-                }
+
+                    #[cfg(not(feature = "linkcheck"))]
+                    {
+                        false
+                    }
+                };
 
                 if actually_broken {
                     std::process::exit(101);

From 127311b75efd47a6f54aca49523c050566fc9823 Mon Sep 17 00:00:00 2001
From: Artyom Pavlov <newpavlov@gmail.com>
Date: Thu, 29 Aug 2019 18:08:13 +0000
Subject: [PATCH 325/943] whitelist wasi crate

---
 src/tools/tidy/src/deps.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 6ca912db5930d..c31da3c6f4887 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -172,6 +172,7 @@ const WHITELIST: &[Crate<'_>] = &[
     Crate("vcpkg"),
     Crate("version_check"),
     Crate("void"),
+    Crate("wasi"),
     Crate("winapi"),
     Crate("winapi-build"),
     Crate("winapi-i686-pc-windows-gnu"),

From 0cc1c8d2e71f798ca28813e5dca3adb0e791684d Mon Sep 17 00:00:00 2001
From: Dante-Broggi <34220985+Dante-Broggi@users.noreply.github.com>
Date: Thu, 29 Aug 2019 14:16:52 -0400
Subject: [PATCH 326/943] `new_thin_place` is only used with `align` =
 `layout.align.abi`

and is not `pub`.
---
 src/librustc_codegen_ssa/mir/place.rs | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index ac72928a89677..bd295565e67b3 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -45,14 +45,13 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         bx: &mut Bx,
         llval: V,
         layout: TyLayout<'tcx>,
-        align: Align,
     ) -> PlaceRef<'tcx, V> {
         assert!(!bx.cx().type_has_metadata(layout.ty));
         PlaceRef {
             llval,
             llextra: None,
             layout,
-            align
+            align: layout.align.abi
         }
     }
 
@@ -498,7 +497,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 // with a static that is an extern_type.
                 let layout = cx.layout_of(self.monomorphize(&ty));
                 let static_ = bx.get_static(*def_id);
-                PlaceRef::new_thin_place(bx, static_, layout, layout.align.abi)
+                PlaceRef::new_thin_place(bx, static_, layout)
             },
             mir::PlaceRef {
                 base,

From 8657fb1140165f770a928b04095fc025308a4fb2 Mon Sep 17 00:00:00 2001
From: Dante-Broggi <34220985+Dante-Broggi@users.noreply.github.com>
Date: Thu, 29 Aug 2019 14:24:50 -0400
Subject: [PATCH 327/943] `new_sized` is mostly used without align

so rename it `new_sized_aligned`.
6/11 use `align` = `layout.align.abi`.
`from_const_alloc` uses `alloc.align`, but that is `assert_eq!` to `layout.align.abi`.
only 4/11 use something interesting for `align`.
---
 src/librustc_codegen_llvm/builder.rs    |  2 +-
 src/librustc_codegen_llvm/common.rs     |  2 +-
 src/librustc_codegen_llvm/intrinsic.rs  |  2 +-
 src/librustc_codegen_ssa/mir/block.rs   |  4 ++--
 src/librustc_codegen_ssa/mir/mod.rs     |  4 ++--
 src/librustc_codegen_ssa/mir/operand.rs |  1 -
 src/librustc_codegen_ssa/mir/place.rs   | 17 +++++++++++++++--
 src/librustc_codegen_ssa/mir/rvalue.rs  |  2 +-
 8 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index 894e5c2fd3d93..1f9b3523fbd94 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -561,7 +561,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
 
         let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
         cg_elem.val.store(&mut body_bx,
-            PlaceRef::new_sized(current, cg_elem.layout, align));
+            PlaceRef::new_sized_aligned(current, cg_elem.layout, align));
 
         let next = body_bx.inbounds_gep(current, &[self.const_usize(1)]);
         body_bx.br(header_bx.llbb());
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index 19f18088579b3..6ce1d4b18693c 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -348,7 +348,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             )};
             self.const_bitcast(llval, llty)
         };
-        PlaceRef::new_sized(llval, layout, alloc.align)
+        PlaceRef::new_sized(llval, layout)
     }
 
     fn const_ptrcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 9483ffca448e3..fc0b9ffd11d83 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -101,7 +101,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         let name = &*tcx.item_name(def_id).as_str();
 
         let llret_ty = self.layout_of(ret_ty).llvm_type(self);
-        let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align.abi);
+        let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout);
 
         let simple = get_simple_intrinsic(self, name);
         let llval = match name {
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index d2a7571fde1e2..30a79f9f1afba 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -989,7 +989,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         // Handle both by-ref and immediate tuples.
         if let Ref(llval, None, align) = tuple.val {
-            let tuple_ptr = PlaceRef::new_sized(llval, tuple.layout, align);
+            let tuple_ptr = PlaceRef::new_sized_aligned(llval, tuple.layout, align);
             for i in 0..tuple.layout.fields.count() {
                 let field_ptr = tuple_ptr.project_field(bx, i);
                 let field = bx.load_operand(field_ptr);
@@ -1203,7 +1203,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let llty = bx.backend_type(src.layout);
         let cast_ptr = bx.pointercast(dst.llval, bx.type_ptr_to(llty));
         let align = src.layout.align.abi.min(dst.align);
-        src.val.store(bx, PlaceRef::new_sized(cast_ptr, src.layout, align));
+        src.val.store(bx, PlaceRef::new_sized_aligned(cast_ptr, src.layout, align));
     }
 
 
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index 32bcdebc1c467..8acb3ba06267e 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -289,7 +289,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 if local == mir::RETURN_PLACE && fx.fn_ty.ret.is_indirect() {
                     debug!("alloc: {:?} (return place) -> place", local);
                     let llretptr = bx.get_param(0);
-                    LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align.abi))
+                    LocalRef::Place(PlaceRef::new_sized(llretptr, layout))
                 } else if memory_locals.contains(local) {
                     debug!("alloc: {:?} -> place", local);
                     if layout.is_unsized() {
@@ -548,7 +548,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             let llarg = bx.get_param(llarg_idx);
             bx.set_value_name(llarg, &name);
             llarg_idx += 1;
-            PlaceRef::new_sized(llarg, arg.layout, arg.layout.align.abi)
+            PlaceRef::new_sized(llarg, arg.layout)
         } else if arg.is_unsized_indirect() {
             // As the storage for the indirect argument lives during
             // the whole function call, we just copy the fat pointer.
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index 254b73da44261..a8ab3ea10ed16 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -485,7 +485,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         bx.load_operand(PlaceRef::new_sized(
                             bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))),
                             layout,
-                            layout.align.abi,
                         ))
                     })
             }
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index bd295565e67b3..b8e10d3430292 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -30,6 +30,19 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
     pub fn new_sized(
         llval: V,
         layout: TyLayout<'tcx>,
+    ) -> PlaceRef<'tcx, V> {
+        assert!(!layout.is_unsized());
+        PlaceRef {
+            llval,
+            llextra: None,
+            layout,
+            align: layout.align.abi
+        }
+    }
+
+    pub fn new_sized_aligned(
+        llval: V,
+        layout: TyLayout<'tcx>,
         align: Align,
     ) -> PlaceRef<'tcx, V> {
         assert!(!layout.is_unsized());
@@ -63,7 +76,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         debug!("alloca({:?}: {:?})", name, layout);
         assert!(!layout.is_unsized(), "tried to statically allocate unsized place");
         let tmp = bx.alloca(bx.cx().backend_type(layout), name, layout.align.abi);
-        Self::new_sized(tmp, layout, layout.align.abi)
+        Self::new_sized(tmp, layout)
     }
 
     /// Returns a place for an indirect reference to an unsized place.
@@ -481,7 +494,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         let llval = bx.cx().const_undef(
                             bx.cx().type_ptr_to(bx.cx().backend_type(layout))
                         );
-                        PlaceRef::new_sized(llval, layout, layout.align.abi)
+                        PlaceRef::new_sized(llval, layout)
                     }
                 }
             }
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index 9da1e5024ba3a..e0ad2527229ba 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -71,7 +71,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         scratch.storage_dead(&mut bx);
                     }
                     OperandValue::Ref(llref, None, align) => {
-                        let source = PlaceRef::new_sized(llref, operand.layout, align);
+                        let source = PlaceRef::new_sized_aligned(llref, operand.layout, align);
                         base::coerce_unsized_into(&mut bx, source, dest);
                     }
                     OperandValue::Ref(_, Some(_), _) => {

From c71004cd218cce39501259ff3dd6e889c682dbbb Mon Sep 17 00:00:00 2001
From: Ilija Tovilo <ilija.tovilo@me.com>
Date: Thu, 29 Aug 2019 21:23:52 +0200
Subject: [PATCH 328/943] Also test isize and usize in wrapping arithmetics

---
 src/test/ui/wrapping-int-combinations.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/test/ui/wrapping-int-combinations.rs b/src/test/ui/wrapping-int-combinations.rs
index e09f7232bd2fb..431194ccd1dec 100644
--- a/src/test/ui/wrapping-int-combinations.rs
+++ b/src/test/ui/wrapping-int-combinations.rs
@@ -65,9 +65,11 @@ fn main() {
     wrapping_test!(i32, std::i32::MIN, std::i32::MAX);
     wrapping_test!(i64, std::i64::MIN, std::i64::MAX);
     wrapping_test!(i128, std::i128::MIN, std::i128::MAX);
+    wrapping_test!(isize, std::isize::MIN, std::isize::MAX);
     wrapping_test!(u8, std::u8::MIN, std::u8::MAX);
     wrapping_test!(u16, std::u16::MIN, std::u16::MAX);
     wrapping_test!(u32, std::u32::MIN, std::u32::MAX);
     wrapping_test!(u64, std::u64::MIN, std::u64::MAX);
     wrapping_test!(u128, std::u128::MIN, std::u128::MAX);
+    wrapping_test!(usize, std::usize::MIN, std::usize::MAX);
 }

From 378c32bc90b230d1f8feffee135942d442d2a5b7 Mon Sep 17 00:00:00 2001
From: Sam Radhakrishan <sk09idm@gmail.com>
Date: Fri, 30 Aug 2019 00:57:20 +0530
Subject: [PATCH 329/943] Fix test.

---
 src/librustc_typeck/check/expr.rs                | 9 ++++++---
 src/test/ui/privacy/union-field-privacy-2.rs     | 2 +-
 src/test/ui/privacy/union-field-privacy-2.stderr | 2 +-
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 4943270e193ec..a53fb12367d0e 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -1392,14 +1392,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         base_did: DefId,
     ) {
         let struct_path = self.tcx().def_path_str(base_did);
+        let kind_name = match self.tcx().def_kind(base_did) {
+            Some(def_kind) => def_kind.descr(base_did),
+            _ => " ",
+        };
         let mut err = struct_span_err!(
             self.tcx().sess,
             expr.span,
             E0616,
-            "field `{}` of `{}` `{}` is private",
+            "field `{}` of {} `{}` is private",
             field,
-            if let Some(def_kind) = self.tcx().def_kind(base_did){ def_kind.descr(base_did) }
-            else { " " },
+            kind_name,
             struct_path
         );
         // Also check if an accessible method exists, which is often what is meant.
diff --git a/src/test/ui/privacy/union-field-privacy-2.rs b/src/test/ui/privacy/union-field-privacy-2.rs
index 48279630c6302..c2458f74bc8f9 100644
--- a/src/test/ui/privacy/union-field-privacy-2.rs
+++ b/src/test/ui/privacy/union-field-privacy-2.rs
@@ -11,5 +11,5 @@ fn main() {
 
     let a = u.a; // OK
     let b = u.b; // OK
-    let c = u.c; //~ ERROR field `c` of struct `m::U` is private
+    let c = u.c; //~ ERROR field `c` of union `m::U` is private
 }
diff --git a/src/test/ui/privacy/union-field-privacy-2.stderr b/src/test/ui/privacy/union-field-privacy-2.stderr
index df054b8cff8a6..8789178caac26 100644
--- a/src/test/ui/privacy/union-field-privacy-2.stderr
+++ b/src/test/ui/privacy/union-field-privacy-2.stderr
@@ -1,4 +1,4 @@
-error[E0616]: field `c` of struct `m::U` is private
+error[E0616]: field `c` of union `m::U` is private
   --> $DIR/union-field-privacy-2.rs:14:13
    |
 LL |     let c = u.c;

From 56ab485fbe61add87ac8febea421e2a576edca26 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403@users.noreply.github.com>
Date: Tue, 27 Aug 2019 08:07:56 +0200
Subject: [PATCH 330/943] support rustdoc test from stdin to rustc

---
 src/librustc_driver/lib.rs | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index e7712ae115f54..885e2fea26a10 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -439,6 +439,15 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>, Option
             } else {
                 None
             };
+            if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") {
+                let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").
+                            expect("when UNSTABLE_RUSTDOC_TEST_PATH is set \
+                                    UNSTABLE_RUSTDOC_TEST_LINE also needs to be set");
+                let line = isize::from_str_radix(&line, 10).
+                            expect("UNSTABLE_RUSTDOC_TEST_LINE needs to be an number");
+                let file_name = FileName::doc_test_source_code(PathBuf::from(path), line);
+                return Some((Input::Str { name: file_name, input: src }, None, err));
+            }
             Some((Input::Str { name: FileName::anon_source_code(&src), input: src },
                   None, err))
         } else {

From 86487329bb385f74bed67718f2358436ddca1aa4 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Thu, 29 Aug 2019 13:22:16 -0700
Subject: [PATCH 331/943] Add `Place::is_indirect`

This returns whether a `Place` references the same region of memory
as its base, or equivalently whether it contains a `Deref` projection.

This is helpful for analyses that must track state for locals, since an
assignment to `x` or `x.field` is fundamentally different than one to
`*x`, which may mutate any memory region.
---
 src/librustc/mir/mod.rs | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 858b77af80468..a07f12cd9c5f2 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1801,6 +1801,23 @@ pub enum ProjectionElem<V, T> {
     Downcast(Option<Symbol>, VariantIdx),
 }
 
+impl<V, T> ProjectionElem<V, T> {
+    /// Returns `true` if the target of this projection may refer to a different region of memory
+    /// than the base.
+    fn is_indirect(&self) -> bool {
+        match self {
+            Self::Deref => true,
+
+            | Self::Field(_, _)
+            | Self::Index(_)
+            | Self::ConstantIndex { .. }
+            | Self::Subslice { .. }
+            | Self::Downcast(_, _)
+            => false
+        }
+    }
+}
+
 /// Alias for projections as they appear in places, where the base is a place
 /// and the index is a local.
 pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
@@ -1862,6 +1879,14 @@ impl<'tcx> Place<'tcx> {
         }
     }
 
+    /// Returns `true` if this `Place` contains a `Deref` projection.
+    ///
+    /// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
+    /// same region of memory as its base.
+    pub fn is_indirect(&self) -> bool {
+        self.iterate(|_, mut projections| projections.any(|proj| proj.elem.is_indirect()))
+    }
+
     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
     /// a single deref of a local.
     //

From b304cd02c033945144404d859b8d031a46e9c8ca Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403@users.noreply.github.com>
Date: Thu, 29 Aug 2019 23:15:31 +0200
Subject: [PATCH 332/943] Run doctests via out-of-process rustc

---
 src/librustdoc/config.rs   |  12 +++
 src/librustdoc/markdown.rs |   7 +-
 src/librustdoc/test.rs     | 214 ++++++++++++-------------------------
 3 files changed, 82 insertions(+), 151 deletions(-)

diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index cefae2e105eda..30b1706f29464 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -39,12 +39,18 @@ pub struct Options {
     pub error_format: ErrorOutputType,
     /// Library search paths to hand to the compiler.
     pub libs: Vec<SearchPath>,
+    /// Library search paths strings to hand to the compiler.
+    pub lib_strs: Vec<String>,
     /// The list of external crates to link against.
     pub externs: Externs,
+    /// The list of external crates strings to link against.
+    pub extern_strs: Vec<String>,
     /// List of `cfg` flags to hand to the compiler. Always includes `rustdoc`.
     pub cfgs: Vec<String>,
     /// Codegen options to hand to the compiler.
     pub codegen_options: CodegenOptions,
+    /// Codegen options strings to hand to the compiler.
+    pub codegen_options_strs: Vec<String>,
     /// Debugging (`-Z`) options to pass to the compiler.
     pub debugging_options: DebuggingOptions,
     /// The target used to compile the crate against.
@@ -461,6 +467,9 @@ impl Options {
         let generate_search_filter = !matches.opt_present("disable-per-crate-search");
         let persist_doctests = matches.opt_str("persist-doctests").map(PathBuf::from);
         let generate_redirect_pages = matches.opt_present("generate-redirect-pages");
+        let codegen_options_strs = matches.opt_strs("C");
+        let lib_strs = matches.opt_strs("L");
+        let extern_strs = matches.opt_strs("extern");
 
         let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
 
@@ -470,9 +479,12 @@ impl Options {
             proc_macro_crate,
             error_format,
             libs,
+            lib_strs,
             externs,
+            extern_strs,
             cfgs,
             codegen_options,
+            codegen_options_strs,
             debugging_options,
             target,
             edition,
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index e735a9779c924..a30fc05f36acd 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -142,11 +142,8 @@ pub fn test(mut options: Options, diag: &errors::Handler) -> i32 {
     let mut opts = TestOptions::default();
     opts.no_crate_inject = true;
     opts.display_warnings = options.display_warnings;
-    let mut collector = Collector::new(options.input.display().to_string(), options.cfgs,
-                                       options.libs, options.codegen_options, options.externs,
-                                       true, opts, options.maybe_sysroot, None,
-                                       Some(options.input),
-                                       options.linker, options.edition, options.persist_doctests);
+    let mut collector = Collector::new(options.input.display().to_string(), options.clone(),
+                                       true, opts, None, Some(options.input));
     collector.set_position(DUMMY_SP);
     let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
 
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index cb6ae1c2bd24b..70511131e5302 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -2,10 +2,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_interface::interface;
 use rustc::hir;
 use rustc::hir::intravisit;
-use rustc::hir::def_id::LOCAL_CRATE;
 use rustc::session::{self, config, DiagnosticOutput};
-use rustc::session::config::{OutputType, OutputTypes, Externs, CodegenOptions};
-use rustc::session::search_paths::SearchPath;
 use rustc::util::common::ErrorReported;
 use syntax::ast;
 use syntax::with_globals;
@@ -13,13 +10,11 @@ use syntax::source_map::SourceMap;
 use syntax::edition::Edition;
 use syntax::feature_gate::UnstableFeatures;
 use std::env;
-use std::io::prelude::*;
-use std::io;
-use std::panic::{self, AssertUnwindSafe};
+use std::io::{self, Write};
+use std::panic;
 use std::path::PathBuf;
-use std::process::{self, Command};
+use std::process::{self, Command, Stdio};
 use std::str;
-use std::sync::{Arc, Mutex};
 use syntax::symbol::sym;
 use syntax_pos::{BytePos, DUMMY_SP, Pos, Span, FileName};
 use tempfile::Builder as TempFileBuilder;
@@ -89,18 +84,11 @@ pub fn run(options: Options) -> i32 {
         opts.display_warnings |= options.display_warnings;
         let mut collector = Collector::new(
             compiler.crate_name()?.peek().to_string(),
-            options.cfgs,
-            options.libs,
-            options.codegen_options,
-            options.externs,
+            options,
             false,
             opts,
-            options.maybe_sysroot,
             Some(compiler.source_map().clone()),
             None,
-            options.linker,
-            options.edition,
-            options.persist_doctests,
         );
 
         let mut global_ctxt = compiler.global_ctxt()?.take();
@@ -189,20 +177,14 @@ fn run_test(
     cratename: &str,
     filename: &FileName,
     line: usize,
-    cfgs: Vec<String>,
-    libs: Vec<SearchPath>,
-    cg: CodegenOptions,
-    externs: Externs,
+    options: Options,
     should_panic: bool,
     no_run: bool,
     as_test_harness: bool,
     compile_fail: bool,
     mut error_codes: Vec<String>,
     opts: &TestOptions,
-    maybe_sysroot: Option<PathBuf>,
-    linker: Option<PathBuf>,
     edition: Edition,
-    persist_doctests: Option<PathBuf>,
 ) -> Result<(), TestFailure> {
     let (test, line_offset) = match panic::catch_unwind(|| {
         make_test(test, Some(cratename), as_test_harness, opts, edition)
@@ -223,61 +205,6 @@ fn run_test(
         _ => PathBuf::from(r"doctest.rs"),
     };
 
-    let input = config::Input::Str {
-        name: FileName::DocTest(path, line as isize - line_offset as isize),
-        input: test,
-    };
-    let outputs = OutputTypes::new(&[(OutputType::Exe, None)]);
-
-    let sessopts = config::Options {
-        maybe_sysroot,
-        search_paths: libs,
-        crate_types: vec![config::CrateType::Executable],
-        output_types: outputs,
-        externs,
-        cg: config::CodegenOptions {
-            linker,
-            ..cg
-        },
-        test: as_test_harness,
-        unstable_features: UnstableFeatures::from_environment(),
-        debugging_opts: config::DebuggingOptions {
-            ..config::basic_debugging_options()
-        },
-        edition,
-        ..config::Options::default()
-    };
-
-    // Shuffle around a few input and output handles here. We're going to pass
-    // an explicit handle into rustc to collect output messages, but we also
-    // want to catch the error message that rustc prints when it fails.
-    //
-    // We take our thread-local stderr (likely set by the test runner) and replace
-    // it with a sink that is also passed to rustc itself. When this function
-    // returns the output of the sink is copied onto the output of our own thread.
-    //
-    // The basic idea is to not use a default Handler for rustc, and then also
-    // not print things by default to the actual stderr.
-    struct Sink(Arc<Mutex<Vec<u8>>>);
-    impl Write for Sink {
-        fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-            Write::write(&mut *self.0.lock().unwrap(), data)
-        }
-        fn flush(&mut self) -> io::Result<()> { Ok(()) }
-    }
-    struct Bomb(Arc<Mutex<Vec<u8>>>, Option<Box<dyn Write+Send>>);
-    impl Drop for Bomb {
-        fn drop(&mut self) {
-            let mut old = self.1.take().unwrap();
-            let _ = old.write_all(&self.0.lock().unwrap());
-            io::set_panic(Some(old));
-        }
-    }
-    let data = Arc::new(Mutex::new(Vec::new()));
-
-    let old = io::set_panic(Some(box Sink(data.clone())));
-    let _bomb = Bomb(data.clone(), Some(old.unwrap_or(box io::stdout())));
-
     enum DirState {
         Temp(tempfile::TempDir),
         Perm(PathBuf),
@@ -292,7 +219,7 @@ fn run_test(
         }
     }
 
-    let outdir = if let Some(mut path) = persist_doctests {
+    let outdir = if let Some(mut path) = options.persist_doctests {
         path.push(format!("{}_{}",
             filename
                 .to_string()
@@ -314,41 +241,65 @@ fn run_test(
     };
     let output_file = outdir.path().join("rust_out");
 
-    let config = interface::Config {
-        opts: sessopts,
-        crate_cfg: config::parse_cfgspecs(cfgs),
-        input,
-        input_path: None,
-        output_file: Some(output_file.clone()),
-        output_dir: None,
-        file_loader: None,
-        diagnostic_output: DiagnosticOutput::Raw(box Sink(data.clone())),
-        stderr: Some(data.clone()),
-        crate_name: None,
-        lint_caps: Default::default(),
-    };
+    let mut compiler = Command::new(std::env::current_exe().unwrap().with_file_name("rustc"));
+    compiler.arg("--crate-type").arg("bin");
+    for cfg in &options.cfgs {
+        compiler.arg("--cfg").arg(&cfg);
+    }
+    if let Some(sysroot) = options.maybe_sysroot {
+        compiler.arg("--sysroot").arg(sysroot);
+    }
+    compiler.arg("--edition").arg(&edition.to_string());
+    compiler.env("UNSTABLE_RUSTDOC_TEST_PATH", path);
+    compiler.env("UNSTABLE_RUSTDOC_TEST_LINE",
+                 format!("{}", line as isize - line_offset as isize));
+    compiler.arg("-o").arg(&output_file);
+    if as_test_harness {
+        compiler.arg("--test");
+    }
+    for lib_str in &options.lib_strs {
+        compiler.arg("-L").arg(&lib_str);
+    }
+    for extern_str in &options.extern_strs {
+        compiler.arg("--extern").arg(&extern_str);
+    }
+    for codegen_options_str in &options.codegen_options_strs {
+        compiler.arg("-C").arg(&codegen_options_str);
+    }
+    if let Some(linker) = options.linker {
+        compiler.arg(&format!("-C linker={:?}", linker));
+    }
+    if no_run {
+        compiler.arg("--emit=metadata");
+    }
 
-    let compile_result = panic::catch_unwind(AssertUnwindSafe(|| {
-        interface::run_compiler(config, |compiler| {
-            if no_run {
-                compiler.global_ctxt().and_then(|global_ctxt| global_ctxt.take().enter(|tcx| {
-                    tcx.analysis(LOCAL_CRATE)
-                })).ok();
-            } else {
-                compiler.compile().ok();
-            };
-            compiler.session().compile_status()
-        })
-    })).map_err(|_| ()).and_then(|s| s.map_err(|_| ()));
+    compiler.arg("-");
+    compiler.stdin(Stdio::piped());
+    compiler.stderr(Stdio::piped());
+
+    let mut child = compiler.spawn().expect("Failed to spawn rustc process");
+    {
+        let stdin = child.stdin.as_mut().expect("Failed to open stdin");
+        stdin.write_all(test.as_bytes()).expect("could write out test sources");
+    }
+    let output = child.wait_with_output().expect("Failed to read stdout");
 
-    match (compile_result, compile_fail) {
-        (Ok(()), true) => {
+    struct Bomb<'a>(&'a str);
+    impl Drop for Bomb<'_> {
+        fn drop(&mut self) {
+            eprint!("{}",self.0);
+        }
+    }
+
+    let out = str::from_utf8(&output.stderr).unwrap();
+    let _bomb = Bomb(&out);
+    match (output.status.success(), compile_fail) {
+        (true, true) => {
             return Err(TestFailure::UnexpectedCompilePass);
         }
-        (Ok(()), false) => {}
-        (Err(_), true) => {
+        (true, false) => {}
+        (false, true) => {
             if !error_codes.is_empty() {
-                let out = String::from_utf8(data.lock().unwrap().to_vec()).unwrap();
                 error_codes.retain(|err| !out.contains(err));
 
                 if !error_codes.is_empty() {
@@ -356,7 +307,7 @@ fn run_test(
                 }
             }
         }
-        (Err(_), false) => {
+        (false, false) => {
             return Err(TestFailure::CompileError);
         }
     }
@@ -652,45 +603,28 @@ pub struct Collector {
     // the `names` vector of that test will be `["Title", "Subtitle"]`.
     names: Vec<String>,
 
-    cfgs: Vec<String>,
-    libs: Vec<SearchPath>,
-    cg: CodegenOptions,
-    externs: Externs,
+    options: Options,
     use_headers: bool,
     cratename: String,
     opts: TestOptions,
-    maybe_sysroot: Option<PathBuf>,
     position: Span,
     source_map: Option<Lrc<SourceMap>>,
     filename: Option<PathBuf>,
-    linker: Option<PathBuf>,
-    edition: Edition,
-    persist_doctests: Option<PathBuf>,
 }
 
 impl Collector {
-    pub fn new(cratename: String, cfgs: Vec<String>, libs: Vec<SearchPath>, cg: CodegenOptions,
-               externs: Externs, use_headers: bool, opts: TestOptions,
-               maybe_sysroot: Option<PathBuf>, source_map: Option<Lrc<SourceMap>>,
-               filename: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition,
-               persist_doctests: Option<PathBuf>) -> Collector {
+    pub fn new(cratename: String, options: Options, use_headers: bool, opts: TestOptions,
+               source_map: Option<Lrc<SourceMap>>, filename: Option<PathBuf>,) -> Collector {
         Collector {
             tests: Vec::new(),
             names: Vec::new(),
-            cfgs,
-            libs,
-            cg,
-            externs,
+            options,
             use_headers,
             cratename,
             opts,
-            maybe_sysroot,
             position: DUMMY_SP,
             source_map,
             filename,
-            linker,
-            edition,
-            persist_doctests,
         }
     }
 
@@ -725,16 +659,10 @@ impl Tester for Collector {
     fn add_test(&mut self, test: String, config: LangString, line: usize) {
         let filename = self.get_filename();
         let name = self.generate_name(line, &filename);
-        let cfgs = self.cfgs.clone();
-        let libs = self.libs.clone();
-        let cg = self.cg.clone();
-        let externs = self.externs.clone();
         let cratename = self.cratename.to_string();
         let opts = self.opts.clone();
-        let maybe_sysroot = self.maybe_sysroot.clone();
-        let linker = self.linker.clone();
-        let edition = config.edition.unwrap_or(self.edition);
-        let persist_doctests = self.persist_doctests.clone();
+        let edition = config.edition.unwrap_or(self.options.edition.clone());
+        let options = self.options.clone();
 
         debug!("creating test {}: {}", name, test);
         self.tests.push(testing::TestDescAndFn {
@@ -751,20 +679,14 @@ impl Tester for Collector {
                     &cratename,
                     &filename,
                     line,
-                    cfgs,
-                    libs,
-                    cg,
-                    externs,
+                    options,
                     config.should_panic,
                     config.no_run,
                     config.test_harness,
                     config.compile_fail,
                     config.error_codes,
                     &opts,
-                    maybe_sysroot,
-                    linker,
                     edition,
-                    persist_doctests
                 );
 
                 if let Err(err) = res {

From c6e7f039aabe3338c400d197a689c94bde425ba6 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Thu, 15 Aug 2019 18:20:35 +0200
Subject: [PATCH 333/943] Merge oli-obk mail addresses

---
 .mailmap | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/.mailmap b/.mailmap
index c5ecfb54fca52..91b2e762d8e40 100644
--- a/.mailmap
+++ b/.mailmap
@@ -181,12 +181,19 @@ Neil Pankey <npankey@gmail.com> <neil@wire.im>
 Nick Platt <platt.nicholas@gmail.com>
 Nicole Mazzuca <npmazzuca@gmail.com>
 Nif Ward <nif.ward@gmail.com>
-Oliver Schneider <oliver.schneider@kit.edu> oli-obk <github6541940@oli-obk.de>
-Oliver Schneider <oliver.schneider@kit.edu> Oliver 'ker' Schneider <rust19446194516@oli-obk.de>
-Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
-Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <git-spam9815368754983@oli-obk.de>
-Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <github333195615777966@oli-obk.de>
-Oliver Schneider <oliver.schneider@kit.edu> Oliver Schneider <github6541940@oli-obk.de>
+Oliver Scherer <oliver.schneider@kit.edu> <git-spam-no-reply9815368754983@oli-obk.de>
+Oliver Scherer <oliver.schneider@kit.edu> <git-spam9815368754983@oli-obk.de>
+Oliver Scherer <oliver.schneider@kit.edu> <github333195615777966@oli-obk.de>
+Oliver Scherer <oliver.schneider@kit.edu> <github6541940@oli-obk.de>
+Oliver Scherer <oliver.schneider@kit.edu> <rust19446194516@oli-obk.de>
+Oliver Scherer <oliver.schneider@kit.edu> <git-no-reply-9879165716479413131@oli-obk.de>
+Oliver Scherer <oliver.schneider@kit.edu> <git1984941651981@oli-obk.de>
+Oliver Scherer <oliver.schneider@kit.edu> <github35764891676564198441@oli-obk.de>
+Oliver Scherer <oliver.schneider@kit.edu> <github6541940@oli-obk.de>
+Oliver Scherer <oliver.schneider@kit.edu> <oli-obk@users.noreply.github.com>
+Oliver Scherer <oliver.schneider@kit.edu> <public.oliver.schneider@kit.edu>
+Oliver Scherer <oliver.schneider@kit.edu> <obk8176014uqher834@olio-obk.de>
+Oliver Scherer <oliver.schneider@kit.edu>
 Ožbolt Menegatti <ozbolt.menegatti@gmail.com> gareins <ozbolt.menegatti@gmail.com>
 Paul Faria <paul_faria@ultimatesoftware.com> Paul Faria <Nashenas88@gmail.com>
 Peer Aramillo Irizar <peer.aramillo.irizar@gmail.com> parir <peer.aramillo.irizar@gmail.com>

From 26e9990198d3c7262d58468f18a722920c897e35 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Sun, 19 May 2019 20:16:04 +0200
Subject: [PATCH 334/943] Add a "diagnostic item" scheme

This allows lints and other diagnostics to refer to items
by a unique ID instead of relying on whacky path
resolution schemes that may break when items are
relocated.
---
 src/liballoc/vec.rs                           |   1 +
 src/libcore/fmt/mod.rs                        |   3 +-
 src/librustc/arena.rs                         |   4 +
 src/librustc/lib.rs                           |   2 +
 src/librustc/lint/internal.rs                 |  16 +--
 src/librustc/middle/diagnostic_items.rs       | 123 ++++++++++++++++++
 src/librustc/middle/lang_items.rs             |   2 -
 src/librustc/query/mod.rs                     |  19 ++-
 src/librustc/ty/context.rs                    |  21 +++
 src/librustc/ty/mod.rs                        |   1 +
 src/librustc/ty/sty.rs                        |   1 +
 src/librustc_lint/builtin.rs                  |   2 +-
 src/librustc_metadata/cstore_impl.rs          |   1 +
 src/librustc_metadata/decoder.rs              |  18 +++
 src/librustc_metadata/encoder.rs              |  15 ++-
 src/librustc_metadata/schema.rs               |   1 +
 src/libsyntax/feature_gate/builtin_attrs.rs   |  11 ++
 src/libsyntax_pos/symbol.rs                   |   5 +-
 .../ui/tool-attributes/diagnostic_item.rs     |   2 +
 .../ui/tool-attributes/diagnostic_item.stderr |  17 +++
 .../ui/tool-attributes/diagnostic_item2.rs    |   6 +
 .../ui/tool-attributes/diagnostic_item3.rs    |   7 +
 22 files changed, 260 insertions(+), 18 deletions(-)
 create mode 100644 src/librustc/middle/diagnostic_items.rs
 create mode 100644 src/test/ui/tool-attributes/diagnostic_item.rs
 create mode 100644 src/test/ui/tool-attributes/diagnostic_item.stderr
 create mode 100644 src/test/ui/tool-attributes/diagnostic_item2.rs
 create mode 100644 src/test/ui/tool-attributes/diagnostic_item3.rs

diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index d2798955c46a9..d5dc2d4b8688d 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -291,6 +291,7 @@ use crate::raw_vec::RawVec;
 /// [`reserve`]: ../../std/vec/struct.Vec.html#method.reserve
 /// [owned slice]: ../../std/boxed/struct.Box.html
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(all(not(bootstrap), not(test)), rustc_diagnostic_item = "vec_type")]
 pub struct Vec<T> {
     buf: RawVec<T>,
     len: usize,
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index bd31d25dd034b..7e35188bc1082 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -518,7 +518,8 @@ impl Display for Arguments<'_> {
     label="`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{Debug}`",
 )]
 #[doc(alias = "{:?}")]
-#[lang = "debug_trait"]
+#[cfg_attr(boostrap_stdarch_ignore_this, lang = "debug_trait")]
+#[cfg_attr(not(boostrap_stdarch_ignore_this), rustc_diagnostic_item = "debug_trait")]
 pub trait Debug {
     /// Formats the value using the given formatter.
     ///
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index a38dbbdd50c57..b3a561ef74be7 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -94,6 +94,10 @@ macro_rules! arena_types {
                         rustc::hir::def_id::CrateNum
                     >
                 >,
+            [few] diagnostic_items: rustc_data_structures::fx::FxHashMap<
+                syntax::symbol::Symbol,
+                rustc::hir::def_id::DefId,
+            >,
             [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
             [decode] generic_predicates: rustc::ty::GenericPredicates<'tcx>,
             [few] lint_levels: rustc::lint::LintLevelMap,
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 8d4cd51e4608c..368f5bb64fe6c 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -62,6 +62,7 @@
 #![feature(log_syntax)]
 #![feature(mem_take)]
 #![feature(associated_type_bounds)]
+#![feature(rustc_attrs)]
 
 #![recursion_limit="512"]
 
@@ -109,6 +110,7 @@ pub mod middle {
     pub mod cstore;
     pub mod dead;
     pub mod dependency_format;
+    pub mod diagnostic_items;
     pub mod entry;
     pub mod exported_symbols;
     pub mod free_region;
diff --git a/src/librustc/lint/internal.rs b/src/librustc/lint/internal.rs
index be73b305e2c50..13834eaf40f57 100644
--- a/src/librustc/lint/internal.rs
+++ b/src/librustc/lint/internal.rs
@@ -159,29 +159,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TyTyKind {
 }
 
 fn lint_ty_kind_usage(cx: &LateContext<'_, '_>, segment: &PathSegment) -> bool {
-    if segment.ident.name == sym::TyKind {
-        if let Some(res) = segment.res {
-            if let Some(did) = res.opt_def_id() {
-                return cx.match_def_path(did, TYKIND_PATH);
-            }
+    if let Some(res) = segment.res {
+        if let Some(did) = res.opt_def_id() {
+            return cx.tcx.is_diagnostic_item(sym::TyKind, did);
         }
     }
 
     false
 }
 
-const TYKIND_PATH: &[Symbol] = &[sym::rustc, sym::ty, sym::sty, sym::TyKind];
-const TY_PATH: &[Symbol] = &[sym::rustc, sym::ty, sym::Ty];
-const TYCTXT_PATH: &[Symbol] = &[sym::rustc, sym::ty, sym::context, sym::TyCtxt];
-
 fn is_ty_or_ty_ctxt(cx: &LateContext<'_, '_>, ty: &Ty) -> Option<String> {
     match &ty.node {
         TyKind::Path(qpath) => {
             if let QPath::Resolved(_, path) = qpath {
                 let did = path.res.opt_def_id()?;
-                if cx.match_def_path(did, TY_PATH) {
+                if cx.tcx.is_diagnostic_item(sym::Ty, did) {
                     return Some(format!("Ty{}", gen_args(path.segments.last().unwrap())));
-                } else if cx.match_def_path(did, TYCTXT_PATH) {
+                } else if cx.tcx.is_diagnostic_item(sym::TyCtxt, did) {
                     return Some(format!("TyCtxt{}", gen_args(path.segments.last().unwrap())));
                 }
             }
diff --git a/src/librustc/middle/diagnostic_items.rs b/src/librustc/middle/diagnostic_items.rs
new file mode 100644
index 0000000000000..dfae169b27824
--- /dev/null
+++ b/src/librustc/middle/diagnostic_items.rs
@@ -0,0 +1,123 @@
+//! Detecting diagnostic items.
+//!
+//! Diagnostic items are items that are not language-inherent, but can reasonably be expected to
+//! exist for diagnostic purposes. This allows diagnostic authors to refer to specific items
+//! directly, without having to guess module paths and crates.
+//! Examples are:
+//!
+//! * Traits like `Debug`, that have no bearing on language semantics
+//!
+//! * Compiler internal types like `Ty` and `TyCtxt`
+
+use crate::hir::def_id::{DefId, LOCAL_CRATE};
+use crate::ty::TyCtxt;
+use crate::util::nodemap::FxHashMap;
+
+use syntax::ast;
+use syntax::symbol::{Symbol, sym};
+use crate::hir::itemlikevisit::ItemLikeVisitor;
+use crate::hir;
+
+struct DiagnosticItemCollector<'tcx> {
+    // items from this crate
+    items: FxHashMap<Symbol, DefId>,
+    tcx: TyCtxt<'tcx>,
+}
+
+impl<'v, 'tcx> ItemLikeVisitor<'v> for DiagnosticItemCollector<'tcx> {
+    fn visit_item(&mut self, item: &hir::Item) {
+        self.observe_item(&item.attrs, item.hir_id);
+    }
+
+    fn visit_trait_item(&mut self, trait_item: &hir::TraitItem) {
+        self.observe_item(&trait_item.attrs, trait_item.hir_id);
+    }
+
+    fn visit_impl_item(&mut self, impl_item: &hir::ImplItem) {
+        self.observe_item(&impl_item.attrs, impl_item.hir_id);
+    }
+}
+
+impl<'tcx> DiagnosticItemCollector<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>) -> DiagnosticItemCollector<'tcx> {
+        DiagnosticItemCollector {
+            tcx,
+            items: Default::default(),
+        }
+    }
+
+    fn observe_item(&mut self, attrs: &[ast::Attribute], hir_id: hir::HirId) {
+        if let Some(name) = extract(attrs) {
+            let def_id = self.tcx.hir().local_def_id(hir_id);
+            // insert into our table
+            collect_item(self.tcx, &mut self.items, name, def_id);
+        }
+    }
+}
+
+fn collect_item(
+    tcx: TyCtxt<'_>,
+    items: &mut FxHashMap<Symbol, DefId>,
+    name: Symbol,
+    item_def_id: DefId,
+) {
+    // Check for duplicates.
+    if let Some(original_def_id) = items.insert(name, item_def_id) {
+        if original_def_id != item_def_id {
+            let mut err = match tcx.hir().span_if_local(item_def_id) {
+                Some(span) => tcx.sess.struct_span_err(
+                    span,
+                    &format!("duplicate diagnostic item found: `{}`.", name)),
+                None => tcx.sess.struct_err(&format!(
+                        "duplicate diagnostic item in crate `{}`: `{}`.",
+                        tcx.crate_name(item_def_id.krate),
+                        name)),
+            };
+            if let Some(span) = tcx.hir().span_if_local(original_def_id) {
+                span_note!(&mut err, span, "first defined here.");
+            } else {
+                err.note(&format!("first defined in crate `{}`.",
+                                    tcx.crate_name(original_def_id.krate)));
+            }
+            err.emit();
+        }
+    }
+}
+
+/// Extract the first `rustc_diagnostic_item = "$name"` out of a list of attributes.
+fn extract(attrs: &[ast::Attribute]) -> Option<Symbol> {
+    attrs.iter().find_map(|attr| {
+        if attr.check_name(sym::rustc_diagnostic_item) {
+            attr.value_str()
+        } else {
+            None
+        }
+    })
+}
+
+/// Traverse and collect the diagnostic items in the current
+pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx FxHashMap<Symbol, DefId> {
+    // Initialize the collector.
+    let mut collector = DiagnosticItemCollector::new(tcx);
+
+    // Collect diagnostic items in this crate.
+    tcx.hir().krate().visit_all_item_likes(&mut collector);
+
+    tcx.arena.alloc(collector.items)
+}
+
+
+/// Traverse and collect all the diagnostic items in all crates.
+pub fn collect_all<'tcx>(tcx: TyCtxt<'tcx>) -> &'tcx FxHashMap<Symbol, DefId> {
+    // Initialize the collector.
+    let mut collector = FxHashMap::default();
+
+    // Collect diagnostic items in other crates.
+    for &cnum in tcx.crates().iter().chain(std::iter::once(&LOCAL_CRATE)) {
+        for (&name, &def_id) in tcx.diagnostic_items(cnum).iter() {
+            collect_item(tcx, &mut collector, name, def_id);
+        }
+    }
+
+    tcx.arena.alloc(collector)
+}
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 334c06618bb28..6b04600eb75f8 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -367,8 +367,6 @@ language_item_table! {
 
     MaybeUninitLangItem,         "maybe_uninit",       maybe_uninit,            Target::Union;
 
-    DebugTraitLangItem,          "debug_trait",        debug_trait,             Target::Trait;
-
     // Align offset for stride != 1, must not panic.
     AlignOffsetLangItem,         "align_offset",       align_offset_fn,         Target::Fn;
 
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index c4f7ca51f4a7a..ef838114f6c36 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -804,7 +804,7 @@ rustc_queries! {
     }
 
     BorrowChecking {
-        // Lifetime resolution. See `middle::resolve_lifetimes`.
+        /// Lifetime resolution. See `middle::resolve_lifetimes`.
         query resolve_lifetimes(_: CrateNum) -> &'tcx ResolveLifetimes {
             desc { "resolving lifetimes" }
         }
@@ -846,13 +846,30 @@ rustc_queries! {
             -> &'tcx [(Symbol, Option<Symbol>)] {
             desc { "calculating the lib features defined in a crate" }
         }
+        /// Returns the lang items defined in another crate by loading it from metadata.
+        // FIXME: It is illegal to pass a `CrateNum` other than `LOCAL_CRATE` here, just get rid
+        // of that argument?
         query get_lang_items(_: CrateNum) -> &'tcx LanguageItems {
             eval_always
             desc { "calculating the lang items map" }
         }
+
+        /// Returns all diagnostic items defined in all crates
+        query all_diagnostic_items(_: CrateNum) -> &'tcx FxHashMap<Symbol, DefId> {
+            eval_always
+            desc { "calculating the diagnostic items map" }
+        }
+
+        /// Returns the lang items defined in another crate by loading it from metadata.
         query defined_lang_items(_: CrateNum) -> &'tcx [(DefId, usize)] {
             desc { "calculating the lang items defined in a crate" }
         }
+
+        /// Returns the diagnostic items defined in a crate
+        query diagnostic_items(_: CrateNum) -> &'tcx FxHashMap<Symbol, DefId> {
+            desc { "calculating the diagnostic items map in a crate" }
+        }
+
         query missing_lang_items(_: CrateNum) -> &'tcx [LangItem] {
             desc { "calculating the missing lang items in a crate" }
         }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index c0d86a79882ef..e240e0df8b948 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -978,6 +978,7 @@ pub struct FreeRegionInfo {
 ///
 /// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html
 #[derive(Copy, Clone)]
+#[cfg_attr(not(bootstrap), rustc_diagnostic_item = "TyCtxt")]
 pub struct TyCtxt<'tcx> {
     gcx: &'tcx GlobalCtxt<'tcx>,
 }
@@ -1308,10 +1309,22 @@ impl<'tcx> TyCtxt<'tcx> {
         self.get_lib_features(LOCAL_CRATE)
     }
 
+    /// Obtain all lang items of this crate and all dependencies (recursively)
     pub fn lang_items(self) -> &'tcx middle::lang_items::LanguageItems {
         self.get_lang_items(LOCAL_CRATE)
     }
 
+    /// Obtain the given diagnostic item's `DefId`. Use `is_diagnostic_item` if you just want to
+    /// compare against another `DefId`, since `is_diagnostic_item` is cheaper.
+    pub fn get_diagnostic_item(self, name: Symbol) -> Option<DefId> {
+        self.all_diagnostic_items(LOCAL_CRATE).get(&name).copied()
+    }
+
+    /// Check whether the diagnostic item with the given `name` has the given `DefId`.
+    pub fn is_diagnostic_item(self, name: Symbol, did: DefId) -> bool {
+        self.diagnostic_items(did.krate).get(&name) == Some(&did)
+    }
+
     pub fn stability(self) -> &'tcx stability::Index<'tcx> {
         self.stability_index(LOCAL_CRATE)
     }
@@ -2896,6 +2909,14 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
         assert_eq!(id, LOCAL_CRATE);
         tcx.arena.alloc(middle::lang_items::collect(tcx))
     };
+    providers.diagnostic_items = |tcx, id| {
+        assert_eq!(id, LOCAL_CRATE);
+        middle::diagnostic_items::collect(tcx)
+    };
+    providers.all_diagnostic_items = |tcx, id| {
+        assert_eq!(id, LOCAL_CRATE);
+        middle::diagnostic_items::collect_all(tcx)
+    };
     providers.maybe_unused_trait_import = |tcx, id| {
         tcx.maybe_unused_trait_imports.contains(&id)
     };
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index eaaaf75f75dd5..56505c04f0f0c 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -581,6 +581,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::TyS<'tcx> {
     }
 }
 
+#[cfg_attr(not(bootstrap), rustc_diagnostic_item = "Ty")]
 pub type Ty<'tcx> = &'tcx TyS<'tcx>;
 
 impl<'tcx> rustc_serialize::UseSpecializedEncodable for Ty<'tcx> {}
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index f41fffe507d97..d2edf6fb1ee80 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -86,6 +86,7 @@ impl BoundRegion {
 /// AST structure in `libsyntax/ast.rs` as well.
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
          RustcEncodable, RustcDecodable, HashStable, Debug)]
+#[cfg_attr(not(bootstrap), rustc_diagnostic_item = "TyKind")]
 pub enum TyKind<'tcx> {
     /// The primitive boolean type. Written as `bool`.
     Bool,
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index d3c94060e274a..26e7b789f8f90 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -570,7 +570,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations {
             _ => return,
         }
 
-        let debug = match cx.tcx.lang_items().debug_trait() {
+        let debug = match cx.tcx.get_diagnostic_item(sym::debug_trait) {
             Some(debug) => debug,
             None => return,
         };
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index ca0cf0a5a661d..d6450f00c8b6a 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -226,6 +226,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     }
     defined_lib_features => { cdata.get_lib_features(tcx) }
     defined_lang_items => { cdata.get_lang_items(tcx) }
+    diagnostic_items => { cdata.get_diagnostic_items(tcx) }
     missing_lang_items => { cdata.get_missing_lang_items(tcx) }
 
     missing_extern_crate_item => {
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index cdee14d07fb4d..75d7261704722 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -12,6 +12,7 @@ use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
 use rustc::hir::def::{self, Res, DefKind, CtorOf, CtorKind};
 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc_data_structures::fingerprint::Fingerprint;
+use rustc_data_structures::fx::FxHashMap;
 use rustc::middle::lang_items;
 use rustc::mir::{self, interpret};
 use rustc::mir::interpret::AllocDecodingSession;
@@ -757,6 +758,23 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
+    /// Iterates over the diagnostic items in the given crate.
+    pub fn get_diagnostic_items(
+        &self,
+        tcx: TyCtxt<'tcx>,
+    ) -> &'tcx FxHashMap<Symbol, DefId> {
+        tcx.arena.alloc(if self.is_proc_macro_crate() {
+            // Proc macro crates do not export any diagnostic-items to the target.
+            Default::default()
+        } else {
+            self.root
+                .diagnostic_items
+                .decode(self)
+                .map(|(name, def_index)| (name, self.local_def_id(def_index)))
+                .collect()
+        })
+    }
+
     /// Iterates over each child of the given item.
     pub fn each_child_of_item<F>(&self, id: DefIndex, mut callback: F, sess: &Session)
         where F: FnMut(def::Export<hir::HirId>)
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 0eafcebefd745..db212408d8ebd 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -33,7 +33,7 @@ use syntax::ast;
 use syntax::attr;
 use syntax::ext::proc_macro::is_proc_macro_attr;
 use syntax::source_map::Spanned;
-use syntax::symbol::{kw, sym, Ident};
+use syntax::symbol::{kw, sym, Ident, Symbol};
 use syntax_pos::{self, FileName, SourceFile, Span};
 use log::{debug, trace};
 
@@ -404,6 +404,11 @@ impl<'tcx> EncodeContext<'tcx> {
         let lang_items_missing = self.encode_lang_items_missing();
         let lang_item_bytes = self.position() - i;
 
+        // Encode the diagnostic items.
+        i = self.position();
+        let diagnostic_items = self.encode_diagnostic_items();
+        let diagnostic_item_bytes = self.position() - i;
+
         // Encode the native libraries used
         i = self.position();
         let native_libraries = self.encode_native_libraries();
@@ -520,6 +525,7 @@ impl<'tcx> EncodeContext<'tcx> {
             dylib_dependency_formats,
             lib_features,
             lang_items,
+            diagnostic_items,
             lang_items_missing,
             native_libraries,
             foreign_modules,
@@ -545,6 +551,7 @@ impl<'tcx> EncodeContext<'tcx> {
             println!("             dep bytes: {}", dep_bytes);
             println!("     lib feature bytes: {}", lib_feature_bytes);
             println!("       lang item bytes: {}", lang_item_bytes);
+            println!(" diagnostic item bytes: {}", diagnostic_item_bytes);
             println!("          native bytes: {}", native_lib_bytes);
             println!("         source_map bytes: {}", source_map_bytes);
             println!("            impl bytes: {}", impl_bytes);
@@ -1555,6 +1562,12 @@ impl EncodeContext<'tcx> {
         self.lazy(lib_features.to_vec())
     }
 
+    fn encode_diagnostic_items(&mut self) -> Lazy<[(Symbol, DefIndex)]> {
+        let tcx = self.tcx;
+        let diagnostic_items = tcx.diagnostic_items(LOCAL_CRATE);
+        self.lazy(diagnostic_items.iter().map(|(&name, def_id)| (name, def_id.index)))
+    }
+
     fn encode_lang_items(&mut self) -> Lazy<[(DefIndex, usize)]> {
         let tcx = self.tcx;
         let lang_items = tcx.lang_items();
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 1a5887bbf4ed8..1a5f0e17ba7ce 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -176,6 +176,7 @@ pub struct CrateRoot<'tcx> {
     pub lib_features: Lazy<[(Symbol, Option<Symbol>)]>,
     pub lang_items: Lazy<[(DefIndex, usize)]>,
     pub lang_items_missing: Lazy<[lang_items::LangItem]>,
+    pub diagnostic_items: Lazy<[(Symbol, DefIndex)]>,
     pub native_libraries: Lazy<[NativeLibrary]>,
     pub foreign_modules: Lazy<[ForeignModule]>,
     pub source_map: Lazy<[syntax_pos::SourceFile]>,
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index b934f2e7f64ef..ee7ac3b15d955 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -461,6 +461,17 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         lang, Normal, template!(NameValueStr: "name"), lang_items,
         "language items are subject to change",
     ),
+    (
+        sym::rustc_diagnostic_item,
+        Normal,
+        template!(NameValueStr: "name"),
+        Gated(
+            Stability::Unstable,
+            sym::rustc_attrs,
+            "diagnostic items compiler internal support for linting",
+            cfg_fn!(rustc_attrs),
+        ),
+    ),
     (
         sym::no_debug, Whitelisted, template!(Word),
         Gated(
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 8833e03c72be2..f44716e013ec8 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -225,9 +225,10 @@ symbols! {
         custom_inner_attributes,
         custom_test_frameworks,
         c_variadic,
-        Debug,
+        debug_trait,
         declare_lint_pass,
         decl_macro,
+        Debug,
         Decodable,
         Default,
         default_lib_allocator,
@@ -238,6 +239,7 @@ symbols! {
         deref,
         deref_mut,
         derive,
+        diagnostic,
         direct,
         doc,
         doc_alias,
@@ -569,6 +571,7 @@ symbols! {
         rustc_conversion_suggestion,
         rustc_def_path,
         rustc_deprecated,
+        rustc_diagnostic_item,
         rustc_diagnostic_macros,
         rustc_dirty,
         rustc_dummy,
diff --git a/src/test/ui/tool-attributes/diagnostic_item.rs b/src/test/ui/tool-attributes/diagnostic_item.rs
new file mode 100644
index 0000000000000..88157bbbf614b
--- /dev/null
+++ b/src/test/ui/tool-attributes/diagnostic_item.rs
@@ -0,0 +1,2 @@
+#[rustc_diagnostic_item = "foomp"] //~ ERROR will never be stabilized
+struct Foomp;
diff --git a/src/test/ui/tool-attributes/diagnostic_item.stderr b/src/test/ui/tool-attributes/diagnostic_item.stderr
new file mode 100644
index 0000000000000..4472914118ba7
--- /dev/null
+++ b/src/test/ui/tool-attributes/diagnostic_item.stderr
@@ -0,0 +1,17 @@
+error[E0658]: diagnostic items compiler are internal support for linting and will never be stabilized
+  --> $DIR/diagnostic_item.rs:1:1
+   |
+LL | #[rustc_diagnostic_item = "foomp"]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
+
+error[E0601]: `main` function not found in crate `diagnostic_item`
+   |
+   = note: consider adding a `main` function to `$DIR/diagnostic_item.rs`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0601, E0658.
+For more information about an error, try `rustc --explain E0601`.
diff --git a/src/test/ui/tool-attributes/diagnostic_item2.rs b/src/test/ui/tool-attributes/diagnostic_item2.rs
new file mode 100644
index 0000000000000..b32a66b16be18
--- /dev/null
+++ b/src/test/ui/tool-attributes/diagnostic_item2.rs
@@ -0,0 +1,6 @@
+// check-pass
+
+#[clippy::diagnostic_item = "mep"]
+struct Mep;
+
+fn main() {}
diff --git a/src/test/ui/tool-attributes/diagnostic_item3.rs b/src/test/ui/tool-attributes/diagnostic_item3.rs
new file mode 100644
index 0000000000000..c1a236ed1cc32
--- /dev/null
+++ b/src/test/ui/tool-attributes/diagnostic_item3.rs
@@ -0,0 +1,7 @@
+// check-pass
+#![feature(rustc_attrs)]
+
+#[rustc_diagnostic_item = "foomp"]
+struct Foomp;
+
+fn main() {}

From 6978b9482b976d991dac1dc55a6effe1f697cd1f Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Fri, 30 Aug 2019 02:46:25 +0200
Subject: [PATCH 335/943] Update tests

---
 src/test/ui/tool-attributes/diagnostic_item.rs     | 2 +-
 src/test/ui/tool-attributes/diagnostic_item.stderr | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/test/ui/tool-attributes/diagnostic_item.rs b/src/test/ui/tool-attributes/diagnostic_item.rs
index 88157bbbf614b..1d35422ed6241 100644
--- a/src/test/ui/tool-attributes/diagnostic_item.rs
+++ b/src/test/ui/tool-attributes/diagnostic_item.rs
@@ -1,2 +1,2 @@
-#[rustc_diagnostic_item = "foomp"] //~ ERROR will never be stabilized
+#[rustc_diagnostic_item = "foomp"] //~ ERROR compiler internal support for linting
 struct Foomp;
diff --git a/src/test/ui/tool-attributes/diagnostic_item.stderr b/src/test/ui/tool-attributes/diagnostic_item.stderr
index 4472914118ba7..deff4da6b8052 100644
--- a/src/test/ui/tool-attributes/diagnostic_item.stderr
+++ b/src/test/ui/tool-attributes/diagnostic_item.stderr
@@ -1,4 +1,4 @@
-error[E0658]: diagnostic items compiler are internal support for linting and will never be stabilized
+error[E0658]: diagnostic items compiler internal support for linting
   --> $DIR/diagnostic_item.rs:1:1
    |
 LL | #[rustc_diagnostic_item = "foomp"]

From 5da1123c5efbd91813fb5ba7cec5298d960ae3af Mon Sep 17 00:00:00 2001
From: Tyler Mandry <tmandry@gmail.com>
Date: Thu, 29 Aug 2019 17:49:46 -0700
Subject: [PATCH 336/943] Update zx_time_t to an i64

---
 src/libstd/sys/unix/process/zircon.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libstd/sys/unix/process/zircon.rs b/src/libstd/sys/unix/process/zircon.rs
index ec715d5490f6f..9224bef7c4a5f 100644
--- a/src/libstd/sys/unix/process/zircon.rs
+++ b/src/libstd/sys/unix/process/zircon.rs
@@ -3,7 +3,7 @@
 use crate::convert::TryInto;
 use crate::io;
 use crate::os::raw::c_char;
-use crate::u64;
+use crate::i64;
 
 use libc::{c_int, c_void, size_t};
 
@@ -14,8 +14,8 @@ pub type zx_status_t = i32;
 
 pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
 
-pub type zx_time_t = u64;
-pub const ZX_TIME_INFINITE : zx_time_t = u64::MAX;
+pub type zx_time_t = i64;
+pub const ZX_TIME_INFINITE : zx_time_t = i64::MAX;
 
 pub type zx_signals_t = u32;
 

From bee2d3748ef472e416b4a690af89543ed0edd302 Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Fri, 30 Aug 2019 04:17:18 +0200
Subject: [PATCH 337/943] Move relocation range copies into allocation

---
 src/librustc/mir/interpret/allocation.rs | 50 ++++++++++++++++++++++++
 src/librustc_mir/interpret/memory.rs     | 30 ++------------
 2 files changed, 53 insertions(+), 27 deletions(-)

diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index 75319a6783167..8f47bf9d0fd5a 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -693,6 +693,56 @@ impl<Tag> DerefMut for Relocations<Tag> {
     }
 }
 
+/// A partial, owned list of relocations to transfer into another allocation.
+pub struct AllocationRelocations<Tag> {
+    relative_relocations: Vec<(Size, (Tag, AllocId))>,
+}
+
+impl<Tag: Copy, Extra> Allocation<Tag, Extra> {
+    pub fn prepare_relocation_copy(
+        &self,
+        cx: &impl HasDataLayout,
+        src: Pointer<Tag>,
+        size: Size,
+        dest: Pointer<Tag>,
+        length: u64,
+    ) -> AllocationRelocations<Tag> {
+        let relocations = self.get_relocations(cx, src, size);
+        if relocations.is_empty() {
+            return AllocationRelocations { relative_relocations: Vec::new() };
+        }
+
+        let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize));
+
+        for i in 0..length {
+            new_relocations.extend(
+                relocations
+                .iter()
+                .map(|&(offset, reloc)| {
+                    // compute offset for current repetition
+                    let dest_offset = dest.offset + (i * size);
+                    (
+                        // shift offsets from source allocation to destination allocation
+                        offset + dest_offset - src.offset,
+                        reloc,
+                        )
+                })
+                );
+        }
+
+        AllocationRelocations {
+            relative_relocations: new_relocations,
+        }
+    }
+
+    pub fn mark_relocation_range(
+        &mut self,
+        relocations: AllocationRelocations<Tag>,
+    ) {
+        self.relocations.insert_presorted(relocations.relative_relocations);
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Undefined byte tracking
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs
index 26b3f0be8c2b8..6e0d77235fe2b 100644
--- a/src/librustc_mir/interpret/memory.rs
+++ b/src/librustc_mir/interpret/memory.rs
@@ -808,32 +808,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // since we don't want to keep any relocations at the target.
         // (`get_bytes_with_undef_and_ptr` below checks that there are no
         // relocations overlapping the edges; those would not be handled correctly).
-        let relocations = {
-            let relocations = self.get(src.alloc_id)?.get_relocations(self, src, size);
-            if relocations.is_empty() {
-                // nothing to copy, ignore even the `length` loop
-                Vec::new()
-            } else {
-                let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize));
-                for i in 0..length {
-                    new_relocations.extend(
-                        relocations
-                        .iter()
-                        .map(|&(offset, reloc)| {
-                            // compute offset for current repetition
-                            let dest_offset = dest.offset + (i * size);
-                            (
-                                // shift offsets from source allocation to destination allocation
-                                offset + dest_offset - src.offset,
-                                reloc,
-                            )
-                        })
-                    );
-                }
-
-                new_relocations
-            }
-        };
+        let relocations = self.get(src.alloc_id)?
+            .prepare_relocation_copy(self, src, size, dest, length);
 
         let tcx = self.tcx.tcx;
 
@@ -880,7 +856,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
         // copy definedness to the destination
         self.copy_undef_mask(src, dest, size, length)?;
         // copy the relocations to the destination
-        self.get_mut(dest.alloc_id)?.relocations.insert_presorted(relocations);
+        self.get_mut(dest.alloc_id)?.mark_relocation_range(relocations);
 
         Ok(())
     }

From 7388cb4cf81523fb2709518ec8b6a16c329b72e5 Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Fri, 30 Aug 2019 04:19:29 +0200
Subject: [PATCH 338/943] Fixup remaining direct relocation field references

---
 src/librustc_codegen_llvm/consts.rs    | 8 ++++----
 src/librustc_mir/interpret/snapshot.rs | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 8725e69b11270..958666cb8858a 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -25,12 +25,12 @@ use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags};
 use std::ffi::{CStr, CString};
 
 pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll Value {
-    let mut llvals = Vec::with_capacity(alloc.relocations.len() + 1);
+    let mut llvals = Vec::with_capacity(alloc.relocations().len() + 1);
     let dl = cx.data_layout();
     let pointer_size = dl.pointer_size.bytes() as usize;
 
     let mut next_offset = 0;
-    for &(offset, ((), alloc_id)) in alloc.relocations.iter() {
+    for &(offset, ((), alloc_id)) in alloc.relocations().iter() {
         let offset = offset.bytes();
         assert_eq!(offset as usize as u64, offset);
         let offset = offset as usize;
@@ -455,7 +455,7 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
                 //
                 // We could remove this hack whenever we decide to drop macOS 10.10 support.
                 if self.tcx.sess.target.target.options.is_like_osx {
-                    assert_eq!(alloc.relocations.len(), 0);
+                    assert_eq!(alloc.relocations().len(), 0);
 
                     let is_zeroed = {
                         // Treats undefined bytes as if they were defined with the byte value that
@@ -490,7 +490,7 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
                         section.as_str().as_ptr() as *const _,
                         section.as_str().len() as c_uint,
                     );
-                    assert!(alloc.relocations.is_empty());
+                    assert!(alloc.relocations().is_empty());
 
                     // The `inspect` method is okay here because we checked relocations, and
                     // because we are doing this access to inspect the final interpreter state (not
diff --git a/src/librustc_mir/interpret/snapshot.rs b/src/librustc_mir/interpret/snapshot.rs
index 0f0c422d8d3f4..2cac8bb0c517e 100644
--- a/src/librustc_mir/interpret/snapshot.rs
+++ b/src/librustc_mir/interpret/snapshot.rs
@@ -287,7 +287,6 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation
 
     fn snapshot(&self, ctx: &'a Ctx) -> Self::Item {
         let Allocation {
-            relocations,
             size,
             align,
             mutability,
@@ -300,7 +299,9 @@ impl<'a, Ctx> Snapshot<'a, Ctx> for &'a Allocation
         // influence interpreter exeuction, but only to detect the error of cycles in evalution
         // dependencies.
         let bytes = self.inspect_with_undef_and_ptr_outside_interpreter(all_bytes);
+
         let undef_mask = self.undef_mask();
+        let relocations = self.relocations();
 
         AllocationSnapshot {
             bytes,

From 0f3e596c1d34b74c79133f3996d2c655a2cf8e66 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Aug 2019 12:54:46 +0200
Subject: [PATCH 339/943] miri: detect too large dynamically sized objects

---
 src/librustc_mir/interpret/eval_context.rs | 27 ++++++++++++----------
 src/librustc_mir/interpret/traits.rs       |  7 +++++-
 2 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index ac01d436bdc9b..054b65f0e1a9e 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -442,27 +442,30 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
                 // Issue #27023: must add any necessary padding to `size`
                 // (to make it a multiple of `align`) before returning it.
-                //
-                // Namely, the returned size should be, in C notation:
-                //
-                //   `size + ((size & (align-1)) ? align : 0)`
-                //
-                // emulated via the semi-standard fast bit trick:
-                //
-                //   `(size + (align-1)) & -align`
-
-                Ok(Some((size.align_to(align), align)))
+                let size = size.align_to(align);
+
+                // Check if this brought us over the size limit.
+                if size.bytes() >= self.tcx.data_layout().obj_size_bound() {
+                    throw_ub_format!("wide pointer metadata contains invalid information: \
+                        total size is bigger than largest supported object");
+                }
+                Ok(Some((size, align)))
             }
             ty::Dynamic(..) => {
                 let vtable = metadata.expect("dyn trait fat ptr must have vtable");
-                // the second entry in the vtable is the dynamic size of the object.
+                // Read size and align from vtable (already checks size).
                 Ok(Some(self.read_size_and_align_from_vtable(vtable)?))
             }
 
             ty::Slice(_) | ty::Str => {
                 let len = metadata.expect("slice fat ptr must have vtable").to_usize(self)?;
                 let elem = layout.field(self, 0)?;
-                Ok(Some((elem.size * len, elem.align.abi)))
+
+                // Make sure the slice is not too big.
+                let size = elem.size.checked_mul(len, &*self.tcx)
+                    .ok_or_else(|| err_ub_format!("invalid slice: \
+                        total size is bigger than largest supported object"))?;
+                Ok(Some((size, elem.align.abi)))
             }
 
             ty::Foreign(_) => {
diff --git a/src/librustc_mir/interpret/traits.rs b/src/librustc_mir/interpret/traits.rs
index 34a10de7de7fc..10b767ebba191 100644
--- a/src/librustc_mir/interpret/traits.rs
+++ b/src/librustc_mir/interpret/traits.rs
@@ -1,5 +1,5 @@
 use rustc::ty::{self, Ty, Instance, TypeFoldable};
-use rustc::ty::layout::{Size, Align, LayoutOf};
+use rustc::ty::layout::{Size, Align, LayoutOf, HasDataLayout};
 use rustc::mir::interpret::{Scalar, Pointer, InterpResult, PointerArithmetic,};
 
 use super::{InterpCx, Machine, MemoryKind, FnVal};
@@ -151,6 +151,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             vtable.offset(pointer_size * 2, self)?,
         )?.not_undef()?;
         let align = self.force_bits(align, pointer_size)? as u64;
+
+        if size >= self.tcx.data_layout().obj_size_bound() {
+            throw_ub_format!("invalid vtable: \
+                size is bigger than largest supported object");
+        }
         Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap()))
     }
 }

From 235ee34a15a272aa7eb540a632e719fbae68329b Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Aug 2019 18:36:11 +0200
Subject: [PATCH 340/943] better variable names

---
 src/test/ui/consts/const-eval/ub-wide-ptr.rs  | 20 +++++------
 .../ui/consts/const-eval/ub-wide-ptr.stderr   | 36 +++++++++----------
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
index 765ed60ee9742..c67108836fa4e 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
@@ -91,10 +91,10 @@ const MY_STR_LENGTH_PTR: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr {
 //~^ ERROR it is undefined behavior to use this value
 
 // invalid UTF-8
-const J1: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
+const STR_NO_UTF8: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
 //~^ ERROR it is undefined behavior to use this value
 // invalid UTF-8 in user-defined str-like
-const J2: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my_str };
+const MYSTR_NO_UTF8: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my_str };
 //~^ ERROR it is undefined behavior to use this value
 
 // # slice
@@ -111,16 +111,16 @@ const SLICE_LENGTH_PTR: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { pt
 //~^ ERROR it is undefined behavior to use this value
 
 // bad data *inside* the slice
-const H: &[bool] = &[unsafe { BoolTransmute { val: 3 }.bl }];
+const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { BoolTransmute { val: 3 }.bl }];
 //~^ ERROR it is undefined behavior to use this value
 
 // good MySliceBool
-const I1: &MySliceBool = &MySlice(true, [false]);
+const MYSLICE_GOOD: &MySliceBool = &MySlice(true, [false]);
 // bad: sized field is not okay
-const I2: &MySliceBool = &MySlice(unsafe { BoolTransmute { val: 3 }.bl }, [false]);
+const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { BoolTransmute { val: 3 }.bl }, [false]);
 //~^ ERROR it is undefined behavior to use this value
 // bad: unsized part is not okay
-const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]);
+const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]);
 //~^ ERROR it is undefined behavior to use this value
 
 // # raw slice
@@ -132,17 +132,17 @@ const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42
 
 // # trait object
 // bad trait object
-const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
+const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
 //~^ ERROR it is undefined behavior to use this value
 // bad trait object
-const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
+const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
 //~^ ERROR it is undefined behavior to use this value
 // bad trait object
-const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
+const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
 //~^ ERROR it is undefined behavior to use this value
 
 // bad data *inside* the trait object
-const G: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
+const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
 //~^ ERROR it is undefined behavior to use this value
 
 // # raw trait object
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
index 88d8af8026193..704b42e09b2ae 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -25,16 +25,16 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { SliceTransmute { bad: BadSliceRe
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:94:1
    |
-LL | const J1: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>
+LL | const STR_NO_UTF8: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:97:1
    |
-LL | const J2: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my_str };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>.0
+LL | const MYSTR_NO_UTF8: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my_str };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>.0
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -65,24 +65,24 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:114:1
    |
-LL | const H: &[bool] = &[unsafe { BoolTransmute { val: 3 }.bl }];
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>[0], but expected something less or equal to 1
+LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { BoolTransmute { val: 3 }.bl }];
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>[0], but expected something less or equal to 1
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:120:1
    |
-LL | const I2: &MySliceBool = &MySlice(unsafe { BoolTransmute { val: 3 }.bl }, [false]);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.0, but expected something less or equal to 1
+LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { BoolTransmute { val: 3 }.bl }, [false]);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.0, but expected something less or equal to 1
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:123:1
    |
-LL | const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.1[0], but expected something less or equal to 1
+LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.1[0], but expected something less or equal to 1
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
@@ -97,32 +97,32 @@ LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:135:1
    |
-LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
+LL | const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:138:1
    |
-LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
+LL | const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:141:1
    |
-LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
+LL | const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:145:1
    |
-LL | const G: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.<dyn-downcast>, but expected something less or equal to 1
+LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.<dyn-downcast>, but expected something less or equal to 1
    |
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 

From d75723e9fe07b71eeaf9dad2d8a76080ea201b83 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Fri, 30 Aug 2019 08:37:02 +0200
Subject: [PATCH 341/943] mod-level doc comment for validity check

---
 src/librustc_mir/interpret/validity.rs | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index c2505547c5b4f..3e14ba3efcc58 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -1,3 +1,9 @@
+//! Check the validity invariant of a given value, and tell the user
+//! where in the value it got violated.
+//! In const context, this goes even further and tries to approximate const safety.
+//! That's useful because it means other passes (e.g. promotion) can rely on `const`s
+//! to be const-safe.
+
 use std::fmt::Write;
 use std::ops::RangeInclusive;
 

From 38f6b96aae299b82d333d72828f3ea589849d907 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Fri, 30 Aug 2019 09:29:58 +0200
Subject: [PATCH 342/943] make unions repr(C)

---
 src/test/ui/consts/const-eval/ub-wide-ptr.rs  |  3 ++
 .../ui/consts/const-eval/ub-wide-ptr.stderr   | 36 +++++++++----------
 2 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.rs b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
index c67108836fa4e..1f810c40572c0 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.rs
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.rs
@@ -7,6 +7,7 @@
 // normalize-stderr-test "allocation \d+" -> "allocation N"
 // normalize-stderr-test "size \d+" -> "size N"
 
+#[repr(C)]
 union BoolTransmute {
   val: u8,
   bl: bool,
@@ -26,6 +27,7 @@ struct BadSliceRepr {
     len: &'static u8,
 }
 
+#[repr(C)]
 union SliceTransmute {
     repr: SliceRepr,
     bad: BadSliceRepr,
@@ -58,6 +60,7 @@ struct BadDynRepr {
     vtable: usize,
 }
 
+#[repr(C)]
 union DynTransmute {
     repr: DynRepr,
     repr2: DynRepr2,
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
index 704b42e09b2ae..aadabc323fbd4 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:84:1
+  --> $DIR/ub-wide-ptr.rs:87:1
    |
 LL | const STR_TOO_LONG: &str = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.str};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (not entirely in bounds)
@@ -7,7 +7,7 @@ LL | const STR_TOO_LONG: &str = unsafe { SliceTransmute { repr: SliceRepr { ptr:
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:87:1
+  --> $DIR/ub-wide-ptr.rs:90:1
    |
 LL | const STR_LENGTH_PTR: &str = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.str};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
@@ -15,7 +15,7 @@ LL | const STR_LENGTH_PTR: &str = unsafe { SliceTransmute { bad: BadSliceRepr {
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:90:1
+  --> $DIR/ub-wide-ptr.rs:93:1
    |
 LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.my_str};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
@@ -23,7 +23,7 @@ LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { SliceTransmute { bad: BadSliceRe
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:94:1
+  --> $DIR/ub-wide-ptr.rs:97:1
    |
 LL | const STR_NO_UTF8: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>
@@ -31,7 +31,7 @@ LL | const STR_NO_UTF8: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:97:1
+  --> $DIR/ub-wide-ptr.rs:100:1
    |
 LL | const MYSTR_NO_UTF8: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my_str };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>.0
@@ -39,7 +39,7 @@ LL | const MYSTR_NO_UTF8: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:104:1
+  --> $DIR/ub-wide-ptr.rs:107:1
    |
 LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { SliceTransmute { addr: 42 }.slice};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
@@ -47,7 +47,7 @@ LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { SliceTransmute { addr: 42 }.sli
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:107:1
+  --> $DIR/ub-wide-ptr.rs:110:1
    |
 LL | const SLICE_TOO_LONG: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.slice};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (not entirely in bounds)
@@ -55,7 +55,7 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { p
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:110:1
+  --> $DIR/ub-wide-ptr.rs:113:1
    |
 LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
@@ -63,7 +63,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:114:1
+  --> $DIR/ub-wide-ptr.rs:117:1
    |
 LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { BoolTransmute { val: 3 }.bl }];
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>[0], but expected something less or equal to 1
@@ -71,7 +71,7 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { BoolTransmute { val: 3 }.
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:120:1
+  --> $DIR/ub-wide-ptr.rs:123:1
    |
 LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { BoolTransmute { val: 3 }.bl }, [false]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.0, but expected something less or equal to 1
@@ -79,7 +79,7 @@ LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { BoolTransmute {
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:123:1
+  --> $DIR/ub-wide-ptr.rs:126:1
    |
 LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.1[0], but expected something less or equal to 1
@@ -87,7 +87,7 @@ LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { BoolTrans
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:130:1
+  --> $DIR/ub-wide-ptr.rs:133:1
    |
 LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
@@ -95,7 +95,7 @@ LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:135:1
+  --> $DIR/ub-wide-ptr.rs:138:1
    |
 LL | const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -103,7 +103,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { DynTransmute { repr:
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:138:1
+  --> $DIR/ub-wide-ptr.rs:141:1
    |
 LL | const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -111,7 +111,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { DynTransmute { repr2:
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:141:1
+  --> $DIR/ub-wide-ptr.rs:144:1
    |
 LL | const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -119,7 +119,7 @@ LL | const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { DynTransmute { bad: BadDy
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:145:1
+  --> $DIR/ub-wide-ptr.rs:148:1
    |
 LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.<dyn-downcast>, but expected something less or equal to 1
@@ -127,7 +127,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = &unsafe { BoolTransmute { val
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:149:1
+  --> $DIR/ub-wide-ptr.rs:152:1
    |
 LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 0 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
@@ -135,7 +135,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { DynTransmute {
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-wide-ptr.rs:151:1
+  --> $DIR/ub-wide-ptr.rs:154:1
    |
 LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.raw_rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable

From cf574091fb10496a72b8f105d6f8f14f3eff0db6 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Fri, 30 Aug 2019 09:30:59 +0200
Subject: [PATCH 343/943] tweak const-valid test

---
 src/test/ui/consts/const-eval/valid-const.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/test/ui/consts/const-eval/valid-const.rs b/src/test/ui/consts/const-eval/valid-const.rs
index 30bd47219239e..65c642d750b51 100644
--- a/src/test/ui/consts/const-eval/valid-const.rs
+++ b/src/test/ui/consts/const-eval/valid-const.rs
@@ -1,7 +1,8 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 // Some constants that *are* valid
 #![feature(const_transmute)]
+#![deny(const_err)]
 
 use std::mem;
 use std::ptr::NonNull;

From e7fed140a4db638562077afc0ec5ef174a25bcc0 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Fri, 30 Aug 2019 09:31:21 +0200
Subject: [PATCH 344/943] explain why REF_AS_USIZE is important

---
 src/test/ui/consts/const-eval/ub-ref.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/test/ui/consts/const-eval/ub-ref.rs b/src/test/ui/consts/const-eval/ub-ref.rs
index bbab85c2121a5..03ac12c8b1ac1 100644
--- a/src/test/ui/consts/const-eval/ub-ref.rs
+++ b/src/test/ui/consts/const-eval/ub-ref.rs
@@ -11,6 +11,9 @@ const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
 const NULL: &u16 = unsafe { mem::transmute(0usize) };
 //~^ ERROR it is undefined behavior to use this value
 
+// It is very important that we reject this: We do promote `&(4 * REF_AS_USIZE)`,
+// but that would fail to compile; so we ended up breaking user code that would
+// have worked fine had we not promoted.
 const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
 //~^ ERROR it is undefined behavior to use this value
 

From 6d86163ffb0209aca8bf097c07304291e0f10a28 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Fri, 30 Aug 2019 09:35:02 +0200
Subject: [PATCH 345/943] const-eval tests: make all unions repr(C)

---
 .../const-pointer-values-in-various-types.rs  |  1 +
 ...nst-pointer-values-in-various-types.stderr | 58 +++++++++----------
 .../ui/consts/const-eval/const_transmute.rs   |  1 +
 src/test/ui/consts/const-eval/double_check.rs |  1 +
 .../ui/consts/const-eval/double_check2.rs     |  1 +
 .../ui/consts/const-eval/double_check2.stderr |  2 +-
 .../const-eval/feature-gate-const_fn_union.rs |  1 +
 .../feature-gate-const_fn_union.stderr        |  2 +-
 src/test/ui/consts/const-eval/issue-49296.rs  |  1 +
 .../ui/consts/const-eval/issue-49296.stderr   |  2 +-
 .../const-eval/promoted_const_fn_fail.rs      |  1 +
 .../const-eval/promoted_const_fn_fail.stderr  |  2 +-
 .../promoted_const_fn_fail_deny_const_err.rs  |  1 +
 ...omoted_const_fn_fail_deny_const_err.stderr |  2 +-
 .../ui/consts/const-eval/ref_to_int_match.rs  |  1 +
 .../consts/const-eval/ref_to_int_match.stderr |  2 +-
 src/test/ui/consts/const-eval/ub-enum.rs      |  3 +
 src/test/ui/consts/const-eval/ub-enum.stderr  | 18 +++---
 src/test/ui/consts/const-eval/ub-nonnull.rs   |  1 +
 .../ui/consts/const-eval/ub-nonnull.stderr    |  6 +-
 src/test/ui/consts/const-eval/ub-ref.stderr   |  6 +-
 src/test/ui/consts/const-eval/ub-uninhabit.rs |  1 +
 .../ui/consts/const-eval/ub-uninhabit.stderr  |  6 +-
 .../const-eval/union-const-eval-field.rs      |  1 +
 .../const-eval/union-const-eval-field.stderr  |  2 +-
 src/test/ui/consts/const-eval/union-ice.rs    |  1 +
 .../ui/consts/const-eval/union-ice.stderr     |  6 +-
 src/test/ui/consts/const-eval/union-ub.rs     |  3 +
 src/test/ui/consts/const-eval/union-ub.stderr |  2 +-
 .../ui/consts/const-eval/union_promotion.rs   |  1 +
 .../consts/const-eval/union_promotion.stderr  |  2 +-
 31 files changed, 79 insertions(+), 59 deletions(-)

diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs
index cc5ddb4401644..a2196db780ce0 100644
--- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs
+++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.rs
@@ -1,5 +1,6 @@
 // only-x86_64
 
+#[repr(C)]
 union Nonsense {
     u: usize,
     int_32_ref: &'static i32,
diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr
index 73aca911531f1..3333ffac4c9b0 100644
--- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr
+++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/const-pointer-values-in-various-types.rs:24:5
+  --> $DIR/const-pointer-values-in-various-types.rs:25:5
    |
 LL |     const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
@@ -7,7 +7,7 @@ LL |     const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:27:43
+  --> $DIR/const-pointer-values-in-various-types.rs:28:43
    |
 LL |     const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 };
    |     --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -17,7 +17,7 @@ LL |     const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_
    = note: `#[deny(const_err)]` on by default
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:30:45
+  --> $DIR/const-pointer-values-in-various-types.rs:31:45
    |
 LL |     const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 };
    |     ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -25,7 +25,7 @@ LL |     const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uin
    |                                             a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:33:45
+  --> $DIR/const-pointer-values-in-various-types.rs:34:45
    |
 LL |     const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 };
    |     ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -33,7 +33,7 @@ LL |     const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uin
    |                                             a raw memory access tried to access part of a pointer value as raw bytes
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/const-pointer-values-in-various-types.rs:36:5
+  --> $DIR/const-pointer-values-in-various-types.rs:37:5
    |
 LL |     const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
@@ -41,7 +41,7 @@ LL |     const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uin
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/const-pointer-values-in-various-types.rs:39:5
+  --> $DIR/const-pointer-values-in-various-types.rs:40:5
    |
 LL |     const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
@@ -49,7 +49,7 @@ LL |     const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.u
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:42:43
+  --> $DIR/const-pointer-values-in-various-types.rs:43:43
    |
 LL |     const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
    |     --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -57,7 +57,7 @@ LL |     const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8
    |                                           a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:45:45
+  --> $DIR/const-pointer-values-in-various-types.rs:46:45
    |
 LL |     const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
    |     ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -65,7 +65,7 @@ LL |     const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int
    |                                             a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:48:45
+  --> $DIR/const-pointer-values-in-various-types.rs:49:45
    |
 LL |     const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
    |     ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -73,7 +73,7 @@ LL |     const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int
    |                                             a raw memory access tried to access part of a pointer value as raw bytes
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/const-pointer-values-in-various-types.rs:51:5
+  --> $DIR/const-pointer-values-in-various-types.rs:52:5
    |
 LL |     const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
@@ -81,7 +81,7 @@ LL |     const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/const-pointer-values-in-various-types.rs:54:5
+  --> $DIR/const-pointer-values-in-various-types.rs:55:5
    |
 LL |     const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
@@ -89,7 +89,7 @@ LL |     const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.i
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:57:45
+  --> $DIR/const-pointer-values-in-various-types.rs:58:45
    |
 LL |     const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
    |     ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -97,7 +97,7 @@ LL |     const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.flo
    |                                             a raw memory access tried to access part of a pointer value as raw bytes
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/const-pointer-values-in-various-types.rs:60:5
+  --> $DIR/const-pointer-values-in-various-types.rs:61:5
    |
 LL |     const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
@@ -105,7 +105,7 @@ LL |     const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.flo
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:63:47
+  --> $DIR/const-pointer-values-in-various-types.rs:64:47
    |
 LL |     const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
    |     ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -113,7 +113,7 @@ LL |     const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.t
    |                                               a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:66:47
+  --> $DIR/const-pointer-values-in-various-types.rs:67:47
    |
 LL |     const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
    |     ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -121,7 +121,7 @@ LL |     const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.c
    |                                               a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:69:39
+  --> $DIR/const-pointer-values-in-various-types.rs:70:39
    |
 LL |     const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
    |     ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -129,7 +129,7 @@ LL |     const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
    |                                       a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:72:41
+  --> $DIR/const-pointer-values-in-various-types.rs:73:41
    |
 LL |     const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
    |     ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -137,7 +137,7 @@ LL |     const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }
    |                                         a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:75:41
+  --> $DIR/const-pointer-values-in-various-types.rs:76:41
    |
 LL |     const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
    |     ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -145,7 +145,7 @@ LL |     const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }
    |                                         a raw memory access tried to access part of a pointer value as raw bytes
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/const-pointer-values-in-various-types.rs:78:5
+  --> $DIR/const-pointer-values-in-various-types.rs:79:5
    |
 LL |     const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
@@ -153,7 +153,7 @@ LL |     const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:81:43
+  --> $DIR/const-pointer-values-in-various-types.rs:82:43
    |
 LL |     const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
    |     --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -161,7 +161,7 @@ LL |     const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_12
    |                                           a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:84:39
+  --> $DIR/const-pointer-values-in-various-types.rs:85:39
    |
 LL |     const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
    |     ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -169,7 +169,7 @@ LL |     const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
    |                                       a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:87:41
+  --> $DIR/const-pointer-values-in-various-types.rs:88:41
    |
 LL |     const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
    |     ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -177,7 +177,7 @@ LL |     const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
    |                                         a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:90:41
+  --> $DIR/const-pointer-values-in-various-types.rs:91:41
    |
 LL |     const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
    |     ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -185,7 +185,7 @@ LL |     const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
    |                                         a raw memory access tried to access part of a pointer value as raw bytes
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/const-pointer-values-in-various-types.rs:93:5
+  --> $DIR/const-pointer-values-in-various-types.rs:94:5
    |
 LL |     const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
@@ -193,7 +193,7 @@ LL |     const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:96:43
+  --> $DIR/const-pointer-values-in-various-types.rs:97:43
    |
 LL |     const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
    |     --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -201,7 +201,7 @@ LL |     const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128
    |                                           a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:99:41
+  --> $DIR/const-pointer-values-in-various-types.rs:100:41
    |
 LL |     const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
    |     ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -209,7 +209,7 @@ LL |     const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32
    |                                         a raw memory access tried to access part of a pointer value as raw bytes
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/const-pointer-values-in-various-types.rs:102:5
+  --> $DIR/const-pointer-values-in-various-types.rs:103:5
    |
 LL |     const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
@@ -217,7 +217,7 @@ LL |     const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:105:43
+  --> $DIR/const-pointer-values-in-various-types.rs:106:43
    |
 LL |     const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
    |     --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
@@ -225,7 +225,7 @@ LL |     const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_
    |                                           a raw memory access tried to access part of a pointer value as raw bytes
 
 error: any use of this value will cause an error
-  --> $DIR/const-pointer-values-in-various-types.rs:108:43
+  --> $DIR/const-pointer-values-in-various-types.rs:109:43
    |
 LL |     const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };
    |     --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
diff --git a/src/test/ui/consts/const-eval/const_transmute.rs b/src/test/ui/consts/const-eval/const_transmute.rs
index 0e0e003dcf476..4a7d8490ef25f 100644
--- a/src/test/ui/consts/const-eval/const_transmute.rs
+++ b/src/test/ui/consts/const-eval/const_transmute.rs
@@ -2,6 +2,7 @@
 
 #![feature(const_fn_union)]
 
+#[repr(C)]
 union Transmute<T: Copy, U: Copy> {
     t: T,
     u: U,
diff --git a/src/test/ui/consts/const-eval/double_check.rs b/src/test/ui/consts/const-eval/double_check.rs
index 2cf6a5494dd8d..ff2fff7fb790e 100644
--- a/src/test/ui/consts/const-eval/double_check.rs
+++ b/src/test/ui/consts/const-eval/double_check.rs
@@ -8,6 +8,7 @@ enum Bar {
     C = 42,
     D = 99,
 }
+#[repr(C)]
 union Union {
     foo: &'static Foo,
     bar: &'static Bar,
diff --git a/src/test/ui/consts/const-eval/double_check2.rs b/src/test/ui/consts/const-eval/double_check2.rs
index dc2b58faf9215..7c222b113cd7d 100644
--- a/src/test/ui/consts/const-eval/double_check2.rs
+++ b/src/test/ui/consts/const-eval/double_check2.rs
@@ -6,6 +6,7 @@ enum Bar {
     C = 42,
     D = 99,
 }
+#[repr(C)]
 union Union {
     foo: &'static Foo,
     bar: &'static Bar,
diff --git a/src/test/ui/consts/const-eval/double_check2.stderr b/src/test/ui/consts/const-eval/double_check2.stderr
index 2b61d33852c98..9c56f1995208f 100644
--- a/src/test/ui/consts/const-eval/double_check2.stderr
+++ b/src/test/ui/consts/const-eval/double_check2.stderr
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/double_check2.rs:15:1
+  --> $DIR/double_check2.rs:16:1
    |
 LL | / static FOO: (&Foo, &Bar) = unsafe {(
 LL | |     Union { u8: &BAR }.foo,
diff --git a/src/test/ui/consts/const-eval/feature-gate-const_fn_union.rs b/src/test/ui/consts/const-eval/feature-gate-const_fn_union.rs
index b0ae746ace58d..3f7bab065869a 100644
--- a/src/test/ui/consts/const-eval/feature-gate-const_fn_union.rs
+++ b/src/test/ui/consts/const-eval/feature-gate-const_fn_union.rs
@@ -2,6 +2,7 @@
 
 fn main() {}
 
+#[repr(C)]
 union Foo {
     u: u32,
     i: i32,
diff --git a/src/test/ui/consts/const-eval/feature-gate-const_fn_union.stderr b/src/test/ui/consts/const-eval/feature-gate-const_fn_union.stderr
index 5bf43cb8b6add..6899b7b82c532 100644
--- a/src/test/ui/consts/const-eval/feature-gate-const_fn_union.stderr
+++ b/src/test/ui/consts/const-eval/feature-gate-const_fn_union.stderr
@@ -1,5 +1,5 @@
 error[E0658]: unions in const fn are unstable
-  --> $DIR/feature-gate-const_fn_union.rs:11:5
+  --> $DIR/feature-gate-const_fn_union.rs:12:5
    |
 LL |     Foo { u }.i
    |     ^^^^^^^^^^^
diff --git a/src/test/ui/consts/const-eval/issue-49296.rs b/src/test/ui/consts/const-eval/issue-49296.rs
index a7c3c5318d430..c6caeeffd22dd 100644
--- a/src/test/ui/consts/const-eval/issue-49296.rs
+++ b/src/test/ui/consts/const-eval/issue-49296.rs
@@ -4,6 +4,7 @@
 #![feature(const_fn_union)]
 
 const unsafe fn transmute<T: Copy, U: Copy>(t: T) -> U {
+    #[repr(C)]
     union Transmute<T: Copy, U: Copy> {
         from: T,
         to: U,
diff --git a/src/test/ui/consts/const-eval/issue-49296.stderr b/src/test/ui/consts/const-eval/issue-49296.stderr
index 7a4bba8daa70b..48809e0ae649c 100644
--- a/src/test/ui/consts/const-eval/issue-49296.stderr
+++ b/src/test/ui/consts/const-eval/issue-49296.stderr
@@ -1,5 +1,5 @@
 error: any use of this value will cause an error
-  --> $DIR/issue-49296.rs:18:16
+  --> $DIR/issue-49296.rs:19:16
    |
 LL | const X: u64 = *wat(42);
    | ---------------^^^^^^^^-
diff --git a/src/test/ui/consts/const-eval/promoted_const_fn_fail.rs b/src/test/ui/consts/const-eval/promoted_const_fn_fail.rs
index 88181cb86100f..3edd4e086867b 100644
--- a/src/test/ui/consts/const-eval/promoted_const_fn_fail.rs
+++ b/src/test/ui/consts/const-eval/promoted_const_fn_fail.rs
@@ -2,6 +2,7 @@
 
 #![allow(const_err)]
 
+#[repr(C)]
 union Bar {
     a: &'static u8,
     b: usize,
diff --git a/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr b/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr
index 519ba7d84b087..6618f1cd1c0b5 100644
--- a/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr
+++ b/src/test/ui/consts/const-eval/promoted_const_fn_fail.stderr
@@ -1,5 +1,5 @@
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_fn_fail.rs:20:27
+  --> $DIR/promoted_const_fn_fail.rs:21:27
    |
 LL |     let x: &'static u8 = &(bar() + 1);
    |            -----------    ^^^^^^^^^^^ creates a temporary which is freed while still in use
diff --git a/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs b/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs
index 061ab7eeb029d..7887e42653464 100644
--- a/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs
+++ b/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs
@@ -2,6 +2,7 @@
 
 #![deny(const_err)]
 
+#[repr(C)]
 union Bar {
     a: &'static u8,
     b: usize,
diff --git a/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr b/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr
index 987d2304ae871..5f9f3bda87b15 100644
--- a/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr
+++ b/src/test/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr
@@ -1,5 +1,5 @@
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_fn_fail_deny_const_err.rs:21:27
+  --> $DIR/promoted_const_fn_fail_deny_const_err.rs:22:27
    |
 LL |     let x: &'static u8 = &(bar() + 1);
    |            -----------    ^^^^^^^^^^^ creates a temporary which is freed while still in use
diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.rs b/src/test/ui/consts/const-eval/ref_to_int_match.rs
index b6a2ed1f9bcf4..45ce040fb9eef 100644
--- a/src/test/ui/consts/const-eval/ref_to_int_match.rs
+++ b/src/test/ui/consts/const-eval/ref_to_int_match.rs
@@ -9,6 +9,7 @@ fn main() {
     }
 }
 
+#[repr(C)]
 union Foo {
     f: Int,
     r: &'static u32,
diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.stderr
index f8eafed68e43d..0be82e3434142 100644
--- a/src/test/ui/consts/const-eval/ref_to_int_match.stderr
+++ b/src/test/ui/consts/const-eval/ref_to_int_match.stderr
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ref_to_int_match.rs:23:1
+  --> $DIR/ref_to_int_match.rs:24:1
    |
 LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
diff --git a/src/test/ui/consts/const-eval/ub-enum.rs b/src/test/ui/consts/const-eval/ub-enum.rs
index d4b2220695102..483285aa4e123 100644
--- a/src/test/ui/consts/const-eval/ub-enum.rs
+++ b/src/test/ui/consts/const-eval/ub-enum.rs
@@ -10,6 +10,7 @@ struct Wrap<T>(T);
 enum Enum {
     A = 0,
 }
+#[repr(C)]
 union TransmuteEnum {
     in1: &'static u8,
     in2: usize,
@@ -35,6 +36,7 @@ enum Enum2 {
     A = 2,
 }
 
+#[repr(C)]
 union TransmuteEnum2 {
     in1: usize,
     in2: &'static u8,
@@ -60,6 +62,7 @@ const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.
 
 // Invalid enum field content (mostly to test printing of paths for enum tuple
 // variants and tuples).
+#[repr(C)]
 union TransmuteChar {
     a: u32,
     b: char,
diff --git a/src/test/ui/consts/const-eval/ub-enum.stderr b/src/test/ui/consts/const-eval/ub-enum.stderr
index 8ecb1aabdd0f7..30dd86592d469 100644
--- a/src/test/ui/consts/const-eval/ub-enum.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum.stderr
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:22:1
+  --> $DIR/ub-enum.rs:23:1
    |
 LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in2: 1 }.out1 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 1, but expected a valid enum discriminant
@@ -7,7 +7,7 @@ LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in2: 1 }.out1 };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:25:1
+  --> $DIR/ub-enum.rs:26:1
    |
 LL | const BAD_ENUM_PTR: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
@@ -15,7 +15,7 @@ LL | const BAD_ENUM_PTR: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:28:1
+  --> $DIR/ub-enum.rs:29:1
    |
 LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { TransmuteEnum { in1: &1 }.out2 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be equal to 0
@@ -23,7 +23,7 @@ LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { TransmuteEnum { in1: &1 }.out
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:46:1
+  --> $DIR/ub-enum.rs:48:1
    |
 LL | const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected a valid enum discriminant
@@ -31,7 +31,7 @@ LL | const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:48:1
+  --> $DIR/ub-enum.rs:50:1
    |
 LL | const BAD_ENUM2_PTR: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
@@ -39,7 +39,7 @@ LL | const BAD_ENUM2_PTR: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:50:1
+  --> $DIR/ub-enum.rs:52:1
    |
 LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be equal to 2
@@ -47,7 +47,7 @@ LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:54:1
+  --> $DIR/ub-enum.rs:56:1
    |
 LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid enum discriminant
@@ -55,7 +55,7 @@ LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:58:1
+  --> $DIR/ub-enum.rs:60:1
    |
 LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
@@ -63,7 +63,7 @@ LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2:
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-enum.rs:68:1
+  --> $DIR/ub-enum.rs:71:1
    |
 LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .<downcast-variant(Some)>.0.1, but expected something less or equal to 1114111
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.rs b/src/test/ui/consts/const-eval/ub-nonnull.rs
index 9edae1965ce16..8ce64ced7dff4 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.rs
+++ b/src/test/ui/consts/const-eval/ub-nonnull.rs
@@ -24,6 +24,7 @@ const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
 const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
 //~^ ERROR it is undefined behavior to use this value
 
+#[repr(C)]
 union Transmute {
     uninit: (),
     out: NonZeroU8,
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr
index 7b3c97e5fbf96..de20c3d0b8cfe 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.stderr
+++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr
@@ -41,7 +41,7 @@ LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:31:1
+  --> $DIR/ub-nonnull.rs:32:1
    |
 LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected something greater or equal to 1
@@ -49,7 +49,7 @@ LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:39:1
+  --> $DIR/ub-nonnull.rs:40:1
    |
 LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30
@@ -57,7 +57,7 @@ LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-nonnull.rs:45:1
+  --> $DIR/ub-nonnull.rs:46:1
    |
 LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 20, but expected something less or equal to 10, or greater or equal to 30
diff --git a/src/test/ui/consts/const-eval/ub-ref.stderr b/src/test/ui/consts/const-eval/ub-ref.stderr
index f1702955ed7b1..cd3cc38467c36 100644
--- a/src/test/ui/consts/const-eval/ub-ref.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref.stderr
@@ -15,7 +15,7 @@ LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-ref.rs:14:1
+  --> $DIR/ub-ref.rs:17:1
    |
 LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
@@ -23,7 +23,7 @@ LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-ref.rs:17:1
+  --> $DIR/ub-ref.rs:20:1
    |
 LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<deref>, but expected plain (non-pointer) bytes
@@ -31,7 +31,7 @@ LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-ref.rs:20:1
+  --> $DIR/ub-ref.rs:23:1
    |
 LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (created from integer)
diff --git a/src/test/ui/consts/const-eval/ub-uninhabit.rs b/src/test/ui/consts/const-eval/ub-uninhabit.rs
index 42cba02f579b7..d2745d71bdb2f 100644
--- a/src/test/ui/consts/const-eval/ub-uninhabit.rs
+++ b/src/test/ui/consts/const-eval/ub-uninhabit.rs
@@ -6,6 +6,7 @@ use std::mem;
 #[derive(Copy, Clone)]
 enum Bar {}
 
+#[repr(C)]
 union TransmuteUnion<A: Clone + Copy, B: Clone + Copy> {
     a: A,
     b: B,
diff --git a/src/test/ui/consts/const-eval/ub-uninhabit.stderr b/src/test/ui/consts/const-eval/ub-uninhabit.stderr
index c8842ecc23ca2..43d91483797bf 100644
--- a/src/test/ui/consts/const-eval/ub-uninhabit.stderr
+++ b/src/test/ui/consts/const-eval/ub-uninhabit.stderr
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-uninhabit.rs:14:1
+  --> $DIR/ub-uninhabit.rs:15:1
    |
 LL | const BAD_BAD_BAD: Bar = unsafe { (TransmuteUnion::<(), Bar> { a: () }).b };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type
@@ -7,7 +7,7 @@ LL | const BAD_BAD_BAD: Bar = unsafe { (TransmuteUnion::<(), Bar> { a: () }).b }
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-uninhabit.rs:17:1
+  --> $DIR/ub-uninhabit.rs:18:1
    |
 LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at .<deref>
@@ -15,7 +15,7 @@ LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/ub-uninhabit.rs:20:1
+  --> $DIR/ub-uninhabit.rs:21:1
    |
 LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { (TransmuteUnion::<(), [Bar; 1]> { a: () }).b };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type
diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.rs b/src/test/ui/consts/const-eval/union-const-eval-field.rs
index 56f3ef3db25d1..7f29a5bc24e4e 100644
--- a/src/test/ui/consts/const-eval/union-const-eval-field.rs
+++ b/src/test/ui/consts/const-eval/union-const-eval-field.rs
@@ -4,6 +4,7 @@ type Field1 = i32;
 type Field2 = f32;
 type Field3 = i64;
 
+#[repr(C)]
 union DummyUnion {
     field1: Field1,
     field2: Field2,
diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.stderr
index 4a53337341e67..4d008a0e02ad7 100644
--- a/src/test/ui/consts/const-eval/union-const-eval-field.stderr
+++ b/src/test/ui/consts/const-eval/union-const-eval-field.stderr
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-const-eval-field.rs:27:5
+  --> $DIR/union-const-eval-field.rs:28:5
    |
 LL |     const FIELD3: Field3 = unsafe { UNION.field3 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
diff --git a/src/test/ui/consts/const-eval/union-ice.rs b/src/test/ui/consts/const-eval/union-ice.rs
index 33736b360d33a..5a14c7fd99345 100644
--- a/src/test/ui/consts/const-eval/union-ice.rs
+++ b/src/test/ui/consts/const-eval/union-ice.rs
@@ -3,6 +3,7 @@
 type Field1 = i32;
 type Field3 = i64;
 
+#[repr(C)]
 union DummyUnion {
     field1: Field1,
     field3: Field3,
diff --git a/src/test/ui/consts/const-eval/union-ice.stderr b/src/test/ui/consts/const-eval/union-ice.stderr
index b25cb8c5aa021..8d950e86d27fc 100644
--- a/src/test/ui/consts/const-eval/union-ice.stderr
+++ b/src/test/ui/consts/const-eval/union-ice.stderr
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ice.rs:13:1
+  --> $DIR/union-ice.rs:14:1
    |
 LL | const FIELD3: Field3 = unsafe { UNION.field3 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
@@ -7,7 +7,7 @@ LL | const FIELD3: Field3 = unsafe { UNION.field3 };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ice.rs:15:1
+  --> $DIR/union-ice.rs:16:1
    |
 LL | / const FIELD_PATH: Struct = Struct {
 LL | |     a: 42,
@@ -18,7 +18,7 @@ LL | | };
    = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
 
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ice.rs:25:1
+  --> $DIR/union-ice.rs:26:1
    |
 LL | / const FIELD_PATH2: Struct2 = Struct2 {
 LL | |     b: [
diff --git a/src/test/ui/consts/const-eval/union-ub.rs b/src/test/ui/consts/const-eval/union-ub.rs
index cf436141c5a02..848826e6ef7f2 100644
--- a/src/test/ui/consts/const-eval/union-ub.rs
+++ b/src/test/ui/consts/const-eval/union-ub.rs
@@ -1,5 +1,6 @@
 #![allow(const_err)] // make sure we cannot allow away the errors tested here
 
+#[repr(C)]
 union DummyUnion {
     u8: u8,
     bool: bool,
@@ -14,11 +15,13 @@ enum Enum {
 }
 
 #[derive(Copy, Clone)]
+#[repr(C)]
 union Foo {
     a: bool,
     b: Enum,
 }
 
+#[repr(C)]
 union Bar {
     foo: Foo,
     u8: u8,
diff --git a/src/test/ui/consts/const-eval/union-ub.stderr b/src/test/ui/consts/const-eval/union-ub.stderr
index 7baa55be6e11e..6a3a397585c89 100644
--- a/src/test/ui/consts/const-eval/union-ub.stderr
+++ b/src/test/ui/consts/const-eval/union-ub.stderr
@@ -1,5 +1,5 @@
 error[E0080]: it is undefined behavior to use this value
-  --> $DIR/union-ub.rs:28:1
+  --> $DIR/union-ub.rs:31:1
    |
 LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something less or equal to 1
diff --git a/src/test/ui/consts/const-eval/union_promotion.rs b/src/test/ui/consts/const-eval/union_promotion.rs
index d3566511ef8ee..7167f88a1185b 100644
--- a/src/test/ui/consts/const-eval/union_promotion.rs
+++ b/src/test/ui/consts/const-eval/union_promotion.rs
@@ -1,5 +1,6 @@
 #![allow(const_err)]
 
+#[repr(C)]
 union Foo {
     a: &'static u32,
     b: usize,
diff --git a/src/test/ui/consts/const-eval/union_promotion.stderr b/src/test/ui/consts/const-eval/union_promotion.stderr
index b530c02f2fb93..ed186e3ebd2f5 100644
--- a/src/test/ui/consts/const-eval/union_promotion.stderr
+++ b/src/test/ui/consts/const-eval/union_promotion.stderr
@@ -1,5 +1,5 @@
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/union_promotion.rs:9:29
+  --> $DIR/union_promotion.rs:10:29
    |
 LL |       let x: &'static bool = &unsafe {
    |  ____________-------------____^

From fdc4f9028f838605d031248abda0ebfb7450bf9f Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Wed, 28 Aug 2019 13:21:47 +0200
Subject: [PATCH 346/943] Add missing examples for Option type

---
 src/libcore/option.rs | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 259ed36c57885..79bd04b724390 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -1110,6 +1110,18 @@ impl<T: Deref> Option<T> {
     /// to the original one, additionally coercing the contents via [`Deref`].
     ///
     /// [`Deref`]: ../../std/ops/trait.Deref.html
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(inner_deref)]
+    ///
+    /// let x: Option<String> = Some("hey".to_owned());
+    /// assert_eq!(x.as_deref(), Some("hey"));
+    ///
+    /// let x: Option<String> = None;
+    /// assert_eq!(x.as_deref(), None);
+    /// ```
     pub fn as_deref(&self) -> Option<&T::Target> {
         self.as_ref().map(|t| t.deref())
     }
@@ -1121,6 +1133,18 @@ impl<T: DerefMut> Option<T> {
     ///
     /// Leaves the original `Option` in-place, creating a new one containing a mutable reference to
     /// the inner type's `Deref::Target` type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(inner_deref)]
+    ///
+    /// let mut x: Option<String> = Some("hey".to_owned());
+    /// assert_eq!(x.as_deref_mut().map(|x| {
+    ///     x.make_ascii_uppercase();
+    ///     x
+    /// }), Some("HEY".to_owned().as_mut_str()));
+    /// ```
     pub fn as_deref_mut(&mut self) -> Option<&mut T::Target> {
         self.as_mut().map(|t| t.deref_mut())
     }
@@ -1199,6 +1223,13 @@ impl<T: Clone> Clone for Option<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Default for Option<T> {
     /// Returns [`None`][Option::None].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// let opt: Option<u32> = Option::default();
+    /// assert!(opt.is_none());
+    /// ```
     #[inline]
     fn default() -> Option<T> { None }
 }

From 4240168edae7c4ec9c8bf78892cbf5316ad7b781 Mon Sep 17 00:00:00 2001
From: flip1995 <hello@philkrones.com>
Date: Fri, 30 Aug 2019 09:53:42 +0200
Subject: [PATCH 347/943] Update Clippy

---
 src/tools/clippy | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/clippy b/src/tools/clippy
index a939d61cf7fea..70e7d075df7b3 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit a939d61cf7feac0f328aec07f050c4ac96c51d2c
+Subproject commit 70e7d075df7b3e11e61fa99b30e1ede26cee6afd

From a8926a5e9c5becdf18acede5f7e114cd5f8655b6 Mon Sep 17 00:00:00 2001
From: Jonas Schievink <jonasschievink@gmail.com>
Date: Mon, 6 May 2019 13:47:58 +0200
Subject: [PATCH 348/943] Use `panic::set_hook` to print the ICE message

---
 Cargo.lock                             |   1 +
 src/librustc_driver/Cargo.toml         |   1 +
 src/librustc_driver/lib.rs             | 109 +++++++++++++++----------
 src/librustdoc/lib.rs                  |   2 +-
 src/test/ui-fulldeps/compiler-calls.rs |   2 +-
 5 files changed, 68 insertions(+), 47 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index ae641d6ae32b1..179bf59388a29 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3204,6 +3204,7 @@ version = "0.0.0"
 dependencies = [
  "env_logger 0.5.13",
  "graphviz",
+ "lazy_static 1.3.0",
  "log",
  "rustc",
  "rustc_ast_borrowck",
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index b030517e28ec2..8bd61c25843aa 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -11,6 +11,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 graphviz = { path = "../libgraphviz" }
+lazy_static = "1.0"
 log = "0.4"
 env_logger = { version = "0.5", default-features = false }
 rustc = { path = "../librustc" }
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index e3ea92dc8ab38..5b7ac14ba3585 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -21,6 +21,8 @@ pub extern crate getopts;
 extern crate libc;
 #[macro_use]
 extern crate log;
+#[macro_use]
+extern crate lazy_static;
 
 pub extern crate rustc_plugin_impl as plugin;
 
@@ -1143,61 +1145,77 @@ fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
     }
 }
 
-/// Runs a procedure which will detect panics in the compiler and print nicer
-/// error messages rather than just failing the test.
+/// Runs a closure and catches unwinds triggered by fatal errors.
 ///
-/// The diagnostic emitter yielded to the procedure should be used for reporting
-/// errors of the compiler.
-pub fn report_ices_to_stderr_if_any<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorReported> {
+/// The compiler currently panics with a special sentinel value to abort
+/// compilation on fatal errors. This function catches that sentinel and turns
+/// the panic into a `Result` instead.
+pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorReported> {
     catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| {
         if value.is::<errors::FatalErrorMarker>() {
             ErrorReported
         } else {
-            // Thread panicked without emitting a fatal diagnostic
-            eprintln!("");
-
-            let emitter = Box::new(errors::emitter::EmitterWriter::stderr(
-                errors::ColorConfig::Auto,
-                None,
-                false,
-                false,
-                None,
-            ));
-            let handler = errors::Handler::with_emitter(true, None, emitter);
-
-            // a .span_bug or .bug call has already printed what
-            // it wants to print.
-            if !value.is::<errors::ExplicitBug>() {
-                handler.emit(&MultiSpan::new(),
-                             "unexpected panic",
-                             errors::Level::Bug);
-            }
+            panic::resume_unwind(value);
+        }
+    })
+}
 
-            let mut xs: Vec<Cow<'static, str>> = vec![
-                "the compiler unexpectedly panicked. this is a bug.".into(),
-                format!("we would appreciate a bug report: {}", BUG_REPORT_URL).into(),
-                format!("rustc {} running on {}",
-                        option_env!("CFG_VERSION").unwrap_or("unknown_version"),
-                        config::host_triple()).into(),
-            ];
+lazy_static! {
+    static ref DEFAULT_HOOK: Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static> = {
+        let hook = panic::take_hook();
+        panic::set_hook(Box::new(report_ice));
+        hook
+    };
+}
 
-            if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() {
-                xs.push(format!("compiler flags: {}", flags.join(" ")).into());
+pub fn report_ice(info: &panic::PanicInfo<'_>) {
+    (*DEFAULT_HOOK)(info);
+
+    // Thread panicked without emitting a fatal diagnostic
+    eprintln!();
+
+    let emitter = Box::new(errors::emitter::EmitterWriter::stderr(
+        errors::ColorConfig::Auto,
+        None,
+        false,
+        false,
+        None,
+    ));
+    let handler = errors::Handler::with_emitter(true, None, emitter);
+
+    // a .span_bug or .bug call has already printed what
+    // it wants to print.
+    if !info.payload().is::<errors::ExplicitBug>() {
+        handler.emit(&MultiSpan::new(),
+                     "unexpected panic",
+                     errors::Level::Bug);
+    }
 
-                if excluded_cargo_defaults {
-                    xs.push("some of the compiler flags provided by cargo are hidden".into());
-                }
-            }
+    let mut xs: Vec<Cow<'static, str>> = vec![
+        "the compiler unexpectedly panicked. this is a bug.".into(),
+        format!("we would appreciate a bug report: {}", BUG_REPORT_URL).into(),
+        format!("rustc {} running on {}",
+                option_env!("CFG_VERSION").unwrap_or("unknown_version"),
+                config::host_triple()).into(),
+    ];
 
-            for note in &xs {
-                handler.emit(&MultiSpan::new(),
-                             note,
-                             errors::Level::Note);
-            }
+    if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() {
+        xs.push(format!("compiler flags: {}", flags.join(" ")).into());
 
-            panic::resume_unwind(Box::new(errors::FatalErrorMarker));
+        if excluded_cargo_defaults {
+            xs.push("some of the compiler flags provided by cargo are hidden".into());
         }
-    })
+    }
+
+    for note in &xs {
+        handler.emit(&MultiSpan::new(),
+                     note,
+                     errors::Level::Note);
+    }
+}
+
+pub fn install_ice_hook() {
+    lazy_static::initialize(&DEFAULT_HOOK);
 }
 
 /// This allows tools to enable rust logging without having to magically match rustc's
@@ -1210,7 +1228,8 @@ pub fn main() {
     let start = Instant::now();
     init_rustc_env_logger();
     let mut callbacks = TimePassesCallbacks::default();
-    let result = report_ices_to_stderr_if_any(|| {
+    install_ice_hook();
+    let result = catch_fatal_errors(|| {
         let args = env::args_os().enumerate()
             .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| {
                     early_error(ErrorOutputType::default(),
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 87dac0f226896..0b366da29d37e 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -453,7 +453,7 @@ where R: 'static + Send,
     // First, parse the crate and extract all relevant information.
     info!("starting to run rustc");
 
-    let result = rustc_driver::report_ices_to_stderr_if_any(move || {
+    let result = rustc_driver::catch_fatal_errors(move || {
         let crate_name = options.crate_name.clone();
         let crate_version = options.crate_version.clone();
         let (mut krate, renderinfo, renderopts) = core::run_core(options);
diff --git a/src/test/ui-fulldeps/compiler-calls.rs b/src/test/ui-fulldeps/compiler-calls.rs
index ea24f5809d52a..bd9113c7079ea 100644
--- a/src/test/ui-fulldeps/compiler-calls.rs
+++ b/src/test/ui-fulldeps/compiler-calls.rs
@@ -24,7 +24,7 @@ impl rustc_driver::Callbacks for TestCalls<'_> {
 fn main() {
     let mut count = 1;
     let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()];
-    rustc_driver::report_ices_to_stderr_if_any(|| {
+    rustc_driver::catch_fatal_errors(|| {
         rustc_driver::run_compiler(&args, &mut TestCalls { count: &mut count }, None, None).ok();
     }).ok();
     assert_eq!(count, 2);

From e296ed321e37dc5ba21536a1f4b277b5536f6838 Mon Sep 17 00:00:00 2001
From: Jonas Schievink <jonasschievink@gmail.com>
Date: Tue, 7 May 2019 00:14:40 +0200
Subject: [PATCH 349/943] Move librustc panic handler into the new one

---
 src/librustc/Cargo.toml     |  1 -
 src/librustc/lib.rs         |  1 -
 src/librustc/util/common.rs | 37 -------------------------------------
 src/librustc_driver/lib.rs  | 27 ++++++++++++++++++++++-----
 4 files changed, 22 insertions(+), 44 deletions(-)

diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index 0222a3dde7ab9..4ab982f6f91f5 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -15,7 +15,6 @@ bitflags = "1.0"
 fmt_macros = { path = "../libfmt_macros" }
 graphviz = { path = "../libgraphviz" }
 jobserver = "0.1"
-lazy_static = "1.0.0"
 num_cpus = "1.0"
 scoped-tls = "1.0"
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 368f5bb64fe6c..c2befabcb69b3 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -68,7 +68,6 @@
 
 #[macro_use] extern crate bitflags;
 extern crate getopts;
-#[macro_use] extern crate lazy_static;
 #[macro_use] extern crate scoped_tls;
 #[cfg(windows)]
 extern crate libc;
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index 7118d05204c3b..2475b93d95f32 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -5,17 +5,13 @@ use rustc_data_structures::{fx::FxHashMap, sync::Lock};
 use std::cell::{RefCell, Cell};
 use std::fmt::Debug;
 use std::hash::Hash;
-use std::panic;
-use std::env;
 use std::time::{Duration, Instant};
 
 use std::sync::mpsc::{Sender};
 use syntax_pos::{SpanData};
 use syntax::symbol::{Symbol, sym};
 use rustc_macros::HashStable;
-use crate::ty::TyCtxt;
 use crate::dep_graph::{DepNode};
-use lazy_static;
 use crate::session::Session;
 
 #[cfg(test)]
@@ -31,39 +27,6 @@ pub struct ErrorReported;
 
 thread_local!(static TIME_DEPTH: Cell<usize> = Cell::new(0));
 
-lazy_static! {
-    static ref DEFAULT_HOOK: Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static> = {
-        let hook = panic::take_hook();
-        panic::set_hook(Box::new(panic_hook));
-        hook
-    };
-}
-
-fn panic_hook(info: &panic::PanicInfo<'_>) {
-    (*DEFAULT_HOOK)(info);
-
-    let backtrace = env::var_os("RUST_BACKTRACE").map(|x| &x != "0").unwrap_or(false);
-
-    if backtrace {
-        TyCtxt::try_print_query_stack();
-    }
-
-    #[cfg(windows)]
-    unsafe {
-        if env::var("RUSTC_BREAK_ON_ICE").is_ok() {
-            extern "system" {
-                fn DebugBreak();
-            }
-            // Trigger a debugger if we crashed during bootstrap.
-            DebugBreak();
-        }
-    }
-}
-
-pub fn install_panic_hook() {
-    lazy_static::initialize(&DEFAULT_HOOK);
-}
-
 /// Parameters to the `Dump` variant of type `ProfileQueriesMsg`.
 #[derive(Clone,Debug)]
 pub struct ProfQDumpParams {
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 5b7ac14ba3585..ece82233e9951 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -38,8 +38,8 @@ use rustc::session::{early_error, early_warn};
 use rustc::lint::Lint;
 use rustc::lint;
 use rustc::hir::def_id::LOCAL_CRATE;
-use rustc::util::common::{ErrorReported, install_panic_hook, print_time_passes_entry};
-use rustc::util::common::{set_time_depth, time};
+use rustc::ty::TyCtxt;
+use rustc::util::common::{set_time_depth, time, print_time_passes_entry, ErrorReported};
 use rustc_metadata::locator;
 use rustc_metadata::cstore::CStore;
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
@@ -164,8 +164,6 @@ pub fn run_compiler(
         None => return Ok(()),
     };
 
-    install_panic_hook();
-
     let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
 
     let mut dummy_config = |sopts, cfg, diagnostic_output| {
@@ -1169,9 +1167,10 @@ lazy_static! {
 }
 
 pub fn report_ice(info: &panic::PanicInfo<'_>) {
+    // Invoke the default handler, which prints the actual panic message and optionally a backtrace
     (*DEFAULT_HOOK)(info);
 
-    // Thread panicked without emitting a fatal diagnostic
+    // Print the infamous ICE message
     eprintln!();
 
     let emitter = Box::new(errors::emitter::EmitterWriter::stderr(
@@ -1212,6 +1211,24 @@ pub fn report_ice(info: &panic::PanicInfo<'_>) {
                      note,
                      errors::Level::Note);
     }
+
+    // If backtraces are enabled, also print the query stack
+    let backtrace = env::var_os("RUST_BACKTRACE").map(|x| &x != "0").unwrap_or(false);
+
+    if backtrace {
+        TyCtxt::try_print_query_stack();
+    }
+
+    #[cfg(windows)]
+    unsafe {
+        if env::var("RUSTC_BREAK_ON_ICE").is_ok() {
+            extern "system" {
+                fn DebugBreak();
+            }
+            // Trigger a debugger if we crashed during bootstrap
+            DebugBreak();
+        }
+    }
 }
 
 pub fn install_ice_hook() {

From 035333993d09df69dd82723881b05cda5f0cde07 Mon Sep 17 00:00:00 2001
From: Jonas Schievink <jonasschievink@gmail.com>
Date: Fri, 10 May 2019 17:44:25 +0200
Subject: [PATCH 350/943] Clarify that rustc unwinds on errors, not panics

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

diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index ece82233e9951..0fd00af0bd03d 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -1145,7 +1145,7 @@ fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
 
 /// Runs a closure and catches unwinds triggered by fatal errors.
 ///
-/// The compiler currently panics with a special sentinel value to abort
+/// The compiler currently unwinds with a special sentinel value to abort
 /// compilation on fatal errors. This function catches that sentinel and turns
 /// the panic into a `Result` instead.
 pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorReported> {

From 3e2d4d28b1c1a96e7c7482ae3e82fbf81505e8a7 Mon Sep 17 00:00:00 2001
From: Jonas Schievink <jonasschievink@gmail.com>
Date: Fri, 26 Jul 2019 23:31:02 +0200
Subject: [PATCH 351/943] Document the ICE hook and make it more flexible

---
 src/librustc_driver/lib.rs | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 0fd00af0bd03d..97542a0e84ed0 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -1161,12 +1161,18 @@ pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorReported>
 lazy_static! {
     static ref DEFAULT_HOOK: Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static> = {
         let hook = panic::take_hook();
-        panic::set_hook(Box::new(report_ice));
+        panic::set_hook(Box::new(|info| report_ice(info, BUG_REPORT_URL)));
         hook
     };
 }
 
-pub fn report_ice(info: &panic::PanicInfo<'_>) {
+/// Prints the ICE message, including backtrace and query stack.
+///
+/// The message will point the user at `bug_report_url` to report the ICE.
+///
+/// When `install_ice_hook` is called, this function will be called as the panic
+/// hook.
+pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
     // Invoke the default handler, which prints the actual panic message and optionally a backtrace
     (*DEFAULT_HOOK)(info);
 
@@ -1192,7 +1198,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>) {
 
     let mut xs: Vec<Cow<'static, str>> = vec![
         "the compiler unexpectedly panicked. this is a bug.".into(),
-        format!("we would appreciate a bug report: {}", BUG_REPORT_URL).into(),
+        format!("we would appreciate a bug report: {}", bug_report_url).into(),
         format!("rustc {} running on {}",
                 option_env!("CFG_VERSION").unwrap_or("unknown_version"),
                 config::host_triple()).into(),
@@ -1231,6 +1237,9 @@ pub fn report_ice(info: &panic::PanicInfo<'_>) {
     }
 }
 
+/// Installs a panic hook that will print the ICE message on unexpected panics.
+///
+/// A custom rustc driver can skip calling this to set up a custom ICE hook.
 pub fn install_ice_hook() {
     lazy_static::initialize(&DEFAULT_HOOK);
 }

From cf1db72281134ab7375447f17bc2becb3943ee5d Mon Sep 17 00:00:00 2001
From: Jonas Schievink <jonasschievink@gmail.com>
Date: Sat, 27 Jul 2019 16:38:52 +0200
Subject: [PATCH 352/943] Update comment

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

diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 97542a0e84ed0..fe1ed10884a4d 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -1176,7 +1176,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
     // Invoke the default handler, which prints the actual panic message and optionally a backtrace
     (*DEFAULT_HOOK)(info);
 
-    // Print the infamous ICE message
+    // Separate the output with an empty line
     eprintln!();
 
     let emitter = Box::new(errors::emitter::EmitterWriter::stderr(

From 547f96f19c45c469a65f5f3862213165cf899d54 Mon Sep 17 00:00:00 2001
From: Jonas Schievink <jonasschievink@gmail.com>
Date: Sun, 4 Aug 2019 14:59:13 +0200
Subject: [PATCH 353/943] Update proc-macro tests

Due to #59998, the panic hook fires incorrectly for errors that should
not be treated as ICEs. Previously, this would only print the default
panic message, but moving the ICE printing into the panic handler will
now print the entire ICE ordeal we all hate to see.

Unfortunately this will make #59998 a lot more visible.
---
 src/test/ui/proc-macro/invalid-punct-ident-1.rs     | 5 +++++
 src/test/ui/proc-macro/invalid-punct-ident-1.stderr | 2 +-
 src/test/ui/proc-macro/invalid-punct-ident-2.rs     | 5 +++++
 src/test/ui/proc-macro/invalid-punct-ident-2.stderr | 2 +-
 src/test/ui/proc-macro/invalid-punct-ident-3.rs     | 5 +++++
 src/test/ui/proc-macro/invalid-punct-ident-3.stderr | 2 +-
 6 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.rs b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
index c9881ad2c38af..3b6498b4b0ee9 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-1.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
@@ -3,6 +3,11 @@
 // FIXME https://github.com/rust-lang/rust/issues/59998
 // normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> ""
 // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// normalize-stderr-test "error: internal compiler error.*\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n" -> ""
 
 #[macro_use]
 extern crate invalid_punct_ident;
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.stderr b/src/test/ui/proc-macro/invalid-punct-ident-1.stderr
index 40333a3f4c211..107f5fb515b1c 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-1.stderr
+++ b/src/test/ui/proc-macro/invalid-punct-ident-1.stderr
@@ -1,5 +1,5 @@
 error: proc macro panicked
-  --> $DIR/invalid-punct-ident-1.rs:10:1
+  --> $DIR/invalid-punct-ident-1.rs:15:1
    |
 LL | invalid_punct!();
    | ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-2.rs b/src/test/ui/proc-macro/invalid-punct-ident-2.rs
index 15e2286a65049..ee57752e2be27 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-2.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-2.rs
@@ -3,6 +3,11 @@
 // FIXME https://github.com/rust-lang/rust/issues/59998
 // normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> ""
 // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// normalize-stderr-test "error: internal compiler error.*\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n" -> ""
 
 #[macro_use]
 extern crate invalid_punct_ident;
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-2.stderr b/src/test/ui/proc-macro/invalid-punct-ident-2.stderr
index ec97e265c3fcd..f1b9ecc6cbfe4 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-2.stderr
+++ b/src/test/ui/proc-macro/invalid-punct-ident-2.stderr
@@ -1,5 +1,5 @@
 error: proc macro panicked
-  --> $DIR/invalid-punct-ident-2.rs:10:1
+  --> $DIR/invalid-punct-ident-2.rs:15:1
    |
 LL | invalid_ident!();
    | ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.rs b/src/test/ui/proc-macro/invalid-punct-ident-3.rs
index 629bbaa9e3888..efcd6801ecbdd 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-3.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-3.rs
@@ -3,6 +3,11 @@
 // FIXME https://github.com/rust-lang/rust/issues/59998
 // normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> ""
 // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
+// normalize-stderr-test "error: internal compiler error.*\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n" -> ""
 
 #[macro_use]
 extern crate invalid_punct_ident;
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.stderr b/src/test/ui/proc-macro/invalid-punct-ident-3.stderr
index a5e5ded65333a..6044b9887401e 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-3.stderr
+++ b/src/test/ui/proc-macro/invalid-punct-ident-3.stderr
@@ -1,5 +1,5 @@
 error: proc macro panicked
-  --> $DIR/invalid-punct-ident-3.rs:10:1
+  --> $DIR/invalid-punct-ident-3.rs:15:1
    |
 LL | invalid_raw_ident!();
    | ^^^^^^^^^^^^^^^^^^^^^

From eefae7b1a9980b10f9b44a3ed14e47cf062b0c96 Mon Sep 17 00:00:00 2001
From: Jonas Schievink <jonasschievink@gmail.com>
Date: Mon, 19 Aug 2019 22:56:02 +0200
Subject: [PATCH 354/943] Update Cargo.lock

---
 Cargo.lock | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Cargo.lock b/Cargo.lock
index 179bf59388a29..91ff6cd1006ed 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2844,7 +2844,6 @@ dependencies = [
  "fmt_macros",
  "graphviz",
  "jobserver",
- "lazy_static 1.3.0",
  "log",
  "measureme",
  "num_cpus",

From 55800ce899d63dd80ad0c99e5617fc275b5e6644 Mon Sep 17 00:00:00 2001
From: Ilija Tovilo <ilija.tovilo@me.com>
Date: Fri, 30 Aug 2019 14:10:46 +0200
Subject: [PATCH 355/943] Skip wrapping arithmetic tests on emscripten for 128
 bit integers

---
 src/test/ui/wrapping-int-combinations.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/test/ui/wrapping-int-combinations.rs b/src/test/ui/wrapping-int-combinations.rs
index 431194ccd1dec..f0bc479ee0ff2 100644
--- a/src/test/ui/wrapping-int-combinations.rs
+++ b/src/test/ui/wrapping-int-combinations.rs
@@ -64,12 +64,14 @@ fn main() {
     wrapping_test!(i16, std::i16::MIN, std::i16::MAX);
     wrapping_test!(i32, std::i32::MIN, std::i32::MAX);
     wrapping_test!(i64, std::i64::MIN, std::i64::MAX);
+    #[cfg(not(target_os = "emscripten"))]
     wrapping_test!(i128, std::i128::MIN, std::i128::MAX);
     wrapping_test!(isize, std::isize::MIN, std::isize::MAX);
     wrapping_test!(u8, std::u8::MIN, std::u8::MAX);
     wrapping_test!(u16, std::u16::MIN, std::u16::MAX);
     wrapping_test!(u32, std::u32::MIN, std::u32::MAX);
     wrapping_test!(u64, std::u64::MIN, std::u64::MAX);
+    #[cfg(not(target_os = "emscripten"))]
     wrapping_test!(u128, std::u128::MIN, std::u128::MAX);
     wrapping_test!(usize, std::usize::MIN, std::usize::MAX);
 }

From bb3474994b94472a292fec6ebfdc21cda4d8cc70 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Fri, 30 Aug 2019 15:04:12 +0200
Subject: [PATCH 356/943] add test

---
 src/test/ui/consts/const-eval/dangling.rs     | 13 +++++++++++++
 src/test/ui/consts/const-eval/dangling.stderr | 16 ++++++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 src/test/ui/consts/const-eval/dangling.rs
 create mode 100644 src/test/ui/consts/const-eval/dangling.stderr

diff --git a/src/test/ui/consts/const-eval/dangling.rs b/src/test/ui/consts/const-eval/dangling.rs
new file mode 100644
index 0000000000000..b5d72d46f2861
--- /dev/null
+++ b/src/test/ui/consts/const-eval/dangling.rs
@@ -0,0 +1,13 @@
+#![feature(const_transmute, const_raw_ptr_deref)]
+
+use std::{mem, usize};
+
+// Make sure we error with the right kind of error on a too large slice.
+const TEST: () = { unsafe { //~ NOTE
+    let slice: *const [u8] = mem::transmute((1usize, usize::MAX));
+    let _val = &*slice; //~ ERROR: any use of this value will cause an error
+    //~^ NOTE: total size is bigger than largest supported object
+    //~^^ on by default
+} };
+
+fn main() {}
diff --git a/src/test/ui/consts/const-eval/dangling.stderr b/src/test/ui/consts/const-eval/dangling.stderr
new file mode 100644
index 0000000000000..286de08009754
--- /dev/null
+++ b/src/test/ui/consts/const-eval/dangling.stderr
@@ -0,0 +1,16 @@
+error: any use of this value will cause an error
+  --> $DIR/dangling.rs:8:16
+   |
+LL | / const TEST: () = { unsafe {
+LL | |     let slice: *const [u8] = mem::transmute((1usize, usize::MAX));
+LL | |     let _val = &*slice;
+   | |                ^^^^^^^ invalid slice: total size is bigger than largest supported object
+LL | |
+LL | |
+LL | | } };
+   | |____-
+   |
+   = note: `#[deny(const_err)]` on by default
+
+error: aborting due to previous error
+

From 0e597d4c479b4533e38016b1adbe565b44aab922 Mon Sep 17 00:00:00 2001
From: Xiang Fan <sfanxiang@gmail.com>
Date: Fri, 30 Aug 2019 21:17:36 +0800
Subject: [PATCH 357/943] Rev::rposition counts from the wrong end

Because of a compiler bug that adding `Self: ExactSizeIterator` makes
the compiler forget `Self::Item` is `<I as Iterator>::Item`, we remove
this specialization for now.
---
 src/libcore/iter/adapters/mod.rs | 7 -------
 src/libcore/tests/iter.rs        | 6 ++++++
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index f50781890ab22..8e1ac6082c8a8 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -66,13 +66,6 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
     {
         self.iter.rfind(predicate)
     }
-
-    #[inline]
-    fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
-        P: FnMut(Self::Item) -> bool
-    {
-        self.iter.position(predicate)
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 3a4f76852a0d7..8e0658d87c1fb 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1688,6 +1688,12 @@ fn test_rposition() {
     assert!(v.iter().rposition(g).is_none());
 }
 
+#[test]
+fn test_rev_rposition() {
+    let v = [0, 0, 1, 1];
+    assert_eq!(v.iter().rev().rposition(|&x| x == 1), Some(1));
+}
+
 #[test]
 #[should_panic]
 fn test_rposition_panic() {

From 9fd203a01e0fe6fb307809fdfdbfcd3bda350cfc Mon Sep 17 00:00:00 2001
From: newpavlov <newpavlov@gmail.com>
Date: Fri, 30 Aug 2019 17:30:33 +0300
Subject: [PATCH 358/943] simplify code

---
 src/libstd/sys/wasi/thread.rs | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/libstd/sys/wasi/thread.rs b/src/libstd/sys/wasi/thread.rs
index 987bf7580838b..28a504f197974 100644
--- a/src/libstd/sys/wasi/thread.rs
+++ b/src/libstd/sys/wasi/thread.rs
@@ -46,11 +46,18 @@ impl Thread {
             type_: wasi::EVENTTYPE_CLOCK,
             u: wasi::raw::__wasi_subscription_u { clock: clock },
         }];
-        let mut out: [wasi::Event; 1] = [unsafe { mem::zeroed() }];
-        let n = unsafe { wasi::poll_oneoff(&in_, &mut out).unwrap() };
-        let wasi::Event { userdata, error, type_, .. } = out[0];
-        match (n, userdata, error) {
-            (1, CLOCK_ID, 0) if type_ == wasi::EVENTTYPE_CLOCK => {}
+        let (res, event) = unsafe {
+            let mut out: [wasi::Event; 1] = mem::zeroed();
+            let res = wasi::poll_oneoff(&in_, &mut out);
+            (res, out[0])
+        };
+        match (res, event) {
+            (Ok(1), wasi::Event {
+                userdata: CLOCK_ID,
+                error: 0,
+                type_: wasi::EVENTTYPE_CLOCK,
+                ..
+            }) => {}
             _ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
         }
     }

From 403701f97628b85bfa3e5ec0e5ca82b81d53ba1e Mon Sep 17 00:00:00 2001
From: Tyler Mandry <tmandry@gmail.com>
Date: Fri, 30 Aug 2019 11:51:04 -0700
Subject: [PATCH 359/943] Don't try to use /dev/null on Fuchsia

---
 src/libstd/sys/unix/process/process_common.rs | 28 +++++++++++++++++--
 .../sys/unix/process/process_fuchsia.rs       | 15 ++++++----
 src/libstd/sys/unix/process/zircon.rs         |  2 +-
 3 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index 6bb20bbe08794..511e67840803e 100644
--- a/src/libstd/sys/unix/process/process_common.rs
+++ b/src/libstd/sys/unix/process/process_common.rs
@@ -1,19 +1,27 @@
 use crate::os::unix::prelude::*;
 
-use crate::ffi::{OsString, OsStr, CString, CStr};
+use crate::ffi::{OsString, OsStr, CString};
 use crate::fmt;
 use crate::io;
 use crate::ptr;
 use crate::sys::fd::FileDesc;
-use crate::sys::fs::{File, OpenOptions};
+use crate::sys::fs::File;
 use crate::sys::pipe::{self, AnonPipe};
 use crate::sys_common::process::{CommandEnv, DefaultEnvKey};
 use crate::collections::BTreeMap;
 
+#[cfg(not(target_os = "fuchsia"))]
+use {
+    crate::ffi::CStr,
+    crate::sys::fs::OpenOptions,
+};
+
 use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
 
 cfg_if::cfg_if! {
-    if #[cfg(target_os = "redox")] {
+    if #[cfg(target_os = "fuchsia")] {
+        // fuchsia doesn't have /dev/null
+    } else if #[cfg(target_os = "redox")] {
         const DEV_NULL: &'static str = "null:\0";
     } else {
         const DEV_NULL: &'static str = "/dev/null\0";
@@ -83,6 +91,11 @@ pub enum ChildStdio {
     Inherit,
     Explicit(c_int),
     Owned(FileDesc),
+
+    // On Fuchsia, null stdio is the default, so we simply don't specify
+    // any actions at the time of spawning.
+    #[cfg(target_os = "fuchsia")]
+    Null,
 }
 
 pub enum Stdio {
@@ -301,6 +314,7 @@ impl Stdio {
                 Ok((ChildStdio::Owned(theirs.into_fd()), Some(ours)))
             }
 
+            #[cfg(not(target_os = "fuchsia"))]
             Stdio::Null => {
                 let mut opts = OpenOptions::new();
                 opts.read(readable);
@@ -311,6 +325,11 @@ impl Stdio {
                 let fd = File::open_c(&path, &opts)?;
                 Ok((ChildStdio::Owned(fd.into_fd()), None))
             }
+
+            #[cfg(target_os = "fuchsia")]
+            Stdio::Null => {
+                Ok((ChildStdio::Null, None))
+            }
         }
     }
 }
@@ -333,6 +352,9 @@ impl ChildStdio {
             ChildStdio::Inherit => None,
             ChildStdio::Explicit(fd) => Some(fd),
             ChildStdio::Owned(ref fd) => Some(fd.raw()),
+
+            #[cfg(target_os = "fuchsia")]
+            ChildStdio::Null => None,
         }
     }
 }
diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs
index 7c6be9b0a6047..295ec59eb32cf 100644
--- a/src/libstd/sys/unix/process/process_fuchsia.rs
+++ b/src/libstd/sys/unix/process/process_fuchsia.rs
@@ -52,7 +52,7 @@ impl Command {
             None => ptr::null(),
         };
 
-        let transfer_or_clone = |opt_fd, target_fd| if let Some(local_fd) = opt_fd {
+        let make_action = |local_io: &ChildStdio, target_fd| if let Some(local_fd) = local_io.fd() {
             fdio_spawn_action_t {
                 action: FDIO_SPAWN_ACTION_TRANSFER_FD,
                 local_fd,
@@ -60,6 +60,10 @@ impl Command {
                 ..Default::default()
             }
         } else {
+            if let ChildStdio::Null = local_io {
+                // acts as no-op
+                return Default::default();
+            }
             fdio_spawn_action_t {
                 action: FDIO_SPAWN_ACTION_CLONE_FD,
                 local_fd: target_fd,
@@ -69,9 +73,9 @@ impl Command {
         };
 
         // Clone stdin, stdout, and stderr
-        let action1 = transfer_or_clone(stdio.stdin.fd(), 0);
-        let action2 = transfer_or_clone(stdio.stdout.fd(), 1);
-        let action3 = transfer_or_clone(stdio.stderr.fd(), 2);
+        let action1 = make_action(&stdio.stdin, 0);
+        let action2 = make_action(&stdio.stdout, 1);
+        let action3 = make_action(&stdio.stderr, 2);
         let actions = [action1, action2, action3];
 
         // We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc
@@ -86,7 +90,8 @@ impl Command {
         zx_cvt(fdio_spawn_etc(
             0,
             FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE,
-            self.get_argv()[0], self.get_argv().as_ptr(), envp, 3, actions.as_ptr(),
+            self.get_argv()[0], self.get_argv().as_ptr(), envp,
+            actions.len() as size_t, actions.as_ptr(),
             &mut process_handle,
             ptr::null_mut(),
         ))?;
diff --git a/src/libstd/sys/unix/process/zircon.rs b/src/libstd/sys/unix/process/zircon.rs
index 9224bef7c4a5f..29032f5e0d200 100644
--- a/src/libstd/sys/unix/process/zircon.rs
+++ b/src/libstd/sys/unix/process/zircon.rs
@@ -120,7 +120,7 @@ pub struct fdio_spawn_action_t {
 extern {
     pub fn fdio_spawn_etc(job: zx_handle_t, flags: u32, path: *const c_char,
                           argv: *const *const c_char, envp: *const *const c_char,
-                          action_count: u64, actions: *const fdio_spawn_action_t,
+                          action_count: size_t, actions: *const fdio_spawn_action_t,
                           process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t;
 }
 

From 3f6db849f7270b9126e6609a87058c1bc3aef1da Mon Sep 17 00:00:00 2001
From: Mark Mansi <markm@cs.wisc.edu>
Date: Fri, 30 Aug 2019 14:05:39 -0500
Subject: [PATCH 360/943] actually compiles now?

---
 src/tools/rustbook/src/main.rs | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs
index e155f3f7607f3..b2111442310ef 100644
--- a/src/tools/rustbook/src/main.rs
+++ b/src/tools/rustbook/src/main.rs
@@ -60,11 +60,14 @@ fn main() {
                     #[cfg(feature = "linkcheck")]
                     {
                         err.downcast::<BrokenLinks>()
+                            .map(|broken_links| {
+                                broken_links
+                                    .links()
+                                    .iter()
+                                    .inspect(|cause| eprintln!("\tCaused By: {}", cause))
+                                    .any(|cause| !format!("{}", cause).contains("timed out"))
+                            })
                             .unwrap_or(false)
-                            .links()
-                            .iter()
-                            .inspect(|cause| eprintln!("\tCaused By: {}", cause))
-                            .any(|cause| !cause.contains("timed out"));
                     }
 
                     #[cfg(not(feature = "linkcheck"))]

From 0b478e6d46f273041ea7a4e048083d7d4e54c8fe Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403@users.noreply.github.com>
Date: Fri, 30 Aug 2019 21:26:04 +0200
Subject: [PATCH 361/943] rustdoc use -Ccodegen-units=1 by default for test
 compile

as the test is small we do not want split up in multiple codegen units
and also as there is multiple test running at the same time this
will reduce the number of concurrent threads
---
 src/librustdoc/test.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 31c0b85a481f5..88397aacac149 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -263,6 +263,7 @@ fn run_test(
     for extern_str in &options.extern_strs {
         compiler.arg("--extern").arg(&extern_str);
     }
+    compiler.arg("-Ccodegen-units=1");
     for codegen_options_str in &options.codegen_options_strs {
         compiler.arg("-C").arg(&codegen_options_str);
     }

From 533a356c49759da02fcb2457c62aed58af70579c Mon Sep 17 00:00:00 2001
From: Baoshan Pang <baoshan.pang@windriver.com>
Date: Fri, 30 Aug 2019 13:44:38 -0700
Subject: [PATCH 362/943] remove directory libstd/sys/vxworks/backtrace which
 is not used any more

---
 src/libstd/sys/vxworks/backtrace/mod.rs       | 110 ------------------
 .../sys/vxworks/backtrace/printing/dladdr.rs  |  35 ------
 .../sys/vxworks/backtrace/printing/mod.rs     |  33 ------
 .../vxworks/backtrace/tracing/backtrace_fn.rs |  39 -------
 .../sys/vxworks/backtrace/tracing/gcc_s.rs    |  99 ----------------
 .../sys/vxworks/backtrace/tracing/mod.rs      |   8 --
 6 files changed, 324 deletions(-)
 delete mode 100644 src/libstd/sys/vxworks/backtrace/mod.rs
 delete mode 100644 src/libstd/sys/vxworks/backtrace/printing/dladdr.rs
 delete mode 100644 src/libstd/sys/vxworks/backtrace/printing/mod.rs
 delete mode 100644 src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs
 delete mode 100644 src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs
 delete mode 100644 src/libstd/sys/vxworks/backtrace/tracing/mod.rs

diff --git a/src/libstd/sys/vxworks/backtrace/mod.rs b/src/libstd/sys/vxworks/backtrace/mod.rs
deleted file mode 100644
index 0887e5a4df937..0000000000000
--- a/src/libstd/sys/vxworks/backtrace/mod.rs
+++ /dev/null
@@ -1,110 +0,0 @@
-/// Backtrace support built on libgcc with some extra OS-specific support
-///
-/// Some methods of getting a backtrace:
-///
-/// * The backtrace() functions on unix. It turns out this doesn't work very
-///   well for green threads on macOS, and the address to symbol portion of it
-///   suffers problems that are described below.
-///
-/// * Using libunwind. This is more difficult than it sounds because libunwind
-///   isn't installed everywhere by default. It's also a bit of a hefty library,
-///   so possibly not the best option. When testing, libunwind was excellent at
-///   getting both accurate backtraces and accurate symbols across platforms.
-///   This route was not chosen in favor of the next option, however.
-///
-/// * We're already using libgcc_s for exceptions in rust (triggering thread
-///   unwinding and running destructors on the stack), and it turns out that it
-///   conveniently comes with a function that also gives us a backtrace. All of
-///   these functions look like _Unwind_*, but it's not quite the full
-///   repertoire of the libunwind API. Due to it already being in use, this was
-///   the chosen route of getting a backtrace.
-///
-/// After choosing libgcc_s for backtraces, the sad part is that it will only
-/// give us a stack trace of instruction pointers. Thankfully these instruction
-/// pointers are accurate (they work for green and native threads), but it's
-/// then up to us again to figure out how to translate these addresses to
-/// symbols. As with before, we have a few options. Before, that, a little bit
-/// of an interlude about symbols. This is my very limited knowledge about
-/// symbol tables, and this information is likely slightly wrong, but the
-/// general idea should be correct.
-///
-/// When talking about symbols, it's helpful to know a few things about where
-/// symbols are located. Some symbols are located in the dynamic symbol table
-/// of the executable which in theory means that they're available for dynamic
-/// linking and lookup. Other symbols end up only in the local symbol table of
-/// the file. This loosely corresponds to pub and priv functions in Rust.
-///
-/// Armed with this knowledge, we know that our solution for address to symbol
-/// translation will need to consult both the local and dynamic symbol tables.
-/// With that in mind, here's our options of translating an address to
-/// a symbol.
-///
-/// * Use dladdr(). The original backtrace()-based idea actually uses dladdr()
-///   behind the scenes to translate, and this is why backtrace() was not used.
-///   Conveniently, this method works fantastically on macOS. It appears dladdr()
-///   uses magic to consult the local symbol table, or we're putting everything
-///   in the dynamic symbol table anyway. Regardless, for macOS, this is the
-///   method used for translation. It's provided by the system and easy to do.o
-///
-///   Sadly, all other systems have a dladdr() implementation that does not
-///   consult the local symbol table. This means that most functions are blank
-///   because they don't have symbols. This means that we need another solution.
-///
-/// * Use unw_get_proc_name(). This is part of the libunwind api (not the
-///   libgcc_s version of the libunwind api), but involves taking a dependency
-///   to libunwind. We may pursue this route in the future if we bundle
-///   libunwind, but libunwind was unwieldy enough that it was not chosen at
-///   this time to provide this functionality.
-///
-/// * Shell out to a utility like `readelf`. Crazy though it may sound, it's a
-///   semi-reasonable solution. The stdlib already knows how to spawn processes,
-///   so in theory it could invoke readelf, parse the output, and consult the
-///   local/dynamic symbol tables from there. This ended up not getting chosen
-///   due to the craziness of the idea plus the advent of the next option.
-///
-/// * Use `libbacktrace`. It turns out that this is a small library bundled in
-///   the gcc repository which provides backtrace and symbol translation
-///   functionality. All we really need from it is the backtrace functionality,
-///   and we only really need this on everything that's not macOS, so this is the
-///   chosen route for now.
-///
-/// In summary, the current situation uses libgcc_s to get a trace of stack
-/// pointers, and we use dladdr() or libbacktrace to translate these addresses
-/// to symbols. This is a bit of a hokey implementation as-is, but it works for
-/// all unix platforms we support right now, so it at least gets the job done.
-
-pub use self::tracing::unwind_backtrace;
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-
-// tracing impls:
-mod tracing;
-// symbol resolvers:
-mod printing;
-
-#[cfg(not(target_os = "emscripten"))]
-pub mod gnu {
-    use crate::io;
-    use crate::fs;
-
-    use libc::c_char;
-
-    #[cfg(not(any(target_os = "macos", target_os = "ios")))]
-    pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
-        Err(io::Error::new(io::ErrorKind::Other, "Not implemented"))
-    }
-
-    #[cfg(any(target_os = "macos", target_os = "ios"))]
-    pub fn get_executable_filename() -> io::Result<(Vec<c_char>, fs::File)> {
-        use crate::env;
-        use crate::os::unix::ffi::OsStrExt;
-
-        let filename = env::current_exe()?;
-        let file = fs::File::open(&filename)?;
-        let mut filename_cstr: Vec<_> = filename.as_os_str().as_bytes().iter()
-            .map(|&x| x as c_char).collect();
-        filename_cstr.push(0); // Null terminate
-        Ok((filename_cstr, file))
-    }
-}
-
-pub struct BacktraceContext;
diff --git a/src/libstd/sys/vxworks/backtrace/printing/dladdr.rs b/src/libstd/sys/vxworks/backtrace/printing/dladdr.rs
deleted file mode 100644
index 202164dd3c4d7..0000000000000
--- a/src/libstd/sys/vxworks/backtrace/printing/dladdr.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-use crate::io;
-use crate::intrinsics;
-use crate::ffi::CStr;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-pub fn resolve_symname<F>(frame: Frame,
-                          callback: F,
-                          _: &BacktraceContext) -> io::Result<()>
-    where F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    unsafe {
-        let mut info: Dl_info = intrinsics::init();
-        let symname = if dladdr(frame.exact_position as *mut _, &mut info) == 0 ||
-                         info.dli_sname.is_null() {
-            None
-        } else {
-            CStr::from_ptr(info.dli_sname).to_str().ok()
-        };
-        callback(symname)
-    }
-}
-
-#[repr(C)]
-struct Dl_info {
-    dli_fname: *const libc::c_char,
-    dli_fbase: *mut libc::c_void,
-    dli_sname: *const libc::c_char,
-    dli_saddr: *mut libc::c_void,
-}
-
-extern {
-    #[ link_name = "_rtld_dladdr" ]
-    fn dladdr(addr: *const libc::c_void, info: *mut Dl_info) -> libc::c_int;
-}
diff --git a/src/libstd/sys/vxworks/backtrace/printing/mod.rs b/src/libstd/sys/vxworks/backtrace/printing/mod.rs
deleted file mode 100644
index d090caede437a..0000000000000
--- a/src/libstd/sys/vxworks/backtrace/printing/mod.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-mod dladdr;
-
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-use crate::io;
-
-#[cfg(target_os = "emscripten")]
-pub use self::dladdr::resolve_symname;
-
-#[cfg(target_os = "emscripten")]
-pub fn foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool>
-where
-    F: FnMut(&[u8], u32) -> io::Result<()>
-{
-    Ok(false)
-}
-
-#[cfg(not(target_os = "emscripten"))]
-pub use crate::sys_common::gnu::libbacktrace::foreach_symbol_fileline;
-
-#[cfg(not(target_os = "emscripten"))]
-pub fn resolve_symname<F>(frame: Frame, callback: F, bc: &BacktraceContext) -> io::Result<()>
-where
-    F: FnOnce(Option<&str>) -> io::Result<()>
-{
-    crate::sys_common::gnu::libbacktrace::resolve_symname(frame, |symname| {
-        if symname.is_some() {
-            callback(symname)
-        } else {
-            dladdr::resolve_symname(frame, callback, bc)
-        }
-    }, bc)
-}
diff --git a/src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs b/src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs
deleted file mode 100644
index a628d107ad6fb..0000000000000
--- a/src/libstd/sys/vxworks/backtrace/tracing/backtrace_fn.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-/// As always - iOS on arm uses SjLj exceptions and
-/// _Unwind_Backtrace is even not available there. Still,
-/// backtraces could be extracted using a backtrace function,
-/// which thanks god is public
-///
-/// As mentioned in a huge comment block in `super::super`, backtrace
-/// doesn't play well with green threads, so while it is extremely nice and
-/// simple to use it should be used only on iOS devices as the only viable
-/// option.
-
-use crate::io;
-use crate::ptr;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-#[inline(never)] // if we know this is a function call, we can skip it when
-                 // tracing
-pub fn unwind_backtrace(frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    const FRAME_LEN: usize = 100;
-    assert!(FRAME_LEN >= frames.len());
-    let mut raw_frames = [ptr::null_mut(); FRAME_LEN];
-    let nb_frames = unsafe {
-        backtrace(raw_frames.as_mut_ptr(), raw_frames.len() as libc::c_int)
-    } as usize;
-    for (from, to) in raw_frames.iter().zip(frames.iter_mut()).take(nb_frames) {
-        *to = Frame {
-            exact_position: *from as *mut u8,
-            symbol_addr: *from as *mut u8,
-            inline_context: 0,
-        };
-    }
-    Ok((nb_frames as usize, BacktraceContext))
-}
-
-extern {
-    fn backtrace(buf: *mut *mut libc::c_void, sz: libc::c_int) -> libc::c_int;
-}
diff --git a/src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs b/src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs
deleted file mode 100644
index e6379132bafbe..0000000000000
--- a/src/libstd/sys/vxworks/backtrace/tracing/gcc_s.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use crate::error::Error;
-use crate::fmt;
-use crate::io;
-use crate::sys::backtrace::BacktraceContext;
-use crate::sys_common::backtrace::Frame;
-
-use unwind as uw;
-
-struct Context<'a> {
-    idx: usize,
-    frames: &'a mut [Frame],
-}
-
-#[derive(Debug)]
-struct UnwindError(uw::_Unwind_Reason_Code);
-
-impl Error for UnwindError {
-    fn description(&self) -> &'static str {
-        "unexpected return value while unwinding"
-    }
-}
-
-impl fmt::Display for UnwindError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "{}: {:?}", self.description(), self.0)
-    }
-}
-
-#[inline(never)] // if we know this is a function call, we can skip it when
-                 // tracing
-pub fn unwind_backtrace(frames: &mut [Frame])
-    -> io::Result<(usize, BacktraceContext)>
-{
-    let mut cx = Context {
-        idx: 0,
-        frames,
-    };
-    let result_unwind = unsafe {
-        uw::_Unwind_Backtrace(trace_fn,
-                              &mut cx as *mut Context<'_>
-                              as *mut libc::c_void)
-    };
-    // See libunwind:src/unwind/Backtrace.c for the return values.
-    // No, there is no doc.
-    match result_unwind {
-        // These return codes seem to be benign and need to be ignored for backtraces
-        // to show up properly on all tested platforms.
-        uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
-            Ok((cx.idx, BacktraceContext))
-        }
-        _ => {
-            Err(io::Error::new(io::ErrorKind::Other,
-                               UnwindError(result_unwind)))
-        }
-    }
-}
-
-extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
-                   arg: *mut libc::c_void) -> uw::_Unwind_Reason_Code {
-    let cx = unsafe { &mut *(arg as *mut Context<'_>) };
-    if cx.idx >= cx.frames.len() {
-        return uw::_URC_NORMAL_STOP;
-    }
-
-    let mut ip_before_insn = 0;
-    let mut ip = unsafe {
-        uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void
-    };
-    if !ip.is_null() && ip_before_insn == 0 {
-        // this is a non-signaling frame, so `ip` refers to the address
-        // after the calling instruction. account for that.
-        ip = (ip as usize - 1) as *mut _;
-    }
-
-    // dladdr() on osx gets whiny when we use FindEnclosingFunction, and
-    // it appears to work fine without it, so we only use
-    // FindEnclosingFunction on non-osx platforms. In doing so, we get a
-    // slightly more accurate stack trace in the process.
-    //
-    // This is often because panic involves the last instruction of a
-    // function being "call std::rt::begin_unwind", with no ret
-    // instructions after it. This means that the return instruction
-    // pointer points *outside* of the calling function, and by
-    // unwinding it we go back to the original function.
-    let symaddr = if cfg!(target_os = "macos") || cfg!(target_os = "ios") {
-        ip
-    } else {
-        unsafe { uw::_Unwind_FindEnclosingFunction(ip) }
-    };
-
-    cx.frames[cx.idx] = Frame {
-        symbol_addr: symaddr as *mut u8,
-        exact_position: ip as *mut u8,
-        inline_context: 0,
-    };
-    cx.idx += 1;
-
-    uw::_URC_NO_REASON
-}
diff --git a/src/libstd/sys/vxworks/backtrace/tracing/mod.rs b/src/libstd/sys/vxworks/backtrace/tracing/mod.rs
deleted file mode 100644
index 11863e6454525..0000000000000
--- a/src/libstd/sys/vxworks/backtrace/tracing/mod.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-pub use self::imp::*;
-
-#[cfg(not(all(target_os = "ios", target_arch = "arm")))]
-#[path = "gcc_s.rs"]
-mod imp;
-#[cfg(all(target_os = "ios", target_arch = "arm"))]
-#[path = "backtrace_fn.rs"]
-mod imp;

From 96ac02b8b3aeebc463d434c57b4a2ada9a3003e6 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Thu, 29 Aug 2019 13:30:53 -0700
Subject: [PATCH 363/943] Use new `Place::is_indirect` API where possible

---
 src/librustc_mir/borrow_check/path_utils.rs   | 23 ++++++-------------
 .../dataflow/impls/borrowed_locals.rs         | 17 ++++----------
 2 files changed, 11 insertions(+), 29 deletions(-)

diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs
index 43a012e1494f8..bac08090817d9 100644
--- a/src/librustc_mir/borrow_check/path_utils.rs
+++ b/src/librustc_mir/borrow_check/path_utils.rs
@@ -3,7 +3,7 @@ use crate::borrow_check::places_conflict;
 use crate::borrow_check::AccessDepth;
 use crate::dataflow::indexes::BorrowIndex;
 use rustc::mir::{BasicBlock, Location, Body, Place, PlaceBase};
-use rustc::mir::{ProjectionElem, BorrowKind};
+use rustc::mir::BorrowKind;
 use rustc::ty::{self, TyCtxt};
 use rustc_data_structures::graph::dominators::Dominators;
 
@@ -133,20 +133,11 @@ pub(super) fn is_active<'tcx>(
 /// Determines if a given borrow is borrowing local data
 /// This is called for all Yield statements on movable generators
 pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool {
-    place.iterate(|place_base, place_projection| {
-        match place_base {
-            PlaceBase::Static(..) => return false,
-            PlaceBase::Local(..) => {},
-        }
-
-        for proj in place_projection {
-            // Reborrow of already borrowed data is ignored
-            // Any errors will be caught on the initial borrow
-            if proj.elem == ProjectionElem::Deref {
-                return false;
-            }
-        }
+    match place.base {
+        PlaceBase::Static(_) => false,
 
-        true
-    })
+        // Reborrow of already borrowed data is ignored
+        // Any errors will be caught on the initial borrow
+        PlaceBase::Local(_) => !place.is_indirect(),
+    }
 }
diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
index d94ebdbae24ae..1c43a553cc3c9 100644
--- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs
+++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
@@ -93,19 +93,10 @@ struct BorrowedLocalsVisitor<'gk> {
 }
 
 fn find_local(place: &Place<'_>) -> Option<Local> {
-    place.iterate(|place_base, place_projection| {
-        for proj in place_projection {
-            if proj.elem == ProjectionElem::Deref {
-                return None;
-            }
-        }
-
-        if let PlaceBase::Local(local) = place_base {
-            Some(*local)
-        } else {
-            None
-        }
-    })
+    match place.base {
+        PlaceBase::Local(local) if !place.is_indirect() => Some(local),
+        _ => None,
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for BorrowedLocalsVisitor<'_> {

From 960ecdce7c5b7638cdb2585088caa666928c2d37 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 29 Aug 2019 05:50:39 +0200
Subject: [PATCH 364/943] improper_ctypes: guard against accidental change to
 Unique<T>.

---
 src/test/ui/lint/lint-ctypes-enum.rs     |  2 ++
 src/test/ui/lint/lint-ctypes-enum.stderr | 34 +++++++++++++++---------
 2 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/src/test/ui/lint/lint-ctypes-enum.rs b/src/test/ui/lint/lint-ctypes-enum.rs
index 45eeffff7a6ac..e1f4b0b34ebaa 100644
--- a/src/test/ui/lint/lint-ctypes-enum.rs
+++ b/src/test/ui/lint/lint-ctypes-enum.rs
@@ -1,4 +1,5 @@
 #![feature(transparent_enums, transparent_unions)]
+#![feature(ptr_internals)]
 #![deny(improper_ctypes)]
 #![allow(dead_code)]
 
@@ -44,6 +45,7 @@ extern {
    fn option_ref(x: Option<&'static u8>);
    fn option_fn(x: Option<extern "C" fn()>);
    fn nonnull(x: Option<std::ptr::NonNull<u8>>);
+   fn unique(x: Option<std::ptr::Unique<u8>>); //~ ERROR enum has no representation hint
    fn nonzero_u8(x: Option<num::NonZeroU8>);
    fn nonzero_u16(x: Option<num::NonZeroU16>);
    fn nonzero_u32(x: Option<num::NonZeroU32>);
diff --git a/src/test/ui/lint/lint-ctypes-enum.stderr b/src/test/ui/lint/lint-ctypes-enum.stderr
index 2a60cd12d9936..20e438606642c 100644
--- a/src/test/ui/lint/lint-ctypes-enum.stderr
+++ b/src/test/ui/lint/lint-ctypes-enum.stderr
@@ -1,61 +1,69 @@
 error: `extern` block uses type `U` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:38:13
+  --> $DIR/lint-ctypes-enum.rs:39:13
    |
 LL |    fn uf(x: U);
    |             ^
    |
 note: lint level defined here
-  --> $DIR/lint-ctypes-enum.rs:2:9
+  --> $DIR/lint-ctypes-enum.rs:3:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 note: type defined here
-  --> $DIR/lint-ctypes-enum.rs:8:1
+  --> $DIR/lint-ctypes-enum.rs:9:1
    |
 LL | enum U { A }
    | ^^^^^^^^^^^^
 
 error: `extern` block uses type `B` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:39:13
+  --> $DIR/lint-ctypes-enum.rs:40:13
    |
 LL |    fn bf(x: B);
    |             ^
    |
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 note: type defined here
-  --> $DIR/lint-ctypes-enum.rs:9:1
+  --> $DIR/lint-ctypes-enum.rs:10:1
    |
 LL | enum B { C, D }
    | ^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `T` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:40:13
+  --> $DIR/lint-ctypes-enum.rs:41:13
    |
 LL |    fn tf(x: T);
    |             ^
    |
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 note: type defined here
-  --> $DIR/lint-ctypes-enum.rs:10:1
+  --> $DIR/lint-ctypes-enum.rs:11:1
    |
 LL | enum T { E, F, G }
    | ^^^^^^^^^^^^^^^^^^
 
+error: `extern` block uses type `std::option::Option<std::ptr::Unique<u8>>` which is not FFI-safe: enum has no representation hint
+  --> $DIR/lint-ctypes-enum.rs:48:17
+   |
+LL |    fn unique(x: Option<std::ptr::Unique<u8>>);
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+
 error: `extern` block uses type `u128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
-  --> $DIR/lint-ctypes-enum.rs:51:23
+  --> $DIR/lint-ctypes-enum.rs:53:23
    |
 LL |    fn nonzero_u128(x: Option<num::NonZeroU128>);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
-  --> $DIR/lint-ctypes-enum.rs:58:23
+  --> $DIR/lint-ctypes-enum.rs:60:23
    |
 LL |    fn nonzero_i128(x: Option<num::NonZeroI128>);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `extern` block uses type `std::option::Option<TransparentUnion<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:63:28
+  --> $DIR/lint-ctypes-enum.rs:65:28
    |
 LL |    fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -63,7 +71,7 @@ LL |    fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 
 error: `extern` block uses type `std::option::Option<Rust<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:65:20
+  --> $DIR/lint-ctypes-enum.rs:67:20
    |
 LL |    fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -71,12 +79,12 @@ LL |    fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 
 error: `extern` block uses type `std::result::Result<(), std::num::NonZeroI32>` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:66:20
+  --> $DIR/lint-ctypes-enum.rs:68:20
    |
 LL |    fn no_result(x: Result<(), num::NonZeroI32>);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 

From 78f62c619006500485e96056f733d74be02cab8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 30 Aug 2019 17:45:34 -0700
Subject: [PATCH 365/943] Account for rounding errors when deciding the
 diagnostic boundaries

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

diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 77d373e7a8ca8..fddb6c5c259c9 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -146,12 +146,12 @@ impl Margin {
             } else if self.label_right - self.span_left <= self.column_width {
                 // Attempt to fit the code window considering only the spans and labels.
                 let padding_left = (self.column_width - (self.label_right - self.span_left)) / 2;
-                self.computed_left = self.span_left - padding_left;
+                self.computed_left = max(self.span_left, padding_left) - padding_left;
                 self.computed_right = self.computed_left + self.column_width;
             } else if self.span_right - self.span_left <= self.column_width {
                 // Attempt to fit the code window considering the spans and labels plus padding.
                 let padding_left = (self.column_width - (self.span_right - self.span_left)) / 5 * 2;
-                self.computed_left = self.span_left - padding_left;
+                self.computed_left = max(self.span_left, padding_left) - padding_left;
                 self.computed_right = self.computed_left + self.column_width;
             } else { // Mostly give up but still don't show the full line.
                 self.computed_left = self.span_left;

From 3cc8087c4849fcbb8eeae208ace59bdf9b156ca8 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 29 Aug 2019 08:52:13 +0200
Subject: [PATCH 366/943] qualify_consts: extractt 'determine_mode'.

---
 src/librustc_mir/transform/qualify_consts.rs | 49 ++++++++++----------
 1 file changed, 25 insertions(+), 24 deletions(-)

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index a77421ce15008..959d21ecfadeb 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -30,6 +30,7 @@ use std::fmt;
 use std::ops::{Deref, Index, IndexMut};
 use std::usize;
 
+use rustc::hir::HirId;
 use crate::transform::{MirPass, MirSource};
 use super::promote_consts::{self, Candidate, TempState};
 
@@ -1596,27 +1597,12 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
         }
 
         let def_id = src.def_id();
-        let id = tcx.hir().as_local_hir_id(def_id).unwrap();
-        let mut const_promoted_temps = None;
-        let mode = match tcx.hir().body_owner_kind(id) {
-            hir::BodyOwnerKind::Closure => Mode::NonConstFn,
-            hir::BodyOwnerKind::Fn => {
-                if tcx.is_const_fn(def_id) {
-                    Mode::ConstFn
-                } else {
-                    Mode::NonConstFn
-                }
-            }
-            hir::BodyOwnerKind::Const => {
-                const_promoted_temps = Some(tcx.mir_const_qualif(def_id).1);
-                Mode::Const
-            }
-            hir::BodyOwnerKind::Static(hir::MutImmutable) => Mode::Static,
-            hir::BodyOwnerKind::Static(hir::MutMutable) => Mode::StaticMut,
-        };
+        let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
+
+        let mode = determine_mode(tcx, hir_id, def_id);
 
         debug!("run_pass: mode={:?}", mode);
-        if mode == Mode::NonConstFn || mode == Mode::ConstFn {
+        if let Mode::NonConstFn | Mode::ConstFn = mode {
             // This is ugly because Checker holds onto mir,
             // which can't be mutated until its scope ends.
             let (temps, candidates) = {
@@ -1664,6 +1650,11 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
                 promote_consts::promote_candidates(def_id, body, tcx, temps, candidates)
             );
         } else {
+            let const_promoted_temps = match mode {
+                Mode::Const => Some(tcx.mir_const_qualif(def_id).1),
+                _ => None,
+            };
+
             if !body.control_flow_destroyed.is_empty() {
                 let mut locals = body.vars_iter();
                 if let Some(local) = locals.next() {
@@ -1695,11 +1686,10 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
                     error.emit();
                 }
             }
-            let promoted_temps = if mode == Mode::Const {
+            let promoted_temps = match mode {
                 // Already computed by `mir_const_qualif`.
-                const_promoted_temps.unwrap()
-            } else {
-                Checker::new(tcx, def_id, body, mode).check_const().1
+                Mode::Const => const_promoted_temps.unwrap(),
+                _ => Checker::new(tcx, def_id, body, mode).check_const().1,
             };
 
             // In `const` and `static` everything without `StorageDead`
@@ -1747,7 +1737,7 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
             let ty = body.return_ty();
             tcx.infer_ctxt().enter(|infcx| {
                 let param_env = ty::ParamEnv::empty();
-                let cause = traits::ObligationCause::new(body.span, id, traits::SharedStatic);
+                let cause = traits::ObligationCause::new(body.span, hir_id, traits::SharedStatic);
                 let mut fulfillment_cx = traits::FulfillmentContext::new();
                 fulfillment_cx.register_bound(&infcx,
                                               param_env,
@@ -1765,6 +1755,17 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
     }
 }
 
+fn determine_mode(tcx: TyCtxt<'_>, hir_id: HirId, def_id: DefId) -> Mode {
+    match tcx.hir().body_owner_kind(hir_id) {
+        hir::BodyOwnerKind::Closure => Mode::NonConstFn,
+        hir::BodyOwnerKind::Fn if tcx.is_const_fn(def_id) => Mode::ConstFn,
+        hir::BodyOwnerKind::Fn => Mode::NonConstFn,
+        hir::BodyOwnerKind::Const => Mode::Const,
+        hir::BodyOwnerKind::Static(hir::MutImmutable) => Mode::Static,
+        hir::BodyOwnerKind::Static(hir::MutMutable) => Mode::StaticMut,
+    }
+}
+
 fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<FxHashSet<usize>> {
     let attrs = tcx.get_attrs(def_id);
     let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?;

From 8f184b369d6332195ef61f0395cf32bd787e4368 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 29 Aug 2019 08:58:52 +0200
Subject: [PATCH 367/943] qualify_consts: misc cleanup.

---
 src/librustc_mir/transform/qualify_consts.rs | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 959d21ecfadeb..fcbb3433a62d9 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1714,12 +1714,8 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
                         },
                         target,
                         ..
-                    } => {
-                        if promoted_temps.contains(index) {
-                            terminator.kind = TerminatorKind::Goto {
-                                target,
-                            };
-                        }
+                    } if promoted_temps.contains(index) => {
+                        terminator.kind = TerminatorKind::Goto { target };
                     }
                     _ => {}
                 }
@@ -1727,7 +1723,7 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
         }
 
         // Statics must be Sync.
-        if mode == Mode::Static {
+        if let Mode::Static = mode {
             // `#[thread_local]` statics don't have to be `Sync`.
             for attr in &tcx.get_attrs(def_id)[..] {
                 if attr.check_name(sym::thread_local) {

From b6360fbc4c6d3898d51dfcbe9b042fef515133d1 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 29 Aug 2019 09:10:26 +0200
Subject: [PATCH 368/943] qualify_consts: extract
 check_short_circuiting_in_const_local.

---
 src/librustc_mir/transform/qualify_consts.rs | 66 +++++++++++---------
 1 file changed, 35 insertions(+), 31 deletions(-)

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index fcbb3433a62d9..0a9e2a5974300 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1655,37 +1655,8 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
                 _ => None,
             };
 
-            if !body.control_flow_destroyed.is_empty() {
-                let mut locals = body.vars_iter();
-                if let Some(local) = locals.next() {
-                    let span = body.local_decls[local].source_info.span;
-                    let mut error = tcx.sess.struct_span_err(
-                        span,
-                        &format!(
-                            "new features like let bindings are not permitted in {}s \
-                            which also use short circuiting operators",
-                            mode,
-                        ),
-                    );
-                    for (span, kind) in body.control_flow_destroyed.iter() {
-                        error.span_note(
-                            *span,
-                            &format!("use of {} here does not actually short circuit due to \
-                            the const evaluator presently not being able to do control flow. \
-                            See https://github.com/rust-lang/rust/issues/49146 for more \
-                            information.", kind),
-                        );
-                    }
-                    for local in locals {
-                        let span = body.local_decls[local].source_info.span;
-                        error.span_note(
-                            span,
-                            "more locals defined here",
-                        );
-                    }
-                    error.emit();
-                }
-            }
+            check_short_circuiting_in_const_local(tcx, body, mode);
+
             let promoted_temps = match mode {
                 // Already computed by `mir_const_qualif`.
                 Mode::Const => const_promoted_temps.unwrap(),
@@ -1762,6 +1733,39 @@ fn determine_mode(tcx: TyCtxt<'_>, hir_id: HirId, def_id: DefId) -> Mode {
     }
 }
 
+fn check_short_circuiting_in_const_local(tcx: TyCtxt<'_>, body: &mut Body<'tcx>, mode: Mode) {
+    if body.control_flow_destroyed.is_empty() {
+        return;
+    }
+
+    let mut locals = body.vars_iter();
+    if let Some(local) = locals.next() {
+        let span = body.local_decls[local].source_info.span;
+        let mut error = tcx.sess.struct_span_err(
+            span,
+            &format!(
+                "new features like let bindings are not permitted in {}s \
+                which also use short circuiting operators",
+                mode,
+            ),
+        );
+        for (span, kind) in body.control_flow_destroyed.iter() {
+            error.span_note(
+                *span,
+                &format!("use of {} here does not actually short circuit due to \
+                the const evaluator presently not being able to do control flow. \
+                See https://github.com/rust-lang/rust/issues/49146 for more \
+                information.", kind),
+            );
+        }
+        for local in locals {
+            let span = body.local_decls[local].source_info.span;
+            error.span_note(span, "more locals defined here");
+        }
+        error.emit();
+    }
+}
+
 fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<FxHashSet<usize>> {
     let attrs = tcx.get_attrs(def_id);
     let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?;

From c1d440070e088c6b239bcf5f9f22dfc6d5b2b639 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 29 Aug 2019 09:15:59 +0200
Subject: [PATCH 369/943] qualify_consts: fuse prompted_temps.

---
 src/librustc_mir/transform/qualify_consts.rs | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 0a9e2a5974300..b052d1e9bb468 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1650,16 +1650,10 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
                 promote_consts::promote_candidates(def_id, body, tcx, temps, candidates)
             );
         } else {
-            let const_promoted_temps = match mode {
-                Mode::Const => Some(tcx.mir_const_qualif(def_id).1),
-                _ => None,
-            };
-
             check_short_circuiting_in_const_local(tcx, body, mode);
 
             let promoted_temps = match mode {
-                // Already computed by `mir_const_qualif`.
-                Mode::Const => const_promoted_temps.unwrap(),
+                Mode::Const => tcx.mir_const_qualif(def_id).1,
                 _ => Checker::new(tcx, def_id, body, mode).check_const().1,
             };
 

From 7bfa2be4efa2d4649e8db7548f1980156d58017e Mon Sep 17 00:00:00 2001
From: Tyler Mandry <tmandry@gmail.com>
Date: Fri, 30 Aug 2019 18:21:57 -0700
Subject: [PATCH 370/943] fuchsia: Don't fail to spawn if no stdin exists

---
 .../sys/unix/process/process_fuchsia.rs       | 57 ++++++++++++-------
 src/libstd/sys/unix/process/zircon.rs         |  6 +-
 2 files changed, 41 insertions(+), 22 deletions(-)

diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs
index 295ec59eb32cf..2b3795292f42a 100644
--- a/src/libstd/sys/unix/process/process_fuchsia.rs
+++ b/src/libstd/sys/unix/process/process_fuchsia.rs
@@ -52,30 +52,45 @@ impl Command {
             None => ptr::null(),
         };
 
-        let make_action = |local_io: &ChildStdio, target_fd| if let Some(local_fd) = local_io.fd() {
-            fdio_spawn_action_t {
-                action: FDIO_SPAWN_ACTION_TRANSFER_FD,
-                local_fd,
-                target_fd,
-                ..Default::default()
-            }
-        } else {
-            if let ChildStdio::Null = local_io {
-                // acts as no-op
-                return Default::default();
-            }
-            fdio_spawn_action_t {
-                action: FDIO_SPAWN_ACTION_CLONE_FD,
-                local_fd: target_fd,
-                target_fd,
-                ..Default::default()
+        let make_action = |local_io: &ChildStdio, target_fd| -> io::Result<fdio_spawn_action_t> {
+            if let Some(local_fd) = local_io.fd() {
+                Ok(fdio_spawn_action_t {
+                    action: FDIO_SPAWN_ACTION_TRANSFER_FD,
+                    local_fd,
+                    target_fd,
+                    ..Default::default()
+                })
+            } else {
+                if let ChildStdio::Null = local_io {
+                    // acts as no-op
+                    return Ok(Default::default());
+                }
+
+                let mut handle = ZX_HANDLE_INVALID;
+                let status = fdio_fd_clone(target_fd, &mut handle);
+                if status == ERR_INVALID_ARGS || status == ERR_NOT_SUPPORTED {
+                    // This descriptor is closed; skip it rather than generating an
+                    // error.
+                    return Ok(Default::default());
+                }
+                zx_cvt(status)?;
+
+                let mut cloned_fd = 0;
+                zx_cvt(fdio_fd_create(handle, &mut cloned_fd))?;
+
+                Ok(fdio_spawn_action_t {
+                    action: FDIO_SPAWN_ACTION_TRANSFER_FD,
+                    local_fd: cloned_fd as i32,
+                    target_fd,
+                    ..Default::default()
+                })
             }
         };
 
         // Clone stdin, stdout, and stderr
-        let action1 = make_action(&stdio.stdin, 0);
-        let action2 = make_action(&stdio.stdout, 1);
-        let action3 = make_action(&stdio.stderr, 2);
+        let action1 = make_action(&stdio.stdin, 0)?;
+        let action2 = make_action(&stdio.stdout, 1)?;
+        let action3 = make_action(&stdio.stderr, 2)?;
         let actions = [action1, action2, action3];
 
         // We don't want FileDesc::drop to be called on any stdio. fdio_spawn_etc
@@ -88,7 +103,7 @@ impl Command {
 
         let mut process_handle: zx_handle_t = 0;
         zx_cvt(fdio_spawn_etc(
-            0,
+            ZX_HANDLE_INVALID,
             FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE,
             self.get_argv()[0], self.get_argv().as_ptr(), envp,
             actions.len() as size_t, actions.as_ptr(),
diff --git a/src/libstd/sys/unix/process/zircon.rs b/src/libstd/sys/unix/process/zircon.rs
index 29032f5e0d200..1ba48de3c0785 100644
--- a/src/libstd/sys/unix/process/zircon.rs
+++ b/src/libstd/sys/unix/process/zircon.rs
@@ -2,8 +2,9 @@
 
 use crate::convert::TryInto;
 use crate::io;
-use crate::os::raw::c_char;
 use crate::i64;
+use crate::mem::MaybeUninit;
+use crate::os::raw::c_char;
 
 use libc::{c_int, c_void, size_t};
 
@@ -122,6 +123,9 @@ extern {
                           argv: *const *const c_char, envp: *const *const c_char,
                           action_count: size_t, actions: *const fdio_spawn_action_t,
                           process: *mut zx_handle_t, err_msg: *mut c_char) -> zx_status_t;
+
+    pub fn fdio_fd_clone(fd: c_int, out_handle: *mut zx_handle_t) -> zx_status_t;
+    pub fn fdio_fd_create(handle: zx_handle_t, fd: *mut c_int) -> zx_status_t;
 }
 
 // fdio_spawn_etc flags

From 5f91ad0e3300c36033bf409ceefb00480fecbed3 Mon Sep 17 00:00:00 2001
From: Tyler Mandry <tmandry@gmail.com>
Date: Fri, 30 Aug 2019 18:52:19 -0700
Subject: [PATCH 371/943] fuchsia: Fix default environment behavior when
 spawning

---
 src/libstd/sys/unix/process/process_fuchsia.rs | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs
index 2b3795292f42a..fff9fc6b3bbc8 100644
--- a/src/libstd/sys/unix/process/process_fuchsia.rs
+++ b/src/libstd/sys/unix/process/process_fuchsia.rs
@@ -48,8 +48,10 @@ impl Command {
         use crate::sys::process::zircon::*;
 
         let envp = match maybe_envp {
-            Some(envp) => envp.as_ptr(),
+            // None means to clone the current environment, which is done in the
+            // flags below.
             None => ptr::null(),
+            Some(envp) => envp.as_ptr(),
         };
 
         let make_action = |local_io: &ChildStdio, target_fd| -> io::Result<fdio_spawn_action_t> {
@@ -104,7 +106,8 @@ impl Command {
         let mut process_handle: zx_handle_t = 0;
         zx_cvt(fdio_spawn_etc(
             ZX_HANDLE_INVALID,
-            FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE,
+            FDIO_SPAWN_CLONE_JOB | FDIO_SPAWN_CLONE_LDSVC | FDIO_SPAWN_CLONE_NAMESPACE
+            | FDIO_SPAWN_CLONE_ENVIRON,  // this is ignored when envp is non-null
             self.get_argv()[0], self.get_argv().as_ptr(), envp,
             actions.len() as size_t, actions.as_ptr(),
             &mut process_handle,

From bf90154410b372ad0c8731a6d470acd9bf820f7e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 30 Aug 2019 19:47:21 -0700
Subject: [PATCH 372/943] Tweak terminal width trimming

Properly account for left margin when setting terminal width through
CLI flag and don't trim code by default if we can't get the terminal's
dimensions.
---
 src/librustc_errors/emitter.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index fddb6c5c259c9..02473cc86bdff 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -1304,11 +1304,11 @@ impl EmitterWriter {
                 };
 
                 let column_width = if let Some(width) = self.terminal_width {
-                    width
+                    max(width, code_offset) - code_offset
                 } else if self.ui_testing {
                     140
                 } else {
-                    term_size::dimensions().map(|(w, _)| w - code_offset).unwrap_or(140)
+                    term_size::dimensions().map(|(w, _)| w - code_offset).unwrap_or(std::usize::MAX)
                 };
 
                 let margin = Margin::new(

From 3c4d157c8419d73574587a22a8095ad32d860af5 Mon Sep 17 00:00:00 2001
From: Jethro Beekman <jethro@fortanix.com>
Date: Fri, 30 Aug 2019 20:35:27 -0700
Subject: [PATCH 373/943] Fix unlock ordering in SGX synchronization primitives

---
 src/libstd/sys/sgx/condvar.rs   |  3 +--
 src/libstd/sys/sgx/mutex.rs     |  4 ++--
 src/libstd/sys/sgx/rwlock.rs    | 34 +++++++++++++++++++--------------
 src/libstd/sys/sgx/waitqueue.rs | 11 +++++++++--
 4 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/src/libstd/sys/sgx/condvar.rs b/src/libstd/sys/sgx/condvar.rs
index 000bb19f2692a..cc1c04a83e752 100644
--- a/src/libstd/sys/sgx/condvar.rs
+++ b/src/libstd/sys/sgx/condvar.rs
@@ -27,8 +27,7 @@ impl Condvar {
 
     pub unsafe fn wait(&self, mutex: &Mutex) {
         let guard = self.inner.lock();
-        mutex.unlock();
-        WaitQueue::wait(guard);
+        WaitQueue::wait(guard, || mutex.unlock());
         mutex.lock()
     }
 
diff --git a/src/libstd/sys/sgx/mutex.rs b/src/libstd/sys/sgx/mutex.rs
index f325fb1dd582f..662da8b3f6685 100644
--- a/src/libstd/sys/sgx/mutex.rs
+++ b/src/libstd/sys/sgx/mutex.rs
@@ -22,7 +22,7 @@ impl Mutex {
         let mut guard = self.inner.lock();
         if *guard.lock_var() {
             // Another thread has the lock, wait
-            WaitQueue::wait(guard)
+            WaitQueue::wait(guard, ||{})
             // Another thread has passed the lock to us
         } else {
             // We are just now obtaining the lock
@@ -83,7 +83,7 @@ impl ReentrantMutex {
         match guard.lock_var().owner {
             Some(tcs) if tcs != thread::current() => {
                 // Another thread has the lock, wait
-                WaitQueue::wait(guard);
+                WaitQueue::wait(guard, ||{});
                 // Another thread has passed the lock to us
             },
             _ => {
diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs
index 30c47e44eef8e..e2f94b1d928e1 100644
--- a/src/libstd/sys/sgx/rwlock.rs
+++ b/src/libstd/sys/sgx/rwlock.rs
@@ -31,7 +31,7 @@ impl RWLock {
         if *wguard.lock_var() || !wguard.queue_empty() {
             // Another thread has or is waiting for the write lock, wait
             drop(wguard);
-            WaitQueue::wait(rguard);
+            WaitQueue::wait(rguard, ||{});
             // Another thread has passed the lock to us
         } else {
             // No waiting writers, acquire the read lock
@@ -62,7 +62,7 @@ impl RWLock {
         if *wguard.lock_var() || rguard.lock_var().is_some() {
             // Another thread has the lock, wait
             drop(rguard);
-            WaitQueue::wait(wguard);
+            WaitQueue::wait(wguard, ||{});
             // Another thread has passed the lock to us
         } else {
             // We are just now obtaining the lock
@@ -97,6 +97,7 @@ impl RWLock {
             if let Ok(mut wguard) = WaitQueue::notify_one(wguard) {
                 // A writer was waiting, pass the lock
                 *wguard.lock_var_mut() = true;
+                wguard.drop_after(rguard);
             } else {
                 // No writers were waiting, the lock is released
                 rtassert!(rguard.queue_empty());
@@ -117,21 +118,26 @@ impl RWLock {
         rguard: SpinMutexGuard<'_, WaitVariable<Option<NonZeroUsize>>>,
         wguard: SpinMutexGuard<'_, WaitVariable<bool>>,
     ) {
-        if let Err(mut wguard) = WaitQueue::notify_one(wguard) {
-            // No writers waiting, release the write lock
-            *wguard.lock_var_mut() = false;
-            if let Ok(mut rguard) = WaitQueue::notify_all(rguard) {
-                // One or more readers were waiting, pass the lock to them
-                if let NotifiedTcs::All { count } = rguard.notified_tcs() {
-                    *rguard.lock_var_mut() = Some(count)
+        match WaitQueue::notify_one(wguard) {
+            Err(mut wguard) => {
+                // No writers waiting, release the write lock
+                *wguard.lock_var_mut() = false;
+                if let Ok(mut rguard) = WaitQueue::notify_all(rguard) {
+                    // One or more readers were waiting, pass the lock to them
+                    if let NotifiedTcs::All { count } = rguard.notified_tcs() {
+                        *rguard.lock_var_mut() = Some(count)
+                    } else {
+                        unreachable!() // called notify_all
+                    }
+                    rguard.drop_after(wguard);
                 } else {
-                    unreachable!() // called notify_all
+                    // No readers waiting, the lock is released
                 }
-            } else {
-                // No readers waiting, the lock is released
+            },
+            Ok(wguard) => {
+                // There was a thread waiting for write, just pass the lock
+                wguard.drop_after(rguard);
             }
-        } else {
-            // There was a thread waiting for write, just pass the lock
         }
     }
 
diff --git a/src/libstd/sys/sgx/waitqueue.rs b/src/libstd/sys/sgx/waitqueue.rs
index d542f9b410127..3cb40e509b6b2 100644
--- a/src/libstd/sys/sgx/waitqueue.rs
+++ b/src/libstd/sys/sgx/waitqueue.rs
@@ -98,6 +98,12 @@ impl<'a, T> WaitGuard<'a, T> {
     pub fn notified_tcs(&self) -> NotifiedTcs {
         self.notified_tcs
     }
+
+    /// Drop this `WaitGuard`, after dropping another `guard`.
+    pub fn drop_after<U>(self, guard: U) {
+        drop(guard);
+        drop(self);
+    }
 }
 
 impl<'a, T> Deref for WaitGuard<'a, T> {
@@ -140,7 +146,7 @@ impl WaitQueue {
     /// until a wakeup event.
     ///
     /// This function does not return until this thread has been awoken.
-    pub fn wait<T>(mut guard: SpinMutexGuard<'_, WaitVariable<T>>) {
+    pub fn wait<T, F: FnOnce()>(mut guard: SpinMutexGuard<'_, WaitVariable<T>>, before_wait: F) {
         // very unsafe: check requirements of UnsafeList::push
         unsafe {
             let mut entry = UnsafeListEntry::new(SpinMutex::new(WaitEntry {
@@ -149,6 +155,7 @@ impl WaitQueue {
             }));
             let entry = guard.queue.inner.push(&mut entry);
             drop(guard);
+            before_wait();
             while !entry.lock().wake {
                 // don't panic, this would invalidate `entry` during unwinding
                 let eventset = rtunwrap!(Ok, usercalls::wait(EV_UNPARK, WAIT_INDEFINITE));
@@ -545,7 +552,7 @@ mod tests {
             assert!(WaitQueue::notify_one(wq2.lock()).is_ok());
         });
 
-        WaitQueue::wait(locked);
+        WaitQueue::wait(locked, ||{});
 
         t1.join().unwrap();
     }

From 8af33b325377ea64fb9bbdc10073f9063293c9a6 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 29 Aug 2019 09:35:37 +0200
Subject: [PATCH 374/943] qualify_consts: extract
 check_non_thread_local_static_is_sync

---
 src/librustc_mir/transform/qualify_consts.rs | 49 ++++++++++----------
 1 file changed, 25 insertions(+), 24 deletions(-)

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index b052d1e9bb468..dbb994183e9d5 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1687,31 +1687,9 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
             }
         }
 
-        // Statics must be Sync.
         if let Mode::Static = mode {
-            // `#[thread_local]` statics don't have to be `Sync`.
-            for attr in &tcx.get_attrs(def_id)[..] {
-                if attr.check_name(sym::thread_local) {
-                    return;
-                }
-            }
-            let ty = body.return_ty();
-            tcx.infer_ctxt().enter(|infcx| {
-                let param_env = ty::ParamEnv::empty();
-                let cause = traits::ObligationCause::new(body.span, hir_id, traits::SharedStatic);
-                let mut fulfillment_cx = traits::FulfillmentContext::new();
-                fulfillment_cx.register_bound(&infcx,
-                                              param_env,
-                                              ty,
-                                              tcx.require_lang_item(
-                                                  lang_items::SyncTraitLangItem,
-                                                  Some(body.span)
-                                              ),
-                                              cause);
-                if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
-                    infcx.report_fulfillment_errors(&err, None, false);
-                }
-            });
+            // `static`s (not `static mut`s) which are not `#[thread_local]` must be `Sync`.
+            check_non_thread_local_static_is_sync(tcx, body, def_id, hir_id);
         }
     }
 }
@@ -1760,6 +1738,29 @@ fn check_short_circuiting_in_const_local(tcx: TyCtxt<'_>, body: &mut Body<'tcx>,
     }
 }
 
+fn check_non_thread_local_static_is_sync(
+    tcx: TyCtxt<'tcx>,
+    body: &mut Body<'tcx>,
+    def_id: DefId,
+    hir_id: HirId,
+) {
+    // `#[thread_local]` statics don't have to be `Sync`.
+    if tcx.has_attr(def_id, sym::thread_local) {
+        return;
+    }
+
+    let ty = body.return_ty();
+    tcx.infer_ctxt().enter(|infcx| {
+        let cause = traits::ObligationCause::new(body.span, hir_id, traits::SharedStatic);
+        let mut fulfillment_cx = traits::FulfillmentContext::new();
+        let sync_def_id = tcx.require_lang_item(lang_items::SyncTraitLangItem, Some(body.span));
+        fulfillment_cx.register_bound(&infcx, ty::ParamEnv::empty(), ty, sync_def_id, cause);
+        if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
+            infcx.report_fulfillment_errors(&err, None, false);
+        }
+    });
+}
+
 fn args_required_const(tcx: TyCtxt<'_>, def_id: DefId) -> Option<FxHashSet<usize>> {
     let attrs = tcx.get_attrs(def_id);
     let attr = attrs.iter().find(|a| a.check_name(sym::rustc_args_required_const))?;

From 2f733aad5a73b7cb8ceec37a8ecec497f8807034 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 29 Aug 2019 09:43:16 +0200
Subject: [PATCH 375/943] qualify_consts: extract
 remove_drop_and_storage_dead_on_promoted_locals.

---
 src/librustc_mir/transform/qualify_consts.rs | 63 +++++++++++---------
 1 file changed, 34 insertions(+), 29 deletions(-)

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index dbb994183e9d5..fe02e120f3b49 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1656,35 +1656,7 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
                 Mode::Const => tcx.mir_const_qualif(def_id).1,
                 _ => Checker::new(tcx, def_id, body, mode).check_const().1,
             };
-
-            // In `const` and `static` everything without `StorageDead`
-            // is `'static`, we don't have to create promoted MIR fragments,
-            // just remove `Drop` and `StorageDead` on "promoted" locals.
-            debug!("run_pass: promoted_temps={:?}", promoted_temps);
-            for block in body.basic_blocks_mut() {
-                block.statements.retain(|statement| {
-                    match statement.kind {
-                        StatementKind::StorageDead(index) => {
-                            !promoted_temps.contains(index)
-                        }
-                        _ => true
-                    }
-                });
-                let terminator = block.terminator_mut();
-                match terminator.kind {
-                    TerminatorKind::Drop {
-                        location: Place {
-                            base: PlaceBase::Local(index),
-                            projection: None,
-                        },
-                        target,
-                        ..
-                    } if promoted_temps.contains(index) => {
-                        terminator.kind = TerminatorKind::Goto { target };
-                    }
-                    _ => {}
-                }
-            }
+            remove_drop_and_storage_dead_on_promoted_locals(body, promoted_temps);
         }
 
         if let Mode::Static = mode {
@@ -1738,6 +1710,39 @@ fn check_short_circuiting_in_const_local(tcx: TyCtxt<'_>, body: &mut Body<'tcx>,
     }
 }
 
+/// In `const` and `static` everything without `StorageDead`
+/// is `'static`, we don't have to create promoted MIR fragments,
+/// just remove `Drop` and `StorageDead` on "promoted" locals.
+fn remove_drop_and_storage_dead_on_promoted_locals(
+    body: &mut Body<'tcx>,
+    promoted_temps: &BitSet<Local>,
+) {
+    debug!("run_pass: promoted_temps={:?}", promoted_temps);
+
+    for block in body.basic_blocks_mut() {
+        block.statements.retain(|statement| {
+            match statement.kind {
+                StatementKind::StorageDead(index) => !promoted_temps.contains(index),
+                _ => true
+            }
+        });
+        let terminator = block.terminator_mut();
+        match terminator.kind {
+            TerminatorKind::Drop {
+                location: Place {
+                    base: PlaceBase::Local(index),
+                    projection: None,
+                },
+                target,
+                ..
+            } if promoted_temps.contains(index) => {
+                terminator.kind = TerminatorKind::Goto { target };
+            }
+            _ => {}
+        }
+    }
+}
+
 fn check_non_thread_local_static_is_sync(
     tcx: TyCtxt<'tcx>,
     body: &mut Body<'tcx>,

From 9196af0b3647c29cb1c268ba9b01546df55fc004 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 29 Aug 2019 10:16:41 +0200
Subject: [PATCH 376/943] qualify_consts: extract error_min_const_fn_violation.

---
 src/librustc_mir/transform/qualify_consts.rs | 26 +++++++++-----------
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index fe02e120f3b49..73475be24d445 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -25,6 +25,7 @@ use syntax::feature_gate::{emit_feature_err, GateIssue};
 use syntax::symbol::sym;
 use syntax_pos::{Span, DUMMY_SP};
 
+use std::borrow::Cow;
 use std::cell::Cell;
 use std::fmt;
 use std::ops::{Deref, Index, IndexMut};
@@ -1607,26 +1608,14 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
             // which can't be mutated until its scope ends.
             let (temps, candidates) = {
                 let mut checker = Checker::new(tcx, def_id, body, mode);
-                if mode == Mode::ConstFn {
+                if let Mode::ConstFn = mode {
                     if tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you {
                         checker.check_const();
                     } else if tcx.is_min_const_fn(def_id) {
-                        // enforce `min_const_fn` for stable const fns
+                        // Enforce `min_const_fn` for stable `const fn`s.
                         use super::qualify_min_const_fn::is_min_const_fn;
                         if let Err((span, err)) = is_min_const_fn(tcx, def_id, body) {
-                            let mut diag = struct_span_err!(
-                                tcx.sess,
-                                span,
-                                E0723,
-                                "{}",
-                                err,
-                            );
-                            diag.note("for more information, see issue \
-                                       https://github.com/rust-lang/rust/issues/57563");
-                            diag.help(
-                                "add `#![feature(const_fn)]` to the crate attributes to enable",
-                            );
-                            diag.emit();
+                            error_min_const_fn_violation(tcx, span, err);
                         } else {
                             // this should not produce any errors, but better safe than sorry
                             // FIXME(#53819)
@@ -1677,6 +1666,13 @@ fn determine_mode(tcx: TyCtxt<'_>, hir_id: HirId, def_id: DefId) -> Mode {
     }
 }
 
+fn error_min_const_fn_violation(tcx: TyCtxt<'_>, span: Span, msg: Cow<'_, str>) {
+    struct_span_err!(tcx.sess, span, E0723, "{}", msg)
+        .note("for more information, see issue https://github.com/rust-lang/rust/issues/57563")
+        .help("add `#![feature(const_fn)]` to the crate attributes to enable")
+        .emit();
+}
+
 fn check_short_circuiting_in_const_local(tcx: TyCtxt<'_>, body: &mut Body<'tcx>, mode: Mode) {
     if body.control_flow_destroyed.is_empty() {
         return;

From 0a8a3dd88a1216e7487b8e39179fbac16d07bafe Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 31 Aug 2019 06:17:10 +0200
Subject: [PATCH 377/943] qualify_consts: move thread_local condition out.

---
 src/librustc_mir/transform/qualify_consts.rs | 16 +++-------------
 1 file changed, 3 insertions(+), 13 deletions(-)

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 73475be24d445..32b49ee942300 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1648,9 +1648,9 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
             remove_drop_and_storage_dead_on_promoted_locals(body, promoted_temps);
         }
 
-        if let Mode::Static = mode {
+        if mode == Mode::Static && !tcx.has_attr(def_id, sym::thread_local) {
             // `static`s (not `static mut`s) which are not `#[thread_local]` must be `Sync`.
-            check_non_thread_local_static_is_sync(tcx, body, def_id, hir_id);
+            check_static_is_sync(tcx, body, hir_id);
         }
     }
 }
@@ -1739,17 +1739,7 @@ fn remove_drop_and_storage_dead_on_promoted_locals(
     }
 }
 
-fn check_non_thread_local_static_is_sync(
-    tcx: TyCtxt<'tcx>,
-    body: &mut Body<'tcx>,
-    def_id: DefId,
-    hir_id: HirId,
-) {
-    // `#[thread_local]` statics don't have to be `Sync`.
-    if tcx.has_attr(def_id, sym::thread_local) {
-        return;
-    }
-
+fn check_static_is_sync(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, hir_id: HirId) {
     let ty = body.return_ty();
     tcx.infer_ctxt().enter(|infcx| {
         let cause = traits::ObligationCause::new(body.span, hir_id, traits::SharedStatic);

From 5187a3e15723c85cd7ef3418b0c0e61c79709f4c Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sat, 31 Aug 2019 07:08:23 +0200
Subject: [PATCH 378/943] Harden param_attrs test wrt. usage of proc macro
 attrs.

---
 .../auxiliary/ident-mac.rs                    |  11 +
 .../proc-macro-cannot-be-used.rs              |  60 +++++
 .../proc-macro-cannot-be-used.stderr          | 228 ++++++++++++++++++
 3 files changed, 299 insertions(+)
 create mode 100644 src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs
 create mode 100644 src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
 create mode 100644 src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr

diff --git a/src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs b/src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs
new file mode 100644
index 0000000000000..b62cf31205fd3
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs
@@ -0,0 +1,11 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn id(_: TokenStream, input: TokenStream) -> TokenStream { input }
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
new file mode 100644
index 0000000000000..8defa26e48d8d
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
@@ -0,0 +1,60 @@
+// aux-build:ident-mac.rs
+
+#![feature(param_attrs)]
+#![feature(c_variadic)]
+
+extern crate ident_mac;
+use ident_mac::id;
+
+struct W(u8);
+
+extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
+//~^ ERROR the attribute `id` is currently unknown to the compiler
+//~| ERROR the attribute `id` is currently unknown to the compiler
+
+unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
+//~^ ERROR the attribute `id` is currently unknown to the compiler
+
+type Alias = extern "C" fn(#[id] u8, #[id] ...);
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+
+fn free(#[id] arg1: u8) {
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    let lam = |#[id] W(x), #[id] y| ();
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+}
+
+impl W {
+    fn inherent1(#[id] self, #[id] arg1: u8) {}
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn inherent2(#[id] &self, #[id] arg1: u8) {}
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+}
+
+trait A {
+    fn trait1(#[id] self, #[id] arg1: u8);
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn trait2(#[id] &self, #[id] arg1: u8);
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
new file mode 100644
index 0000000000000..69b9a46b3d502
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
@@ -0,0 +1,228 @@
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:11:21
+   |
+LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
+   |                     ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:11:38
+   |
+LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
+   |                                      ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:15:38
+   |
+LL | unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
+   |                                      ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:18:28
+   |
+LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
+   |                            ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:18:38
+   |
+LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
+   |                                      ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:22:9
+   |
+LL | fn free(#[id] arg1: u8) {
+   |         ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:24:16
+   |
+LL |     let lam = |#[id] W(x), #[id] y| ();
+   |                ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:24:28
+   |
+LL |     let lam = |#[id] W(x), #[id] y| ();
+   |                            ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:30:18
+   |
+LL |     fn inherent1(#[id] self, #[id] arg1: u8) {}
+   |                  ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:30:30
+   |
+LL |     fn inherent1(#[id] self, #[id] arg1: u8) {}
+   |                              ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:33:18
+   |
+LL |     fn inherent2(#[id] &self, #[id] arg1: u8) {}
+   |                  ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:33:31
+   |
+LL |     fn inherent2(#[id] &self, #[id] arg1: u8) {}
+   |                               ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:36:22
+   |
+LL |     fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
+   |                      ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:36:42
+   |
+LL |     fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
+   |                                          ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:39:22
+   |
+LL |     fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
+   |                      ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:39:45
+   |
+LL |     fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
+   |                                             ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:45:15
+   |
+LL |     fn trait1(#[id] self, #[id] arg1: u8);
+   |               ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:45:27
+   |
+LL |     fn trait1(#[id] self, #[id] arg1: u8);
+   |                           ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:48:15
+   |
+LL |     fn trait2(#[id] &self, #[id] arg1: u8);
+   |               ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:48:28
+   |
+LL |     fn trait2(#[id] &self, #[id] arg1: u8);
+   |                            ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:51:19
+   |
+LL |     fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
+   |                   ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:51:39
+   |
+LL |     fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
+   |                                       ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:54:19
+   |
+LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
+   |                   ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:54:42
+   |
+LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
+   |                                          ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:54:58
+   |
+LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
+   |                                                          ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error: aborting due to 25 previous errors
+
+For more information about this error, try `rustc --explain E0658`.

From 444bc3ca6607f7bdeb088b34db23c01e056900b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 24 Aug 2019 14:44:43 -0700
Subject: [PATCH 379/943] Use span label instead of note for cause in E0631

---
 src/librustc/traits/error_reporting.rs        |  37 +-
 .../anonymous-higher-ranked-lifetime.stderr   | 154 ++-----
 .../associated-const-array-len.stderr         |   9 +-
 ...iated-const-type-parameter-arrays-2.stderr |   8 +-
 ...ociated-const-type-parameter-arrays.stderr |   8 +-
 .../bad-bounds-on-assoc-in-trait.stderr       |  24 +-
 ...nding-to-type-defined-in-supertrait.stderr |  16 +-
 .../associated-types-bound-failure.stderr     |   8 +-
 .../associated-types-eq-3.stderr              |   8 +-
 .../associated-types-eq-hr.stderr             | 102 ++---
 .../associated-types-issue-20346.stderr       |   8 +-
 ...ated-types-multiple-types-one-trait.stderr |  16 +-
 ...associated-types-overridden-binding.stderr |   8 +-
 .../associated-types-path-2.stderr            |  18 +-
 .../higher-ranked-projection.bad.stderr       |  11 +-
 .../ui/async-await/async-fn-nonsend.stderr    |  32 +-
 src/test/ui/chalkify/type_inference.stderr    |   8 +-
 .../expect-fn-supply-fn.stderr                |  45 +-
 .../expect-infer-var-appearing-twice.stderr   |  15 +-
 ...ds-cant-promote-superkind-in-struct.stderr |   8 +-
 .../ui/closures/closure-bounds-subtype.stderr |   8 +-
 .../ui/consts/too_generic_eval_ice.stderr     |  16 +-
 src/test/ui/defaulted-never-note.stderr       |   8 +-
 src/test/ui/derives/deriving-copyclone.stderr |  24 +-
 .../issue-39802-show-5-trait-impls.stderr     |  24 +-
 .../ui/did_you_mean/recursion_limit.stderr    |   8 +-
 src/test/ui/error-codes/E0271.stderr          |   8 +-
 src/test/ui/error-codes/E0275.stderr          |   8 +-
 src/test/ui/error-codes/E0277-2.stderr        |   8 +-
 src/test/ui/error-codes/E0277.stderr          |   9 +-
 src/test/ui/error-codes/E0283.stderr          |   9 +-
 .../ui/error-should-say-copy-not-pod.stderr   |   9 +-
 .../extern/extern-types-not-sync-send.stderr  |  16 +-
 .../ui/extern/extern-types-unsized.stderr     |  32 +-
 .../ui/extern/extern-wrong-value-type.stderr  |   8 +-
 src/test/ui/fmt/send-sync.stderr              |  16 +-
 src/test/ui/fn/fn-trait-formatting.stderr     |   8 +-
 ...erator-yielding-or-returning-itself.stderr |  18 +-
 src/test/ui/generator/not-send-sync.stderr    |  16 +-
 src/test/ui/generator/static-not-unpin.stderr |   9 +-
 src/test/ui/hrtb/hrtb-conflate-regions.stderr |  16 +-
 ...b-exists-forall-trait-contravariant.stderr |  16 +-
 .../hrtb-exists-forall-trait-covariant.stderr |  16 +-
 .../hrtb-exists-forall-trait-invariant.stderr |  16 +-
 ...igher-ranker-supertraits-transitive.stderr |  14 +-
 .../hrtb-higher-ranker-supertraits.stderr     |  28 +-
 src/test/ui/hrtb/hrtb-just-for-static.stderr  |  32 +-
 src/test/ui/hrtb/issue-46989.stderr           |   8 +-
 src/test/ui/impl-trait/auto-trait-leak.stderr |   8 +-
 .../ui/impl-trait/auto-trait-leak2.stderr     |  16 +-
 src/test/ui/issues/issue-1920-1.stderr        |   9 +-
 src/test/ui/issues/issue-1920-2.stderr        |   9 +-
 src/test/ui/issues/issue-1920-3.stderr        |   9 +-
 src/test/ui/issues/issue-20005.stderr         |   8 +-
 src/test/ui/issues/issue-20413.stderr         |  16 +-
 src/test/ui/issues/issue-21763.stderr         |   8 +-
 src/test/ui/issues/issue-21837.stderr         |   8 +-
 src/test/ui/issues/issue-21974.stderr         |   9 +-
 src/test/ui/issues/issue-24204.stderr         |   8 +-
 src/test/ui/issues/issue-24424.stderr         |   9 +-
 src/test/ui/issues/issue-25076.stderr         |   9 +-
 src/test/ui/issues/issue-29147.stderr         |   9 +-
 src/test/ui/issues/issue-32963.stderr         |   9 +-
 src/test/ui/issues/issue-39970.stderr         |   8 +-
 src/test/ui/issues/issue-40827.stderr         |  16 +-
 src/test/ui/issues/issue-43623.stderr         |  24 +-
 src/test/ui/issues/issue-47706.stderr         |  15 +-
 src/test/ui/issues/issue-60283.stderr         |  28 +-
 src/test/ui/iterators/bound.stderr            |   7 +-
 src/test/ui/kindck/kindck-copy.stderr         |  97 ++---
 .../kindck/kindck-impl-type-params-2.stderr   |   8 +-
 .../kindck/kindck-inherited-copy-bound.stderr |   8 +-
 .../ui/kindck/kindck-nonsendable-1.stderr     |   8 +-
 src/test/ui/kindck/kindck-send-object.stderr  |  16 +-
 src/test/ui/kindck/kindck-send-object1.stderr |  16 +-
 src/test/ui/kindck/kindck-send-object2.stderr |  16 +-
 src/test/ui/kindck/kindck-send-owned.stderr   |   8 +-
 src/test/ui/kindck/kindck-send-unsafe.stderr  |   8 +-
 .../overlap-marker-trait.stderr               |   9 +-
 src/test/ui/mismatched_types/E0631.stderr     |  36 +-
 .../mismatched_types/closure-arg-count.stderr |  26 +-
 .../closure-arg-type-mismatch.stderr          |  18 +-
 .../mismatched_types/closure-mismatch.stderr  |  16 +-
 .../ui/mismatched_types/fn-variance-1.stderr  |  18 +-
 .../unboxed-closures-vtable-mismatch.stderr   |   9 +-
 src/test/ui/mut/mutable-enum-indirect.stderr  |   8 +-
 src/test/ui/mutexguard-sync.stderr            |   8 +-
 src/test/ui/namespace/namespace-mix.stderr    | 396 ++++++------------
 src/test/ui/no_send-enum.stderr               |   8 +-
 src/test/ui/no_send-rc.stderr                 |   8 +-
 src/test/ui/no_send-struct.stderr             |   8 +-
 src/test/ui/no_share-enum.stderr              |   8 +-
 src/test/ui/no_share-struct.stderr            |   8 +-
 src/test/ui/not-panic/not-panic-safe-2.stderr |  16 +-
 src/test/ui/not-panic/not-panic-safe-3.stderr |  16 +-
 src/test/ui/not-panic/not-panic-safe-4.stderr |  16 +-
 src/test/ui/not-panic/not-panic-safe-5.stderr |   8 +-
 src/test/ui/not-panic/not-panic-safe-6.stderr |  16 +-
 src/test/ui/not-panic/not-panic-safe.stderr   |   8 +-
 src/test/ui/not-sync.stderr                   |  48 +--
 src/test/ui/object-does-not-impl-trait.stderr |   8 +-
 .../ui/on-unimplemented/multiple-impls.stderr |  24 +-
 src/test/ui/on-unimplemented/on-impl.stderr   |   8 +-
 src/test/ui/on-unimplemented/on-trait.stderr  |  16 +-
 src/test/ui/overlap-marker-trait.stderr       |   9 +-
 src/test/ui/phantom-oibit.stderr              |  16 +-
 .../recursion/recursive-requirements.stderr   |  16 +-
 src/test/ui/span/issue-29595.stderr           |   9 +-
 src/test/ui/str/str-mut-idx.stderr            |   8 +-
 .../structs/struct-path-alias-bounds.stderr   |   9 +-
 src/test/ui/substs-ppaux.normal.stderr        |   8 +-
 src/test/ui/substs-ppaux.verbose.stderr       |   8 +-
 src/test/ui/suggestions/into-str.stderr       |   8 +-
 .../trait-alias-cross-crate.stderr            |  16 +-
 .../traits/trait-alias/trait-alias-wf.stderr  |   7 +-
 ...-bounds-on-structs-and-enums-in-fns.stderr |  18 +-
 ...ounds-on-structs-and-enums-in-impls.stderr |   9 +-
 ...-bounds-on-structs-and-enums-locals.stderr |  18 +-
 ...-bounds-on-structs-and-enums-static.stderr |   9 +-
 .../trait-bounds-on-structs-and-enums.stderr  |  60 +--
 ...ait-static-method-generic-inference.stderr |   9 +-
 ...its-inductive-overflow-simultaneous.stderr |   8 +-
 ...inductive-overflow-supertrait-oibit.stderr |   8 +-
 ...raits-inductive-overflow-supertrait.stderr |   8 +-
 ...raits-inductive-overflow-two-traits.stderr |   9 +-
 .../ui/traits/traits-negative-impls.stderr    |  56 +--
 .../traits-repeated-supertrait-ambig.stderr   |  17 +-
 .../trivial-bounds/trivial-bounds-leak.stderr |  16 +-
 src/test/ui/try-operator-on-main.stderr       |   7 +-
 .../ui/type/type-annotation-needed.stderr     |   9 +-
 src/test/ui/type/type-check-defaults.stderr   |  61 +--
 .../ui/type/type-check/issue-40294.stderr     |   9 +-
 .../type-params-in-different-spaces-2.stderr  |  16 +-
 ...ypeck-default-trait-impl-assoc-type.stderr |   8 +-
 ...ault-trait-impl-constituent-types-2.stderr |   8 +-
 ...efault-trait-impl-constituent-types.stderr |   8 +-
 ...ck-default-trait-impl-negation-send.stderr |   8 +-
 ...ck-default-trait-impl-negation-sync.stderr |  24 +-
 .../typeck-default-trait-impl-negation.stderr |  16 +-
 ...ypeck-default-trait-impl-precedence.stderr |   8 +-
 ...ypeck-default-trait-impl-send-param.stderr |   8 +-
 .../typeck/typeck-unsafe-always-share.stderr  |  32 +-
 .../unboxed-closure-sugar-default.stderr      |   9 +-
 .../unboxed-closure-sugar-equiv.stderr        |   9 +-
 .../unboxed-closures-fnmut-as-fn.stderr       |   8 +-
 .../unboxed-closures-unsafe-extern-fn.stderr  |  40 +-
 .../unboxed-closures-wrong-abi.stderr         |  40 +-
 ...d-closures-wrong-arg-type-extern-fn.stderr |  40 +-
 .../unevaluated_fixed_size_array_len.stderr   |   8 +-
 src/test/ui/union/union-generic.stderr        |  18 +-
 .../ui/unsized/unsized-bare-typaram.stderr    |   7 +-
 src/test/ui/unsized/unsized-enum.stderr       |   8 +-
 .../unsized-inherent-impl-self-type.stderr    |   8 +-
 src/test/ui/unsized/unsized-struct.stderr     |  16 +-
 .../unsized-trait-impl-self-type.stderr       |   8 +-
 src/test/ui/unsized3.stderr                   |  32 +-
 src/test/ui/wf/wf-const-type.stderr           |   8 +-
 src/test/ui/wf/wf-enum-bound.stderr           |   8 +-
 .../wf/wf-enum-fields-struct-variant.stderr   |   8 +-
 src/test/ui/wf/wf-enum-fields.stderr          |   8 +-
 src/test/ui/wf/wf-fn-where-clause.stderr      |   8 +-
 .../wf/wf-impl-associated-type-trait.stderr   |   8 +-
 src/test/ui/wf/wf-in-fn-arg.stderr            |   8 +-
 src/test/ui/wf/wf-in-fn-ret.stderr            |   8 +-
 src/test/ui/wf/wf-in-fn-type-arg.stderr       |   8 +-
 src/test/ui/wf/wf-in-fn-type-ret.stderr       |   8 +-
 src/test/ui/wf/wf-in-fn-where-clause.stderr   |   8 +-
 src/test/ui/wf/wf-in-obj-type-trait.stderr    |   8 +-
 ...f-inherent-impl-method-where-clause.stderr |   8 +-
 .../wf/wf-inherent-impl-where-clause.stderr   |   8 +-
 src/test/ui/wf/wf-static-type.stderr          |   8 +-
 src/test/ui/wf/wf-struct-bound.stderr         |   8 +-
 src/test/ui/wf/wf-struct-field.stderr         |   8 +-
 .../wf/wf-trait-associated-type-bound.stderr  |   8 +-
 .../wf/wf-trait-associated-type-trait.stderr  |   8 +-
 src/test/ui/wf/wf-trait-bound.stderr          |   8 +-
 src/test/ui/wf/wf-trait-default-fn-arg.stderr |   8 +-
 src/test/ui/wf/wf-trait-default-fn-ret.stderr |   8 +-
 .../wf-trait-default-fn-where-clause.stderr   |   8 +-
 src/test/ui/wf/wf-trait-fn-arg.stderr         |   8 +-
 src/test/ui/wf/wf-trait-fn-ret.stderr         |   8 +-
 .../ui/wf/wf-trait-fn-where-clause.stderr     |   8 +-
 src/test/ui/wf/wf-trait-superbound.stderr     |   8 +-
 ...traints-are-local-for-inherent-impl.stderr |   8 +-
 ...onstraints-are-local-for-trait-impl.stderr |   8 +-
 .../where-clauses-unsatisfied.stderr          |   9 +-
 .../ui/where-clauses/where-for-self-2.stderr  |  16 +-
 187 files changed, 1177 insertions(+), 2058 deletions(-)

diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 93742c83be440..aa0fcafbb0e6b 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -657,19 +657,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                             span,
                             E0277,
                             "{}",
-                            message.unwrap_or_else(||
-                                format!("the trait bound `{}` is not satisfied{}",
-                                        trait_ref.to_predicate(), post_message)
-                            ));
+                            message.unwrap_or_else(|| format!(
+                                "the trait bound `{}` is not satisfied{}",
+                                trait_ref.to_predicate(),
+                                post_message,
+                            )));
 
                         let explanation =
                             if obligation.cause.code == ObligationCauseCode::MainFunctionType {
                                 "consider using `()`, or a `Result`".to_owned()
                             } else {
-                                format!("{}the trait `{}` is not implemented for `{}`",
+                                format!(
+                                    "{}the trait `{}` is not implemented for `{}`",
                                         pre_message,
                                         trait_ref,
-                                        trait_ref.self_ty())
+                                    trait_ref.self_ty(),
+                                )
                             };
 
                         if let Some(ref s) = label {
@@ -1535,17 +1538,23 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 err.note("only the last element of a tuple may have a dynamically sized type");
             }
             ObligationCauseCode::ProjectionWf(data) => {
-                err.note(&format!("required so that the projection `{}` is well-formed",
-                                  data));
+                err.note(&format!(
+                    "required so that the projection `{}` is well-formed",
+                    data,
+                ));
             }
             ObligationCauseCode::ReferenceOutlivesReferent(ref_ty) => {
-                err.note(&format!("required so that reference `{}` does not outlive its referent",
-                                  ref_ty));
+                err.note(&format!(
+                    "required so that reference `{}` does not outlive its referent",
+                    ref_ty,
+                ));
             }
             ObligationCauseCode::ObjectTypeBound(object_ty, region) => {
-                err.note(&format!("required so that the lifetime bound of `{}` for `{}` \
-                                   is satisfied",
-                                  region, object_ty));
+                err.note(&format!(
+                    "required so that the lifetime bound of `{}` for `{}` is satisfied",
+                    region,
+                    object_ty,
+                ));
             }
             ObligationCauseCode::ItemObligation(item_def_id) => {
                 let item_name = tcx.def_path_str(item_def_id);
@@ -1553,7 +1562,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
                 if let Some(sp) = tcx.hir().span_if_local(item_def_id) {
                     let sp = tcx.sess.source_map().def_span(sp);
-                    err.span_note(sp, &msg);
+                    err.span_label(sp, &msg);
                 } else {
                     err.note(&msg);
                 }
diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
index 0ca3ca8437463..c65a44bfbccfe 100644
--- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr
+++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
@@ -5,12 +5,9 @@ LL |     f1(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _`
-   |
-note: required by `f1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:27:1
-   |
+...
 LL | fn f1<F>(_: F) where F: Fn(&(), &()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ------------------------------------ required by `f1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:2:5
@@ -19,12 +16,9 @@ LL |     f1(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `fn(&(), &()) -> _`
-   |
-note: required by `f1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:27:1
-   |
+...
 LL | fn f1<F>(_: F) where F: Fn(&(), &()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ------------------------------------ required by `f1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
@@ -33,12 +27,9 @@ LL |     f2(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _`
-   |
-note: required by `f2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:28:1
-   |
+...
 LL | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ----------------------------------------------- required by `f2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
@@ -47,12 +38,9 @@ LL |     f2(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `fn(&'a (), &()) -> _`
-   |
-note: required by `f2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:28:1
-   |
+...
 LL | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ----------------------------------------------- required by `f2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
@@ -61,12 +49,9 @@ LL |     f3(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `for<'r> fn(&(), &'r ()) -> _`
-   |
-note: required by `f3`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1
-   |
+...
 LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ------------------------------------------- required by `f3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
@@ -75,12 +60,9 @@ LL |     f3(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `fn(&(), &()) -> _`
-   |
-note: required by `f3`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:29:1
-   |
+...
 LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ------------------------------------------- required by `f3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
@@ -89,12 +71,9 @@ LL |     f4(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _`
-   |
-note: required by `f4`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1
-   |
+...
 LL | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ----------------------------------------------- required by `f4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
@@ -103,12 +82,9 @@ LL |     f4(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `fn(&(), &'r ()) -> _`
-   |
-note: required by `f4`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:30:1
-   |
+...
 LL | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ----------------------------------------------- required by `f4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
@@ -117,12 +93,9 @@ LL |     f5(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `for<'r> fn(&'r (), &'r ()) -> _`
-   |
-note: required by `f5`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:31:1
-   |
+...
 LL | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | -------------------------------------------------- required by `f5`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
@@ -131,12 +104,9 @@ LL |     f5(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `fn(&'r (), &'r ()) -> _`
-   |
-note: required by `f5`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:31:1
-   |
+...
 LL | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | -------------------------------------------------- required by `f5`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
@@ -145,12 +115,9 @@ LL |     g1(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `for<'r> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>) -> _`
-   |
-note: required by `g1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:34:1
-   |
+...
 LL | fn g1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ------------------------------------------------- required by `g1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
@@ -159,12 +126,9 @@ LL |     g1(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
-   |
-note: required by `g1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:34:1
-   |
+...
 LL | fn g1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ------------------------------------------------- required by `g1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
@@ -173,12 +137,9 @@ LL |     g2(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _`
-   |
-note: required by `g2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1
-   |
+...
 LL | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ---------------------------------------- required by `g2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
@@ -187,12 +148,9 @@ LL |     g2(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `fn(&(), for<'r> fn(&'r ())) -> _`
-   |
-note: required by `g2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:35:1
-   |
+...
 LL | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ---------------------------------------- required by `g2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
@@ -201,12 +159,9 @@ LL |     g3(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `for<'s> fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
-   |
-note: required by `g3`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:36:1
-   |
+...
 LL | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<dyn Fn(&())>) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ------------------------------------------------------------ required by `g3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
@@ -215,12 +170,9 @@ LL |     g3(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
-   |
-note: required by `g3`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:36:1
-   |
+...
 LL | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<dyn Fn(&())>) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ------------------------------------------------------------ required by `g3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
@@ -229,12 +181,9 @@ LL |     g4(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _`
-   |
-note: required by `g4`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:37:1
-   |
+...
 LL | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | --------------------------------------------------- required by `g4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
@@ -243,12 +192,9 @@ LL |     g4(|_: (), _: ()| {});
    |     ^^ -------------- found signature of `fn((), ()) -> _`
    |     |
    |     expected signature of `fn(&(), for<'r> fn(&'r ())) -> _`
-   |
-note: required by `g4`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:37:1
-   |
+...
 LL | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | --------------------------------------------------- required by `g4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
@@ -257,12 +203,9 @@ LL |     h1(|_: (), _: (), _: (), _: ()| {});
    |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
    |     |
    |     expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<(dyn for<'t0> std::ops::Fn(&'t0 ()) + 'static)>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
-   |
-note: required by `h1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1
-   |
+...
 LL | fn h1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>, &(), fn(&(), &())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | -------------------------------------------------------------------- required by `h1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
@@ -271,12 +214,9 @@ LL |     h1(|_: (), _: (), _: (), _: ()| {});
    |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
    |     |
    |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &(), for<'r, 's> fn(&'r (), &'s ())) -> _`
-   |
-note: required by `h1`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:40:1
-   |
+...
 LL | fn h1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>, &(), fn(&(), &())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | -------------------------------------------------------------------- required by `h1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
@@ -285,12 +225,9 @@ LL |     h2(|_: (), _: (), _: (), _: ()| {});
    |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
    |     |
    |     expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
-   |
-note: required by `h2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:41:1
-   |
+...
 LL | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<dyn Fn(&())>, &'t0 (), fn(&(), &())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | --------------------------------------------------------------------------------- required by `h2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
@@ -299,12 +236,9 @@ LL |     h2(|_: (), _: (), _: (), _: ()| {});
    |     ^^ ---------------------------- found signature of `fn((), (), (), ()) -> _`
    |     |
    |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &'t0 (), for<'r, 's> fn(&'r (), &'s ())) -> _`
-   |
-note: required by `h2`
-  --> $DIR/anonymous-higher-ranked-lifetime.rs:41:1
-   |
+...
 LL | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<dyn Fn(&())>, &'t0 (), fn(&(), &())) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | --------------------------------------------------------------------------------- required by `h2`
 
 error: aborting due to 22 previous errors
 
diff --git a/src/test/ui/associated-const/associated-const-array-len.stderr b/src/test/ui/associated-const/associated-const-array-len.stderr
index ff56d112c8184..2fdfa3da3086c 100644
--- a/src/test/ui/associated-const/associated-const-array-len.stderr
+++ b/src/test/ui/associated-const/associated-const-array-len.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/associated-const-array-len.rs:5:16
    |
+LL |     const ID: usize;
+   |     ---------------- required by `Foo::ID`
+...
 LL | const X: [i32; <i32 as Foo>::ID] = [0, 1, 2];
    |                ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32`
-   |
-note: required by `Foo::ID`
-  --> $DIR/associated-const-array-len.rs:2:5
-   |
-LL |     const ID: usize;
-   |     ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
index 573b8ed39bcaa..30b6b4f3909b2 100644
--- a/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
+++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays-2.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `A: Foo` is not satisfied
   --> $DIR/associated-const-type-parameter-arrays-2.rs:16:22
    |
+LL |     const Y: usize;
+   |     --------------- required by `Foo::Y`
+...
 LL |     let _array = [4; <A as Foo>::Y];
    |                      ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
    |
    = help: consider adding a `where A: Foo` bound
-note: required by `Foo::Y`
-  --> $DIR/associated-const-type-parameter-arrays-2.rs:2:5
-   |
-LL |     const Y: usize;
-   |     ^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr b/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr
index bf1ee38571404..30fa9891a13e1 100644
--- a/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr
+++ b/src/test/ui/associated-const/associated-const-type-parameter-arrays.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `A: Foo` is not satisfied
   --> $DIR/associated-const-type-parameter-arrays.rs:16:23
    |
+LL |     const Y: usize;
+   |     --------------- required by `Foo::Y`
+...
 LL |     let _array: [u32; <A as Foo>::Y];
    |                       ^^^^^^^^^^^^^ the trait `Foo` is not implemented for `A`
    |
    = help: consider adding a `where A: Foo` bound
-note: required by `Foo::Y`
-  --> $DIR/associated-const-type-parameter-arrays.rs:2:5
-   |
-LL |     const Y: usize;
-   |     ^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
index aebf29cc332ab..06e8230aa1589 100644
--- a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
+++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
@@ -24,6 +24,9 @@ LL | | }
 error[E0277]: `<<T as Case1>::C as std::iter::Iterator>::Item` cannot be sent between threads safely
   --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1
    |
+LL |   trait Case1 {
+   |   ----------- required by `Case1`
+...
 LL | / fn assume_case1<T: Case1>() {
 LL | |
 LL | |
@@ -35,15 +38,13 @@ LL | | }
    |
    = help: the trait `std::marker::Send` is not implemented for `<<T as Case1>::C as std::iter::Iterator>::Item`
    = help: consider adding a `where <<T as Case1>::C as std::iter::Iterator>::Item: std::marker::Send` bound
-note: required by `Case1`
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1
-   |
-LL | trait Case1 {
-   | ^^^^^^^^^^^
 
 error[E0277]: `<<T as Case1>::C as std::iter::Iterator>::Item` cannot be shared between threads safely
   --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1
    |
+LL |   trait Case1 {
+   |   ----------- required by `Case1`
+...
 LL | / fn assume_case1<T: Case1>() {
 LL | |
 LL | |
@@ -55,15 +56,13 @@ LL | | }
    |
    = help: the trait `std::marker::Sync` is not implemented for `<<T as Case1>::C as std::iter::Iterator>::Item`
    = help: consider adding a `where <<T as Case1>::C as std::iter::Iterator>::Item: std::marker::Sync` bound
-note: required by `Case1`
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1
-   |
-LL | trait Case1 {
-   | ^^^^^^^^^^^
 
 error[E0277]: `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug`
   --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1
    |
+LL |   trait Case1 {
+   |   ----------- required by `Case1`
+...
 LL | / fn assume_case1<T: Case1>() {
 LL | |
 LL | |
@@ -74,11 +73,6 @@ LL | | }
    | |_^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
    |
    = help: the trait `for<'a> std::fmt::Debug` is not implemented for `<_ as Lam<&'a u8>>::App`
-note: required by `Case1`
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1
-   |
-LL | trait Case1 {
-   | ^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
index 89c48d50cdb65..a3049892abc39 100644
--- a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
+++ b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
@@ -1,30 +1,26 @@
 error[E0271]: type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
   --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:10
    |
+LL | fn blue_car<C:Car<Color=Blue>>(c: C) {
+   | ------------------------------------ required by `blue_car`
+...
 LL | fn b() { blue_car(ModelT); }
    |          ^^^^^^^^ expected struct `Black`, found struct `Blue`
    |
    = note: expected type `Black`
               found type `Blue`
-note: required by `blue_car`
-  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:27:1
-   |
-LL | fn blue_car<C:Car<Color=Blue>>(c: C) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `<ModelU as Vehicle>::Color == Black`
   --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:10
    |
+LL | fn black_car<C:Car<Color=Black>>(c: C) {
+   | -------------------------------------- required by `black_car`
+...
 LL | fn c() { black_car(ModelU); }
    |          ^^^^^^^^^ expected struct `Blue`, found struct `Black`
    |
    = note: expected type `Blue`
               found type `Black`
-note: required by `black_car`
-  --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:24:1
-   |
-LL | fn black_car<C:Car<Color=Black>>(c: C) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/associated-types/associated-types-bound-failure.stderr b/src/test/ui/associated-types/associated-types-bound-failure.stderr
index 502fb4f1c3033..54654b95edd90 100644
--- a/src/test/ui/associated-types/associated-types-bound-failure.stderr
+++ b/src/test/ui/associated-types/associated-types-bound-failure.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `<G as GetToInt>::R: ToInt` is not satisfied
   --> $DIR/associated-types-bound-failure.rs:17:5
    |
+LL |     fn to_int(&self) -> isize;
+   |     -------------------------- required by `ToInt::to_int`
+...
 LL |     ToInt::to_int(&g.get())
    |     ^^^^^^^^^^^^^ the trait `ToInt` is not implemented for `<G as GetToInt>::R`
    |
    = help: consider adding a `where <G as GetToInt>::R: ToInt` bound
-note: required by `ToInt::to_int`
-  --> $DIR/associated-types-bound-failure.rs:4:5
-   |
-LL |     fn to_int(&self) -> isize;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr
index 66fa4c288ca46..0f8c5257d445f 100644
--- a/src/test/ui/associated-types/associated-types-eq-3.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-3.stderr
@@ -10,16 +10,14 @@ LL |     let _: Bar = x.boo();
 error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
   --> $DIR/associated-types-eq-3.rs:38:5
    |
+LL | fn foo1<I: Foo<A=Bar>>(x: I) {
+   | ---------------------------- required by `foo1`
+...
 LL |     foo1(a);
    |     ^^^^ expected usize, found struct `Bar`
    |
    = note: expected type `usize`
               found type `Bar`
-note: required by `foo1`
-  --> $DIR/associated-types-eq-3.rs:18:1
-   |
-LL | fn foo1<I: Foo<A=Bar>>(x: I) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
   --> $DIR/associated-types-eq-3.rs:41:9
diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr
index 353829c2f7631..05e6ed69812ad 100644
--- a/src/test/ui/associated-types/associated-types-eq-hr.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr
@@ -1,124 +1,108 @@
 error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
   --> $DIR/associated-types-eq-hr.rs:82:5
    |
-LL |     foo::<UintStruct>();
-   |     ^^^^^^^^^^^^^^^^^ expected usize, found isize
-   |
-   = note: expected type `&usize`
-              found type `&isize`
-note: required by `foo`
-  --> $DIR/associated-types-eq-hr.rs:44:1
-   |
 LL | / fn foo<T>()
 LL | |     where T : for<'x> TheTrait<&'x isize, A = &'x isize>
 LL | | {
 LL | |     // ok for IntStruct, but not UintStruct
 LL | | }
-   | |_^
+   | |_- required by `foo`
+...
+LL |       foo::<UintStruct>();
+   |       ^^^^^^^^^^^^^^^^^ expected usize, found isize
+   |
+   = note: expected type `&usize`
+              found type `&isize`
 
 error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
   --> $DIR/associated-types-eq-hr.rs:86:5
    |
-LL |     bar::<IntStruct>();
-   |     ^^^^^^^^^^^^^^^^ expected isize, found usize
-   |
-   = note: expected type `&isize`
-              found type `&usize`
-note: required by `bar`
-  --> $DIR/associated-types-eq-hr.rs:50:1
-   |
 LL | / fn bar<T>()
 LL | |     where T : for<'x> TheTrait<&'x isize, A = &'x usize>
 LL | | {
 LL | |     // ok for UintStruct, but not IntStruct
 LL | | }
-   | |_^
+   | |_- required by `bar`
+...
+LL |       bar::<IntStruct>();
+   |       ^^^^^^^^^^^^^^^^ expected isize, found usize
+   |
+   = note: expected type `&isize`
+              found type `&usize`
 
 error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
   --> $DIR/associated-types-eq-hr.rs:91:5
    |
-LL |     tuple_one::<Tuple>();
-   |     ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
-   |
-   = help: the following implementations were found:
-             <Tuple as TheTrait<(&'a isize, &'a isize)>>
-note: required by `tuple_one`
-  --> $DIR/associated-types-eq-hr.rs:56:1
-   |
 LL | / fn tuple_one<T>()
 LL | |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
 LL | | {
 LL | |     // not ok for tuple, two lifetimes and we pick first
 LL | | }
-   | |_^
+   | |_- required by `tuple_one`
+...
+LL |       tuple_one::<Tuple>();
+   |       ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
+   |
+   = help: the following implementations were found:
+             <Tuple as TheTrait<(&'a isize, &'a isize)>>
 
 error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'x isize`
   --> $DIR/associated-types-eq-hr.rs:91:5
    |
-LL |     tuple_one::<Tuple>();
-   |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
-   |
-note: required by `tuple_one`
-  --> $DIR/associated-types-eq-hr.rs:56:1
-   |
 LL | / fn tuple_one<T>()
 LL | |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
 LL | | {
 LL | |     // not ok for tuple, two lifetimes and we pick first
 LL | | }
-   | |_^
+   | |_- required by `tuple_one`
+...
+LL |       tuple_one::<Tuple>();
+   |       ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
 
 error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
   --> $DIR/associated-types-eq-hr.rs:97:5
    |
-LL |     tuple_two::<Tuple>();
-   |     ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
-   |
-   = help: the following implementations were found:
-             <Tuple as TheTrait<(&'a isize, &'a isize)>>
-note: required by `tuple_two`
-  --> $DIR/associated-types-eq-hr.rs:62:1
-   |
 LL | / fn tuple_two<T>()
 LL | |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
 LL | | {
 LL | |     // not ok for tuple, two lifetimes and we pick second
 LL | | }
-   | |_^
+   | |_- required by `tuple_two`
+...
+LL |       tuple_two::<Tuple>();
+   |       ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
+   |
+   = help: the following implementations were found:
+             <Tuple as TheTrait<(&'a isize, &'a isize)>>
 
 error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'y isize`
   --> $DIR/associated-types-eq-hr.rs:97:5
    |
-LL |     tuple_two::<Tuple>();
-   |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
-   |
-note: required by `tuple_two`
-  --> $DIR/associated-types-eq-hr.rs:62:1
-   |
 LL | / fn tuple_two<T>()
 LL | |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
 LL | | {
 LL | |     // not ok for tuple, two lifetimes and we pick second
 LL | | }
-   | |_^
+   | |_- required by `tuple_two`
+...
+LL |       tuple_two::<Tuple>();
+   |       ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
 
 error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
   --> $DIR/associated-types-eq-hr.rs:107:5
    |
-LL |     tuple_four::<Tuple>();
-   |     ^^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
-   |
-   = help: the following implementations were found:
-             <Tuple as TheTrait<(&'a isize, &'a isize)>>
-note: required by `tuple_four`
-  --> $DIR/associated-types-eq-hr.rs:74:1
-   |
 LL | / fn tuple_four<T>()
 LL | |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)>
 LL | | {
 LL | |     // not ok for tuple, two lifetimes, and lifetime matching is invariant
 LL | | }
-   | |_^
+   | |_- required by `tuple_four`
+...
+LL |       tuple_four::<Tuple>();
+   |       ^^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
+   |
+   = help: the following implementations were found:
+             <Tuple as TheTrait<(&'a isize, &'a isize)>>
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr
index 7d5b16c6e62d0..7d6c025d69d55 100644
--- a/src/test/ui/associated-types/associated-types-issue-20346.stderr
+++ b/src/test/ui/associated-types/associated-types-issue-20346.stderr
@@ -1,16 +1,14 @@
 error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == std::option::Option<T>`
   --> $DIR/associated-types-issue-20346.rs:34:5
    |
+LL | fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
+   | ------------------------------------------------ required by `is_iterator_of`
+...
 LL |     is_iterator_of::<Option<T>, _>(&adapter);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found enum `std::option::Option`
    |
    = note: expected type `T`
               found type `std::option::Option<T>`
-note: required by `is_iterator_of`
-  --> $DIR/associated-types-issue-20346.rs:15:1
-   |
-LL | fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
index 2926bdae0525b..4a2a6d03c607f 100644
--- a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
+++ b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
@@ -3,28 +3,24 @@ error[E0271]: type mismatch resolving `<T as Foo>::Y == i32`
    |
 LL |     want_y(t);
    |     ^^^^^^ expected associated type, found i32
+...
+LL | fn want_y<T:Foo<Y=i32>>(t: &T) { }
+   | ------------------------------ required by `want_y`
    |
    = note: expected type `<T as Foo>::Y`
               found type `i32`
-note: required by `want_y`
-  --> $DIR/associated-types-multiple-types-one-trait.rs:44:1
-   |
-LL | fn want_y<T:Foo<Y=i32>>(t: &T) { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
   --> $DIR/associated-types-multiple-types-one-trait.rs:18:5
    |
 LL |     want_x(t);
    |     ^^^^^^ expected associated type, found u32
+...
+LL | fn want_x<T:Foo<X=u32>>(t: &T) { }
+   | ------------------------------ required by `want_x`
    |
    = note: expected type `<T as Foo>::X`
               found type `u32`
-note: required by `want_x`
-  --> $DIR/associated-types-multiple-types-one-trait.rs:42:1
-   |
-LL | fn want_x<T:Foo<X=u32>>(t: &T) { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
index a26ee23894f6d..a7238541cd96e 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding.stderr
+++ b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
@@ -1,14 +1,10 @@
 error[E0284]: type annotations required: cannot resolve `<Self as std::iter::Iterator>::Item == i32`
   --> $DIR/associated-types-overridden-binding.rs:4:1
    |
+LL | trait Foo: Iterator<Item = i32> {}
+   | ------------------------------- required by `Foo`
 LL | trait Bar: Foo<Item = u32> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: required by `Foo`
-  --> $DIR/associated-types-overridden-binding.rs:3:1
-   |
-LL | trait Foo: Iterator<Item = i32> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr
index 1405cb1b4736c..a8fcaeac95d5f 100644
--- a/src/test/ui/associated-types/associated-types-path-2.stderr
+++ b/src/test/ui/associated-types/associated-types-path-2.stderr
@@ -11,14 +11,11 @@ LL |     f1(2i32, 4u32);
 error[E0277]: the trait bound `u32: Foo` is not satisfied
   --> $DIR/associated-types-path-2.rs:29:5
    |
+LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
+   | -------------------------------- required by `f1`
+...
 LL |     f1(2u32, 4u32);
    |     ^^ the trait `Foo` is not implemented for `u32`
-   |
-note: required by `f1`
-  --> $DIR/associated-types-path-2.rs:13:1
-   |
-LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `u32: Foo` is not satisfied
   --> $DIR/associated-types-path-2.rs:29:5
@@ -29,14 +26,11 @@ LL |     f1(2u32, 4u32);
 error[E0277]: the trait bound `u32: Foo` is not satisfied
   --> $DIR/associated-types-path-2.rs:35:5
    |
+LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
+   | -------------------------------- required by `f1`
+...
 LL |     f1(2u32, 4i32);
    |     ^^ the trait `Foo` is not implemented for `u32`
-   |
-note: required by `f1`
-  --> $DIR/associated-types-path-2.rs:13:1
-   |
-LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `u32: Foo` is not satisfied
   --> $DIR/associated-types-path-2.rs:35:5
diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr
index cc69e849fe144..22d44888e951b 100644
--- a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr
+++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr
@@ -1,16 +1,13 @@
 error[E0271]: type mismatch resolving `for<'a> <&'a _ as Mirror>::Image == _`
   --> $DIR/higher-ranked-projection.rs:25:5
    |
-LL |     foo(());
-   |     ^^^ expected bound lifetime parameter 'a, found concrete lifetime
-   |
-note: required by `foo`
-  --> $DIR/higher-ranked-projection.rs:14:1
-   |
 LL | / fn foo<U, T>(_t: T)
 LL | |     where for<'a> &'a T: Mirror<Image=U>
 LL | | {}
-   | |__^
+   | |__- required by `foo`
+...
+LL |       foo(());
+   |       ^^^ expected bound lifetime parameter 'a, found concrete lifetime
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr
index 6b4fff2dc6844..fad90b29c0e6e 100644
--- a/src/test/ui/async-await/async-fn-nonsend.stderr
+++ b/src/test/ui/async-await/async-fn-nonsend.stderr
@@ -1,6 +1,9 @@
 error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
   --> $DIR/async-fn-nonsend.rs:50:5
    |
+LL | fn assert_send(_: impl Send) {}
+   | ---------------------------- required by `assert_send`
+...
 LL |     assert_send(local_dropped_before_await());
    |     ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
    |
@@ -11,15 +14,13 @@ LL |     assert_send(local_dropped_before_await());
    = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
-note: required by `assert_send`
-  --> $DIR/async-fn-nonsend.rs:47:1
-   |
-LL | fn assert_send(_: impl Send) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
   --> $DIR/async-fn-nonsend.rs:52:5
    |
+LL | fn assert_send(_: impl Send) {}
+   | ---------------------------- required by `assert_send`
+...
 LL |     assert_send(non_send_temporary_in_match());
    |     ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
    |
@@ -30,15 +31,13 @@ LL |     assert_send(non_send_temporary_in_match());
    = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
-note: required by `assert_send`
-  --> $DIR/async-fn-nonsend.rs:47:1
-   |
-LL | fn assert_send(_: impl Send) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `dyn std::fmt::Write` cannot be sent between threads safely
   --> $DIR/async-fn-nonsend.rs:54:5
    |
+LL | fn assert_send(_: impl Send) {}
+   | ---------------------------- required by `assert_send`
+...
 LL |     assert_send(non_sync_with_method_call());
    |     ^^^^^^^^^^^ `dyn std::fmt::Write` cannot be sent between threads safely
    |
@@ -51,15 +50,13 @@ LL |     assert_send(non_sync_with_method_call());
    = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
-note: required by `assert_send`
-  --> $DIR/async-fn-nonsend.rs:47:1
-   |
-LL | fn assert_send(_: impl Send) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
   --> $DIR/async-fn-nonsend.rs:54:5
    |
+LL | fn assert_send(_: impl Send) {}
+   | ---------------------------- required by `assert_send`
+...
 LL |     assert_send(non_sync_with_method_call());
    |     ^^^^^^^^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
    |
@@ -76,11 +73,6 @@ LL |     assert_send(non_sync_with_method_call());
    = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
-note: required by `assert_send`
-  --> $DIR/async-fn-nonsend.rs:47:1
-   |
-LL | fn assert_send(_: impl Send) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/chalkify/type_inference.stderr b/src/test/ui/chalkify/type_inference.stderr
index 6cb33f2f2c8c6..15c52f461c183 100644
--- a/src/test/ui/chalkify/type_inference.stderr
+++ b/src/test/ui/chalkify/type_inference.stderr
@@ -10,17 +10,15 @@ LL |     only_foo(x);
 error[E0277]: the trait bound `{float}: Bar` is not satisfied
   --> $DIR/type_inference.rs:25:5
    |
+LL | fn only_bar<T: Bar>(_x: T) { }
+   | -------------------------- required by `only_bar`
+...
 LL |     only_bar(x);
    |     ^^^^^^^^ the trait `Bar` is not implemented for `{float}`
    |
    = help: the following implementations were found:
              <i32 as Bar>
              <u32 as Bar>
-note: required by `only_bar`
-  --> $DIR/type_inference.rs:12:1
-   |
-LL | fn only_bar<T: Bar>(_x: T) { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
index 40fab4d4edf78..c618c2c550ba1 100644
--- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
@@ -39,53 +39,44 @@ LL |     with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:30:5
    |
-LL |     with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
-   |     |
-   |     expected signature of `fn(fn(&'a u32), &i32) -> _`
-   |
-note: required by `with_closure_expecting_fn_with_free_region`
-  --> $DIR/expect-fn-supply-fn.rs:1:1
-   |
 LL | / fn with_closure_expecting_fn_with_free_region<F>(_: F)
 LL | |     where F: for<'a> FnOnce(fn(&'a u32), &i32)
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `with_closure_expecting_fn_with_free_region`
+...
+LL |       with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
+   |       |
+   |       expected signature of `fn(fn(&'a u32), &i32) -> _`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:37:5
    |
-LL |     with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
-   |     |
-   |     expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
-   |
-note: required by `with_closure_expecting_fn_with_bound_region`
-  --> $DIR/expect-fn-supply-fn.rs:6:1
-   |
 LL | / fn with_closure_expecting_fn_with_bound_region<F>(_: F)
 LL | |     where F: FnOnce(fn(&u32), &i32)
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `with_closure_expecting_fn_with_bound_region`
+...
+LL |       with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
+   |       |
+   |       expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:46:5
    |
-LL |     with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
-   |     |
-   |     expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
-   |
-note: required by `with_closure_expecting_fn_with_bound_region`
-  --> $DIR/expect-fn-supply-fn.rs:6:1
-   |
 LL | / fn with_closure_expecting_fn_with_bound_region<F>(_: F)
 LL | |     where F: FnOnce(fn(&u32), &i32)
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `with_closure_expecting_fn_with_bound_region`
+...
+LL |       with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
+   |       |
+   |       expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
index c9a697496de59..a2b3a66dc4d23 100644
--- a/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
+++ b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
@@ -1,19 +1,16 @@
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-infer-var-appearing-twice.rs:14:5
    |
-LL |     with_closure(|x: u32, y: i32| {
-   |     ^^^^^^^^^^^^ ---------------- found signature of `fn(u32, i32) -> _`
-   |     |
-   |     expected signature of `fn(_, _) -> _`
-   |
-note: required by `with_closure`
-  --> $DIR/expect-infer-var-appearing-twice.rs:1:1
-   |
 LL | / fn with_closure<F, A>(_: F)
 LL | |     where F: FnOnce(A, A)
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `with_closure`
+...
+LL |       with_closure(|x: u32, y: i32| {
+   |       ^^^^^^^^^^^^ ---------------- found signature of `fn(u32, i32) -> _`
+   |       |
+   |       expected signature of `fn(_, _) -> _`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr b/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
index 81c4f4e00aba0..51077b1b2922e 100644
--- a/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
+++ b/src/test/ui/closures/closure-bounds-cant-promote-superkind-in-struct.stderr
@@ -1,6 +1,9 @@
 error[E0277]: `F` cannot be sent between threads safely
   --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:5:1
    |
+LL |   struct X<F> where F: FnOnce() + 'static + Send {
+   |   ---------------------------------------------- required by `X`
+...
 LL | / fn foo<F>(blk: F) -> X<F> where F: FnOnce() + 'static {
 LL | |
 LL | |     return X { field: blk };
@@ -9,11 +12,6 @@ LL | | }
    |
    = help: the trait `std::marker::Send` is not implemented for `F`
    = help: consider adding a `where F: std::marker::Send` bound
-note: required by `X`
-  --> $DIR/closure-bounds-cant-promote-superkind-in-struct.rs:1:1
-   |
-LL | struct X<F> where F: FnOnce() + 'static + Send {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/closure-bounds-subtype.stderr b/src/test/ui/closures/closure-bounds-subtype.stderr
index 3b9fd10af3860..4958bd06d9b16 100644
--- a/src/test/ui/closures/closure-bounds-subtype.stderr
+++ b/src/test/ui/closures/closure-bounds-subtype.stderr
@@ -1,16 +1,14 @@
 error[E0277]: `F` cannot be shared between threads safely
   --> $DIR/closure-bounds-subtype.rs:13:5
    |
+LL | fn take_const_owned<F>(_: F) where F: FnOnce() + Sync + Send {
+   | ------------------------------------------------------------ required by `take_const_owned`
+...
 LL |     take_const_owned(f);
    |     ^^^^^^^^^^^^^^^^ `F` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `F`
    = help: consider adding a `where F: std::marker::Sync` bound
-note: required by `take_const_owned`
-  --> $DIR/closure-bounds-subtype.rs:4:1
-   |
-LL | fn take_const_owned<F>(_: F) where F: FnOnce() + Sync + Send {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/too_generic_eval_ice.stderr b/src/test/ui/consts/too_generic_eval_ice.stderr
index eef79421270ce..0733a51233e33 100644
--- a/src/test/ui/consts/too_generic_eval_ice.stderr
+++ b/src/test/ui/consts/too_generic_eval_ice.stderr
@@ -14,32 +14,28 @@ LL |         [5; Self::HOST_SIZE] == [6; 0]
 error[E0277]: the size for values of type `A` cannot be known at compilation time
   --> $DIR/too_generic_eval_ice.rs:7:13
    |
+LL | pub struct Foo<A, B>(A, B);
+   | --------------------------- required by `Foo`
+...
 LL |         [5; Self::HOST_SIZE] == [6; 0]
    |             ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `A`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where A: std::marker::Sized` bound
-note: required by `Foo`
-  --> $DIR/too_generic_eval_ice.rs:1:1
-   |
-LL | pub struct Foo<A, B>(A, B);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `B` cannot be known at compilation time
   --> $DIR/too_generic_eval_ice.rs:7:13
    |
+LL | pub struct Foo<A, B>(A, B);
+   | --------------------------- required by `Foo`
+...
 LL |         [5; Self::HOST_SIZE] == [6; 0]
    |             ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `B`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where B: std::marker::Sized` bound
-note: required by `Foo`
-  --> $DIR/too_generic_eval_ice.rs:1:1
-   |
-LL | pub struct Foo<A, B>(A, B);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/defaulted-never-note.stderr b/src/test/ui/defaulted-never-note.stderr
index 45174c322947d..277477a0b0acd 100644
--- a/src/test/ui/defaulted-never-note.stderr
+++ b/src/test/ui/defaulted-never-note.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
   --> $DIR/defaulted-never-note.rs:26:5
    |
+LL | fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
+   | ----------------------------------------------- required by `foo`
+...
 LL |     foo(_x);
    |     ^^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!`
    |
    = note: the trait is implemented for `()`. Possibly this error has been caused by changes to Rust's type-inference algorithm (see: https://github.com/rust-lang/rust/issues/48950 for more info). Consider whether you meant to use the type `()` here instead.
-note: required by `foo`
-  --> $DIR/defaulted-never-note.rs:21:1
-   |
-LL | fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/derives/deriving-copyclone.stderr b/src/test/ui/derives/deriving-copyclone.stderr
index e6060c269e10a..46b6a0d337695 100644
--- a/src/test/ui/derives/deriving-copyclone.stderr
+++ b/src/test/ui/derives/deriving-copyclone.stderr
@@ -1,41 +1,35 @@
 error[E0277]: the trait bound `C: std::marker::Copy` is not satisfied
   --> $DIR/deriving-copyclone.rs:31:5
    |
+LL | fn is_copy<T: Copy>(_: T) {}
+   | ------------------------- required by `is_copy`
+...
 LL |     is_copy(B { a: 1, b: C });
    |     ^^^^^^^ the trait `std::marker::Copy` is not implemented for `C`
    |
    = note: required because of the requirements on the impl of `std::marker::Copy` for `B<C>`
-note: required by `is_copy`
-  --> $DIR/deriving-copyclone.rs:18:1
-   |
-LL | fn is_copy<T: Copy>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `C: std::clone::Clone` is not satisfied
   --> $DIR/deriving-copyclone.rs:32:5
    |
+LL | fn is_clone<T: Clone>(_: T) {}
+   | --------------------------- required by `is_clone`
+...
 LL |     is_clone(B { a: 1, b: C });
    |     ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `C`
    |
    = note: required because of the requirements on the impl of `std::clone::Clone` for `B<C>`
-note: required by `is_clone`
-  --> $DIR/deriving-copyclone.rs:19:1
-   |
-LL | fn is_clone<T: Clone>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `D: std::marker::Copy` is not satisfied
   --> $DIR/deriving-copyclone.rs:35:5
    |
+LL | fn is_copy<T: Copy>(_: T) {}
+   | ------------------------- required by `is_copy`
+...
 LL |     is_copy(B { a: 1, b: D });
    |     ^^^^^^^ the trait `std::marker::Copy` is not implemented for `D`
    |
    = note: required because of the requirements on the impl of `std::marker::Copy` for `B<D>`
-note: required by `is_copy`
-  --> $DIR/deriving-copyclone.rs:18:1
-   |
-LL | fn is_copy<T: Copy>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
index cfb1da037dc07..ea2017f485a7b 100644
--- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
+++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `i8: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:24:5
    |
+LL |     fn bar(&self){}
+   |     ------------- required by `Foo::bar`
+...
 LL |     Foo::<i32>::bar(&1i8);
    |     ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `i8`
    |
@@ -10,15 +13,13 @@ LL |     Foo::<i32>::bar(&1i8);
              <i8 as Foo<u32>>
              <i8 as Foo<u64>>
              <i8 as Foo<u8>>
-note: required by `Foo::bar`
-  --> $DIR/issue-39802-show-5-trait-impls.rs:2:5
-   |
-LL |     fn bar(&self){}
-   |     ^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:25:5
    |
+LL |     fn bar(&self){}
+   |     ------------- required by `Foo::bar`
+...
 LL |     Foo::<i32>::bar(&1u8);
    |     ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `u8`
    |
@@ -27,15 +28,13 @@ LL |     Foo::<i32>::bar(&1u8);
              <u8 as Foo<u16>>
              <u8 as Foo<u32>>
              <u8 as Foo<u64>>
-note: required by `Foo::bar`
-  --> $DIR/issue-39802-show-5-trait-impls.rs:2:5
-   |
-LL |     fn bar(&self){}
-   |     ^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
   --> $DIR/issue-39802-show-5-trait-impls.rs:26:5
    |
+LL |     fn bar(&self){}
+   |     ------------- required by `Foo::bar`
+...
 LL |     Foo::<i32>::bar(&true);
    |     ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `bool`
    |
@@ -45,11 +44,6 @@ LL |     Foo::<i32>::bar(&true);
              <bool as Foo<u16>>
              <bool as Foo<u32>>
            and 2 others
-note: required by `Foo::bar`
-  --> $DIR/issue-39802-show-5-trait-impls.rs:2:5
-   |
-LL |     fn bar(&self){}
-   |     ^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr
index a646d98324e09..745d90a5d4cbf 100644
--- a/src/test/ui/did_you_mean/recursion_limit.stderr
+++ b/src/test/ui/did_you_mean/recursion_limit.stderr
@@ -1,6 +1,9 @@
 error[E0275]: overflow evaluating the requirement `J: std::marker::Send`
   --> $DIR/recursion_limit.rs:34:5
    |
+LL | fn is_send<T:Send>() { }
+   | -------------------- required by `is_send`
+...
 LL |     is_send::<A>();
    |     ^^^^^^^^^^^^
    |
@@ -14,11 +17,6 @@ LL |     is_send::<A>();
    = note: required because it appears within the type `C`
    = note: required because it appears within the type `B`
    = note: required because it appears within the type `A`
-note: required by `is_send`
-  --> $DIR/recursion_limit.rs:31:1
-   |
-LL | fn is_send<T:Send>() { }
-   | ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0271.stderr b/src/test/ui/error-codes/E0271.stderr
index 16c3ab9d7425b..0afcbcc79eee9 100644
--- a/src/test/ui/error-codes/E0271.stderr
+++ b/src/test/ui/error-codes/E0271.stderr
@@ -1,16 +1,14 @@
 error[E0271]: type mismatch resolving `<i8 as Trait>::AssociatedType == u32`
   --> $DIR/E0271.rs:10:5
    |
+LL | fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
+   | -------------------------------------------------- required by `foo`
+...
 LL |     foo(3_i8);
    |     ^^^ expected reference, found u32
    |
    = note: expected type `&'static str`
               found type `u32`
-note: required by `foo`
-  --> $DIR/E0271.rs:3:1
-   |
-LL | fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr
index 40991cb2297c9..f607a9fbbf269 100644
--- a/src/test/ui/error-codes/E0275.stderr
+++ b/src/test/ui/error-codes/E0275.stderr
@@ -1,6 +1,9 @@
 error[E0275]: overflow evaluating the requirement `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo`
   --> $DIR/E0275.rs:5:1
    |
+LL | trait Foo {}
+   | --------- required by `Foo`
+...
 LL | impl<T> Foo for T where Bar<T>: Foo {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
@@ -132,11 +135,6 @@ LL | impl<T> Foo for T where Bar<T>: Foo {}
    = note: required because of the requirements on the impl of `Foo` for `Bar<Bar<Bar<T>>>`
    = note: required because of the requirements on the impl of `Foo` for `Bar<Bar<T>>`
    = note: required because of the requirements on the impl of `Foo` for `Bar<T>`
-note: required by `Foo`
-  --> $DIR/E0275.rs:1:1
-   |
-LL | trait Foo {}
-   | ^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0277-2.stderr b/src/test/ui/error-codes/E0277-2.stderr
index a4db1c8b09523..b42849cd84201 100644
--- a/src/test/ui/error-codes/E0277-2.stderr
+++ b/src/test/ui/error-codes/E0277-2.stderr
@@ -1,6 +1,9 @@
 error[E0277]: `*const u8` cannot be sent between threads safely
   --> $DIR/E0277-2.rs:16:5
    |
+LL | fn is_send<T: Send>() { }
+   | --------------------- required by `is_send`
+...
 LL |     is_send::<Foo>();
    |     ^^^^^^^^^^^^^^ `*const u8` cannot be sent between threads safely
    |
@@ -8,11 +11,6 @@ LL |     is_send::<Foo>();
    = note: required because it appears within the type `Baz`
    = note: required because it appears within the type `Bar`
    = note: required because it appears within the type `Foo`
-note: required by `is_send`
-  --> $DIR/E0277-2.rs:13:1
-   |
-LL | fn is_send<T: Send>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0277.stderr b/src/test/ui/error-codes/E0277.stderr
index e5e416da883de..352102dd38629 100644
--- a/src/test/ui/error-codes/E0277.stderr
+++ b/src/test/ui/error-codes/E0277.stderr
@@ -13,14 +13,11 @@ LL | fn f(p: Path) { }
 error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/E0277.rs:17:5
    |
+LL | fn some_func<T: Foo>(foo: T) {
+   | ---------------------------- required by `some_func`
+...
 LL |     some_func(5i32);
    |     ^^^^^^^^^ the trait `Foo` is not implemented for `i32`
-   |
-note: required by `some_func`
-  --> $DIR/E0277.rs:9:1
-   |
-LL | fn some_func<T: Foo>(foo: T) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr
index e1f53e592fc85..1d99f99c62383 100644
--- a/src/test/ui/error-codes/E0283.stderr
+++ b/src/test/ui/error-codes/E0283.stderr
@@ -1,14 +1,11 @@
 error[E0283]: type annotations required: cannot resolve `_: Generator`
   --> $DIR/E0283.rs:18:21
    |
+LL |     fn create() -> u32;
+   |     ------------------- required by `Generator::create`
+...
 LL |     let cont: u32 = Generator::create();
    |                     ^^^^^^^^^^^^^^^^^
-   |
-note: required by `Generator::create`
-  --> $DIR/E0283.rs:2:5
-   |
-LL |     fn create() -> u32;
-   |     ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-should-say-copy-not-pod.stderr b/src/test/ui/error-should-say-copy-not-pod.stderr
index 7143f8c914dd0..78d54c3836db4 100644
--- a/src/test/ui/error-should-say-copy-not-pod.stderr
+++ b/src/test/ui/error-should-say-copy-not-pod.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
   --> $DIR/error-should-say-copy-not-pod.rs:6:5
    |
+LL | fn check_bound<T:Copy>(_: T) {}
+   | ---------------------------- required by `check_bound`
+...
 LL |     check_bound("nocopy".to_string());
    |     ^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
-   |
-note: required by `check_bound`
-  --> $DIR/error-should-say-copy-not-pod.rs:3:1
-   |
-LL | fn check_bound<T:Copy>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/extern/extern-types-not-sync-send.stderr b/src/test/ui/extern/extern-types-not-sync-send.stderr
index bc9d96df776ed..0f32d4489dece 100644
--- a/src/test/ui/extern/extern-types-not-sync-send.stderr
+++ b/src/test/ui/extern/extern-types-not-sync-send.stderr
@@ -1,28 +1,24 @@
 error[E0277]: `A` cannot be shared between threads safely
   --> $DIR/extern-types-not-sync-send.rs:13:5
    |
+LL | fn assert_sync<T: ?Sized + Sync>() { }
+   | ---------------------------------- required by `assert_sync`
+...
 LL |     assert_sync::<A>();
    |     ^^^^^^^^^^^^^^^^ `A` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `A`
-note: required by `assert_sync`
-  --> $DIR/extern-types-not-sync-send.rs:9:1
-   |
-LL | fn assert_sync<T: ?Sized + Sync>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `A` cannot be sent between threads safely
   --> $DIR/extern-types-not-sync-send.rs:16:5
    |
+LL | fn assert_send<T: ?Sized + Send>() { }
+   | ---------------------------------- required by `assert_send`
+...
 LL |     assert_send::<A>();
    |     ^^^^^^^^^^^^^^^^ `A` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `A`
-note: required by `assert_send`
-  --> $DIR/extern-types-not-sync-send.rs:10:1
-   |
-LL | fn assert_send<T: ?Sized + Send>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/extern/extern-types-unsized.stderr b/src/test/ui/extern/extern-types-unsized.stderr
index 4e4f5550fe833..06527d973e2ab 100644
--- a/src/test/ui/extern/extern-types-unsized.stderr
+++ b/src/test/ui/extern/extern-types-unsized.stderr
@@ -1,50 +1,47 @@
 error[E0277]: the size for values of type `A` cannot be known at compilation time
   --> $DIR/extern-types-unsized.rs:22:5
    |
+LL | fn assert_sized<T>() { }
+   | -------------------- required by `assert_sized`
+...
 LL |     assert_sized::<A>();
    |     ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `A`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
-note: required by `assert_sized`
-  --> $DIR/extern-types-unsized.rs:19:1
-   |
-LL | fn assert_sized<T>() { }
-   | ^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `A` cannot be known at compilation time
   --> $DIR/extern-types-unsized.rs:25:5
    |
+LL | fn assert_sized<T>() { }
+   | -------------------- required by `assert_sized`
+...
 LL |     assert_sized::<Foo>();
    |     ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `Foo`, the trait `std::marker::Sized` is not implemented for `A`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required because it appears within the type `Foo`
-note: required by `assert_sized`
-  --> $DIR/extern-types-unsized.rs:19:1
-   |
-LL | fn assert_sized<T>() { }
-   | ^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `A` cannot be known at compilation time
   --> $DIR/extern-types-unsized.rs:28:5
    |
+LL | fn assert_sized<T>() { }
+   | -------------------- required by `assert_sized`
+...
 LL |     assert_sized::<Bar<A>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `Bar<A>`, the trait `std::marker::Sized` is not implemented for `A`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required because it appears within the type `Bar<A>`
-note: required by `assert_sized`
-  --> $DIR/extern-types-unsized.rs:19:1
-   |
-LL | fn assert_sized<T>() { }
-   | ^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `A` cannot be known at compilation time
   --> $DIR/extern-types-unsized.rs:31:5
    |
+LL | fn assert_sized<T>() { }
+   | -------------------- required by `assert_sized`
+...
 LL |     assert_sized::<Bar<Bar<A>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
@@ -52,11 +49,6 @@ LL |     assert_sized::<Bar<Bar<A>>>();
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required because it appears within the type `Bar<A>`
    = note: required because it appears within the type `Bar<Bar<A>>`
-note: required by `assert_sized`
-  --> $DIR/extern-types-unsized.rs:19:1
-   |
-LL | fn assert_sized<T>() { }
-   | ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/extern/extern-wrong-value-type.stderr b/src/test/ui/extern/extern-wrong-value-type.stderr
index dce33f3d6323d..52fcb90e6de0c 100644
--- a/src/test/ui/extern/extern-wrong-value-type.stderr
+++ b/src/test/ui/extern/extern-wrong-value-type.stderr
@@ -1,16 +1,14 @@
 error[E0277]: expected a `std::ops::Fn<()>` closure, found `extern "C" fn() {f}`
   --> $DIR/extern-wrong-value-type.rs:9:5
    |
+LL | fn is_fn<F>(_: F) where F: Fn() {}
+   | ------------------------------- required by `is_fn`
+...
 LL |     is_fn(f);
    |     ^^^^^ expected an `Fn<()>` closure, found `extern "C" fn() {f}`
    |
    = help: the trait `std::ops::Fn<()>` is not implemented for `extern "C" fn() {f}`
    = note: wrap the `extern "C" fn() {f}` in a closure with no arguments: `|| { /* code */ }
-note: required by `is_fn`
-  --> $DIR/extern-wrong-value-type.rs:4:1
-   |
-LL | fn is_fn<F>(_: F) where F: Fn() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr
index 1f698c90cb9a4..599dcfaa72617 100644
--- a/src/test/ui/fmt/send-sync.stderr
+++ b/src/test/ui/fmt/send-sync.stderr
@@ -1,6 +1,9 @@
 error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
   --> $DIR/send-sync.rs:8:5
    |
+LL | fn send<T: Send>(_: T) {}
+   | ---------------------- required by `send`
+...
 LL |     send(format_args!("{:?}", c));
    |     ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
    |
@@ -12,15 +15,13 @@ LL |     send(format_args!("{:?}", c));
    = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&[std::fmt::ArgumentV1<'_>]`
    = note: required because it appears within the type `std::fmt::Arguments<'_>`
-note: required by `send`
-  --> $DIR/send-sync.rs:1:1
-   |
-LL | fn send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
   --> $DIR/send-sync.rs:9:5
    |
+LL | fn sync<T: Sync>(_: T) {}
+   | ---------------------- required by `sync`
+...
 LL |     sync(format_args!("{:?}", c));
    |     ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
    |
@@ -32,11 +33,6 @@ LL |     sync(format_args!("{:?}", c));
    = note: required because it appears within the type `[std::fmt::ArgumentV1<'_>]`
    = note: required because it appears within the type `&[std::fmt::ArgumentV1<'_>]`
    = note: required because it appears within the type `std::fmt::Arguments<'_>`
-note: required by `sync`
-  --> $DIR/send-sync.rs:2:1
-   |
-LL | fn sync<T: Sync>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/fn/fn-trait-formatting.stderr b/src/test/ui/fn/fn-trait-formatting.stderr
index 504bc2605ec38..20d7d9ea5b7a8 100644
--- a/src/test/ui/fn/fn-trait-formatting.stderr
+++ b/src/test/ui/fn/fn-trait-formatting.stderr
@@ -28,15 +28,13 @@ LL |     let _: () = (box || -> isize { unimplemented!() }) as Box<dyn FnMut() -
 error[E0277]: expected a `std::ops::Fn<(isize,)>` closure, found `{integer}`
   --> $DIR/fn-trait-formatting.rs:19:5
    |
+LL | fn needs_fn<F>(x: F) where F: Fn(isize) -> isize {}
+   | ------------------------------------------------ required by `needs_fn`
+...
 LL |     needs_fn(1);
    |     ^^^^^^^^ expected an `Fn<(isize,)>` closure, found `{integer}`
    |
    = help: the trait `std::ops::Fn<(isize,)>` is not implemented for `{integer}`
-note: required by `needs_fn`
-  --> $DIR/fn-trait-formatting.rs:3:1
-   |
-LL | fn needs_fn<F>(x: F) where F: Fn(isize) -> isize {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/generator-yielding-or-returning-itself.stderr b/src/test/ui/generator-yielding-or-returning-itself.stderr
index 42591683fe4e3..1049bb6240a24 100644
--- a/src/test/ui/generator-yielding-or-returning-itself.stderr
+++ b/src/test/ui/generator-yielding-or-returning-itself.stderr
@@ -16,20 +16,18 @@ LL | |     })
 error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 32:6 _] as std::ops::Generator>::Yield == [generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 32:6 _]`
   --> $DIR/generator-yielding-or-returning-itself.rs:28:5
    |
-LL |     want_cyclic_generator_yield(|| {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
-   |
-   = note: closures cannot capture themselves or take themselves as argument;
-           this error may be the result of a recent compiler bug-fix,
-           see https://github.com/rust-lang/rust/issues/46062 for more details
-note: required by `want_cyclic_generator_yield`
-  --> $DIR/generator-yielding-or-returning-itself.rs:22:1
-   |
 LL | / pub fn want_cyclic_generator_yield<T>(_: T)
 LL | |     where T: Generator<Yield = T, Return = ()>
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `want_cyclic_generator_yield`
+...
+LL |       want_cyclic_generator_yield(|| {
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
+   |
+   = note: closures cannot capture themselves or take themselves as argument;
+           this error may be the result of a recent compiler bug-fix,
+           see https://github.com/rust-lang/rust/issues/46062 for more details
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr
index 7ea9832c99a24..51416ce0d2f7a 100644
--- a/src/test/ui/generator/not-send-sync.stderr
+++ b/src/test/ui/generator/not-send-sync.stderr
@@ -1,32 +1,28 @@
 error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
   --> $DIR/not-send-sync.rs:16:5
    |
+LL |     fn assert_send<T: Send>(_: T) {}
+   |     ----------------------------- required by `main::assert_send`
+...
 LL |     assert_send(|| {
    |     ^^^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::cell::Cell<i32>`
    = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:16:17: 20:6 a:&std::cell::Cell<i32> _]`
-note: required by `main::assert_send`
-  --> $DIR/not-send-sync.rs:7:5
-   |
-LL |     fn assert_send<T: Send>(_: T) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
   --> $DIR/not-send-sync.rs:9:5
    |
+LL |     fn assert_sync<T: Sync>(_: T) {}
+   |     ----------------------------- required by `main::assert_sync`
+...
 LL |     assert_sync(|| {
    |     ^^^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
    |
    = help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell<i32>, ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
    = note: required because it appears within the type `{std::cell::Cell<i32>, ()}`
    = note: required because it appears within the type `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell<i32>, ()}]`
-note: required by `main::assert_sync`
-  --> $DIR/not-send-sync.rs:6:5
-   |
-LL |     fn assert_sync<T: Sync>(_: T) {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/generator/static-not-unpin.stderr b/src/test/ui/generator/static-not-unpin.stderr
index 404d3069f79f3..28a6fac5b85e3 100644
--- a/src/test/ui/generator/static-not-unpin.stderr
+++ b/src/test/ui/generator/static-not-unpin.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]: std::marker::Unpin` is not satisfied
   --> $DIR/static-not-unpin.rs:14:5
    |
+LL | fn assert_unpin<T: Unpin>(_: T) {
+   | ------------------------------- required by `assert_unpin`
+...
 LL |     assert_unpin(generator);
    |     ^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]`
-   |
-note: required by `assert_unpin`
-  --> $DIR/static-not-unpin.rs:7:1
-   |
-LL | fn assert_unpin<T: Unpin>(_: T) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
index 20265d66c6f43..e0b968b67645e 100644
--- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr
+++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
@@ -1,19 +1,17 @@
 error[E0277]: the trait bound `for<'a, 'b> SomeStruct: Foo<(&'a isize, &'b isize)>` is not satisfied
   --> $DIR/hrtb-conflate-regions.rs:27:10
    |
-LL | fn b() { want_foo2::<SomeStruct>(); }
-   |          ^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct`
-   |
-   = help: the following implementations were found:
-             <SomeStruct as Foo<(&'a isize, &'a isize)>>
-note: required by `want_foo2`
-  --> $DIR/hrtb-conflate-regions.rs:8:1
-   |
 LL | / fn want_foo2<T>()
 LL | |     where T : for<'a,'b> Foo<(&'a isize, &'b isize)>
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `want_foo2`
+...
+LL |   fn b() { want_foo2::<SomeStruct>(); }
+   |            ^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct`
+   |
+   = help: the following implementations were found:
+             <SomeStruct as Foo<(&'a isize, &'a isize)>>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
index 7f2ca037f0f49..bc58b8e16aaf2 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
@@ -1,20 +1,18 @@
 error[E0277]: the trait bound `(): Trait<for<'b> fn(&'b u32)>` is not satisfied
   --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
    |
-LL |     foo::<()>();
-   |     ^^^^^^^^^ the trait `Trait<for<'b> fn(&'b u32)>` is not implemented for `()`
-   |
-   = help: the following implementations were found:
-             <() as Trait<fn(&'a u32)>>
-note: required by `foo`
-  --> $DIR/hrtb-exists-forall-trait-contravariant.rs:8:1
-   |
 LL | / fn foo<T>()
 LL | | where
 LL | |     T: Trait<for<'b> fn(&'b u32)>,
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `foo`
+...
+LL |       foo::<()>();
+   |       ^^^^^^^^^ the trait `Trait<for<'b> fn(&'b u32)>` is not implemented for `()`
+   |
+   = help: the following implementations were found:
+             <() as Trait<fn(&'a u32)>>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr
index cd5982e7588a7..441f75135f3a4 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr
@@ -1,20 +1,18 @@
 error[E0277]: the trait bound `(): Trait<for<'b> fn(fn(&'b u32))>` is not satisfied
   --> $DIR/hrtb-exists-forall-trait-covariant.rs:36:5
    |
-LL |     foo::<()>();
-   |     ^^^^^^^^^ the trait `Trait<for<'b> fn(fn(&'b u32))>` is not implemented for `()`
-   |
-   = help: the following implementations were found:
-             <() as Trait<fn(fn(&'a u32))>>
-note: required by `foo`
-  --> $DIR/hrtb-exists-forall-trait-covariant.rs:8:1
-   |
 LL | / fn foo<T>()
 LL | | where
 LL | |     T: Trait<for<'b> fn(fn(&'b u32))>,
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `foo`
+...
+LL |       foo::<()>();
+   |       ^^^^^^^^^ the trait `Trait<for<'b> fn(fn(&'b u32))>` is not implemented for `()`
+   |
+   = help: the following implementations were found:
+             <() as Trait<fn(fn(&'a u32))>>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
index f10e427a545fb..a11949735b9d2 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
@@ -1,20 +1,18 @@
 error[E0277]: the trait bound `(): Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not satisfied
   --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5
    |
-LL |     foo::<()>();
-   |     ^^^^^^^^^ the trait `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not implemented for `()`
-   |
-   = help: the following implementations were found:
-             <() as Trait<fn(std::cell::Cell<&'a u32>)>>
-note: required by `foo`
-  --> $DIR/hrtb-exists-forall-trait-invariant.rs:10:1
-   |
 LL | / fn foo<T>()
 LL | | where
 LL | |     T: Trait<for<'b> fn(Cell<&'b u32>)>,
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `foo`
+...
+LL |       foo::<()>();
+   |       ^^^^^^^^^ the trait `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not implemented for `()`
+   |
+   = help: the following implementations were found:
+             <() as Trait<fn(std::cell::Cell<&'a u32>)>>
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
index b5d945fe15ca0..0cddd353d679e 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
+++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
@@ -1,18 +1,16 @@
 error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
   --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5
    |
-LL |     want_bar_for_any_ccx(b);
-   |     ^^^^^^^^^^^^^^^^^^^^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
-   |
-   = help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound
-note: required by `want_bar_for_any_ccx`
-  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:31:1
-   |
 LL | / fn want_bar_for_any_ccx<B>(b: &B)
 LL | |     where B : for<'ccx> Bar<'ccx>
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `want_bar_for_any_ccx`
+...
+LL |       want_bar_for_any_ccx(b);
+   |       ^^^^^^^^^^^^^^^^^^^^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+   |
+   = help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
index 20a8fd459fa41..6df486ebaff38 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
+++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
@@ -1,31 +1,25 @@
 error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
   --> $DIR/hrtb-higher-ranker-supertraits.rs:18:5
    |
-LL |     want_foo_for_any_tcx(f);
-   |     ^^^^^^^^^^^^^^^^^^^^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
-   |
-   = help: consider adding a `where for<'tcx> F: Foo<'tcx>` bound
-note: required by `want_foo_for_any_tcx`
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:21:1
-   |
+LL |       want_foo_for_any_tcx(f);
+   |       ^^^^^^^^^^^^^^^^^^^^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
+...
 LL | / fn want_foo_for_any_tcx<F>(f: &F)
 LL | |     where F : for<'tcx> Foo<'tcx>
 LL | | {
 LL | |     want_foo_for_some_tcx(f);
 LL | |     want_foo_for_any_tcx(f);
 LL | | }
-   | |_^
+   | |_- required by `want_foo_for_any_tcx`
+   |
+   = help: consider adding a `where for<'tcx> F: Foo<'tcx>` bound
 
 error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
   --> $DIR/hrtb-higher-ranker-supertraits.rs:35:5
    |
-LL |     want_bar_for_any_ccx(b);
-   |     ^^^^^^^^^^^^^^^^^^^^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
-   |
-   = help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound
-note: required by `want_bar_for_any_ccx`
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:38:1
-   |
+LL |       want_bar_for_any_ccx(b);
+   |       ^^^^^^^^^^^^^^^^^^^^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+...
 LL | / fn want_bar_for_any_ccx<B>(b: &B)
 LL | |     where B : for<'ccx> Bar<'ccx>
 LL | | {
@@ -33,7 +27,9 @@ LL | |     want_foo_for_some_tcx(b);
 ...  |
 LL | |     want_bar_for_any_ccx(b);
 LL | | }
-   | |_^
+   | |_- required by `want_bar_for_any_ccx`
+   |
+   = help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr
index 115851ddf9385..b2938e541fdd8 100644
--- a/src/test/ui/hrtb/hrtb-just-for-static.stderr
+++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr
@@ -1,36 +1,32 @@
 error[E0277]: the trait bound `for<'a> StaticInt: Foo<&'a isize>` is not satisfied
   --> $DIR/hrtb-just-for-static.rs:24:5
    |
-LL |     want_hrtb::<StaticInt>()
-   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt`
-   |
-   = help: the following implementations were found:
-             <StaticInt as Foo<&'static isize>>
-note: required by `want_hrtb`
-  --> $DIR/hrtb-just-for-static.rs:8:1
-   |
 LL | / fn want_hrtb<T>()
 LL | |     where T : for<'a> Foo<&'a isize>
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `want_hrtb`
+...
+LL |       want_hrtb::<StaticInt>()
+   |       ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt`
+   |
+   = help: the following implementations were found:
+             <StaticInt as Foo<&'static isize>>
 
 error[E0277]: the trait bound `for<'a> &'a u32: Foo<&'a isize>` is not satisfied
   --> $DIR/hrtb-just-for-static.rs:30:5
    |
-LL |     want_hrtb::<&'a u32>()
-   |     ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `&'a u32`
-   |
-   = help: the following implementations were found:
-             <&'a u32 as Foo<&'a isize>>
-note: required by `want_hrtb`
-  --> $DIR/hrtb-just-for-static.rs:8:1
-   |
 LL | / fn want_hrtb<T>()
 LL | |     where T : for<'a> Foo<&'a isize>
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `want_hrtb`
+...
+LL |       want_hrtb::<&'a u32>()
+   |       ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `&'a u32`
+   |
+   = help: the following implementations were found:
+             <&'a u32 as Foo<&'a isize>>
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/hrtb/issue-46989.stderr b/src/test/ui/hrtb/issue-46989.stderr
index b308291d5c0eb..57eaf2aad2bc5 100644
--- a/src/test/ui/hrtb/issue-46989.stderr
+++ b/src/test/ui/hrtb/issue-46989.stderr
@@ -1,16 +1,14 @@
 error[E0277]: the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied
   --> $DIR/issue-46989.rs:40:5
    |
+LL | fn assert_foo<T: Foo>() {}
+   | ----------------------- required by `assert_foo`
+...
 LL |     assert_foo::<fn(&i32)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `for<'r> fn(&'r i32)`
    |
    = help: the following implementations were found:
              <fn(A) as Foo>
-note: required by `assert_foo`
-  --> $DIR/issue-46989.rs:37:1
-   |
-LL | fn assert_foo<T: Foo>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index 61450d3203cd8..af641a89e7f9c 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -72,16 +72,14 @@ LL | | }
 error[E0277]: `std::rc::Rc<std::string::String>` cannot be sent between threads safely
   --> $DIR/auto-trait-leak.rs:15:5
    |
+LL | fn send<T: Send>(_: T) {}
+   | ---------------------- required by `send`
+...
 LL |     send(cycle2().clone());
    |     ^^^^ `std::rc::Rc<std::string::String>` cannot be sent between threads safely
    |
    = help: within `impl std::clone::Clone`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::string::String>`
    = note: required because it appears within the type `impl std::clone::Clone`
-note: required by `send`
-  --> $DIR/auto-trait-leak.rs:4:1
-   |
-LL | fn send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/impl-trait/auto-trait-leak2.stderr b/src/test/ui/impl-trait/auto-trait-leak2.stderr
index 19899ff83f7c3..460af7dedbea8 100644
--- a/src/test/ui/impl-trait/auto-trait-leak2.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak2.stderr
@@ -1,32 +1,28 @@
 error[E0277]: `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
   --> $DIR/auto-trait-leak2.rs:13:5
    |
+LL | fn send<T: Send>(_: T) {}
+   | ---------------------- required by `send`
+...
 LL |     send(before());
    |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
    |
    = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
    = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:7:5: 7:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
    = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
-note: required by `send`
-  --> $DIR/auto-trait-leak2.rs:10:1
-   |
-LL | fn send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
   --> $DIR/auto-trait-leak2.rs:16:5
    |
+LL | fn send<T: Send>(_: T) {}
+   | ---------------------- required by `send`
+...
 LL |     send(after());
    |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
    |
    = help: within `impl std::ops::Fn<(i32,)>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::cell::Cell<i32>>`
    = note: required because it appears within the type `[closure@$DIR/auto-trait-leak2.rs:24:5: 24:22 p:std::rc::Rc<std::cell::Cell<i32>>]`
    = note: required because it appears within the type `impl std::ops::Fn<(i32,)>`
-note: required by `send`
-  --> $DIR/auto-trait-leak2.rs:10:1
-   |
-LL | fn send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-1920-1.stderr b/src/test/ui/issues/issue-1920-1.stderr
index b3ac05031b00f..c62cbb0cf8b96 100644
--- a/src/test/ui/issues/issue-1920-1.stderr
+++ b/src/test/ui/issues/issue-1920-1.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `foo::issue_1920::S: std::clone::Clone` is not satisfied
   --> $DIR/issue-1920-1.rs:12:5
    |
+LL | fn assert_clone<T>() where T : Clone { }
+   | ------------------------------------ required by `assert_clone`
+...
 LL |     assert_clone::<foo::issue_1920::S>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `foo::issue_1920::S`
-   |
-note: required by `assert_clone`
-  --> $DIR/issue-1920-1.rs:9:1
-   |
-LL | fn assert_clone<T>() where T : Clone { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-1920-2.stderr b/src/test/ui/issues/issue-1920-2.stderr
index a000a87302bf7..aad076244699a 100644
--- a/src/test/ui/issues/issue-1920-2.stderr
+++ b/src/test/ui/issues/issue-1920-2.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `bar::S: std::clone::Clone` is not satisfied
   --> $DIR/issue-1920-2.rs:10:5
    |
+LL | fn assert_clone<T>() where T : Clone { }
+   | ------------------------------------ required by `assert_clone`
+...
 LL |     assert_clone::<bar::S>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `bar::S`
-   |
-note: required by `assert_clone`
-  --> $DIR/issue-1920-2.rs:7:1
-   |
-LL | fn assert_clone<T>() where T : Clone { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-1920-3.stderr b/src/test/ui/issues/issue-1920-3.stderr
index 62e47a6866e63..4378ea49755a7 100644
--- a/src/test/ui/issues/issue-1920-3.stderr
+++ b/src/test/ui/issues/issue-1920-3.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `issue_1920::S: std::clone::Clone` is not satisfied
   --> $DIR/issue-1920-3.rs:14:5
    |
+LL | fn assert_clone<T>() where T : Clone { }
+   | ------------------------------------ required by `assert_clone`
+...
 LL |     assert_clone::<foo::issue_1920::S>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `issue_1920::S`
-   |
-note: required by `assert_clone`
-  --> $DIR/issue-1920-3.rs:11:1
-   |
-LL | fn assert_clone<T>() where T : Clone { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-20005.stderr b/src/test/ui/issues/issue-20005.stderr
index e271005e74d1d..2754d6bdd8306 100644
--- a/src/test/ui/issues/issue-20005.stderr
+++ b/src/test/ui/issues/issue-20005.stderr
@@ -1,6 +1,9 @@
 error[E0277]: the size for values of type `Self` cannot be known at compilation time
   --> $DIR/issue-20005.rs:8:5
    |
+LL |   trait From<Src> {
+   |   --------------- required by `From`
+...
 LL | /     fn to<Dst>(
 LL | |         self
 LL | |     ) -> <Dst as From<Self>>::Result where Dst: From<Self> {
@@ -11,11 +14,6 @@ LL | |     }
    = help: the trait `std::marker::Sized` is not implemented for `Self`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where Self: std::marker::Sized` bound
-note: required by `From`
-  --> $DIR/issue-20005.rs:1:1
-   |
-LL | trait From<Src> {
-   | ^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr
index 762816c5a98c4..72a8fe4283b56 100644
--- a/src/test/ui/issues/issue-20413.stderr
+++ b/src/test/ui/issues/issue-20413.stderr
@@ -9,6 +9,9 @@ LL | struct NoData<T>;
 error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo`
   --> $DIR/issue-20413.rs:8:1
    |
+LL |   trait Foo {
+   |   --------- required by `Foo`
+...
 LL | / impl<T> Foo for T where NoData<T>: Foo {
 LL | |
 LL | |   fn answer(self) {
@@ -146,15 +149,13 @@ LL | | }
    = note: required because of the requirements on the impl of `Foo` for `NoData<NoData<NoData<T>>>`
    = note: required because of the requirements on the impl of `Foo` for `NoData<NoData<T>>`
    = note: required because of the requirements on the impl of `Foo` for `NoData<T>`
-note: required by `Foo`
-  --> $DIR/issue-20413.rs:1:1
-   |
-LL | trait Foo {
-   | ^^^^^^^^^
 
 error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo`
   --> $DIR/issue-20413.rs:10:3
    |
+LL |   trait Foo {
+   |   --------- required by `Foo`
+...
 LL | /   fn answer(self) {
 LL | |
 LL | |     let val: NoData<T> = NoData;
@@ -289,11 +290,6 @@ LL | |   }
    = note: required because of the requirements on the impl of `Foo` for `NoData<NoData<NoData<T>>>`
    = note: required because of the requirements on the impl of `Foo` for `NoData<NoData<T>>`
    = note: required because of the requirements on the impl of `Foo` for `NoData<T>`
-note: required by `Foo`
-  --> $DIR/issue-20413.rs:1:1
-   |
-LL | trait Foo {
-   | ^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-21763.stderr b/src/test/ui/issues/issue-21763.stderr
index 87c048fdf4c11..99d004a973a26 100644
--- a/src/test/ui/issues/issue-21763.stderr
+++ b/src/test/ui/issues/issue-21763.stderr
@@ -1,6 +1,9 @@
 error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
   --> $DIR/issue-21763.rs:9:5
    |
+LL | fn foo<T: Send>() {}
+   | ----------------- required by `foo`
+...
 LL |     foo::<HashMap<Rc<()>, Rc<()>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
    |
@@ -9,11 +12,6 @@ LL |     foo::<HashMap<Rc<()>, Rc<()>>>();
    = note: required because of the requirements on the impl of `std::marker::Send` for `hashbrown::raw::RawTable<(std::rc::Rc<()>, std::rc::Rc<()>)>`
    = note: required because it appears within the type `hashbrown::map::HashMap<std::rc::Rc<()>, std::rc::Rc<()>, std::collections::hash_map::RandomState>`
    = note: required because it appears within the type `std::collections::HashMap<std::rc::Rc<()>, std::rc::Rc<()>>`
-note: required by `foo`
-  --> $DIR/issue-21763.rs:6:1
-   |
-LL | fn foo<T: Send>() {}
-   | ^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-21837.stderr b/src/test/ui/issues/issue-21837.stderr
index 3111d3a47414b..20d02a90315d0 100644
--- a/src/test/ui/issues/issue-21837.stderr
+++ b/src/test/ui/issues/issue-21837.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `T: Bound` is not satisfied
   --> $DIR/issue-21837.rs:8:9
    |
+LL | pub struct Foo<T: Bound>(T);
+   | ---------------------------- required by `Foo`
+...
 LL | impl<T> Trait2 for Foo<T> {}
    |         ^^^^^^ the trait `Bound` is not implemented for `T`
    |
    = help: consider adding a `where T: Bound` bound
-note: required by `Foo`
-  --> $DIR/issue-21837.rs:2:1
-   |
-LL | pub struct Foo<T: Bound>(T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-21974.stderr b/src/test/ui/issues/issue-21974.stderr
index 85e59d7bede5f..a6cce7846e81d 100644
--- a/src/test/ui/issues/issue-21974.stderr
+++ b/src/test/ui/issues/issue-21974.stderr
@@ -1,6 +1,9 @@
 error[E0283]: type annotations required: cannot resolve `&'a T: Foo`
   --> $DIR/issue-21974.rs:10:1
    |
+LL |   trait Foo {
+   |   --------- required by `Foo`
+...
 LL | / fn foo<'a,'b,T>(x: &'a T, y: &'b T)
 LL | |     where &'a T : Foo,
 LL | |           &'b T : Foo
@@ -9,12 +12,6 @@ LL | |     x.foo();
 LL | |     y.foo();
 LL | | }
    | |_^
-   |
-note: required by `Foo`
-  --> $DIR/issue-21974.rs:6:1
-   |
-LL | trait Foo {
-   | ^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-24204.stderr b/src/test/ui/issues/issue-24204.stderr
index 8e04c0ddccea6..eb9aada389f8f 100644
--- a/src/test/ui/issues/issue-24204.stderr
+++ b/src/test/ui/issues/issue-24204.stderr
@@ -1,16 +1,14 @@
 error[E0271]: type mismatch resolving `<<T as Trait>::A as MultiDispatch<i32>>::O == T`
   --> $DIR/issue-24204.rs:14:1
    |
+LL | trait Trait: Sized {
+   | ------------------ required by `Trait`
+...
 LL | fn test<T: Trait<B=i32>>(b: i32) -> T where T::A: MultiDispatch<i32> { T::new(b) }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found type parameter
    |
    = note: expected type `<<T as Trait>::A as MultiDispatch<i32>>::O`
               found type `T`
-note: required by `Trait`
-  --> $DIR/issue-24204.rs:7:1
-   |
-LL | trait Trait: Sized {
-   | ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-24424.stderr b/src/test/ui/issues/issue-24424.stderr
index 4c6ac0180a873..7ff019a30a864 100644
--- a/src/test/ui/issues/issue-24424.stderr
+++ b/src/test/ui/issues/issue-24424.stderr
@@ -1,14 +1,11 @@
 error[E0283]: type annotations required: cannot resolve `T0: Trait0<'l0>`
   --> $DIR/issue-24424.rs:4:1
    |
+LL | trait Trait0<'l0>  {}
+   | ----------------- required by `Trait0`
+LL | 
 LL | impl <'l0, 'l1, T0> Trait1<'l0, T0> for bool where T0 : Trait0<'l0>, T0 : Trait0<'l1> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: required by `Trait0`
-  --> $DIR/issue-24424.rs:2:1
-   |
-LL | trait Trait0<'l0>  {}
-   | ^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-25076.stderr b/src/test/ui/issues/issue-25076.stderr
index 435ab13edada5..b583a6b54bf9f 100644
--- a/src/test/ui/issues/issue-25076.stderr
+++ b/src/test/ui/issues/issue-25076.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `(): InOut<_>` is not satisfied
   --> $DIR/issue-25076.rs:10:5
    |
+LL | fn do_fold<B, F: InOut<B, Out=B>>(init: B, f: F) {}
+   | ------------------------------------------------ required by `do_fold`
+...
 LL |     do_fold(bot(), ());
    |     ^^^^^^^ the trait `InOut<_>` is not implemented for `()`
-   |
-note: required by `do_fold`
-  --> $DIR/issue-25076.rs:5:1
-   |
-LL | fn do_fold<B, F: InOut<B, Out=B>>(init: B, f: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-29147.stderr b/src/test/ui/issues/issue-29147.stderr
index 3b42186b25138..0dc9b0c9e10cd 100644
--- a/src/test/ui/issues/issue-29147.stderr
+++ b/src/test/ui/issues/issue-29147.stderr
@@ -1,14 +1,11 @@
 error[E0283]: type annotations required: cannot resolve `S5<_>: Foo`
   --> $DIR/issue-29147.rs:21:13
    |
+LL | trait Foo { fn xxx(&self); }
+   |             -------------- required by `Foo::xxx`
+...
 LL |     let _ = <S5<_>>::xxx;
    |             ^^^^^^^^^^^^
-   |
-note: required by `Foo::xxx`
-  --> $DIR/issue-29147.rs:10:13
-   |
-LL | trait Foo { fn xxx(&self); }
-   |             ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-32963.stderr b/src/test/ui/issues/issue-32963.stderr
index a31a74a07f46e..2960f4e598997 100644
--- a/src/test/ui/issues/issue-32963.stderr
+++ b/src/test/ui/issues/issue-32963.stderr
@@ -12,14 +12,11 @@ LL |     size_of_copy::<dyn Misc + Copy>();
 error[E0277]: the trait bound `dyn Misc: std::marker::Copy` is not satisfied
   --> $DIR/issue-32963.rs:8:5
    |
+LL | fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
+   | ------------------------------------------ required by `size_of_copy`
+...
 LL |     size_of_copy::<dyn Misc + Copy>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `dyn Misc`
-   |
-note: required by `size_of_copy`
-  --> $DIR/issue-32963.rs:5:1
-   |
-LL | fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-39970.stderr b/src/test/ui/issues/issue-39970.stderr
index e4f158706457c..f15f771fa9f6e 100644
--- a/src/test/ui/issues/issue-39970.stderr
+++ b/src/test/ui/issues/issue-39970.stderr
@@ -1,17 +1,15 @@
 error[E0271]: type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()`
   --> $DIR/issue-39970.rs:19:5
    |
+LL |     fn visit() {}
+   |     ---------- required by `Visit::visit`
+...
 LL |     <() as Visit>::visit();
    |     ^^^^^^^^^^^^^^^^^^^^ expected &(), found ()
    |
    = note: expected type `&()`
               found type `()`
    = note: required because of the requirements on the impl of `Visit` for `()`
-note: required by `Visit::visit`
-  --> $DIR/issue-39970.rs:6:5
-   |
-LL |     fn visit() {}
-   |     ^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-40827.stderr b/src/test/ui/issues/issue-40827.stderr
index 96b411bfb1d22..9131120671f4c 100644
--- a/src/test/ui/issues/issue-40827.stderr
+++ b/src/test/ui/issues/issue-40827.stderr
@@ -1,6 +1,9 @@
 error[E0277]: `std::rc::Rc<Foo>` cannot be sent between threads safely
   --> $DIR/issue-40827.rs:14:5
    |
+LL | fn f<T: Send>(_: T) {}
+   | ------------------- required by `f`
+...
 LL |     f(Foo(Arc::new(Bar::B(None))));
    |     ^ `std::rc::Rc<Foo>` cannot be sent between threads safely
    |
@@ -8,15 +11,13 @@ LL |     f(Foo(Arc::new(Bar::B(None))));
    = note: required because it appears within the type `Bar`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<Bar>`
    = note: required because it appears within the type `Foo`
-note: required by `f`
-  --> $DIR/issue-40827.rs:11:1
-   |
-LL | fn f<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::rc::Rc<Foo>` cannot be shared between threads safely
   --> $DIR/issue-40827.rs:14:5
    |
+LL | fn f<T: Send>(_: T) {}
+   | ------------------- required by `f`
+...
 LL |     f(Foo(Arc::new(Bar::B(None))));
    |     ^ `std::rc::Rc<Foo>` cannot be shared between threads safely
    |
@@ -24,11 +25,6 @@ LL |     f(Foo(Arc::new(Bar::B(None))));
    = note: required because it appears within the type `Bar`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<Bar>`
    = note: required because it appears within the type `Foo`
-note: required by `f`
-  --> $DIR/issue-40827.rs:11:1
-   |
-LL | fn f<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-43623.stderr b/src/test/ui/issues/issue-43623.stderr
index b5674105f75d2..d843629e8a26f 100644
--- a/src/test/ui/issues/issue-43623.stderr
+++ b/src/test/ui/issues/issue-43623.stderr
@@ -1,41 +1,31 @@
 error[E0631]: type mismatch in function arguments
   --> $DIR/issue-43623.rs:14:5
    |
-LL |     break_me::<Type, fn(_)>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
-   |     |
-   |     expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
-   |     found signature of `fn(_) -> _`
-   |
-note: required by `break_me`
-  --> $DIR/issue-43623.rs:11:1
-   |
 LL | / pub fn break_me<T, F>(f: F)
 LL | | where T: for<'b> Trait<'b>,
 LL | |       F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
 LL | |     break_me::<Type, fn(_)>;
+   | |     ^^^^^^^^^^^^^^^^^^^^^^^
+   | |     |
+   | |     expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
+   | |     found signature of `fn(_) -> _`
 LL | |
 LL | |
 LL | | }
-   | |_^
+   | |_- required by `break_me`
 
 error[E0271]: type mismatch resolving `for<'b> <fn(_) as std::ops::FnOnce<(<Type as Trait<'b>>::Assoc,)>>::Output == ()`
   --> $DIR/issue-43623.rs:14:5
    |
-LL |     break_me::<Type, fn(_)>;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'b, found concrete lifetime
-   |
-note: required by `break_me`
-  --> $DIR/issue-43623.rs:11:1
-   |
 LL | / pub fn break_me<T, F>(f: F)
 LL | | where T: for<'b> Trait<'b>,
 LL | |       F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
 LL | |     break_me::<Type, fn(_)>;
+   | |     ^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'b, found concrete lifetime
 LL | |
 LL | |
 LL | | }
-   | |_^
+   | |_- required by `break_me`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-47706.stderr b/src/test/ui/issues/issue-47706.stderr
index fa2e00cde4dff..c47eebb8e5c07 100644
--- a/src/test/ui/issues/issue-47706.stderr
+++ b/src/test/ui/issues/issue-47706.stderr
@@ -10,21 +10,18 @@ LL |         self.foo.map(Foo::new)
 error[E0593]: function is expected to take 0 arguments, but it takes 1 argument
   --> $DIR/issue-47706.rs:27:5
    |
-LL |     Bar(i32),
-   |     -------- takes 1 argument
+LL |       Bar(i32),
+   |       -------- takes 1 argument
 ...
-LL |     foo(Qux::Bar);
-   |     ^^^ expected function that takes 0 arguments
-   |
-note: required by `foo`
-  --> $DIR/issue-47706.rs:20:1
-   |
 LL | / fn foo<F>(f: F)
 LL | | where
 LL | |     F: Fn(),
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `foo`
+...
+LL |       foo(Qux::Bar);
+   |       ^^^ expected function that takes 0 arguments
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-60283.stderr b/src/test/ui/issues/issue-60283.stderr
index a79b1959dca2f..a977ba392769f 100644
--- a/src/test/ui/issues/issue-60283.stderr
+++ b/src/test/ui/issues/issue-60283.stderr
@@ -1,33 +1,27 @@
 error[E0631]: type mismatch in function arguments
   --> $DIR/issue-60283.rs:14:5
    |
-LL |     foo((), drop)
-   |     ^^^
-   |     |
-   |     expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
-   |     found signature of `fn(_) -> _`
-   |
-note: required by `foo`
-  --> $DIR/issue-60283.rs:9:1
-   |
 LL | / pub fn foo<T, F>(_: T, _: F)
 LL | | where T: for<'a> Trait<'a>,
 LL | |       F: for<'a> FnMut(<T as Trait<'a>>::Item) {}
-   | |_________________________________________________^
+   | |_________________________________________________- required by `foo`
+...
+LL |       foo((), drop)
+   |       ^^^
+   |       |
+   |       expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
+   |       found signature of `fn(_) -> _`
 
 error[E0271]: type mismatch resolving `for<'a> <fn(_) {std::mem::drop::<_>} as std::ops::FnOnce<(<() as Trait<'a>>::Item,)>>::Output == ()`
   --> $DIR/issue-60283.rs:14:5
    |
-LL |     foo((), drop)
-   |     ^^^ expected bound lifetime parameter 'a, found concrete lifetime
-   |
-note: required by `foo`
-  --> $DIR/issue-60283.rs:9:1
-   |
 LL | / pub fn foo<T, F>(_: T, _: F)
 LL | | where T: for<'a> Trait<'a>,
 LL | |       F: for<'a> FnMut(<T as Trait<'a>>::Item) {}
-   | |_________________________________________________^
+   | |_________________________________________________- required by `foo`
+...
+LL |       foo((), drop)
+   |       ^^^ expected bound lifetime parameter 'a, found concrete lifetime
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/iterators/bound.stderr b/src/test/ui/iterators/bound.stderr
index 14057387c4f40..92a91ff4cb1ba 100644
--- a/src/test/ui/iterators/bound.stderr
+++ b/src/test/ui/iterators/bound.stderr
@@ -1,16 +1,13 @@
 error[E0277]: `u8` is not an iterator
   --> $DIR/bound.rs:2:10
    |
+LL | struct S<I: Iterator>(I);
+   | ------------------------- required by `S`
 LL | struct T(S<u8>);
    |          ^^^^^ `u8` is not an iterator
    |
    = help: the trait `std::iter::Iterator` is not implemented for `u8`
    = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
-note: required by `S`
-  --> $DIR/bound.rs:1:1
-   |
-LL | struct S<I: Iterator>(I);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/kindck/kindck-copy.stderr b/src/test/ui/kindck/kindck-copy.stderr
index 929a807656209..1fe59460e057f 100644
--- a/src/test/ui/kindck/kindck-copy.stderr
+++ b/src/test/ui/kindck/kindck-copy.stderr
@@ -1,138 +1,107 @@
 error[E0277]: the trait bound `&'static mut isize: std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:27:5
    |
+LL | fn assert_copy<T:Copy>() { }
+   | ------------------------ required by `assert_copy`
+...
 LL |     assert_copy::<&'static mut isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'static mut isize`
    |
    = help: the following implementations were found:
              <isize as std::marker::Copy>
-note: required by `assert_copy`
-  --> $DIR/kindck-copy.rs:5:1
-   |
-LL | fn assert_copy<T:Copy>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `&'a mut isize: std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:28:5
    |
+LL | fn assert_copy<T:Copy>() { }
+   | ------------------------ required by `assert_copy`
+...
 LL |     assert_copy::<&'a mut isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'a mut isize`
    |
    = help: the following implementations were found:
              <isize as std::marker::Copy>
-note: required by `assert_copy`
-  --> $DIR/kindck-copy.rs:5:1
-   |
-LL | fn assert_copy<T:Copy>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::boxed::Box<isize>: std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:31:5
    |
+LL | fn assert_copy<T:Copy>() { }
+   | ------------------------ required by `assert_copy`
+...
 LL |     assert_copy::<Box<isize>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<isize>`
-   |
-note: required by `assert_copy`
-  --> $DIR/kindck-copy.rs:5:1
-   |
-LL | fn assert_copy<T:Copy>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:32:5
    |
+LL | fn assert_copy<T:Copy>() { }
+   | ------------------------ required by `assert_copy`
+...
 LL |     assert_copy::<String>();
    |     ^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
-   |
-note: required by `assert_copy`
-  --> $DIR/kindck-copy.rs:5:1
-   |
-LL | fn assert_copy<T:Copy>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::vec::Vec<isize>: std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:33:5
    |
+LL | fn assert_copy<T:Copy>() { }
+   | ------------------------ required by `assert_copy`
+...
 LL |     assert_copy::<Vec<isize> >();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::vec::Vec<isize>`
-   |
-note: required by `assert_copy`
-  --> $DIR/kindck-copy.rs:5:1
-   |
-LL | fn assert_copy<T:Copy>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::boxed::Box<&'a mut isize>: std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:34:5
    |
+LL | fn assert_copy<T:Copy>() { }
+   | ------------------------ required by `assert_copy`
+...
 LL |     assert_copy::<Box<&'a mut isize>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<&'a mut isize>`
-   |
-note: required by `assert_copy`
-  --> $DIR/kindck-copy.rs:5:1
-   |
-LL | fn assert_copy<T:Copy>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::boxed::Box<dyn Dummy>: std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:42:5
    |
+LL | fn assert_copy<T:Copy>() { }
+   | ------------------------ required by `assert_copy`
+...
 LL |     assert_copy::<Box<dyn Dummy>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<dyn Dummy>`
-   |
-note: required by `assert_copy`
-  --> $DIR/kindck-copy.rs:5:1
-   |
-LL | fn assert_copy<T:Copy>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::boxed::Box<dyn Dummy + std::marker::Send>: std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:43:5
    |
+LL | fn assert_copy<T:Copy>() { }
+   | ------------------------ required by `assert_copy`
+...
 LL |     assert_copy::<Box<dyn Dummy + Send>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<dyn Dummy + std::marker::Send>`
-   |
-note: required by `assert_copy`
-  --> $DIR/kindck-copy.rs:5:1
-   |
-LL | fn assert_copy<T:Copy>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `&'a mut (dyn Dummy + std::marker::Send + 'a): std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:46:5
    |
+LL | fn assert_copy<T:Copy>() { }
+   | ------------------------ required by `assert_copy`
+...
 LL |     assert_copy::<&'a mut (dyn Dummy + Send)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'a mut (dyn Dummy + std::marker::Send + 'a)`
-   |
-note: required by `assert_copy`
-  --> $DIR/kindck-copy.rs:5:1
-   |
-LL | fn assert_copy<T:Copy>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `MyNoncopyStruct: std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:64:5
    |
+LL | fn assert_copy<T:Copy>() { }
+   | ------------------------ required by `assert_copy`
+...
 LL |     assert_copy::<MyNoncopyStruct>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `MyNoncopyStruct`
-   |
-note: required by `assert_copy`
-  --> $DIR/kindck-copy.rs:5:1
-   |
-LL | fn assert_copy<T:Copy>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::rc::Rc<isize>: std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:67:5
    |
+LL | fn assert_copy<T:Copy>() { }
+   | ------------------------ required by `assert_copy`
+...
 LL |     assert_copy::<Rc<isize>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::rc::Rc<isize>`
-   |
-note: required by `assert_copy`
-  --> $DIR/kindck-copy.rs:5:1
-   |
-LL | fn assert_copy<T:Copy>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/kindck/kindck-impl-type-params-2.stderr b/src/test/ui/kindck/kindck-impl-type-params-2.stderr
index bd971c903727b..6d599423d2548 100644
--- a/src/test/ui/kindck/kindck-impl-type-params-2.stderr
+++ b/src/test/ui/kindck/kindck-impl-type-params-2.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `std::boxed::Box<{integer}>: std::marker::Copy` is not satisfied
   --> $DIR/kindck-impl-type-params-2.rs:13:5
    |
+LL | fn take_param<T:Foo>(foo: &T) { }
+   | ----------------------------- required by `take_param`
+...
 LL |     take_param(&x);
    |     ^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<{integer}>`
    |
    = note: required because of the requirements on the impl of `Foo` for `std::boxed::Box<{integer}>`
-note: required by `take_param`
-  --> $DIR/kindck-impl-type-params-2.rs:9:1
-   |
-LL | fn take_param<T:Foo>(foo: &T) { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.stderr
index 1e719e2608425..a53063157fc8e 100644
--- a/src/test/ui/kindck/kindck-inherited-copy-bound.stderr
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `std::boxed::Box<{integer}>: std::marker::Copy` is not satisfied
   --> $DIR/kindck-inherited-copy-bound.rs:18:5
    |
+LL | fn take_param<T:Foo>(foo: &T) { }
+   | ----------------------------- required by `take_param`
+...
 LL |     take_param(&x);
    |     ^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<{integer}>`
    |
    = note: required because of the requirements on the impl of `Foo` for `std::boxed::Box<{integer}>`
-note: required by `take_param`
-  --> $DIR/kindck-inherited-copy-bound.rs:14:1
-   |
-LL | fn take_param<T:Foo>(foo: &T) { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/kindck-inherited-copy-bound.rs:24:19
diff --git a/src/test/ui/kindck/kindck-nonsendable-1.stderr b/src/test/ui/kindck/kindck-nonsendable-1.stderr
index 2aacd2741d388..6d60de888c98d 100644
--- a/src/test/ui/kindck/kindck-nonsendable-1.stderr
+++ b/src/test/ui/kindck/kindck-nonsendable-1.stderr
@@ -1,16 +1,14 @@
 error[E0277]: `std::rc::Rc<usize>` cannot be sent between threads safely
   --> $DIR/kindck-nonsendable-1.rs:9:5
    |
+LL | fn bar<F:FnOnce() + Send>(_: F) { }
+   | ------------------------------- required by `bar`
+...
 LL |     bar(move|| foo(x));
    |     ^^^ `std::rc::Rc<usize>` cannot be sent between threads safely
    |
    = help: within `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22 x:std::rc::Rc<usize>]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<usize>`
    = note: required because it appears within the type `[closure@$DIR/kindck-nonsendable-1.rs:9:9: 9:22 x:std::rc::Rc<usize>]`
-note: required by `bar`
-  --> $DIR/kindck-nonsendable-1.rs:5:1
-   |
-LL | fn bar<F:FnOnce() + Send>(_: F) { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/kindck/kindck-send-object.stderr b/src/test/ui/kindck/kindck-send-object.stderr
index c9aadd85a53f2..3ca2d730cbae9 100644
--- a/src/test/ui/kindck/kindck-send-object.stderr
+++ b/src/test/ui/kindck/kindck-send-object.stderr
@@ -1,31 +1,27 @@
 error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely
   --> $DIR/kindck-send-object.rs:12:5
    |
+LL | fn assert_send<T:Send>() { }
+   | ------------------------ required by `assert_send`
+...
 LL |     assert_send::<&'static (dyn Dummy + 'static)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `(dyn Dummy + 'static)`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&'static (dyn Dummy + 'static)`
-note: required by `assert_send`
-  --> $DIR/kindck-send-object.rs:5:1
-   |
-LL | fn assert_send<T:Send>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `dyn Dummy` cannot be sent between threads safely
   --> $DIR/kindck-send-object.rs:17:5
    |
+LL | fn assert_send<T:Send>() { }
+   | ------------------------ required by `assert_send`
+...
 LL |     assert_send::<Box<dyn Dummy>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `dyn Dummy`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<dyn Dummy>`
    = note: required because it appears within the type `std::boxed::Box<dyn Dummy>`
-note: required by `assert_send`
-  --> $DIR/kindck-send-object.rs:5:1
-   |
-LL | fn assert_send<T:Send>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/kindck/kindck-send-object1.stderr b/src/test/ui/kindck/kindck-send-object1.stderr
index 757b41ab6cb7e..0f5f7e0890b23 100644
--- a/src/test/ui/kindck/kindck-send-object1.stderr
+++ b/src/test/ui/kindck/kindck-send-object1.stderr
@@ -1,16 +1,14 @@
 error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely
   --> $DIR/kindck-send-object1.rs:10:5
    |
+LL | fn assert_send<T:Send+'static>() { }
+   | -------------------------------- required by `assert_send`
+...
 LL |     assert_send::<&'a dyn Dummy>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `(dyn Dummy + 'a)`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&'a (dyn Dummy + 'a)`
-note: required by `assert_send`
-  --> $DIR/kindck-send-object1.rs:5:1
-   |
-LL | fn assert_send<T:Send+'static>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0477]: the type `&'a (dyn Dummy + std::marker::Sync + 'a)` does not fulfill the required lifetime
   --> $DIR/kindck-send-object1.rs:14:5
@@ -23,17 +21,15 @@ LL |     assert_send::<&'a (dyn Dummy + Sync)>();
 error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely
   --> $DIR/kindck-send-object1.rs:29:5
    |
+LL | fn assert_send<T:Send+'static>() { }
+   | -------------------------------- required by `assert_send`
+...
 LL |     assert_send::<Box<dyn Dummy + 'a>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `(dyn Dummy + 'a)`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn Dummy + 'a)>`
    = note: required because it appears within the type `std::boxed::Box<(dyn Dummy + 'a)>`
-note: required by `assert_send`
-  --> $DIR/kindck-send-object1.rs:5:1
-   |
-LL | fn assert_send<T:Send+'static>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/kindck/kindck-send-object2.stderr b/src/test/ui/kindck/kindck-send-object2.stderr
index c1c9db9da839a..72cd985cc8639 100644
--- a/src/test/ui/kindck/kindck-send-object2.stderr
+++ b/src/test/ui/kindck/kindck-send-object2.stderr
@@ -1,31 +1,27 @@
 error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely
   --> $DIR/kindck-send-object2.rs:7:5
    |
+LL | fn assert_send<T:Send>() { }
+   | ------------------------ required by `assert_send`
+...
 LL |     assert_send::<&'static dyn Dummy>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `(dyn Dummy + 'static)`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&'static (dyn Dummy + 'static)`
-note: required by `assert_send`
-  --> $DIR/kindck-send-object2.rs:3:1
-   |
-LL | fn assert_send<T:Send>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `dyn Dummy` cannot be sent between threads safely
   --> $DIR/kindck-send-object2.rs:12:5
    |
+LL | fn assert_send<T:Send>() { }
+   | ------------------------ required by `assert_send`
+...
 LL |     assert_send::<Box<dyn Dummy>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `dyn Dummy`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<dyn Dummy>`
    = note: required because it appears within the type `std::boxed::Box<dyn Dummy>`
-note: required by `assert_send`
-  --> $DIR/kindck-send-object2.rs:3:1
-   |
-LL | fn assert_send<T:Send>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/kindck/kindck-send-owned.stderr b/src/test/ui/kindck/kindck-send-owned.stderr
index 75c757dc54646..ee919f02d6537 100644
--- a/src/test/ui/kindck/kindck-send-owned.stderr
+++ b/src/test/ui/kindck/kindck-send-owned.stderr
@@ -1,17 +1,15 @@
 error[E0277]: `*mut u8` cannot be sent between threads safely
   --> $DIR/kindck-send-owned.rs:12:5
    |
+LL | fn assert_send<T:Send>() { }
+   | ------------------------ required by `assert_send`
+...
 LL |     assert_send::<Box<*mut u8>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `*mut u8`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<*mut u8>`
    = note: required because it appears within the type `std::boxed::Box<*mut u8>`
-note: required by `assert_send`
-  --> $DIR/kindck-send-owned.rs:3:1
-   |
-LL | fn assert_send<T:Send>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/kindck/kindck-send-unsafe.stderr b/src/test/ui/kindck/kindck-send-unsafe.stderr
index 2fbb07a0df51a..a87e1c7db2a2e 100644
--- a/src/test/ui/kindck/kindck-send-unsafe.stderr
+++ b/src/test/ui/kindck/kindck-send-unsafe.stderr
@@ -1,15 +1,13 @@
 error[E0277]: `*mut &'a isize` cannot be sent between threads safely
   --> $DIR/kindck-send-unsafe.rs:6:5
    |
+LL | fn assert_send<T:Send>() { }
+   | ------------------------ required by `assert_send`
+...
 LL |     assert_send::<*mut &'a isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `*mut &'a isize`
-note: required by `assert_send`
-  --> $DIR/kindck-send-unsafe.rs:3:1
-   |
-LL | fn assert_send<T:Send>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr b/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr
index f4a52a65af6aa..4e79fbdeadc5c 100644
--- a/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr
+++ b/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `NotDebugOrDisplay: Marker` is not satisfied
   --> $DIR/overlap-marker-trait.rs:27:5
    |
+LL | fn is_marker<T: Marker>() { }
+   | ------------------------- required by `is_marker`
+...
 LL |     is_marker::<NotDebugOrDisplay>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Marker` is not implemented for `NotDebugOrDisplay`
-   |
-note: required by `is_marker`
-  --> $DIR/overlap-marker-trait.rs:15:1
-   |
-LL | fn is_marker<T: Marker>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr
index 8662bb7795382..319eb86480af5 100644
--- a/src/test/ui/mismatched_types/E0631.stderr
+++ b/src/test/ui/mismatched_types/E0631.stderr
@@ -1,60 +1,48 @@
 error[E0631]: type mismatch in closure arguments
   --> $DIR/E0631.rs:7:5
    |
+LL | fn foo<F: Fn(usize)>(_: F) {}
+   | -------------------------- required by `foo`
+...
 LL |     foo(|_: isize| {});
    |     ^^^ ---------- found signature of `fn(isize) -> _`
    |     |
    |     expected signature of `fn(usize) -> _`
-   |
-note: required by `foo`
-  --> $DIR/E0631.rs:3:1
-   |
-LL | fn foo<F: Fn(usize)>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/E0631.rs:8:5
    |
+LL | fn bar<F: Fn<usize>>(_: F) {}
+   | -------------------------- required by `bar`
+...
 LL |     bar(|_: isize| {});
    |     ^^^ ---------- found signature of `fn(isize) -> _`
    |     |
    |     expected signature of `fn(usize) -> _`
-   |
-note: required by `bar`
-  --> $DIR/E0631.rs:4:1
-   |
-LL | fn bar<F: Fn<usize>>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/E0631.rs:9:5
    |
+LL | fn foo<F: Fn(usize)>(_: F) {}
+   | -------------------------- required by `foo`
+...
 LL |     fn f(_: u64) {}
    |     ------------ found signature of `fn(u64) -> _`
 ...
 LL |     foo(f);
    |     ^^^ expected signature of `fn(usize) -> _`
-   |
-note: required by `foo`
-  --> $DIR/E0631.rs:3:1
-   |
-LL | fn foo<F: Fn(usize)>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/E0631.rs:10:5
    |
+LL | fn bar<F: Fn<usize>>(_: F) {}
+   | -------------------------- required by `bar`
+LL | fn main() {
 LL |     fn f(_: u64) {}
    |     ------------ found signature of `fn(u64) -> _`
 ...
 LL |     bar(f);
    |     ^^^ expected signature of `fn(usize) -> _`
-   |
-note: required by `bar`
-  --> $DIR/E0631.rs:4:1
-   |
-LL | fn bar<F: Fn<usize>>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr
index 25d5d25ec1deb..b7b5b50b0b4e4 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-count.stderr
@@ -45,16 +45,13 @@ LL |     [1, 2, 3].sort_by(|tuple, tuple2| panic!());
 error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
   --> $DIR/closure-arg-count.rs:13:5
    |
+LL | fn f<F: Fn<usize>>(_: F) {}
+   | ------------------------ required by `f`
+...
 LL |     f(|| panic!());
    |     ^ -- takes 0 arguments
    |     |
    |     expected closure that takes 1 argument
-   |
-note: required by `f`
-  --> $DIR/closure-arg-count.rs:3:1
-   |
-LL | fn f<F: Fn<usize>>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider changing the closure to take and ignore the expected argument
    |
 LL |     f(|_| panic!());
@@ -63,16 +60,13 @@ LL |     f(|_| panic!());
 error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
   --> $DIR/closure-arg-count.rs:15:5
    |
+LL | fn f<F: Fn<usize>>(_: F) {}
+   | ------------------------ required by `f`
+...
 LL |     f(  move    || panic!());
    |     ^   ---------- takes 0 arguments
    |     |
    |     expected closure that takes 1 argument
-   |
-note: required by `f`
-  --> $DIR/closure-arg-count.rs:3:1
-   |
-LL | fn f<F: Fn<usize>>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider changing the closure to take and ignore the expected argument
    |
 LL |     f(  move    |_| panic!());
@@ -148,14 +142,10 @@ error[E0593]: function is expected to take 0 arguments, but it takes 1 argument
 LL |     call(Foo);
    |     ^^^^ expected function that takes 0 arguments
 ...
+LL | fn call<F, R>(_: F) where F: FnOnce() -> R {}
+   | ------------------------------------------ required by `call`
 LL | struct Foo(u8);
    | --------------- takes 1 argument
-   |
-note: required by `call`
-  --> $DIR/closure-arg-count.rs:42:1
-   |
-LL | fn call<F, R>(_: F) where F: FnOnce() -> R {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 14 previous errors
 
diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
index d4ccf8d451c12..2a65759dd17f8 100644
--- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
@@ -25,29 +25,23 @@ LL |     a.iter().map(|_: (u16, u16)| 45);
 error[E0631]: type mismatch in function arguments
   --> $DIR/closure-arg-type-mismatch.rs:10:5
    |
+LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
+   | ------------------------------ required by `baz`
+LL | fn _test<'a>(f: fn(*mut &'a u32)) {
 LL |     baz(f);
    |     ^^^
    |     |
    |     expected signature of `for<'r> fn(*mut &'r u32) -> _`
    |     found signature of `fn(*mut &'a u32) -> _`
-   |
-note: required by `baz`
-  --> $DIR/closure-arg-type-mismatch.rs:8:1
-   |
-LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::FnOnce<(*mut &'r u32,)>>::Output == ()`
   --> $DIR/closure-arg-type-mismatch.rs:10:5
    |
+LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
+   | ------------------------------ required by `baz`
+LL | fn _test<'a>(f: fn(*mut &'a u32)) {
 LL |     baz(f);
    |     ^^^ expected bound lifetime parameter, found concrete lifetime
-   |
-note: required by `baz`
-  --> $DIR/closure-arg-type-mismatch.rs:8:1
-   |
-LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr
index 7161f6979087a..0fe4909eaa778 100644
--- a/src/test/ui/mismatched_types/closure-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-mismatch.stderr
@@ -1,30 +1,26 @@
 error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.rs:8:9: 8:15] as std::ops::FnOnce<(&'r (),)>>::Output == ()`
   --> $DIR/closure-mismatch.rs:8:5
    |
+LL | fn baz<T: Foo>(_: T) {}
+   | -------------------- required by `baz`
+...
 LL |     baz(|_| ());
    |     ^^^ expected bound lifetime parameter, found concrete lifetime
    |
    = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:8:9: 8:15]`
-note: required by `baz`
-  --> $DIR/closure-mismatch.rs:5:1
-   |
-LL | fn baz<T: Foo>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/closure-mismatch.rs:8:5
    |
+LL | fn baz<T: Foo>(_: T) {}
+   | -------------------- required by `baz`
+...
 LL |     baz(|_| ());
    |     ^^^ ------ found signature of `fn(_) -> _`
    |     |
    |     expected signature of `for<'r> fn(&'r ()) -> _`
    |
    = note: required because of the requirements on the impl of `Foo` for `[closure@$DIR/closure-mismatch.rs:8:9: 8:15]`
-note: required by `baz`
-  --> $DIR/closure-mismatch.rs:5:1
-   |
-LL | fn baz<T: Foo>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/mismatched_types/fn-variance-1.stderr b/src/test/ui/mismatched_types/fn-variance-1.stderr
index c15d6620e18da..d4db7bda06e7e 100644
--- a/src/test/ui/mismatched_types/fn-variance-1.stderr
+++ b/src/test/ui/mismatched_types/fn-variance-1.stderr
@@ -3,15 +3,12 @@ error[E0631]: type mismatch in function arguments
    |
 LL | fn takes_mut(x: &mut isize) { }
    | --------------------------- found signature of `for<'r> fn(&'r mut isize) -> _`
+LL | 
+LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
+   | --------------------------------------------- required by `apply`
 ...
 LL |     apply(&3, takes_mut);
    |     ^^^^^ expected signature of `fn(&{integer}) -> _`
-   |
-note: required by `apply`
-  --> $DIR/fn-variance-1.rs:5:1
-   |
-LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0631]: type mismatch in function arguments
   --> $DIR/fn-variance-1.rs:15:5
@@ -19,14 +16,11 @@ error[E0631]: type mismatch in function arguments
 LL | fn takes_imm(x: &isize) { }
    | ----------------------- found signature of `for<'r> fn(&'r isize) -> _`
 ...
+LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
+   | --------------------------------------------- required by `apply`
+...
 LL |     apply(&mut 3, takes_imm);
    |     ^^^^^ expected signature of `fn(&mut {integer}) -> _`
-   |
-note: required by `apply`
-  --> $DIR/fn-variance-1.rs:5:1
-   |
-LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
index 47aa3c21f5301..53c9fcd70a23d 100644
--- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
+++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
@@ -1,17 +1,14 @@
 error[E0631]: type mismatch in closure arguments
   --> $DIR/unboxed-closures-vtable-mismatch.rs:15:13
    |
+LL | fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize {
+   | -------------------------------------------------------------------- required by `call_it`
+...
 LL |     let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
    |                       ----------------------------- found signature of `fn(usize, isize) -> _`
 LL |
 LL |     let z = call_it(3, f);
    |             ^^^^^^^ expected signature of `fn(isize, isize) -> _`
-   |
-note: required by `call_it`
-  --> $DIR/unboxed-closures-vtable-mismatch.rs:7:1
-   |
-LL | fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mut/mutable-enum-indirect.stderr b/src/test/ui/mut/mutable-enum-indirect.stderr
index 1268e487f333d..4efb10b56290e 100644
--- a/src/test/ui/mut/mutable-enum-indirect.stderr
+++ b/src/test/ui/mut/mutable-enum-indirect.stderr
@@ -1,17 +1,15 @@
 error[E0277]: `NoSync` cannot be shared between threads safely
   --> $DIR/mutable-enum-indirect.rs:17:5
    |
+LL | fn bar<T: Sync>(_: T) {}
+   | --------------------- required by `bar`
+...
 LL |     bar(&x);
    |     ^^^ `NoSync` cannot be shared between threads safely
    |
    = help: within `&Foo`, the trait `std::marker::Sync` is not implemented for `NoSync`
    = note: required because it appears within the type `Foo`
    = note: required because it appears within the type `&Foo`
-note: required by `bar`
-  --> $DIR/mutable-enum-indirect.rs:13:1
-   |
-LL | fn bar<T: Sync>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mutexguard-sync.stderr b/src/test/ui/mutexguard-sync.stderr
index d1f7d13937578..4a93c9f09b788 100644
--- a/src/test/ui/mutexguard-sync.stderr
+++ b/src/test/ui/mutexguard-sync.stderr
@@ -1,16 +1,14 @@
 error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
   --> $DIR/mutexguard-sync.rs:11:5
    |
+LL | fn test_sync<T: Sync>(_t: T) {}
+   | ---------------------------- required by `test_sync`
+...
 LL |     test_sync(guard);
    |     ^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
    = note: required because of the requirements on the impl of `std::marker::Sync` for `std::sync::MutexGuard<'_, std::cell::Cell<i32>>`
-note: required by `test_sync`
-  --> $DIR/mutexguard-sync.rs:5:1
-   |
-LL | fn test_sync<T: Sync>(_t: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr
index ef2d0d87f09d5..39aaddb390caa 100644
--- a/src/test/ui/namespace/namespace-mix.stderr
+++ b/src/test/ui/namespace/namespace-mix.stderr
@@ -69,530 +69,398 @@ LL | use namespace_mix::xm8::V;
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:33:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m1::S{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::S: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:35:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m2::S{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::S`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:36:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m2::S);
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:39:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm1::S{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::S: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:41:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm2::S{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::S`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:42:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm2::S);
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:55:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m3::TS{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `fn() -> c::TS {c::TS}: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:56:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m3::TS);
    |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> c::TS {c::TS}`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::TS: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:57:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m4::TS{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::TS`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:58:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m4::TS);
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:61:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm3::TS{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:62:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm3::TS);
    |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::TS: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:63:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm4::TS{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::TS`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:64:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm4::TS);
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:77:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m5::US{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::US: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:78:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m5::US);
    |     ^^^^^ the trait `Impossible` is not implemented for `c::US`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::US: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:79:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m6::US{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::US`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:80:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m6::US);
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:83:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm5::US{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::US: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:84:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm5::US);
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::US: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:85:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm6::US{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:86:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm6::US);
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:99:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m7::V{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:101:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m8::V{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::E`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:102:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m8::V);
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:105:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm7::V{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:107:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm8::V{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:108:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm8::V);
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:121:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m9::TV{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `fn() -> c::E {c::E::TV}: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:122:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(m9::TV);
    |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> c::E {c::E::TV}`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:123:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(mA::TV{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::E`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:124:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(mA::TV);
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:127:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm9::TV{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:128:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xm9::TV);
    |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:129:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xmA::TV{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:130:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xmA::TV);
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:143:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(mB::UV{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:144:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(mB::UV);
    |     ^^^^^ the trait `Impossible` is not implemented for `c::E`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:145:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(mC::UV{});
    |     ^^^^^ the trait `Impossible` is not implemented for `c::E`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:146:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(mC::UV);
    |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:149:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xmB::UV{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:150:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xmB::UV);
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:151:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xmC::UV{});
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:152:5
    |
+LL | fn check<T: Impossible>(_: T) {}
+   | ----------------------------- required by `check`
+...
 LL |     check(xmC::UV);
    |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
-   |
-note: required by `check`
-  --> $DIR/namespace-mix.rs:21:1
-   |
-LL | fn check<T: Impossible>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 48 previous errors
 
diff --git a/src/test/ui/no_send-enum.stderr b/src/test/ui/no_send-enum.stderr
index 71e3aee919431..d1f3398ff9027 100644
--- a/src/test/ui/no_send-enum.stderr
+++ b/src/test/ui/no_send-enum.stderr
@@ -1,16 +1,14 @@
 error[E0277]: `NoSend` cannot be sent between threads safely
   --> $DIR/no_send-enum.rs:16:5
    |
+LL | fn bar<T: Send>(_: T) {}
+   | --------------------- required by `bar`
+...
 LL |     bar(x);
    |     ^^^ `NoSend` cannot be sent between threads safely
    |
    = help: within `Foo`, the trait `std::marker::Send` is not implemented for `NoSend`
    = note: required because it appears within the type `Foo`
-note: required by `bar`
-  --> $DIR/no_send-enum.rs:12:1
-   |
-LL | fn bar<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/no_send-rc.stderr b/src/test/ui/no_send-rc.stderr
index 2028cf77374f1..eaf3103060eff 100644
--- a/src/test/ui/no_send-rc.stderr
+++ b/src/test/ui/no_send-rc.stderr
@@ -1,15 +1,13 @@
 error[E0277]: `std::rc::Rc<{integer}>` cannot be sent between threads safely
   --> $DIR/no_send-rc.rs:7:5
    |
+LL | fn bar<T: Send>(_: T) {}
+   | --------------------- required by `bar`
+...
 LL |     bar(x);
    |     ^^^ `std::rc::Rc<{integer}>` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `std::rc::Rc<{integer}>`
-note: required by `bar`
-  --> $DIR/no_send-rc.rs:3:1
-   |
-LL | fn bar<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/no_send-struct.stderr b/src/test/ui/no_send-struct.stderr
index ca4ae054fd0f9..1808cef45f184 100644
--- a/src/test/ui/no_send-struct.stderr
+++ b/src/test/ui/no_send-struct.stderr
@@ -1,15 +1,13 @@
 error[E0277]: `Foo` cannot be sent between threads safely
   --> $DIR/no_send-struct.rs:15:5
    |
+LL | fn bar<T: Send>(_: T) {}
+   | --------------------- required by `bar`
+...
 LL |     bar(x);
    |     ^^^ `Foo` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `Foo`
-note: required by `bar`
-  --> $DIR/no_send-struct.rs:11:1
-   |
-LL | fn bar<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/no_share-enum.stderr b/src/test/ui/no_share-enum.stderr
index 64d791d02623e..5a9b7cae0b9f6 100644
--- a/src/test/ui/no_share-enum.stderr
+++ b/src/test/ui/no_share-enum.stderr
@@ -1,16 +1,14 @@
 error[E0277]: `NoSync` cannot be shared between threads safely
   --> $DIR/no_share-enum.rs:14:5
    |
+LL | fn bar<T: Sync>(_: T) {}
+   | --------------------- required by `bar`
+...
 LL |     bar(x);
    |     ^^^ `NoSync` cannot be shared between threads safely
    |
    = help: within `Foo`, the trait `std::marker::Sync` is not implemented for `NoSync`
    = note: required because it appears within the type `Foo`
-note: required by `bar`
-  --> $DIR/no_share-enum.rs:10:1
-   |
-LL | fn bar<T: Sync>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/no_share-struct.stderr b/src/test/ui/no_share-struct.stderr
index fc4bcfb5b3e7e..c12ee7c5eae85 100644
--- a/src/test/ui/no_share-struct.stderr
+++ b/src/test/ui/no_share-struct.stderr
@@ -1,15 +1,13 @@
 error[E0277]: `Foo` cannot be shared between threads safely
   --> $DIR/no_share-struct.rs:12:5
    |
+LL | fn bar<T: Sync>(_: T) {}
+   | --------------------- required by `bar`
+...
 LL |     bar(x);
    |     ^^^ `Foo` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `Foo`
-note: required by `bar`
-  --> $DIR/no_share-struct.rs:8:1
-   |
-LL | fn bar<T: Sync>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/not-panic/not-panic-safe-2.stderr b/src/test/ui/not-panic/not-panic-safe-2.stderr
index 4db127a463932..5bacf0bbc6b45 100644
--- a/src/test/ui/not-panic/not-panic-safe-2.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-2.stderr
@@ -1,21 +1,22 @@
 error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/not-panic-safe-2.rs:10:5
    |
+LL | fn assert<T: UnwindSafe + ?Sized>() {}
+   | ----------------------------------- required by `assert`
+...
 LL |     assert::<Rc<RefCell<i32>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    |
    = help: within `std::cell::RefCell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
    = note: required because it appears within the type `std::cell::RefCell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `std::rc::Rc<std::cell::RefCell<i32>>`
-note: required by `assert`
-  --> $DIR/not-panic-safe-2.rs:7:1
-   |
-LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the type `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/not-panic-safe-2.rs:10:5
    |
+LL | fn assert<T: UnwindSafe + ?Sized>() {}
+   | ----------------------------------- required by `assert`
+...
 LL |     assert::<Rc<RefCell<i32>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    |
@@ -23,11 +24,6 @@ LL |     assert::<Rc<RefCell<i32>>>();
    = note: required because it appears within the type `std::cell::Cell<isize>`
    = note: required because it appears within the type `std::cell::RefCell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `std::rc::Rc<std::cell::RefCell<i32>>`
-note: required by `assert`
-  --> $DIR/not-panic-safe-2.rs:7:1
-   |
-LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/not-panic/not-panic-safe-3.stderr b/src/test/ui/not-panic/not-panic-safe-3.stderr
index 1f87f20f2e284..6d2a450115dff 100644
--- a/src/test/ui/not-panic/not-panic-safe-3.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-3.stderr
@@ -1,21 +1,22 @@
 error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/not-panic-safe-3.rs:10:5
    |
+LL | fn assert<T: UnwindSafe + ?Sized>() {}
+   | ----------------------------------- required by `assert`
+...
 LL |     assert::<Arc<RefCell<i32>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    |
    = help: within `std::cell::RefCell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
    = note: required because it appears within the type `std::cell::RefCell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `std::sync::Arc<std::cell::RefCell<i32>>`
-note: required by `assert`
-  --> $DIR/not-panic-safe-3.rs:7:1
-   |
-LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the type `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/not-panic-safe-3.rs:10:5
    |
+LL | fn assert<T: UnwindSafe + ?Sized>() {}
+   | ----------------------------------- required by `assert`
+...
 LL |     assert::<Arc<RefCell<i32>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    |
@@ -23,11 +24,6 @@ LL |     assert::<Arc<RefCell<i32>>>();
    = note: required because it appears within the type `std::cell::Cell<isize>`
    = note: required because it appears within the type `std::cell::RefCell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `std::sync::Arc<std::cell::RefCell<i32>>`
-note: required by `assert`
-  --> $DIR/not-panic-safe-3.rs:7:1
-   |
-LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/not-panic/not-panic-safe-4.stderr b/src/test/ui/not-panic/not-panic-safe-4.stderr
index 24f649002960c..e28f169b72b6c 100644
--- a/src/test/ui/not-panic/not-panic-safe-4.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-4.stderr
@@ -1,21 +1,22 @@
 error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/not-panic-safe-4.rs:9:5
    |
+LL | fn assert<T: UnwindSafe + ?Sized>() {}
+   | ----------------------------------- required by `assert`
+...
 LL |     assert::<&RefCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    |
    = help: within `std::cell::RefCell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
    = note: required because it appears within the type `std::cell::RefCell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&std::cell::RefCell<i32>`
-note: required by `assert`
-  --> $DIR/not-panic-safe-4.rs:6:1
-   |
-LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the type `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/not-panic-safe-4.rs:9:5
    |
+LL | fn assert<T: UnwindSafe + ?Sized>() {}
+   | ----------------------------------- required by `assert`
+...
 LL |     assert::<&RefCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    |
@@ -23,11 +24,6 @@ LL |     assert::<&RefCell<i32>>();
    = note: required because it appears within the type `std::cell::Cell<isize>`
    = note: required because it appears within the type `std::cell::RefCell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&std::cell::RefCell<i32>`
-note: required by `assert`
-  --> $DIR/not-panic-safe-4.rs:6:1
-   |
-LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/not-panic/not-panic-safe-5.stderr b/src/test/ui/not-panic/not-panic-safe-5.stderr
index a603acb2f1fed..f8c4fe68dde7b 100644
--- a/src/test/ui/not-panic/not-panic-safe-5.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-5.stderr
@@ -1,16 +1,14 @@
 error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/not-panic-safe-5.rs:9:5
    |
+LL | fn assert<T: UnwindSafe + ?Sized>() {}
+   | ----------------------------------- required by `assert`
+...
 LL |     assert::<*const UnsafeCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    |
    = help: the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `*const std::cell::UnsafeCell<i32>`
-note: required by `assert`
-  --> $DIR/not-panic-safe-5.rs:6:1
-   |
-LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/not-panic/not-panic-safe-6.stderr b/src/test/ui/not-panic/not-panic-safe-6.stderr
index a4c75ec7c6188..2cd780590729c 100644
--- a/src/test/ui/not-panic/not-panic-safe-6.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-6.stderr
@@ -1,21 +1,22 @@
 error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/not-panic-safe-6.rs:9:5
    |
+LL | fn assert<T: UnwindSafe + ?Sized>() {}
+   | ----------------------------------- required by `assert`
+...
 LL |     assert::<*mut RefCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    |
    = help: within `std::cell::RefCell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
    = note: required because it appears within the type `std::cell::RefCell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `*mut std::cell::RefCell<i32>`
-note: required by `assert`
-  --> $DIR/not-panic-safe-6.rs:6:1
-   |
-LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the type `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/not-panic-safe-6.rs:9:5
    |
+LL | fn assert<T: UnwindSafe + ?Sized>() {}
+   | ----------------------------------- required by `assert`
+...
 LL |     assert::<*mut RefCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
    |
@@ -23,11 +24,6 @@ LL |     assert::<*mut RefCell<i32>>();
    = note: required because it appears within the type `std::cell::Cell<isize>`
    = note: required because it appears within the type `std::cell::RefCell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `*mut std::cell::RefCell<i32>`
-note: required by `assert`
-  --> $DIR/not-panic-safe-6.rs:6:1
-   |
-LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/not-panic/not-panic-safe.stderr b/src/test/ui/not-panic/not-panic-safe.stderr
index 2d12e697d5a7a..315ea17971aa9 100644
--- a/src/test/ui/not-panic/not-panic-safe.stderr
+++ b/src/test/ui/not-panic/not-panic-safe.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the type `&mut i32` may not be safely transferred across an unwind boundary
   --> $DIR/not-panic-safe.rs:9:5
    |
+LL | fn assert<T: UnwindSafe + ?Sized>() {}
+   | ----------------------------------- required by `assert`
+...
 LL |     assert::<&mut i32>();
    |     ^^^^^^^^^^^^^^^^^^ `&mut i32` may not be safely transferred across an unwind boundary
    |
    = help: the trait `std::panic::UnwindSafe` is not implemented for `&mut i32`
-note: required by `assert`
-  --> $DIR/not-panic-safe.rs:6:1
-   |
-LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/not-sync.stderr b/src/test/ui/not-sync.stderr
index d102528bc6e92..57f1122be2b35 100644
--- a/src/test/ui/not-sync.stderr
+++ b/src/test/ui/not-sync.stderr
@@ -1,80 +1,68 @@
 error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
   --> $DIR/not-sync.rs:8:5
    |
+LL | fn test<T: Sync>() {}
+   | ------------------ required by `test`
+...
 LL |     test::<Cell<i32>>();
    |     ^^^^^^^^^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
-note: required by `test`
-  --> $DIR/not-sync.rs:5:1
-   |
-LL | fn test<T: Sync>() {}
-   | ^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely
   --> $DIR/not-sync.rs:10:5
    |
+LL | fn test<T: Sync>() {}
+   | ------------------ required by `test`
+...
 LL |     test::<RefCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
-note: required by `test`
-  --> $DIR/not-sync.rs:5:1
-   |
-LL | fn test<T: Sync>() {}
-   | ^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::rc::Rc<i32>` cannot be shared between threads safely
   --> $DIR/not-sync.rs:13:5
    |
+LL | fn test<T: Sync>() {}
+   | ------------------ required by `test`
+...
 LL |     test::<Rc<i32>>();
    |     ^^^^^^^^^^^^^^^ `std::rc::Rc<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::rc::Rc<i32>`
-note: required by `test`
-  --> $DIR/not-sync.rs:5:1
-   |
-LL | fn test<T: Sync>() {}
-   | ^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::rc::Weak<i32>` cannot be shared between threads safely
   --> $DIR/not-sync.rs:15:5
    |
+LL | fn test<T: Sync>() {}
+   | ------------------ required by `test`
+...
 LL |     test::<Weak<i32>>();
    |     ^^^^^^^^^^^^^^^^^ `std::rc::Weak<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::rc::Weak<i32>`
-note: required by `test`
-  --> $DIR/not-sync.rs:5:1
-   |
-LL | fn test<T: Sync>() {}
-   | ^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
   --> $DIR/not-sync.rs:18:5
    |
+LL | fn test<T: Sync>() {}
+   | ------------------ required by `test`
+...
 LL |     test::<Receiver<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<i32>`
-note: required by `test`
-  --> $DIR/not-sync.rs:5:1
-   |
-LL | fn test<T: Sync>() {}
-   | ^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::sync::mpsc::Sender<i32>` cannot be shared between threads safely
   --> $DIR/not-sync.rs:20:5
    |
+LL | fn test<T: Sync>() {}
+   | ------------------ required by `test`
+...
 LL |     test::<Sender<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^ `std::sync::mpsc::Sender<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<i32>`
-note: required by `test`
-  --> $DIR/not-sync.rs:5:1
-   |
-LL | fn test<T: Sync>() {}
-   | ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/object-does-not-impl-trait.stderr b/src/test/ui/object-does-not-impl-trait.stderr
index 288ce9682c209..d3add6398bd98 100644
--- a/src/test/ui/object-does-not-impl-trait.stderr
+++ b/src/test/ui/object-does-not-impl-trait.stderr
@@ -1,14 +1,10 @@
 error[E0277]: the trait bound `std::boxed::Box<dyn Foo>: Foo` is not satisfied
   --> $DIR/object-does-not-impl-trait.rs:6:35
    |
+LL | fn take_foo<F:Foo>(f: F) {}
+   | ------------------------ required by `take_foo`
 LL | fn take_object(f: Box<dyn Foo>) { take_foo(f); }
    |                                   ^^^^^^^^ the trait `Foo` is not implemented for `std::boxed::Box<dyn Foo>`
-   |
-note: required by `take_foo`
-  --> $DIR/object-does-not-impl-trait.rs:5:1
-   |
-LL | fn take_foo<F:Foo>(f: F) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr
index 5d5db21f7263c..b286265bf01c0 100644
--- a/src/test/ui/on-unimplemented/multiple-impls.stderr
+++ b/src/test/ui/on-unimplemented/multiple-impls.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/multiple-impls.rs:33:5
    |
+LL |     fn index(&self, index: Idx) -> &Self::Output;
+   |     --------------------------------------------- required by `Index::index`
+...
 LL |     Index::index(&[] as &[i32], 2u32);
    |     ^^^^^^^^^^^^ trait message
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
-note: required by `Index::index`
-  --> $DIR/multiple-impls.rs:12:5
-   |
-LL |     fn index(&self, index: Idx) -> &Self::Output;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/multiple-impls.rs:33:5
@@ -22,15 +20,13 @@ LL |     Index::index(&[] as &[i32], 2u32);
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:36:5
    |
+LL |     fn index(&self, index: Idx) -> &Self::Output;
+   |     --------------------------------------------- required by `Index::index`
+...
 LL |     Index::index(&[] as &[i32], Foo(2u32));
    |     ^^^^^^^^^^^^ on impl for Foo
    |
    = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
-note: required by `Index::index`
-  --> $DIR/multiple-impls.rs:12:5
-   |
-LL |     fn index(&self, index: Idx) -> &Self::Output;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:36:5
@@ -43,15 +39,13 @@ LL |     Index::index(&[] as &[i32], Foo(2u32));
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:39:5
    |
+LL |     fn index(&self, index: Idx) -> &Self::Output;
+   |     --------------------------------------------- required by `Index::index`
+...
 LL |     Index::index(&[] as &[i32], Bar(2u32));
    |     ^^^^^^^^^^^^ on impl for Bar
    |
    = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
-note: required by `Index::index`
-  --> $DIR/multiple-impls.rs:12:5
-   |
-LL |     fn index(&self, index: Idx) -> &Self::Output;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:39:5
diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr
index 79cf22f609c79..78dc9a53761c5 100644
--- a/src/test/ui/on-unimplemented/on-impl.stderr
+++ b/src/test/ui/on-unimplemented/on-impl.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:22:5
    |
+LL |     fn index(&self, index: Idx) -> &Self::Output;
+   |     --------------------------------------------- required by `Index::index`
+...
 LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
    |     ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
-note: required by `Index::index`
-  --> $DIR/on-impl.rs:9:5
-   |
-LL |     fn index(&self, index: Idx) -> &Self::Output;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:22:5
diff --git a/src/test/ui/on-unimplemented/on-trait.stderr b/src/test/ui/on-unimplemented/on-trait.stderr
index ece8dee0afe97..992f53b1da6b6 100644
--- a/src/test/ui/on-unimplemented/on-trait.stderr
+++ b/src/test/ui/on-unimplemented/on-trait.stderr
@@ -1,28 +1,24 @@
 error[E0277]: the trait bound `std::option::Option<std::vec::Vec<u8>>: MyFromIterator<&u8>` is not satisfied
   --> $DIR/on-trait.rs:28:30
    |
+LL | fn collect<A, I: Iterator<Item=A>, B: MyFromIterator<A>>(it: I) -> B {
+   | -------------------------------------------------------------------- required by `collect`
+...
 LL |     let y: Option<Vec<u8>> = collect(x.iter()); // this should give approximately the same error for x.iter().collect()
    |                              ^^^^^^^ a collection of type `std::option::Option<std::vec::Vec<u8>>` cannot be built from an iterator over elements of type `&u8`
    |
    = help: the trait `MyFromIterator<&u8>` is not implemented for `std::option::Option<std::vec::Vec<u8>>`
-note: required by `collect`
-  --> $DIR/on-trait.rs:22:1
-   |
-LL | fn collect<A, I: Iterator<Item=A>, B: MyFromIterator<A>>(it: I) -> B {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::string::String: Bar::Foo<u8, _, u32>` is not satisfied
   --> $DIR/on-trait.rs:31:21
    |
+LL | fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T {
+   | ---------------------------------------------- required by `foobar`
+...
 LL |     let x: String = foobar();
    |                     ^^^^^^ test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo`
    |
    = help: the trait `Bar::Foo<u8, _, u32>` is not implemented for `std::string::String`
-note: required by `foobar`
-  --> $DIR/on-trait.rs:12:1
-   |
-LL | fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/overlap-marker-trait.stderr b/src/test/ui/overlap-marker-trait.stderr
index a59af8dcdbcf7..a66e3990e8bd9 100644
--- a/src/test/ui/overlap-marker-trait.stderr
+++ b/src/test/ui/overlap-marker-trait.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `NotDebugOrDisplay: Marker` is not satisfied
   --> $DIR/overlap-marker-trait.rs:30:5
    |
+LL | fn is_marker<T: Marker>() { }
+   | ------------------------- required by `is_marker`
+...
 LL |     is_marker::<NotDebugOrDisplay>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Marker` is not implemented for `NotDebugOrDisplay`
-   |
-note: required by `is_marker`
-  --> $DIR/overlap-marker-trait.rs:18:1
-   |
-LL | fn is_marker<T: Marker>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/phantom-oibit.stderr b/src/test/ui/phantom-oibit.stderr
index ec8b3181bc553..284102a6df028 100644
--- a/src/test/ui/phantom-oibit.stderr
+++ b/src/test/ui/phantom-oibit.stderr
@@ -1,6 +1,9 @@
 error[E0277]: `T` cannot be shared between threads safely
   --> $DIR/phantom-oibit.rs:21:5
    |
+LL | fn is_zen<T: Zen>(_: T) {}
+   | ----------------------- required by `is_zen`
+...
 LL |     is_zen(x)
    |     ^^^^^^ `T` cannot be shared between threads safely
    |
@@ -9,15 +12,13 @@ LL |     is_zen(x)
    = note: required because of the requirements on the impl of `Zen` for `&T`
    = note: required because it appears within the type `std::marker::PhantomData<&T>`
    = note: required because it appears within the type `Guard<'_, T>`
-note: required by `is_zen`
-  --> $DIR/phantom-oibit.rs:18:1
-   |
-LL | fn is_zen<T: Zen>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `T` cannot be shared between threads safely
   --> $DIR/phantom-oibit.rs:26:5
    |
+LL | fn is_zen<T: Zen>(_: T) {}
+   | ----------------------- required by `is_zen`
+...
 LL |     is_zen(x)
    |     ^^^^^^ `T` cannot be shared between threads safely
    |
@@ -27,11 +28,6 @@ LL |     is_zen(x)
    = note: required because it appears within the type `std::marker::PhantomData<&T>`
    = note: required because it appears within the type `Guard<'_, T>`
    = note: required because it appears within the type `Nested<Guard<'_, T>>`
-note: required by `is_zen`
-  --> $DIR/phantom-oibit.rs:18:1
-   |
-LL | fn is_zen<T: Zen>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/recursion/recursive-requirements.stderr b/src/test/ui/recursion/recursive-requirements.stderr
index b3041902acac3..9846c938ba90b 100644
--- a/src/test/ui/recursion/recursive-requirements.stderr
+++ b/src/test/ui/recursion/recursive-requirements.stderr
@@ -1,20 +1,21 @@
 error[E0277]: `*const Bar` cannot be shared between threads safely
   --> $DIR/recursive-requirements.rs:16:12
    |
+LL | struct AssertSync<T: Sync>(PhantomData<T>);
+   | ------------------------------------------- required by `AssertSync`
+...
 LL |     let _: AssertSync<Foo> = unimplemented!();
    |            ^^^^^^^^^^^^^^^ `*const Bar` cannot be shared between threads safely
    |
    = help: within `Foo`, the trait `std::marker::Sync` is not implemented for `*const Bar`
    = note: required because it appears within the type `Foo`
-note: required by `AssertSync`
-  --> $DIR/recursive-requirements.rs:3:1
-   |
-LL | struct AssertSync<T: Sync>(PhantomData<T>);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `*const Foo` cannot be shared between threads safely
   --> $DIR/recursive-requirements.rs:16:12
    |
+LL | struct AssertSync<T: Sync>(PhantomData<T>);
+   | ------------------------------------------- required by `AssertSync`
+...
 LL |     let _: AssertSync<Foo> = unimplemented!();
    |            ^^^^^^^^^^^^^^^ `*const Foo` cannot be shared between threads safely
    |
@@ -22,11 +23,6 @@ LL |     let _: AssertSync<Foo> = unimplemented!();
    = note: required because it appears within the type `Bar`
    = note: required because it appears within the type `std::marker::PhantomData<Bar>`
    = note: required because it appears within the type `Foo`
-note: required by `AssertSync`
-  --> $DIR/recursive-requirements.rs:3:1
-   |
-LL | struct AssertSync<T: Sync>(PhantomData<T>);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/span/issue-29595.stderr b/src/test/ui/span/issue-29595.stderr
index 24dfdf8ebc299..1d3e33e4b0503 100644
--- a/src/test/ui/span/issue-29595.stderr
+++ b/src/test/ui/span/issue-29595.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `u8: Tr` is not satisfied
   --> $DIR/issue-29595.rs:6:17
    |
+LL |     const C: Self;
+   |     -------------- required by `Tr::C`
+...
 LL |     let a: u8 = Tr::C;
    |                 ^^^^^ the trait `Tr` is not implemented for `u8`
-   |
-note: required by `Tr::C`
-  --> $DIR/issue-29595.rs:2:5
-   |
-LL |     const C: Self;
-   |     ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr
index beb2272452363..08baa478b8bfa 100644
--- a/src/test/ui/str/str-mut-idx.stderr
+++ b/src/test/ui/str/str-mut-idx.stderr
@@ -1,16 +1,14 @@
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/str-mut-idx.rs:4:15
    |
+LL | fn bot<T>() -> T { loop {} }
+   | ---------------- required by `bot`
+...
 LL |     s[1..2] = bot();
    |               ^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
-note: required by `bot`
-  --> $DIR/str-mut-idx.rs:1:1
-   |
-LL | fn bot<T>() -> T { loop {} }
-   | ^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/str-mut-idx.rs:4:5
diff --git a/src/test/ui/structs/struct-path-alias-bounds.stderr b/src/test/ui/structs/struct-path-alias-bounds.stderr
index 70eb2610ea5d2..1c2c205e01c1b 100644
--- a/src/test/ui/structs/struct-path-alias-bounds.stderr
+++ b/src/test/ui/structs/struct-path-alias-bounds.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `NoClone: std::clone::Clone` is not satisfied
   --> $DIR/struct-path-alias-bounds.rs:9:13
    |
+LL | struct S<T: Clone> { a: T }
+   | ------------------ required by `S`
+...
 LL |     let s = A { a: NoClone };
    |             ^ the trait `std::clone::Clone` is not implemented for `NoClone`
-   |
-note: required by `S`
-  --> $DIR/struct-path-alias-bounds.rs:3:1
-   |
-LL | struct S<T: Clone> { a: T }
-   | ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/substs-ppaux.normal.stderr b/src/test/ui/substs-ppaux.normal.stderr
index b3b879ef9acbe..4a8c99cdef3f5 100644
--- a/src/test/ui/substs-ppaux.normal.stderr
+++ b/src/test/ui/substs-ppaux.normal.stderr
@@ -61,17 +61,15 @@ LL |     let x: () = foo::<'static>;
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/substs-ppaux.rs:49:5
    |
+LL |     fn bar<'a, T>() where T: 'a {}
+   |     --------------------------- required by `Foo::bar`
+...
 LL |     <str as Foo<u8>>::bar;
    |     ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required because of the requirements on the impl of `Foo<'_, '_, u8>` for `str`
-note: required by `Foo::bar`
-  --> $DIR/substs-ppaux.rs:7:5
-   |
-LL |     fn bar<'a, T>() where T: 'a {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/substs-ppaux.verbose.stderr b/src/test/ui/substs-ppaux.verbose.stderr
index 363018db232d8..3314eb60cdea6 100644
--- a/src/test/ui/substs-ppaux.verbose.stderr
+++ b/src/test/ui/substs-ppaux.verbose.stderr
@@ -61,17 +61,15 @@ LL |     let x: () = foo::<'static>;
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/substs-ppaux.rs:49:5
    |
+LL |     fn bar<'a, T>() where T: 'a {}
+   |     --------------------------- required by `Foo::bar`
+...
 LL |     <str as Foo<u8>>::bar;
    |     ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `str`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = note: required because of the requirements on the impl of `Foo<'_#0r, '_#1r, u8>` for `str`
-note: required by `Foo::bar`
-  --> $DIR/substs-ppaux.rs:7:5
-   |
-LL |     fn bar<'a, T>() where T: 'a {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/suggestions/into-str.stderr b/src/test/ui/suggestions/into-str.stderr
index 3e28700ce9552..da5aeb63b909a 100644
--- a/src/test/ui/suggestions/into-str.stderr
+++ b/src/test/ui/suggestions/into-str.stderr
@@ -1,16 +1,14 @@
 error[E0277]: the trait bound `&str: std::convert::From<std::string::String>` is not satisfied
   --> $DIR/into-str.rs:4:5
    |
+LL | fn foo<'a, T>(_t: T) where T: Into<&'a str> {}
+   | ------------------------------------------- required by `foo`
+...
 LL |     foo(String::new());
    |     ^^^ the trait `std::convert::From<std::string::String>` is not implemented for `&str`
    |
    = note: to coerce a `std::string::String` into a `&str`, use `&*` as a prefix
    = note: required because of the requirements on the impl of `std::convert::Into<&str>` for `std::string::String`
-note: required by `foo`
-  --> $DIR/into-str.rs:1:1
-   |
-LL | fn foo<'a, T>(_t: T) where T: Into<&'a str> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr b/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr
index 972d213ac8f8f..8403b2ebaca10 100644
--- a/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr
+++ b/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr
@@ -1,28 +1,24 @@
 error[E0277]: `std::rc::Rc<u32>` cannot be sent between threads safely
   --> $DIR/trait-alias-cross-crate.rs:14:5
    |
+LL | fn use_alias<T: SendSync>() {}
+   | --------------------------- required by `use_alias`
+...
 LL |     use_alias::<Rc<u32>>();
    |     ^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc<u32>` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `std::rc::Rc<u32>`
-note: required by `use_alias`
-  --> $DIR/trait-alias-cross-crate.rs:10:1
-   |
-LL | fn use_alias<T: SendSync>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::rc::Rc<u32>` cannot be shared between threads safely
   --> $DIR/trait-alias-cross-crate.rs:14:5
    |
+LL | fn use_alias<T: SendSync>() {}
+   | --------------------------- required by `use_alias`
+...
 LL |     use_alias::<Rc<u32>>();
    |     ^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc<u32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::rc::Rc<u32>`
-note: required by `use_alias`
-  --> $DIR/trait-alias-cross-crate.rs:10:1
-   |
-LL | fn use_alias<T: SendSync>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/trait-alias/trait-alias-wf.stderr b/src/test/ui/traits/trait-alias/trait-alias-wf.stderr
index ee2dd5b24afed..ca6d058471667 100644
--- a/src/test/ui/traits/trait-alias/trait-alias-wf.stderr
+++ b/src/test/ui/traits/trait-alias/trait-alias-wf.stderr
@@ -1,15 +1,12 @@
 error[E0277]: the trait bound `T: Foo` is not satisfied
   --> $DIR/trait-alias-wf.rs:5:1
    |
+LL | trait A<T: Foo> {}
+   | --------------- required by `A`
 LL | trait B<T> = A<T>;
    | ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `T`
    |
    = help: consider adding a `where T: Foo` bound
-note: required by `A`
-  --> $DIR/trait-alias-wf.rs:4:1
-   |
-LL | trait A<T: Foo> {}
-   | ^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr b/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr
index 6fdd2ceaaac9c..3c68d461f80d6 100644
--- a/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr
+++ b/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-fns.stderr
@@ -1,26 +1,20 @@
 error[E0277]: the trait bound `u32: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:13:1
    |
+LL | struct Foo<T:Trait> {
+   | ------------------- required by `Foo`
+...
 LL | fn explode(x: Foo<u32>) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `u32`
-   |
-note: required by `Foo`
-  --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:3:1
-   |
-LL | struct Foo<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `f32: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:16:1
    |
+LL | enum Bar<T:Trait> {
+   | ----------------- required by `Bar`
+...
 LL | fn kaboom(y: Bar<f32>) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `f32`
-   |
-note: required by `Bar`
-  --> $DIR/trait-bounds-on-structs-and-enums-in-fns.rs:7:1
-   |
-LL | enum Bar<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-impls.stderr b/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-impls.stderr
index 15441b583cef2..7e8db610fe233 100644
--- a/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-impls.stderr
+++ b/src/test/ui/traits/trait-bounds-on-structs-and-enums-in-impls.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `u16: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums-in-impls.rs:20:6
    |
+LL | struct Foo<T:Trait> {
+   | ------------------- required by `Foo`
+...
 LL | impl PolyTrait<Foo<u16>> for Struct {
    |      ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `u16`
-   |
-note: required by `Foo`
-  --> $DIR/trait-bounds-on-structs-and-enums-in-impls.rs:3:1
-   |
-LL | struct Foo<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-bounds-on-structs-and-enums-locals.stderr b/src/test/ui/traits/trait-bounds-on-structs-and-enums-locals.stderr
index cdcfff97bd020..070b7b013e5cc 100644
--- a/src/test/ui/traits/trait-bounds-on-structs-and-enums-locals.stderr
+++ b/src/test/ui/traits/trait-bounds-on-structs-and-enums-locals.stderr
@@ -1,26 +1,20 @@
 error[E0277]: the trait bound `usize: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums-locals.rs:15:14
    |
+LL | struct Foo<T:Trait> {
+   | ------------------- required by `Foo`
+...
 LL |     let baz: Foo<usize> = loop { };
    |              ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
-   |
-note: required by `Foo`
-  --> $DIR/trait-bounds-on-structs-and-enums-locals.rs:5:1
-   |
-LL | struct Foo<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `{integer}: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums-locals.rs:10:15
    |
+LL | struct Foo<T:Trait> {
+   | ------------------- required by `Foo`
+...
 LL |     let foo = Foo {
    |               ^^^ the trait `Trait` is not implemented for `{integer}`
-   |
-note: required by `Foo`
-  --> $DIR/trait-bounds-on-structs-and-enums-locals.rs:5:1
-   |
-LL | struct Foo<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/trait-bounds-on-structs-and-enums-static.stderr b/src/test/ui/traits/trait-bounds-on-structs-and-enums-static.stderr
index b019c2979202f..722f01750cb66 100644
--- a/src/test/ui/traits/trait-bounds-on-structs-and-enums-static.stderr
+++ b/src/test/ui/traits/trait-bounds-on-structs-and-enums-static.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `usize: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums-static.rs:9:11
    |
+LL | struct Foo<T:Trait> {
+   | ------------------- required by `Foo`
+...
 LL | static X: Foo<usize> = Foo {
    |           ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
-   |
-note: required by `Foo`
-  --> $DIR/trait-bounds-on-structs-and-enums-static.rs:5:1
-   |
-LL | struct Foo<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-bounds-on-structs-and-enums.stderr b/src/test/ui/traits/trait-bounds-on-structs-and-enums.stderr
index 9a4cc90f3a5e0..bd76df8071a53 100644
--- a/src/test/ui/traits/trait-bounds-on-structs-and-enums.stderr
+++ b/src/test/ui/traits/trait-bounds-on-structs-and-enums.stderr
@@ -1,89 +1,71 @@
 error[E0277]: the trait bound `T: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums.rs:13:9
    |
+LL | struct Foo<T:Trait> {
+   | ------------------- required by `Foo`
+...
 LL | impl<T> Foo<T> {
    |         ^^^^^^ the trait `Trait` is not implemented for `T`
    |
    = help: consider adding a `where T: Trait` bound
-note: required by `Foo`
-  --> $DIR/trait-bounds-on-structs-and-enums.rs:3:1
-   |
-LL | struct Foo<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `isize: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums.rs:19:5
    |
+LL | struct Foo<T:Trait> {
+   | ------------------- required by `Foo`
+...
 LL |     a: Foo<isize>,
    |     ^^^^^^^^^^^^^ the trait `Trait` is not implemented for `isize`
-   |
-note: required by `Foo`
-  --> $DIR/trait-bounds-on-structs-and-enums.rs:3:1
-   |
-LL | struct Foo<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `usize: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums.rs:23:10
    |
+LL | enum Bar<T:Trait> {
+   | ----------------- required by `Bar`
+...
 LL |     Quux(Bar<usize>),
    |          ^^^^^^^^^^ the trait `Trait` is not implemented for `usize`
-   |
-note: required by `Bar`
-  --> $DIR/trait-bounds-on-structs-and-enums.rs:7:1
-   |
-LL | enum Bar<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `U: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums.rs:27:5
    |
+LL | struct Foo<T:Trait> {
+   | ------------------- required by `Foo`
+...
 LL |     b: Foo<U>,
    |     ^^^^^^^^^ the trait `Trait` is not implemented for `U`
    |
    = help: consider adding a `where U: Trait` bound
-note: required by `Foo`
-  --> $DIR/trait-bounds-on-structs-and-enums.rs:3:1
-   |
-LL | struct Foo<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `V: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums.rs:31:21
    |
+LL | enum Bar<T:Trait> {
+   | ----------------- required by `Bar`
+...
 LL |     EvenMoreBadness(Bar<V>),
    |                     ^^^^^^ the trait `Trait` is not implemented for `V`
    |
    = help: consider adding a `where V: Trait` bound
-note: required by `Bar`
-  --> $DIR/trait-bounds-on-structs-and-enums.rs:7:1
-   |
-LL | enum Bar<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `i32: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums.rs:35:5
    |
+LL | struct Foo<T:Trait> {
+   | ------------------- required by `Foo`
+...
 LL |     Foo<i32>,
    |     ^^^^^^^^ the trait `Trait` is not implemented for `i32`
-   |
-note: required by `Foo`
-  --> $DIR/trait-bounds-on-structs-and-enums.rs:3:1
-   |
-LL | struct Foo<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `u8: Trait` is not satisfied
   --> $DIR/trait-bounds-on-structs-and-enums.rs:39:22
    |
+LL | enum Bar<T:Trait> {
+   | ----------------- required by `Bar`
+...
 LL |     DictionaryLike { field: Bar<u8> },
    |                      ^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `u8`
-   |
-note: required by `Bar`
-  --> $DIR/trait-bounds-on-structs-and-enums.rs:7:1
-   |
-LL | enum Bar<T:Trait> {
-   | ^^^^^^^^^^^^^^^^^
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/traits/trait-static-method-generic-inference.stderr b/src/test/ui/traits/trait-static-method-generic-inference.stderr
index 390d21c4a699e..a99536d31ef84 100644
--- a/src/test/ui/traits/trait-static-method-generic-inference.stderr
+++ b/src/test/ui/traits/trait-static-method-generic-inference.stderr
@@ -1,14 +1,11 @@
 error[E0283]: type annotations required: cannot resolve `_: base::HasNew<base::Foo>`
   --> $DIR/trait-static-method-generic-inference.rs:24:25
    |
+LL |         fn new() -> T;
+   |         -------------- required by `base::HasNew::new`
+...
 LL |     let _f: base::Foo = base::HasNew::new();
    |                         ^^^^^^^^^^^^^^^^^
-   |
-note: required by `base::HasNew::new`
-  --> $DIR/trait-static-method-generic-inference.rs:8:9
-   |
-LL |         fn new() -> T;
-   |         ^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/traits-inductive-overflow-simultaneous.stderr b/src/test/ui/traits/traits-inductive-overflow-simultaneous.stderr
index cd8501e4df421..b29d726fbba94 100644
--- a/src/test/ui/traits/traits-inductive-overflow-simultaneous.stderr
+++ b/src/test/ui/traits/traits-inductive-overflow-simultaneous.stderr
@@ -1,15 +1,13 @@
 error[E0275]: overflow evaluating the requirement `{integer}: Tweedledum`
   --> $DIR/traits-inductive-overflow-simultaneous.rs:18:5
    |
+LL | fn is_ee<T: Combo>(t: T) {
+   | ------------------------ required by `is_ee`
+...
 LL |     is_ee(4);
    |     ^^^^^
    |
    = note: required because of the requirements on the impl of `Combo` for `{integer}`
-note: required by `is_ee`
-  --> $DIR/traits-inductive-overflow-simultaneous.rs:13:1
-   |
-LL | fn is_ee<T: Combo>(t: T) {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr
index 87e7ba3e7efcf..0b543616d7c9a 100644
--- a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr
+++ b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr
@@ -7,15 +7,13 @@ LL | auto trait Magic: Copy {}
 error[E0277]: the trait bound `NoClone: std::marker::Copy` is not satisfied
   --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:15:18
    |
+LL | fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
+   | --------------------------------- required by `copy`
+...
 LL |     let (a, b) = copy(NoClone);
    |                  ^^^^ the trait `std::marker::Copy` is not implemented for `NoClone`
    |
    = note: required because of the requirements on the impl of `Magic` for `NoClone`
-note: required by `copy`
-  --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:9:1
-   |
-LL | fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/traits-inductive-overflow-supertrait.stderr b/src/test/ui/traits/traits-inductive-overflow-supertrait.stderr
index 769582a778bcf..92747be7d2c6b 100644
--- a/src/test/ui/traits/traits-inductive-overflow-supertrait.stderr
+++ b/src/test/ui/traits/traits-inductive-overflow-supertrait.stderr
@@ -1,15 +1,13 @@
 error[E0275]: overflow evaluating the requirement `NoClone: Magic`
   --> $DIR/traits-inductive-overflow-supertrait.rs:13:18
    |
+LL | fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
+   | --------------------------------- required by `copy`
+...
 LL |     let (a, b) = copy(NoClone);
    |                  ^^^^
    |
    = note: required because of the requirements on the impl of `Magic` for `NoClone`
-note: required by `copy`
-  --> $DIR/traits-inductive-overflow-supertrait.rs:7:1
-   |
-LL | fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/traits-inductive-overflow-two-traits.stderr b/src/test/ui/traits/traits-inductive-overflow-two-traits.stderr
index 61adbf00f7188..58d7fcd56c71e 100644
--- a/src/test/ui/traits/traits-inductive-overflow-two-traits.stderr
+++ b/src/test/ui/traits/traits-inductive-overflow-two-traits.stderr
@@ -1,14 +1,11 @@
 error[E0275]: overflow evaluating the requirement `*mut (): Magic`
   --> $DIR/traits-inductive-overflow-two-traits.rs:19:5
    |
+LL | fn wizard<T: Magic>() { check::<<T as Magic>::X>(); }
+   | --------------------- required by `wizard`
+...
 LL |     wizard::<*mut ()>();
    |     ^^^^^^^^^^^^^^^^^
-   |
-note: required by `wizard`
-  --> $DIR/traits-inductive-overflow-two-traits.rs:16:1
-   |
-LL | fn wizard<T: Magic>() { check::<<T as Magic>::X>(); }
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/traits-negative-impls.stderr b/src/test/ui/traits/traits-negative-impls.stderr
index 1bdd73eb6f9b1..23bd334a3e776 100644
--- a/src/test/ui/traits/traits-negative-impls.stderr
+++ b/src/test/ui/traits/traits-negative-impls.stderr
@@ -1,74 +1,67 @@
 error[E0277]: `dummy::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:23:5
    |
+LL | struct Outer<T: Send>(T);
+   | ------------------------- required by `Outer`
+...
 LL |     Outer(TestType);
    |     ^^^^^ `dummy::TestType` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `dummy::TestType`
-note: required by `Outer`
-  --> $DIR/traits-negative-impls.rs:10:1
-   |
-LL | struct Outer<T: Send>(T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `dummy::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:23:5
    |
+LL | struct Outer<T: Send>(T);
+   | ------------------------- required by `Outer`
+...
 LL |     Outer(TestType);
    |     ^^^^^^^^^^^^^^^ `dummy::TestType` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `dummy::TestType`
-note: required by `Outer`
-  --> $DIR/traits-negative-impls.rs:10:1
-   |
-LL | struct Outer<T: Send>(T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `dummy1b::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:32:5
    |
+LL | fn is_send<T: Send>(_: T) {}
+   | ------------------------- required by `is_send`
+...
 LL |     is_send(TestType);
    |     ^^^^^^^ `dummy1b::TestType` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `dummy1b::TestType`
-note: required by `is_send`
-  --> $DIR/traits-negative-impls.rs:16:1
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `dummy1c::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:40:5
    |
+LL | fn is_send<T: Send>(_: T) {}
+   | ------------------------- required by `is_send`
+...
 LL |     is_send((8, TestType));
    |     ^^^^^^^ `dummy1c::TestType` cannot be sent between threads safely
    |
    = help: within `({integer}, dummy1c::TestType)`, the trait `std::marker::Send` is not implemented for `dummy1c::TestType`
    = note: required because it appears within the type `({integer}, dummy1c::TestType)`
-note: required by `is_send`
-  --> $DIR/traits-negative-impls.rs:16:1
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `dummy2::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:48:5
    |
+LL | fn is_send<T: Send>(_: T) {}
+   | ------------------------- required by `is_send`
+...
 LL |     is_send(Box::new(TestType));
    |     ^^^^^^^ `dummy2::TestType` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `dummy2::TestType`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<dummy2::TestType>`
    = note: required because it appears within the type `std::boxed::Box<dummy2::TestType>`
-note: required by `is_send`
-  --> $DIR/traits-negative-impls.rs:16:1
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `dummy3::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:56:5
    |
+LL | fn is_send<T: Send>(_: T) {}
+   | ------------------------- required by `is_send`
+...
 LL |     is_send(Box::new(Outer2(TestType)));
    |     ^^^^^^^ `dummy3::TestType` cannot be sent between threads safely
    |
@@ -76,25 +69,18 @@ LL |     is_send(Box::new(Outer2(TestType)));
    = note: required because it appears within the type `Outer2<dummy3::TestType>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<Outer2<dummy3::TestType>>`
    = note: required because it appears within the type `std::boxed::Box<Outer2<dummy3::TestType>>`
-note: required by `is_send`
-  --> $DIR/traits-negative-impls.rs:16:1
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `main::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:66:5
    |
+LL | fn is_sync<T: Sync>(_: T) {}
+   | ------------------------- required by `is_sync`
+...
 LL |     is_sync(Outer2(TestType));
    |     ^^^^^^^ `main::TestType` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `main::TestType`
    = note: required because of the requirements on the impl of `std::marker::Sync` for `Outer2<main::TestType>`
-note: required by `is_sync`
-  --> $DIR/traits-negative-impls.rs:17:1
-   |
-LL | fn is_sync<T: Sync>(_: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/traits/traits-repeated-supertrait-ambig.stderr b/src/test/ui/traits/traits-repeated-supertrait-ambig.stderr
index 5d1c91376868f..db77e82adbd00 100644
--- a/src/test/ui/traits/traits-repeated-supertrait-ambig.stderr
+++ b/src/test/ui/traits/traits-repeated-supertrait-ambig.stderr
@@ -15,27 +15,22 @@ LL |     c.same_as(22)
 error[E0277]: the trait bound `dyn CompareToInts: CompareTo<i32>` is not satisfied
   --> $DIR/traits-repeated-supertrait-ambig.rs:34:5
    |
+LL |     fn same_as(&self, t: T) -> bool;
+   |     -------------------------------- required by `CompareTo::same_as`
+...
 LL |     CompareToInts::same_as(c, 22)
    |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `dyn CompareToInts`
-   |
-note: required by `CompareTo::same_as`
-  --> $DIR/traits-repeated-supertrait-ambig.rs:9:5
-   |
-LL |     fn same_as(&self, t: T) -> bool;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `C: CompareTo<i32>` is not satisfied
   --> $DIR/traits-repeated-supertrait-ambig.rs:38:5
    |
+LL |     fn same_as(&self, t: T) -> bool;
+   |     -------------------------------- required by `CompareTo::same_as`
+...
 LL |     CompareTo::same_as(c, 22)
    |     ^^^^^^^^^^^^^^^^^^ the trait `CompareTo<i32>` is not implemented for `C`
    |
    = help: consider adding a `where C: CompareTo<i32>` bound
-note: required by `CompareTo::same_as`
-  --> $DIR/traits-repeated-supertrait-ambig.rs:9:5
-   |
-LL |     fn same_as(&self, t: T) -> bool;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `i64: CompareTo<i32>` is not satisfied
   --> $DIR/traits-repeated-supertrait-ambig.rs:42:23
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
index 46b4b2a878492..f0f048159ec73 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
+++ b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
@@ -21,26 +21,20 @@ LL |     3i32.test();
 error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/trivial-bounds-leak.rs:25:5
    |
+LL |     fn test(&self);
+   |     --------------- required by `Foo::test`
+...
 LL |     Foo::test(&4i32);
    |     ^^^^^^^^^ the trait `Foo` is not implemented for `i32`
-   |
-note: required by `Foo::test`
-  --> $DIR/trivial-bounds-leak.rs:5:5
-   |
-LL |     fn test(&self);
-   |     ^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/trivial-bounds-leak.rs:26:5
    |
 LL |     generic_function(5i32);
    |     ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32`
-   |
-note: required by `generic_function`
-  --> $DIR/trivial-bounds-leak.rs:29:1
-   |
+...
 LL | fn generic_function<T: Foo>(t: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | --------------------------------- required by `generic_function`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/try-operator-on-main.stderr b/src/test/ui/try-operator-on-main.stderr
index 9f120e009485e..6878cd80629bc 100644
--- a/src/test/ui/try-operator-on-main.stderr
+++ b/src/test/ui/try-operator-on-main.stderr
@@ -21,12 +21,9 @@ error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
    |
 LL |     try_trait_generic::<()>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()`
-   |
-note: required by `try_trait_generic`
-  --> $DIR/try-operator-on-main.rs:20:1
-   |
+...
 LL | fn try_trait_generic<T: Try>() -> T {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ----------------------------------- required by `try_trait_generic`
 
 error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
   --> $DIR/try-operator-on-main.rs:22:5
diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr
index 92ae9746b150b..1dd2aafeb62fa 100644
--- a/src/test/ui/type/type-annotation-needed.stderr
+++ b/src/test/ui/type/type-annotation-needed.stderr
@@ -1,14 +1,11 @@
 error[E0283]: type annotations required: cannot resolve `_: std::convert::Into<std::string::String>`
   --> $DIR/type-annotation-needed.rs:5:5
    |
+LL | fn foo<T: Into<String>>(x: i32) {}
+   | ------------------------------- required by `foo`
+...
 LL |     foo(42);
    |     ^^^
-   |
-note: required by `foo`
-  --> $DIR/type-annotation-needed.rs:1:1
-   |
-LL | fn foo<T: Into<String>>(x: i32) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr
index a46d79ec3183e..42cca76451fd1 100644
--- a/src/test/ui/type/type-check-defaults.stderr
+++ b/src/test/ui/type/type-check-defaults.stderr
@@ -1,90 +1,71 @@
 error[E0277]: a collection of type `i32` cannot be built from an iterator over elements of type `i32`
   --> $DIR/type-check-defaults.rs:6:19
    |
+LL | struct Foo<T, U: FromIterator<T>>(T, U);
+   | ---------------------------------------- required by `Foo`
 LL | struct WellFormed<Z = Foo<i32, i32>>(Z);
    |                   ^ a collection of type `i32` cannot be built from `std::iter::Iterator<Item=i32>`
    |
    = help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
-note: required by `Foo`
-  --> $DIR/type-check-defaults.rs:5:1
-   |
-LL | struct Foo<T, U: FromIterator<T>>(T, U);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: a collection of type `i32` cannot be built from an iterator over elements of type `i32`
   --> $DIR/type-check-defaults.rs:8:27
    |
+LL | struct Foo<T, U: FromIterator<T>>(T, U);
+   | ---------------------------------------- required by `Foo`
+...
 LL | struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z);
    |                           ^ a collection of type `i32` cannot be built from `std::iter::Iterator<Item=i32>`
    |
    = help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
-note: required by `Foo`
-  --> $DIR/type-check-defaults.rs:5:1
-   |
-LL | struct Foo<T, U: FromIterator<T>>(T, U);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
   --> $DIR/type-check-defaults.rs:11:1
    |
-LL | struct Bounds<T:Copy=String>(T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
-   |
-note: required by `Bounds`
-  --> $DIR/type-check-defaults.rs:11:1
-   |
 LL | struct Bounds<T:Copy=String>(T);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | the trait `std::marker::Copy` is not implemented for `std::string::String`
+   | required by `Bounds`
 
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
   --> $DIR/type-check-defaults.rs:14:1
    |
-LL | struct WhereClause<T=String>(T) where T: Copy;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
-   |
-note: required by `WhereClause`
-  --> $DIR/type-check-defaults.rs:14:1
-   |
 LL | struct WhereClause<T=String>(T) where T: Copy;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | the trait `std::marker::Copy` is not implemented for `std::string::String`
+   | required by `WhereClause`
 
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
   --> $DIR/type-check-defaults.rs:17:1
    |
 LL | trait TraitBound<T:Copy=String> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
-   |
-note: required by `TraitBound`
-  --> $DIR/type-check-defaults.rs:17:1
-   |
-LL | trait TraitBound<T:Copy=String> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | -------------------------------^^^
+   | |
+   | the trait `std::marker::Copy` is not implemented for `std::string::String`
+   | required by `TraitBound`
 
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/type-check-defaults.rs:21:1
    |
+LL | trait Super<T: Copy> { }
+   | -------------------- required by `Super`
 LL | trait Base<T = String>: Super<T> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
-note: required by `Super`
-  --> $DIR/type-check-defaults.rs:20:1
-   |
-LL | trait Super<T: Copy> { }
-   | ^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: cannot add `u8` to `i32`
   --> $DIR/type-check-defaults.rs:24:1
    |
 LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `i32 + u8`
+   | ------------------------------------------------------------------------^^^
+   | |
+   | no implementation for `i32 + u8`
+   | required by `ProjectionPred`
    |
    = help: the trait `std::ops::Add<u8>` is not implemented for `i32`
-note: required by `ProjectionPred`
-  --> $DIR/type-check-defaults.rs:24:1
-   |
-LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/type/type-check/issue-40294.stderr b/src/test/ui/type/type-check/issue-40294.stderr
index 254875fcaab3a..732a81c8a244a 100644
--- a/src/test/ui/type/type-check/issue-40294.stderr
+++ b/src/test/ui/type/type-check/issue-40294.stderr
@@ -1,6 +1,9 @@
 error[E0283]: type annotations required: cannot resolve `&'a T: Foo`
   --> $DIR/issue-40294.rs:5:1
    |
+LL |   trait Foo: Sized {
+   |   ---------------- required by `Foo`
+...
 LL | / fn foo<'a,'b,T>(x: &'a T, y: &'b T)
 LL | |     where &'a T : Foo,
 LL | |           &'b T : Foo
@@ -9,12 +12,6 @@ LL | |     x.foo();
 LL | |     y.foo();
 LL | | }
    | |_^
-   |
-note: required by `Foo`
-  --> $DIR/issue-40294.rs:1:1
-   |
-LL | trait Foo: Sized {
-   | ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type/type-params-in-different-spaces-2.stderr b/src/test/ui/type/type-params-in-different-spaces-2.stderr
index 15db94ef1e3c3..7d4bbc813c09c 100644
--- a/src/test/ui/type/type-params-in-different-spaces-2.stderr
+++ b/src/test/ui/type/type-params-in-different-spaces-2.stderr
@@ -1,28 +1,24 @@
 error[E0277]: the trait bound `Self: Tr<U>` is not satisfied
   --> $DIR/type-params-in-different-spaces-2.rs:10:9
    |
+LL |     fn op(_: T) -> Self;
+   |     -------------------- required by `Tr::op`
+...
 LL |         Tr::op(u)
    |         ^^^^^^ the trait `Tr<U>` is not implemented for `Self`
    |
    = help: consider adding a `where Self: Tr<U>` bound
-note: required by `Tr::op`
-  --> $DIR/type-params-in-different-spaces-2.rs:5:5
-   |
-LL |     fn op(_: T) -> Self;
-   |     ^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `Self: Tr<U>` is not satisfied
   --> $DIR/type-params-in-different-spaces-2.rs:16:9
    |
+LL |     fn op(_: T) -> Self;
+   |     -------------------- required by `Tr::op`
+...
 LL |         Tr::op(u)
    |         ^^^^^^ the trait `Tr<U>` is not implemented for `Self`
    |
    = help: consider adding a `where Self: Tr<U>` bound
-note: required by `Tr::op`
-  --> $DIR/type-params-in-different-spaces-2.rs:5:5
-   |
-LL |     fn op(_: T) -> Self;
-   |     ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr
index a31ee83ae1ccc..7fb3731be23e6 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr
@@ -3,14 +3,12 @@ error[E0277]: `<T as Trait>::AssocType` cannot be sent between threads safely
    |
 LL |     is_send::<T::AssocType>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ `<T as Trait>::AssocType` cannot be sent between threads safely
+...
+LL | fn is_send<T:Send>() {
+   | -------------------- required by `is_send`
    |
    = help: the trait `std::marker::Send` is not implemented for `<T as Trait>::AssocType`
    = help: consider adding a `where <T as Trait>::AssocType: std::marker::Send` bound
-note: required by `is_send`
-  --> $DIR/typeck-default-trait-impl-assoc-type.rs:12:1
-   |
-LL | fn is_send<T:Send>() {
-   | ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr
index db1d7d8c0b74b..8389356fdd6f6 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr
@@ -1,17 +1,15 @@
 error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied in `(MyS2, MyS)`
   --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:16:5
    |
+LL | fn is_mytrait<T: MyTrait>() {}
+   | --------------------------- required by `is_mytrait`
+...
 LL |     is_mytrait::<(MyS2, MyS)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2`
    |
    = help: the following implementations were found:
              <MyS2 as MyTrait>
    = note: required because it appears within the type `(MyS2, MyS)`
-note: required by `is_mytrait`
-  --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:11:1
-   |
-LL | fn is_mytrait<T: MyTrait>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr
index 0f90518964340..eee186feea67d 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr
@@ -1,16 +1,14 @@
 error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied
   --> $DIR/typeck-default-trait-impl-constituent-types.rs:20:5
    |
+LL | fn is_mytrait<T: MyTrait>() {}
+   | --------------------------- required by `is_mytrait`
+...
 LL |     is_mytrait::<MyS2>();
    |     ^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `MyS2`
    |
    = help: the following implementations were found:
              <MyS2 as MyTrait>
-note: required by `is_mytrait`
-  --> $DIR/typeck-default-trait-impl-constituent-types.rs:15:1
-   |
-LL | fn is_mytrait<T: MyTrait>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr
index 8442f47e82c48..1e6adeb430998 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr
@@ -1,15 +1,13 @@
 error[E0277]: `MyNotSendable` cannot be sent between threads safely
   --> $DIR/typeck-default-trait-impl-negation-send.rs:19:5
    |
+LL | fn is_send<T: Send>() {}
+   | --------------------- required by `is_send`
+...
 LL |     is_send::<MyNotSendable>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ `MyNotSendable` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `MyNotSendable`
-note: required by `is_send`
-  --> $DIR/typeck-default-trait-impl-negation-send.rs:15:1
-   |
-LL | fn is_send<T: Send>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
index 4d435bf4e8b24..d4f8f5ad82c9e 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
@@ -1,43 +1,37 @@
 error[E0277]: `MyNotSync` cannot be shared between threads safely
   --> $DIR/typeck-default-trait-impl-negation-sync.rs:33:5
    |
+LL | fn is_sync<T: Sync>() {}
+   | --------------------- required by `is_sync`
+...
 LL |     is_sync::<MyNotSync>();
    |     ^^^^^^^^^^^^^^^^^^^^ `MyNotSync` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `MyNotSync`
-note: required by `is_sync`
-  --> $DIR/typeck-default-trait-impl-negation-sync.rs:29:1
-   |
-LL | fn is_sync<T: Sync>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::cell::UnsafeCell<u8>` cannot be shared between threads safely
   --> $DIR/typeck-default-trait-impl-negation-sync.rs:36:5
    |
+LL | fn is_sync<T: Sync>() {}
+   | --------------------- required by `is_sync`
+...
 LL |     is_sync::<MyTypeWUnsafe>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<u8>` cannot be shared between threads safely
    |
    = help: within `MyTypeWUnsafe`, the trait `std::marker::Sync` is not implemented for `std::cell::UnsafeCell<u8>`
    = note: required because it appears within the type `MyTypeWUnsafe`
-note: required by `is_sync`
-  --> $DIR/typeck-default-trait-impl-negation-sync.rs:29:1
-   |
-LL | fn is_sync<T: Sync>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `Managed` cannot be shared between threads safely
   --> $DIR/typeck-default-trait-impl-negation-sync.rs:39:5
    |
+LL | fn is_sync<T: Sync>() {}
+   | --------------------- required by `is_sync`
+...
 LL |     is_sync::<MyTypeManaged>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ `Managed` cannot be shared between threads safely
    |
    = help: within `MyTypeManaged`, the trait `std::marker::Sync` is not implemented for `Managed`
    = note: required because it appears within the type `MyTypeManaged`
-note: required by `is_sync`
-  --> $DIR/typeck-default-trait-impl-negation-sync.rs:29:1
-   |
-LL | fn is_sync<T: Sync>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr
index 751083d0358b6..e993098b2deed 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr
@@ -1,30 +1,26 @@
 error[E0277]: the trait bound `ThisImplsUnsafeTrait: MyTrait` is not satisfied
   --> $DIR/typeck-default-trait-impl-negation.rs:21:5
    |
+LL | fn is_my_trait<T: MyTrait>() {}
+   | ---------------------------- required by `is_my_trait`
+...
 LL |     is_my_trait::<ThisImplsUnsafeTrait>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `ThisImplsUnsafeTrait`
    |
    = help: the following implementations were found:
              <ThisImplsUnsafeTrait as MyTrait>
-note: required by `is_my_trait`
-  --> $DIR/typeck-default-trait-impl-negation.rs:16:1
-   |
-LL | fn is_my_trait<T: MyTrait>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `ThisImplsTrait: MyUnsafeTrait` is not satisfied
   --> $DIR/typeck-default-trait-impl-negation.rs:24:5
    |
+LL | fn is_my_unsafe_trait<T: MyUnsafeTrait>() {}
+   | ----------------------------------------- required by `is_my_unsafe_trait`
+...
 LL |     is_my_unsafe_trait::<ThisImplsTrait>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyUnsafeTrait` is not implemented for `ThisImplsTrait`
    |
    = help: the following implementations were found:
              <ThisImplsTrait as MyUnsafeTrait>
-note: required by `is_my_unsafe_trait`
-  --> $DIR/typeck-default-trait-impl-negation.rs:17:1
-   |
-LL | fn is_my_unsafe_trait<T: MyUnsafeTrait>() {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr b/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr
index d45cbb27a5f16..d87a6384e5c01 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `u32: Signed` is not satisfied
   --> $DIR/typeck-default-trait-impl-precedence.rs:18:5
    |
+LL | fn is_defaulted<T:Defaulted>() { }
+   | ------------------------------ required by `is_defaulted`
+...
 LL |     is_defaulted::<&'static u32>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
    |
    = note: required because of the requirements on the impl of `Defaulted` for `&'static u32`
-note: required by `is_defaulted`
-  --> $DIR/typeck-default-trait-impl-precedence.rs:11:1
-   |
-LL | fn is_defaulted<T:Defaulted>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
index a850cc7b377d0..5f3a5bc6e0054 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
@@ -3,14 +3,12 @@ error[E0277]: `T` cannot be sent between threads safely
    |
 LL |     is_send::<T>()
    |     ^^^^^^^^^^^^ `T` cannot be sent between threads safely
+...
+LL | fn is_send<T:Send>() {
+   | -------------------- required by `is_send`
    |
    = help: the trait `std::marker::Send` is not implemented for `T`
    = help: consider adding a `where T: std::marker::Send` bound
-note: required by `is_send`
-  --> $DIR/typeck-default-trait-impl-send-param.rs:8:1
-   |
-LL | fn is_send<T:Send>() {
-   | ^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/typeck/typeck-unsafe-always-share.stderr b/src/test/ui/typeck/typeck-unsafe-always-share.stderr
index ff351afdcaedf..7ed85a14259aa 100644
--- a/src/test/ui/typeck/typeck-unsafe-always-share.stderr
+++ b/src/test/ui/typeck/typeck-unsafe-always-share.stderr
@@ -1,55 +1,47 @@
 error[E0277]: `std::cell::UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely
   --> $DIR/typeck-unsafe-always-share.rs:19:5
    |
+LL | fn test<T: Sync>(s: T) {}
+   | ---------------------- required by `test`
+...
 LL |     test(us);
    |     ^^^^ `std::cell::UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::UnsafeCell<MySync<{integer}>>`
-note: required by `test`
-  --> $DIR/typeck-unsafe-always-share.rs:15:1
-   |
-LL | fn test<T: Sync>(s: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::cell::UnsafeCell<NoSync>` cannot be shared between threads safely
   --> $DIR/typeck-unsafe-always-share.rs:23:5
    |
+LL | fn test<T: Sync>(s: T) {}
+   | ---------------------- required by `test`
+...
 LL |     test(uns);
    |     ^^^^ `std::cell::UnsafeCell<NoSync>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::UnsafeCell<NoSync>`
-note: required by `test`
-  --> $DIR/typeck-unsafe-always-share.rs:15:1
-   |
-LL | fn test<T: Sync>(s: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `std::cell::UnsafeCell<NoSync>` cannot be shared between threads safely
   --> $DIR/typeck-unsafe-always-share.rs:27:5
    |
+LL | fn test<T: Sync>(s: T) {}
+   | ---------------------- required by `test`
+...
 LL |     test(ms);
    |     ^^^^ `std::cell::UnsafeCell<NoSync>` cannot be shared between threads safely
    |
    = help: within `MySync<NoSync>`, the trait `std::marker::Sync` is not implemented for `std::cell::UnsafeCell<NoSync>`
    = note: required because it appears within the type `MySync<NoSync>`
-note: required by `test`
-  --> $DIR/typeck-unsafe-always-share.rs:15:1
-   |
-LL | fn test<T: Sync>(s: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `NoSync` cannot be shared between threads safely
   --> $DIR/typeck-unsafe-always-share.rs:30:5
    |
+LL | fn test<T: Sync>(s: T) {}
+   | ---------------------- required by `test`
+...
 LL |     test(NoSync);
    |     ^^^^ `NoSync` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `NoSync`
-note: required by `test`
-  --> $DIR/typeck-unsafe-always-share.rs:15:1
-   |
-LL | fn test<T: Sync>(s: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr
index fd5ef4b9df15a..dd024b76c3ba7 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `dyn Foo<(isize,), isize, Output = ()>: Eq<dyn Foo<(isize,), Output = ()>>` is not satisfied
   --> $DIR/unboxed-closure-sugar-default.rs:21:5
    |
+LL | fn eq<A: ?Sized,B: ?Sized>() where A : Eq<B> { }
+   | -------------------------------------------- required by `eq`
+...
 LL |     eq::<dyn Foo<(isize,), isize, Output=()>, dyn Foo(isize)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq<dyn Foo<(isize,), Output = ()>>` is not implemented for `dyn Foo<(isize,), isize, Output = ()>`
-   |
-note: required by `eq`
-  --> $DIR/unboxed-closure-sugar-default.rs:14:1
-   |
-LL | fn eq<A: ?Sized,B: ?Sized>() where A : Eq<B> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr
index 005a86bc2178b..83754bd36ef2a 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr
@@ -1,15 +1,12 @@
 error[E0277]: the trait bound `dyn Foo<(char,), Output = ()>: Eq<dyn Foo<(), Output = ()>>` is not satisfied
   --> $DIR/unboxed-closure-sugar-equiv.rs:43:5
    |
+LL |   fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
+   |   ----------------------------------- required by `eq`
+...
 LL | /     eq::< dyn Foo<(),Output=()>,
 LL | |           dyn Foo(char)                                               >();
    | |_______________________________________________________________________^ the trait `Eq<dyn Foo<(), Output = ()>>` is not implemented for `dyn Foo<(char,), Output = ()>`
-   |
-note: required by `eq`
-  --> $DIR/unboxed-closure-sugar-equiv.rs:16:1
-   |
-LL | fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr
index fcf11290c81d9..d64e54a548442 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr
@@ -1,15 +1,13 @@
 error[E0277]: expected a `std::ops::Fn<(isize,)>` closure, found `S`
   --> $DIR/unboxed-closures-fnmut-as-fn.rs:28:13
    |
+LL | fn call_it<F:Fn(isize)->isize>(f: &F, x: isize) -> isize {
+   | -------------------------------------------------------- required by `call_it`
+...
 LL |     let x = call_it(&S, 22);
    |             ^^^^^^^ expected an `Fn<(isize,)>` closure, found `S`
    |
    = help: the trait `std::ops::Fn<(isize,)>` is not implemented for `S`
-note: required by `call_it`
-  --> $DIR/unboxed-closures-fnmut-as-fn.rs:23:1
-   |
-LL | fn call_it<F:Fn(isize)->isize>(f: &F, x: isize) -> isize {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
index ca0298283661f..3d20b5df1e3f3 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
@@ -1,67 +1,57 @@
 error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:13
    |
+LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
+   | --------------------------------------------------------- required by `call_it`
+...
 LL |     let x = call_it(&square, 22);
    |             ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
-note: required by `call_it`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:7:1
-   |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:13
    |
+LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
+   | --------------------------------------------------------- required by `call_it`
+...
 LL |     let x = call_it(&square, 22);
    |             ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
-note: required by `call_it`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:7:1
-   |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:13
    |
+LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
+   | -------------------------------------------------------------------- required by `call_it_mut`
+...
 LL |     let y = call_it_mut(&mut square, 22);
    |             ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
-note: required by `call_it_mut`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:8:1
-   |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:13
    |
+LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
+   | -------------------------------------------------------------------- required by `call_it_mut`
+...
 LL |     let y = call_it_mut(&mut square, 22);
    |             ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
-note: required by `call_it_mut`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:8:1
-   |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:24:13
    |
+LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
+   | ----------------------------------------------------------------- required by `call_it_once`
+...
 LL |     let z = call_it_once(square, 22);
    |             ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
-note: required by `call_it_once`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:9:1
-   |
-LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
index 0abc58aeebfe5..f435a05e04901 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
@@ -1,67 +1,57 @@
 error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
   --> $DIR/unboxed-closures-wrong-abi.rs:12:13
    |
+LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
+   | --------------------------------------------------------- required by `call_it`
+...
 LL |     let x = call_it(&square, 22);
    |             ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-note: required by `call_it`
-  --> $DIR/unboxed-closures-wrong-abi.rs:7:1
-   |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
   --> $DIR/unboxed-closures-wrong-abi.rs:12:13
    |
+LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
+   | --------------------------------------------------------- required by `call_it`
+...
 LL |     let x = call_it(&square, 22);
    |             ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-note: required by `call_it`
-  --> $DIR/unboxed-closures-wrong-abi.rs:7:1
-   |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
   --> $DIR/unboxed-closures-wrong-abi.rs:18:13
    |
+LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
+   | -------------------------------------------------------------------- required by `call_it_mut`
+...
 LL |     let y = call_it_mut(&mut square, 22);
    |             ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-note: required by `call_it_mut`
-  --> $DIR/unboxed-closures-wrong-abi.rs:8:1
-   |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
   --> $DIR/unboxed-closures-wrong-abi.rs:18:13
    |
+LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
+   | -------------------------------------------------------------------- required by `call_it_mut`
+...
 LL |     let y = call_it_mut(&mut square, 22);
    |             ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-note: required by `call_it_mut`
-  --> $DIR/unboxed-closures-wrong-abi.rs:8:1
-   |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
   --> $DIR/unboxed-closures-wrong-abi.rs:24:13
    |
+LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
+   | ----------------------------------------------------------------- required by `call_it_once`
+...
 LL |     let z = call_it_once(square, 22);
    |             ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-note: required by `call_it_once`
-  --> $DIR/unboxed-closures-wrong-abi.rs:9:1
-   |
-LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
index 19b87ad171a51..efdb2e8efa4e8 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
@@ -1,67 +1,57 @@
 error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:13
    |
+LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
+   | --------------------------------------------------------- required by `call_it`
+...
 LL |     let x = call_it(&square, 22);
    |             ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
-note: required by `call_it`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:8:1
-   |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:13
    |
+LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
+   | --------------------------------------------------------- required by `call_it`
+...
 LL |     let x = call_it(&square, 22);
    |             ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
-note: required by `call_it`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:8:1
-   |
-LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:13
    |
+LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
+   | -------------------------------------------------------------------- required by `call_it_mut`
+...
 LL |     let y = call_it_mut(&mut square, 22);
    |             ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
-note: required by `call_it_mut`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:9:1
-   |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:13
    |
+LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
+   | -------------------------------------------------------------------- required by `call_it_mut`
+...
 LL |     let y = call_it_mut(&mut square, 22);
    |             ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
-note: required by `call_it_mut`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:9:1
-   |
-LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:25:13
    |
+LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
+   | ----------------------------------------------------------------- required by `call_it_once`
+...
 LL |     let z = call_it_once(square, 22);
    |             ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
-note: required by `call_it_once`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:10:1
-   |
-LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/unevaluated_fixed_size_array_len.stderr b/src/test/ui/unevaluated_fixed_size_array_len.stderr
index be6ed8d56232e..2079f6fd53173 100644
--- a/src/test/ui/unevaluated_fixed_size_array_len.stderr
+++ b/src/test/ui/unevaluated_fixed_size_array_len.stderr
@@ -1,16 +1,14 @@
 error[E0277]: the trait bound `[(); 0]: Foo` is not satisfied
   --> $DIR/unevaluated_fixed_size_array_len.rs:12:5
    |
+LL |     fn foo();
+   |     --------- required by `Foo::foo`
+...
 LL |     <[(); 0] as Foo>::foo()
    |     ^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `[(); 0]`
    |
    = help: the following implementations were found:
              <[(); 1] as Foo>
-note: required by `Foo::foo`
-  --> $DIR/unevaluated_fixed_size_array_len.rs:4:5
-   |
-LL |     fn foo();
-   |     ^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/union/union-generic.stderr b/src/test/ui/union/union-generic.stderr
index 6a3216db64301..f13b2def6db84 100644
--- a/src/test/ui/union/union-generic.stderr
+++ b/src/test/ui/union/union-generic.stderr
@@ -1,26 +1,20 @@
 error[E0277]: the trait bound `std::rc::Rc<u32>: std::marker::Copy` is not satisfied
   --> $DIR/union-generic.rs:8:13
    |
+LL | union U<T: Copy> {
+   | ---------------- required by `U`
+...
 LL |     let u = U { a: Rc::new(0u32) };
    |             ^ the trait `std::marker::Copy` is not implemented for `std::rc::Rc<u32>`
-   |
-note: required by `U`
-  --> $DIR/union-generic.rs:3:1
-   |
-LL | union U<T: Copy> {
-   | ^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `std::rc::Rc<u32>: std::marker::Copy` is not satisfied
   --> $DIR/union-generic.rs:10:13
    |
+LL | union U<T: Copy> {
+   | ---------------- required by `U`
+...
 LL |     let u = U::<Rc<u32>> { a: Default::default() };
    |             ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::rc::Rc<u32>`
-   |
-note: required by `U`
-  --> $DIR/union-generic.rs:3:1
-   |
-LL | union U<T: Copy> {
-   | ^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unsized/unsized-bare-typaram.stderr b/src/test/ui/unsized/unsized-bare-typaram.stderr
index cee1459c7915d..c39c648f661c6 100644
--- a/src/test/ui/unsized/unsized-bare-typaram.stderr
+++ b/src/test/ui/unsized/unsized-bare-typaram.stderr
@@ -1,17 +1,14 @@
 error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/unsized-bare-typaram.rs:2:23
    |
+LL | fn bar<T: Sized>() { }
+   | ------------------ required by `bar`
 LL | fn foo<T: ?Sized>() { bar::<T>() }
    |                       ^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `T`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where T: std::marker::Sized` bound
-note: required by `bar`
-  --> $DIR/unsized-bare-typaram.rs:1:1
-   |
-LL | fn bar<T: Sized>() { }
-   | ^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsized/unsized-enum.stderr b/src/test/ui/unsized/unsized-enum.stderr
index 20857a1d65e75..dff934834ef2c 100644
--- a/src/test/ui/unsized/unsized-enum.stderr
+++ b/src/test/ui/unsized/unsized-enum.stderr
@@ -1,17 +1,15 @@
 error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/unsized-enum.rs:6:36
    |
+LL | enum Foo<U> { FooSome(U), FooNone }
+   | ----------- required by `Foo`
+LL | fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
 LL | fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
    |                                    ^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `T`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where T: std::marker::Sized` bound
-note: required by `Foo`
-  --> $DIR/unsized-enum.rs:4:1
-   |
-LL | enum Foo<U> { FooSome(U), FooNone }
-   | ^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr
index 98eecabc84cb8..1a726bb089f6e 100644
--- a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr
+++ b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr
@@ -1,17 +1,15 @@
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized-inherent-impl-self-type.rs:7:17
    |
+LL | struct S5<Y>(Y);
+   | ---------------- required by `S5`
+LL | 
 LL | impl<X: ?Sized> S5<X> {
    |                 ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
-note: required by `S5`
-  --> $DIR/unsized-inherent-impl-self-type.rs:5:1
-   |
-LL | struct S5<Y>(Y);
-   | ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr
index 7add65c07866b..795115154e72b 100644
--- a/src/test/ui/unsized/unsized-struct.stderr
+++ b/src/test/ui/unsized/unsized-struct.stderr
@@ -1,21 +1,22 @@
 error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/unsized-struct.rs:6:36
    |
+LL | struct Foo<T> { data: T }
+   | ------------- required by `Foo`
+LL | fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
 LL | fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
    |                                    ^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `T`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where T: std::marker::Sized` bound
-note: required by `Foo`
-  --> $DIR/unsized-struct.rs:4:1
-   |
-LL | struct Foo<T> { data: T }
-   | ^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/unsized-struct.rs:13:24
    |
+LL | fn is_sized<T:Sized>() { }
+   | ---------------------- required by `is_sized`
+...
 LL | fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
    |                        ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
@@ -23,11 +24,6 @@ LL | fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where T: std::marker::Sized` bound
    = note: required because it appears within the type `Bar<T>`
-note: required by `is_sized`
-  --> $DIR/unsized-struct.rs:1:1
-   |
-LL | fn is_sized<T:Sized>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr
index c39f3652b647c..f399f8ded1085 100644
--- a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr
+++ b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr
@@ -1,17 +1,15 @@
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized-trait-impl-self-type.rs:10:17
    |
+LL | struct S5<Y>(Y);
+   | ---------------- required by `S5`
+LL | 
 LL | impl<X: ?Sized> T3<X> for S5<X> {
    |                 ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
-note: required by `S5`
-  --> $DIR/unsized-trait-impl-self-type.rs:8:1
-   |
-LL | struct S5<Y>(Y);
-   | ^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsized3.stderr b/src/test/ui/unsized3.stderr
index 2c7b86c5d8284..9064aa14d429f 100644
--- a/src/test/ui/unsized3.stderr
+++ b/src/test/ui/unsized3.stderr
@@ -3,34 +3,33 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
    |
 LL |     f2::<X>(x);
    |     ^^^^^^^ doesn't have a size known at compile-time
+...
+LL | fn f2<X>(x: &X) {
+   | --------------- required by `f2`
    |
    = help: the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
-note: required by `f2`
-  --> $DIR/unsized3.rs:10:1
-   |
-LL | fn f2<X>(x: &X) {
-   | ^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized3.rs:18:5
    |
 LL |     f4::<X>(x);
    |     ^^^^^^^ doesn't have a size known at compile-time
+...
+LL | fn f4<X: T>(x: &X) {
+   | ------------------ required by `f4`
    |
    = help: the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
-note: required by `f4`
-  --> $DIR/unsized3.rs:21:1
-   |
-LL | fn f4<X: T>(x: &X) {
-   | ^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized3.rs:33:5
    |
+LL | fn f5<Y>(x: &Y) {}
+   | --------------- required by `f5`
+...
 LL |     f5(x1);
    |     ^^ doesn't have a size known at compile-time
    |
@@ -38,11 +37,6 @@ LL |     f5(x1);
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: required because it appears within the type `S<X>`
-note: required by `f5`
-  --> $DIR/unsized3.rs:24:1
-   |
-LL | fn f5<Y>(x: &Y) {}
-   | ^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized3.rs:40:5
@@ -72,6 +66,9 @@ LL |     f5(&(32, *x1));
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized3.rs:45:5
    |
+LL | fn f5<Y>(x: &Y) {}
+   | --------------- required by `f5`
+...
 LL |     f5(&(32, *x1));
    |     ^^ doesn't have a size known at compile-time
    |
@@ -80,11 +77,6 @@ LL |     f5(&(32, *x1));
    = help: consider adding a `where X: std::marker::Sized` bound
    = note: required because it appears within the type `S<X>`
    = note: required because it appears within the type `({integer}, S<X>)`
-note: required by `f5`
-  --> $DIR/unsized3.rs:24:1
-   |
-LL | fn f5<Y>(x: &Y) {}
-   | ^^^^^^^^^^^^^^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/wf/wf-const-type.stderr b/src/test/ui/wf/wf-const-type.stderr
index 4df429259ed1f..531aadc25dd2a 100644
--- a/src/test/ui/wf/wf-const-type.stderr
+++ b/src/test/ui/wf/wf-const-type.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `NotCopy: std::marker::Copy` is not satisfied
   --> $DIR/wf-const-type.rs:10:12
    |
+LL | struct IsCopy<T:Copy> { t: T }
+   | --------------------- required by `IsCopy`
+...
 LL | const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
    |            ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `NotCopy`
    |
    = note: required because of the requirements on the impl of `std::marker::Copy` for `std::option::Option<NotCopy>`
-note: required by `IsCopy`
-  --> $DIR/wf-const-type.rs:7:1
-   |
-LL | struct IsCopy<T:Copy> { t: T }
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-enum-bound.stderr b/src/test/ui/wf/wf-enum-bound.stderr
index de28a882f13c3..d5632f4a9c24e 100644
--- a/src/test/ui/wf/wf-enum-bound.stderr
+++ b/src/test/ui/wf/wf-enum-bound.stderr
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied
   --> $DIR/wf-enum-bound.rs:9:1
    |
+LL |   trait ExtraCopy<T:Copy> { }
+   |   ----------------------- required by `ExtraCopy`
+LL | 
 LL | / enum SomeEnum<T,U>
 LL | |     where T: ExtraCopy<U>
 LL | | {
@@ -9,11 +12,6 @@ LL | | }
    | |_^ the trait `std::marker::Copy` is not implemented for `U`
    |
    = help: consider adding a `where U: std::marker::Copy` bound
-note: required by `ExtraCopy`
-  --> $DIR/wf-enum-bound.rs:7:1
-   |
-LL | trait ExtraCopy<T:Copy> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-enum-fields-struct-variant.stderr b/src/test/ui/wf/wf-enum-fields-struct-variant.stderr
index 6c1267cf7e1b4..51ee23fc5aa6d 100644
--- a/src/test/ui/wf/wf-enum-fields-struct-variant.stderr
+++ b/src/test/ui/wf/wf-enum-fields-struct-variant.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `A: std::marker::Copy` is not satisfied
   --> $DIR/wf-enum-fields-struct-variant.rs:13:9
    |
+LL | struct IsCopy<T:Copy> {
+   | --------------------- required by `IsCopy`
+...
 LL |         f: IsCopy<A>
    |         ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `A`
    |
    = help: consider adding a `where A: std::marker::Copy` bound
-note: required by `IsCopy`
-  --> $DIR/wf-enum-fields-struct-variant.rs:7:1
-   |
-LL | struct IsCopy<T:Copy> {
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-enum-fields.stderr b/src/test/ui/wf/wf-enum-fields.stderr
index 9c4eec6c5fbf0..5f4e7c66f54ca 100644
--- a/src/test/ui/wf/wf-enum-fields.stderr
+++ b/src/test/ui/wf/wf-enum-fields.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `A: std::marker::Copy` is not satisfied
   --> $DIR/wf-enum-fields.rs:12:17
    |
+LL | struct IsCopy<T:Copy> {
+   | --------------------- required by `IsCopy`
+...
 LL |     SomeVariant(IsCopy<A>)
    |                 ^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `A`
    |
    = help: consider adding a `where A: std::marker::Copy` bound
-note: required by `IsCopy`
-  --> $DIR/wf-enum-fields.rs:7:1
-   |
-LL | struct IsCopy<T:Copy> {
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-fn-where-clause.stderr b/src/test/ui/wf/wf-fn-where-clause.stderr
index b50e895d8655c..4bc2e370f29fa 100644
--- a/src/test/ui/wf/wf-fn-where-clause.stderr
+++ b/src/test/ui/wf/wf-fn-where-clause.stderr
@@ -1,17 +1,15 @@
 error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied
   --> $DIR/wf-fn-where-clause.rs:8:1
    |
+LL |   trait ExtraCopy<T:Copy> { }
+   |   ----------------------- required by `ExtraCopy`
+LL | 
 LL | / fn foo<T,U>() where T: ExtraCopy<U>
 LL | | {
 LL | | }
    | |_^ the trait `std::marker::Copy` is not implemented for `U`
    |
    = help: consider adding a `where U: std::marker::Copy` bound
-note: required by `ExtraCopy`
-  --> $DIR/wf-fn-where-clause.rs:6:1
-   |
-LL | trait ExtraCopy<T:Copy> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the size for values of type `(dyn std::marker::Copy + 'static)` cannot be known at compilation time
   --> $DIR/wf-fn-where-clause.rs:12:1
diff --git a/src/test/ui/wf/wf-impl-associated-type-trait.stderr b/src/test/ui/wf/wf-impl-associated-type-trait.stderr
index 158b55a3f4165..ceafb4f61578b 100644
--- a/src/test/ui/wf/wf-impl-associated-type-trait.stderr
+++ b/src/test/ui/wf/wf-impl-associated-type-trait.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `T: MyHash` is not satisfied
   --> $DIR/wf-impl-associated-type-trait.rs:17:5
    |
+LL | pub struct MySet<T:MyHash> {
+   | -------------------------- required by `MySet`
+...
 LL |     type Bar = MySet<T>;
    |     ^^^^^^^^^^^^^^^^^^^^ the trait `MyHash` is not implemented for `T`
    |
    = help: consider adding a `where T: MyHash` bound
-note: required by `MySet`
-  --> $DIR/wf-impl-associated-type-trait.rs:8:1
-   |
-LL | pub struct MySet<T:MyHash> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-fn-arg.stderr b/src/test/ui/wf/wf-in-fn-arg.stderr
index 8635dad851667..e7432f8198734 100644
--- a/src/test/ui/wf/wf-in-fn-arg.stderr
+++ b/src/test/ui/wf/wf-in-fn-arg.stderr
@@ -1,17 +1,15 @@
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/wf-in-fn-arg.rs:10:1
    |
+LL |   struct MustBeCopy<T:Copy> {
+   |   ------------------------- required by `MustBeCopy`
+...
 LL | / fn bar<T>(_: &MustBeCopy<T>)
 LL | | {
 LL | | }
    | |_^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
-note: required by `MustBeCopy`
-  --> $DIR/wf-in-fn-arg.rs:6:1
-   |
-LL | struct MustBeCopy<T:Copy> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-fn-ret.stderr b/src/test/ui/wf/wf-in-fn-ret.stderr
index 3879f7b0a4bf0..005ffe84502de 100644
--- a/src/test/ui/wf/wf-in-fn-ret.stderr
+++ b/src/test/ui/wf/wf-in-fn-ret.stderr
@@ -1,17 +1,15 @@
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/wf-in-fn-ret.rs:10:1
    |
+LL |   struct MustBeCopy<T:Copy> {
+   |   ------------------------- required by `MustBeCopy`
+...
 LL | / fn bar<T>() -> MustBeCopy<T>
 LL | | {
 LL | | }
    | |_^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
-note: required by `MustBeCopy`
-  --> $DIR/wf-in-fn-ret.rs:6:1
-   |
-LL | struct MustBeCopy<T:Copy> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-fn-type-arg.stderr b/src/test/ui/wf/wf-in-fn-type-arg.stderr
index 40cb4a7050cca..b4cd921040225 100644
--- a/src/test/ui/wf/wf-in-fn-type-arg.stderr
+++ b/src/test/ui/wf/wf-in-fn-type-arg.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/wf-in-fn-type-arg.rs:9:5
    |
+LL | struct MustBeCopy<T:Copy> {
+   | ------------------------- required by `MustBeCopy`
+...
 LL |     x: fn(MustBeCopy<T>)
    |     ^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
-note: required by `MustBeCopy`
-  --> $DIR/wf-in-fn-type-arg.rs:3:1
-   |
-LL | struct MustBeCopy<T:Copy> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-fn-type-ret.stderr b/src/test/ui/wf/wf-in-fn-type-ret.stderr
index 059f164e25c28..988fbed8e9107 100644
--- a/src/test/ui/wf/wf-in-fn-type-ret.stderr
+++ b/src/test/ui/wf/wf-in-fn-type-ret.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/wf-in-fn-type-ret.rs:9:5
    |
+LL | struct MustBeCopy<T:Copy> {
+   | ------------------------- required by `MustBeCopy`
+...
 LL |     x: fn() -> MustBeCopy<T>
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
-note: required by `MustBeCopy`
-  --> $DIR/wf-in-fn-type-ret.rs:3:1
-   |
-LL | struct MustBeCopy<T:Copy> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-fn-where-clause.stderr b/src/test/ui/wf/wf-in-fn-where-clause.stderr
index 1e732a3341c0b..0af38ddcffea3 100644
--- a/src/test/ui/wf/wf-in-fn-where-clause.stderr
+++ b/src/test/ui/wf/wf-in-fn-where-clause.stderr
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied
   --> $DIR/wf-in-fn-where-clause.rs:9:1
    |
+LL |   trait MustBeCopy<T:Copy> {
+   |   ------------------------ required by `MustBeCopy`
+...
 LL | / fn bar<T,U>()
 LL | |     where T: MustBeCopy<U>
 LL | | {
@@ -8,11 +11,6 @@ LL | | }
    | |_^ the trait `std::marker::Copy` is not implemented for `U`
    |
    = help: consider adding a `where U: std::marker::Copy` bound
-note: required by `MustBeCopy`
-  --> $DIR/wf-in-fn-where-clause.rs:6:1
-   |
-LL | trait MustBeCopy<T:Copy> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-in-obj-type-trait.stderr b/src/test/ui/wf/wf-in-obj-type-trait.stderr
index 2c85dd042e7ba..0f4b4e417ca4f 100644
--- a/src/test/ui/wf/wf-in-obj-type-trait.stderr
+++ b/src/test/ui/wf/wf-in-obj-type-trait.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/wf-in-obj-type-trait.rs:11:5
    |
+LL | struct MustBeCopy<T:Copy> {
+   | ------------------------- required by `MustBeCopy`
+...
 LL |     x: dyn Object<MustBeCopy<T>>
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
-note: required by `MustBeCopy`
-  --> $DIR/wf-in-obj-type-trait.rs:5:1
-   |
-LL | struct MustBeCopy<T:Copy> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr
index b79093f7d0235..1e258864d0367 100644
--- a/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr
+++ b/src/test/ui/wf/wf-inherent-impl-method-where-clause.stderr
@@ -1,16 +1,14 @@
 error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied
   --> $DIR/wf-inherent-impl-method-where-clause.rs:12:5
    |
+LL |   trait ExtraCopy<T:Copy> { }
+   |   ----------------------- required by `ExtraCopy`
+...
 LL | /     fn foo(self) where T: ExtraCopy<U>
 LL | |     {}
    | |______^ the trait `std::marker::Copy` is not implemented for `U`
    |
    = help: consider adding a `where U: std::marker::Copy` bound
-note: required by `ExtraCopy`
-  --> $DIR/wf-inherent-impl-method-where-clause.rs:7:1
-   |
-LL | trait ExtraCopy<T:Copy> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-inherent-impl-where-clause.stderr b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr
index f10ff841acbf6..4c389b3ef3ef2 100644
--- a/src/test/ui/wf/wf-inherent-impl-where-clause.stderr
+++ b/src/test/ui/wf/wf-inherent-impl-where-clause.stderr
@@ -1,17 +1,15 @@
 error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied
   --> $DIR/wf-inherent-impl-where-clause.rs:11:1
    |
+LL |   trait ExtraCopy<T:Copy> { }
+   |   ----------------------- required by `ExtraCopy`
+...
 LL | / impl<T,U> Foo<T,U> where T: ExtraCopy<U>
 LL | | {
 LL | | }
    | |_^ the trait `std::marker::Copy` is not implemented for `U`
    |
    = help: consider adding a `where U: std::marker::Copy` bound
-note: required by `ExtraCopy`
-  --> $DIR/wf-inherent-impl-where-clause.rs:7:1
-   |
-LL | trait ExtraCopy<T:Copy> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-static-type.stderr b/src/test/ui/wf/wf-static-type.stderr
index 4234c7161b1b2..05a628d7c3e19 100644
--- a/src/test/ui/wf/wf-static-type.stderr
+++ b/src/test/ui/wf/wf-static-type.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `NotCopy: std::marker::Copy` is not satisfied
   --> $DIR/wf-static-type.rs:10:13
    |
+LL | struct IsCopy<T:Copy> { t: T }
+   | --------------------- required by `IsCopy`
+...
 LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
    |             ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `NotCopy`
    |
    = note: required because of the requirements on the impl of `std::marker::Copy` for `std::option::Option<NotCopy>`
-note: required by `IsCopy`
-  --> $DIR/wf-static-type.rs:7:1
-   |
-LL | struct IsCopy<T:Copy> { t: T }
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-struct-bound.stderr b/src/test/ui/wf/wf-struct-bound.stderr
index 1fdcced90cc56..2028a0baa17fb 100644
--- a/src/test/ui/wf/wf-struct-bound.stderr
+++ b/src/test/ui/wf/wf-struct-bound.stderr
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied
   --> $DIR/wf-struct-bound.rs:9:1
    |
+LL |   trait ExtraCopy<T:Copy> { }
+   |   ----------------------- required by `ExtraCopy`
+LL | 
 LL | / struct SomeStruct<T,U>
 LL | |     where T: ExtraCopy<U>
 LL | | {
@@ -9,11 +12,6 @@ LL | | }
    | |_^ the trait `std::marker::Copy` is not implemented for `U`
    |
    = help: consider adding a `where U: std::marker::Copy` bound
-note: required by `ExtraCopy`
-  --> $DIR/wf-struct-bound.rs:7:1
-   |
-LL | trait ExtraCopy<T:Copy> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-struct-field.stderr b/src/test/ui/wf/wf-struct-field.stderr
index e609f93ff700b..d2bff253678ee 100644
--- a/src/test/ui/wf/wf-struct-field.stderr
+++ b/src/test/ui/wf/wf-struct-field.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `A: std::marker::Copy` is not satisfied
   --> $DIR/wf-struct-field.rs:12:5
    |
+LL | struct IsCopy<T:Copy> {
+   | --------------------- required by `IsCopy`
+...
 LL |     data: IsCopy<A>
    |     ^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `A`
    |
    = help: consider adding a `where A: std::marker::Copy` bound
-note: required by `IsCopy`
-  --> $DIR/wf-struct-field.rs:7:1
-   |
-LL | struct IsCopy<T:Copy> {
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-associated-type-bound.stderr b/src/test/ui/wf/wf-trait-associated-type-bound.stderr
index 658d41218e483..d5b2b5762a43a 100644
--- a/src/test/ui/wf/wf-trait-associated-type-bound.stderr
+++ b/src/test/ui/wf/wf-trait-associated-type-bound.stderr
@@ -1,17 +1,15 @@
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/wf-trait-associated-type-bound.rs:9:1
    |
+LL |   trait ExtraCopy<T:Copy> { }
+   |   ----------------------- required by `ExtraCopy`
+LL | 
 LL | / trait SomeTrait<T> {
 LL | |     type Type1: ExtraCopy<T>;
 LL | | }
    | |_^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
-note: required by `ExtraCopy`
-  --> $DIR/wf-trait-associated-type-bound.rs:7:1
-   |
-LL | trait ExtraCopy<T:Copy> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-associated-type-trait.stderr b/src/test/ui/wf/wf-trait-associated-type-trait.stderr
index 70fabcd4b3074..d8ab955048239 100644
--- a/src/test/ui/wf/wf-trait-associated-type-trait.stderr
+++ b/src/test/ui/wf/wf-trait-associated-type-trait.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `<Self as SomeTrait>::Type1: std::marker::Copy` is not satisfied
   --> $DIR/wf-trait-associated-type-trait.rs:11:5
    |
+LL | struct IsCopy<T:Copy> { x: T }
+   | --------------------- required by `IsCopy`
+...
 LL |     type Type2 = IsCopy<Self::Type1>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `<Self as SomeTrait>::Type1`
    |
    = help: consider adding a `where <Self as SomeTrait>::Type1: std::marker::Copy` bound
-note: required by `IsCopy`
-  --> $DIR/wf-trait-associated-type-trait.rs:7:1
-   |
-LL | struct IsCopy<T:Copy> { x: T }
-   | ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-bound.stderr b/src/test/ui/wf/wf-trait-bound.stderr
index 5cc9451bf5cac..85f12b2de5489 100644
--- a/src/test/ui/wf/wf-trait-bound.stderr
+++ b/src/test/ui/wf/wf-trait-bound.stderr
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `U: std::marker::Copy` is not satisfied
   --> $DIR/wf-trait-bound.rs:9:1
    |
+LL |   trait ExtraCopy<T:Copy> { }
+   |   ----------------------- required by `ExtraCopy`
+LL | 
 LL | / trait SomeTrait<T,U>
 LL | |     where T: ExtraCopy<U>
 LL | | {
@@ -8,11 +11,6 @@ LL | | }
    | |_^ the trait `std::marker::Copy` is not implemented for `U`
    |
    = help: consider adding a `where U: std::marker::Copy` bound
-note: required by `ExtraCopy`
-  --> $DIR/wf-trait-bound.rs:7:1
-   |
-LL | trait ExtraCopy<T:Copy> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-default-fn-arg.stderr b/src/test/ui/wf/wf-trait-default-fn-arg.stderr
index e713389223654..4d0e1f2f0f4cc 100644
--- a/src/test/ui/wf/wf-trait-default-fn-arg.stderr
+++ b/src/test/ui/wf/wf-trait-default-fn-arg.stderr
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied
   --> $DIR/wf-trait-default-fn-arg.rs:11:5
    |
+LL |   struct Bar<T:Eq+?Sized> { value: Box<T> }
+   |   ----------------------- required by `Bar`
+...
 LL | /     fn bar(&self, x: &Bar<Self>) {
 LL | |
 LL | |         //
@@ -9,11 +12,6 @@ LL | |     }
    | |_____^ the trait `std::cmp::Eq` is not implemented for `Self`
    |
    = help: consider adding a `where Self: std::cmp::Eq` bound
-note: required by `Bar`
-  --> $DIR/wf-trait-default-fn-arg.rs:8:1
-   |
-LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-default-fn-ret.stderr b/src/test/ui/wf/wf-trait-default-fn-ret.stderr
index 5a310a826dd90..e82b76b61c4a9 100644
--- a/src/test/ui/wf/wf-trait-default-fn-ret.stderr
+++ b/src/test/ui/wf/wf-trait-default-fn-ret.stderr
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied
   --> $DIR/wf-trait-default-fn-ret.rs:11:5
    |
+LL |   struct Bar<T:Eq+?Sized> { value: Box<T> }
+   |   ----------------------- required by `Bar`
+...
 LL | /     fn bar(&self) -> Bar<Self> {
 LL | |
 LL | |         //
@@ -10,11 +13,6 @@ LL | |     }
    | |_____^ the trait `std::cmp::Eq` is not implemented for `Self`
    |
    = help: consider adding a `where Self: std::cmp::Eq` bound
-note: required by `Bar`
-  --> $DIR/wf-trait-default-fn-ret.rs:8:1
-   |
-LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr
index d5a00be6d3464..6504f6698d9b1 100644
--- a/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr
+++ b/src/test/ui/wf/wf-trait-default-fn-where-clause.stderr
@@ -1,6 +1,9 @@
 error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied
   --> $DIR/wf-trait-default-fn-where-clause.rs:11:5
    |
+LL |   trait Bar<T:Eq+?Sized> { }
+   |   ---------------------- required by `Bar`
+...
 LL | /     fn bar<A>(&self) where A: Bar<Self> {
 LL | |
 LL | |         //
@@ -9,11 +12,6 @@ LL | |     }
    | |_____^ the trait `std::cmp::Eq` is not implemented for `Self`
    |
    = help: consider adding a `where Self: std::cmp::Eq` bound
-note: required by `Bar`
-  --> $DIR/wf-trait-default-fn-where-clause.rs:8:1
-   |
-LL | trait Bar<T:Eq+?Sized> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-fn-arg.stderr b/src/test/ui/wf/wf-trait-fn-arg.stderr
index 2b26eac9c06b6..0887d4b2fcda2 100644
--- a/src/test/ui/wf/wf-trait-fn-arg.stderr
+++ b/src/test/ui/wf/wf-trait-fn-arg.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied
   --> $DIR/wf-trait-fn-arg.rs:10:5
    |
+LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
+   | ----------------------- required by `Bar`
+...
 LL |     fn bar(&self, x: &Bar<Self>);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Self`
    |
    = help: consider adding a `where Self: std::cmp::Eq` bound
-note: required by `Bar`
-  --> $DIR/wf-trait-fn-arg.rs:7:1
-   |
-LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-fn-ret.stderr b/src/test/ui/wf/wf-trait-fn-ret.stderr
index 70f07f02e93ea..5555081498c61 100644
--- a/src/test/ui/wf/wf-trait-fn-ret.stderr
+++ b/src/test/ui/wf/wf-trait-fn-ret.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied
   --> $DIR/wf-trait-fn-ret.rs:10:5
    |
+LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
+   | ----------------------- required by `Bar`
+...
 LL |     fn bar(&self) -> &Bar<Self>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Self`
    |
    = help: consider adding a `where Self: std::cmp::Eq` bound
-note: required by `Bar`
-  --> $DIR/wf-trait-fn-ret.rs:7:1
-   |
-LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-fn-where-clause.stderr b/src/test/ui/wf/wf-trait-fn-where-clause.stderr
index 2d6223e6d9332..5e8fd8982390d 100644
--- a/src/test/ui/wf/wf-trait-fn-where-clause.stderr
+++ b/src/test/ui/wf/wf-trait-fn-where-clause.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `Self: std::cmp::Eq` is not satisfied
   --> $DIR/wf-trait-fn-where-clause.rs:10:5
    |
+LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
+   | ----------------------- required by `Bar`
+...
 LL |     fn bar(&self) where Self: Sized, Bar<Self>: Copy;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `Self`
    |
    = help: consider adding a `where Self: std::cmp::Eq` bound
-note: required by `Bar`
-  --> $DIR/wf-trait-fn-where-clause.rs:7:1
-   |
-LL | struct Bar<T:Eq+?Sized> { value: Box<T> }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/wf/wf-trait-superbound.stderr b/src/test/ui/wf/wf-trait-superbound.stderr
index a3c4ab58f65f7..377ca640536cf 100644
--- a/src/test/ui/wf/wf-trait-superbound.stderr
+++ b/src/test/ui/wf/wf-trait-superbound.stderr
@@ -1,16 +1,14 @@
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/wf-trait-superbound.rs:9:1
    |
+LL |   trait ExtraCopy<T:Copy> { }
+   |   ----------------------- required by `ExtraCopy`
+LL | 
 LL | / trait SomeTrait<T>: ExtraCopy<T> {
 LL | | }
    | |_^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
-note: required by `ExtraCopy`
-  --> $DIR/wf-trait-superbound.rs:7:1
-   |
-LL | trait ExtraCopy<T:Copy> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
index 125b65b1872e5..f923c6798829f 100644
--- a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
+++ b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/where-clause-constraints-are-local-for-inherent-impl.rs:13:9
    |
+LL | fn require_copy<T: Copy>(x: T) {}
+   | ------------------------------ required by `require_copy`
+...
 LL |         require_copy(self.x);
    |         ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
-note: required by `require_copy`
-  --> $DIR/where-clause-constraints-are-local-for-inherent-impl.rs:1:1
-   |
-LL | fn require_copy<T: Copy>(x: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
index eb555b181f48a..32736836ef8a3 100644
--- a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
+++ b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
@@ -1,15 +1,13 @@
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/where-clause-constraints-are-local-for-trait-impl.rs:18:9
    |
+LL | fn require_copy<T: Copy>(x: T) {}
+   | ------------------------------ required by `require_copy`
+...
 LL |         require_copy(self.x);
    |         ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
-note: required by `require_copy`
-  --> $DIR/where-clause-constraints-are-local-for-trait-impl.rs:1:1
-   |
-LL | fn require_copy<T: Copy>(x: T) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/where-clauses/where-clauses-unsatisfied.stderr b/src/test/ui/where-clauses/where-clauses-unsatisfied.stderr
index fb69e2d141129..e59d6089ea539 100644
--- a/src/test/ui/where-clauses/where-clauses-unsatisfied.stderr
+++ b/src/test/ui/where-clauses/where-clauses-unsatisfied.stderr
@@ -1,14 +1,11 @@
 error[E0277]: the trait bound `Struct: std::cmp::Eq` is not satisfied
   --> $DIR/where-clauses-unsatisfied.rs:6:10
    |
+LL | fn equal<T>(a: &T, b: &T) -> bool where T : Eq { a == b }
+   | ---------------------------------------------- required by `equal`
+...
 LL |     drop(equal(&Struct, &Struct))
    |          ^^^^^ the trait `std::cmp::Eq` is not implemented for `Struct`
-   |
-note: required by `equal`
-  --> $DIR/where-clauses-unsatisfied.rs:1:1
-   |
-LL | fn equal<T>(a: &T, b: &T) -> bool where T : Eq { a == b }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/where-clauses/where-for-self-2.stderr b/src/test/ui/where-clauses/where-for-self-2.stderr
index dbe68b82c24cb..32dc0e7359cbe 100644
--- a/src/test/ui/where-clauses/where-for-self-2.stderr
+++ b/src/test/ui/where-clauses/where-for-self-2.stderr
@@ -1,18 +1,16 @@
 error[E0277]: the trait bound `for<'a> &'a _: Bar` is not satisfied
   --> $DIR/where-for-self-2.rs:21:5
    |
-LL |     foo(&X);
-   |     ^^^ the trait `for<'a> Bar` is not implemented for `&'a _`
-   |
-   = help: the following implementations were found:
-             <&'static u32 as Bar>
-note: required by `foo`
-  --> $DIR/where-for-self-2.rs:16:1
-   |
 LL | / fn foo<T>(x: &T)
 LL | |     where for<'a> &'a T: Bar
 LL | | {}
-   | |__^
+   | |__- required by `foo`
+...
+LL |       foo(&X);
+   |       ^^^ the trait `for<'a> Bar` is not implemented for `&'a _`
+   |
+   = help: the following implementations were found:
+             <&'static u32 as Bar>
 
 error: aborting due to previous error
 

From 5384d5584f6fd596df3a86e2cd4e0281b27d10db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 24 Aug 2019 14:45:03 -0700
Subject: [PATCH 380/943] Suggest call fn ctor passed as arg to fn with type
 param bounds

---
 src/librustc/traits/error_reporting.rs        | 68 +++++++++++++++++--
 ...as-arg-where-it-should-have-been-called.rs | 10 +++
 ...rg-where-it-should-have-been-called.stderr | 14 ++++
 ...as-arg-where-it-should-have-been-called.rs | 18 +++++
 ...rg-where-it-should-have-been-called.stderr | 14 ++++
 5 files changed, 117 insertions(+), 7 deletions(-)
 create mode 100644 src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs
 create mode 100644 src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
 create mode 100644 src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs
 create mode 100644 src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr

diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index aa0fcafbb0e6b..07083f155d62a 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1,20 +1,21 @@
 use super::{
+    ConstEvalFailure,
+    EvaluationResult,
     FulfillmentError,
     FulfillmentErrorCode,
     MismatchedProjectionTypes,
+    ObjectSafetyViolation,
     Obligation,
     ObligationCause,
     ObligationCauseCode,
     OnUnimplementedDirective,
     OnUnimplementedNote,
     OutputTypeParameterMismatch,
-    TraitNotObjectSafe,
-    ConstEvalFailure,
+    Overflow,
     PredicateObligation,
     SelectionContext,
     SelectionError,
-    ObjectSafetyViolation,
-    Overflow,
+    TraitNotObjectSafe,
 };
 
 use crate::hir;
@@ -35,7 +36,7 @@ use crate::util::nodemap::{FxHashMap, FxHashSet};
 use errors::{Applicability, DiagnosticBuilder};
 use std::fmt;
 use syntax::ast;
-use syntax::symbol::sym;
+use syntax::symbol::{sym, kw};
 use syntax_pos::{DUMMY_SP, Span, ExpnKind};
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
@@ -669,8 +670,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                             } else {
                                 format!(
                                     "{}the trait `{}` is not implemented for `{}`",
-                                        pre_message,
-                                        trait_ref,
+                                    pre_message,
+                                    trait_ref,
                                     trait_ref.self_ty(),
                                 )
                             };
@@ -689,6 +690,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         }
 
                         self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
+                        self.suggest_fn_call(&obligation, &mut err, &trait_ref);
                         self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
                         self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref);
 
@@ -956,6 +958,58 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         }
     }
 
+    fn suggest_fn_call(
+        &self,
+        obligation: &PredicateObligation<'tcx>,
+        err: &mut DiagnosticBuilder<'tcx>,
+        trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
+    ) {
+        let self_ty = trait_ref.self_ty();
+        match self_ty.sty {
+            ty::FnDef(def_id, _) => {
+                // We tried to apply the bound to an `fn`. Check wether calling it
+                // would evaluate to a type that *would* satisfy the trait binding.
+                // If it would, suggest calling it: `bar(foo)` -> `bar(foo)`. This
+                // case is *very* to hit if `foo` is `async`.
+                let output_ty = self_ty.fn_sig(self.tcx).output();
+                let new_trait_ref = ty::TraitRef {
+                    def_id: trait_ref.def_id(),
+                    substs: self.tcx.mk_substs_trait(output_ty.skip_binder(), &[]),
+                };
+                let obligation = Obligation::new(
+                    obligation.cause.clone(),
+                    obligation.param_env,
+                    new_trait_ref.to_predicate(),
+                );
+                match self.evaluate_obligation(&obligation) {
+                    Ok(EvaluationResult::EvaluatedToOk) |
+                    Ok(EvaluationResult::EvaluatedToOkModuloRegions) |
+                    Ok(EvaluationResult::EvaluatedToAmbig) => {
+                        if let Some(hir::Node::Item(hir::Item {
+                            ident,
+                            node: hir::ItemKind::Fn(.., body_id),
+                            ..
+                        })) = self.tcx.hir().get_if_local(def_id) {
+                            let body = self.tcx.hir().body(*body_id);
+                            err.help(&format!(
+                                "it looks like you forgot to use parentheses to \
+                                 call the function: `{}({})`",
+                                ident,
+                                body.arguments.iter()
+                                    .map(|arg| match &arg.pat.node {
+                                        hir::PatKind::Binding(_, _, ident, None)
+                                        if ident.name != kw::SelfLower => ident.to_string(),
+                                        _ => "_".to_string(),
+                                    }).collect::<Vec<_>>().join(", ")));
+                        }
+                    }
+                    _ => {}
+                }
+            }
+            _ => {}
+        }
+    }
+
     /// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`,
     /// suggest removing these references until we reach a type that implements the trait.
     fn suggest_remove_reference(
diff --git a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs
new file mode 100644
index 0000000000000..a2d2ba145bc5e
--- /dev/null
+++ b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs
@@ -0,0 +1,10 @@
+// edition:2018
+use std::future::Future;
+
+async fn foo() {}
+
+fn bar(f: impl Future<Output=()>) {}
+
+fn main() {
+    bar(foo); //~ERROR E0277
+}
diff --git a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
new file mode 100644
index 0000000000000..5735f725dc380
--- /dev/null
+++ b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::future::Future` is not satisfied
+  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:5
+   |
+LL | fn bar(f: impl Future<Output=()>) {}
+   | --------------------------------- required by `bar`
+...
+LL |     bar(foo);
+   |     ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
+   |
+   = help: it looks like you forgot to use parentheses to call the function: `foo()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs
new file mode 100644
index 0000000000000..acd149c5854e8
--- /dev/null
+++ b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs
@@ -0,0 +1,18 @@
+// edition:2018
+trait T {
+    type O;
+}
+
+struct S;
+
+impl T for S {
+    type O = ();
+}
+
+fn foo() -> impl T<O=()> { S }
+
+fn bar(f: impl T<O=()>) {}
+
+fn main() {
+    bar(foo); //~ERROR E0277
+}
diff --git a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
new file mode 100644
index 0000000000000..2e4505c740588
--- /dev/null
+++ b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the trait bound `fn() -> impl T {foo}: T` is not satisfied
+  --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:17:5
+   |
+LL | fn bar(f: impl T<O=()>) {}
+   | ----------------------- required by `bar`
+...
+LL |     bar(foo);
+   |     ^^^ the trait `T` is not implemented for `fn() -> impl T {foo}`
+   |
+   = help: it looks like you forgot to use parentheses to call the function: `foo()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.

From 7604eed2a9bf5cf67f9bcf742f030148afb8fe2a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 25 Aug 2019 11:27:04 -0700
Subject: [PATCH 381/943] review comments: reword comment

---
 src/librustc/traits/error_reporting.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 07083f155d62a..ff3626ffb8576 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -967,10 +967,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         let self_ty = trait_ref.self_ty();
         match self_ty.sty {
             ty::FnDef(def_id, _) => {
-                // We tried to apply the bound to an `fn`. Check wether calling it
-                // would evaluate to a type that *would* satisfy the trait binding.
-                // If it would, suggest calling it: `bar(foo)` -> `bar(foo)`. This
-                // case is *very* to hit if `foo` is `async`.
+                // We tried to apply the bound to an `fn`. Check whether calling it would evaluate
+                // to a type that *would* satisfy the trait binding. If it would, suggest calling
+                // it: `bar(foo)` -> `bar(foo)`. This case is *very* likely to be hit if `foo` is
+                // `async`.
                 let output_ty = self_ty.fn_sig(self.tcx).output();
                 let new_trait_ref = ty::TraitRef {
                     def_id: trait_ref.def_id(),

From 9d15b6fb95d7aed3bcadaadaf0516c4733c4f439 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 31 Aug 2019 00:15:52 -0700
Subject: [PATCH 382/943] fix rebase

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

diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index ff3626ffb8576..181efeb2f985b 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -995,7 +995,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                 "it looks like you forgot to use parentheses to \
                                  call the function: `{}({})`",
                                 ident,
-                                body.arguments.iter()
+                                body.params.iter()
                                     .map(|arg| match &arg.pat.node {
                                         hir::PatKind::Binding(_, _, ident, None)
                                         if ident.name != kw::SelfLower => ident.to_string(),

From c621919deb00448e2287213a0d0bc65ff382af66 Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sat, 31 Aug 2019 15:35:20 +0100
Subject: [PATCH 383/943] Kill borrows from assignments after generating new
 borrows

---
 src/librustc_mir/dataflow/impls/borrows.rs |  8 ++++----
 src/test/ui/nll/self-assign-ref-mut.rs     | 20 ++++++++++++++++++++
 2 files changed, 24 insertions(+), 4 deletions(-)
 create mode 100644 src/test/ui/nll/self-assign-ref-mut.rs

diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index 018fd2e97b264..2ea6c4ae10fdc 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -269,10 +269,6 @@ impl<'a, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'tcx> {
         debug!("Borrows::statement_effect: stmt={:?}", stmt);
         match stmt.kind {
             mir::StatementKind::Assign(ref lhs, ref rhs) => {
-                // Make sure there are no remaining borrows for variables
-                // that are assigned over.
-                self.kill_borrows_on_place(trans, lhs);
-
                 if let mir::Rvalue::Ref(_, _, ref place) = **rhs {
                     if place.ignore_borrow(
                         self.tcx,
@@ -287,6 +283,10 @@ impl<'a, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'tcx> {
 
                     trans.gen(*index);
                 }
+
+                // Make sure there are no remaining borrows for variables
+                // that are assigned over.
+                self.kill_borrows_on_place(trans, lhs);
             }
 
             mir::StatementKind::StorageDead(local) => {
diff --git a/src/test/ui/nll/self-assign-ref-mut.rs b/src/test/ui/nll/self-assign-ref-mut.rs
new file mode 100644
index 0000000000000..1ca4cf3a775ca
--- /dev/null
+++ b/src/test/ui/nll/self-assign-ref-mut.rs
@@ -0,0 +1,20 @@
+// Check that `*y` isn't borrowed after `y = y`.
+
+// check-pass
+
+fn main() {
+    let mut x = 1;
+    {
+        let mut y = &mut x;
+        y = y;
+        y;
+    }
+    x;
+    {
+        let mut y = &mut x;
+        y = y;
+        y = y;
+        y;
+    }
+    x;
+}

From c8e474871ab5c13b0bdd92caecfb0bbc99f96541 Mon Sep 17 00:00:00 2001
From: John Erickson <john.t.erickson@gmail.com>
Date: Fri, 9 Aug 2019 06:49:10 -0700
Subject: [PATCH 384/943] Update BufWriter example to include call to flush()

---
 src/libstd/io/buffered.rs | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index aaf628e6c260f..70d80a2ea9025 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -364,10 +364,10 @@ impl<R: Seek> Seek for BufReader<R> {
 /// times. It also provides no advantage when writing to a destination that is
 /// in memory, like a `Vec<u8>`.
 ///
-/// When the `BufWriter` is dropped, the contents of its buffer will be written
-/// out. However, any errors that happen in the process of flushing the buffer
-/// when the writer is dropped will be ignored. Code that wishes to handle such
-/// errors must manually call [`flush`] before the writer is dropped.
+/// It is critical to call [`flush`] before `BufWriter` is dropped. Though
+/// dropping will attempt to flush the the contents of the buffer, any errors
+/// that happen in the process will be ignored. Calling ['flush'] ensures that
+/// the buffer is empty and all errors have been observed.
 ///
 /// # Examples
 ///
@@ -398,11 +398,12 @@ impl<R: Seek> Seek for BufReader<R> {
 /// for i in 0..10 {
 ///     stream.write(&[i+1]).unwrap();
 /// }
+/// stream.flush().unwrap();
 /// ```
 ///
 /// By wrapping the stream with a `BufWriter`, these ten writes are all grouped
-/// together by the buffer, and will all be written out in one system call when
-/// the `stream` is dropped.
+/// together by the buffer and will all be written out in one system call when
+/// the `stream` is flushed.
 ///
 /// [`Write`]: ../../std/io/trait.Write.html
 /// [`TcpStream::write`]: ../../std/net/struct.TcpStream.html#method.write

From cccce09dda14a3a76a61fc3abade19479a927534 Mon Sep 17 00:00:00 2001
From: John Erickson <john.t.erickson@gmail.com>
Date: Fri, 9 Aug 2019 07:36:39 -0700
Subject: [PATCH 385/943] Add in generic type to description of BufReader and
 BufWriter

---
 src/libstd/io/buffered.rs | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 70d80a2ea9025..2dc7d6fe6d2ac 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -9,21 +9,21 @@ use crate::io::{self, Initializer, DEFAULT_BUF_SIZE, Error, ErrorKind, SeekFrom,
         IoSliceMut};
 use crate::memchr;
 
-/// The `BufReader` struct adds buffering to any reader.
+/// The `BufReader<R>` struct adds buffering to any reader.
 ///
 /// It can be excessively inefficient to work directly with a [`Read`] instance.
 /// For example, every call to [`read`][`TcpStream::read`] on [`TcpStream`]
-/// results in a system call. A `BufReader` performs large, infrequent reads on
+/// results in a system call. A `BufReader<R>` performs large, infrequent reads on
 /// the underlying [`Read`] and maintains an in-memory buffer of the results.
 ///
-/// `BufReader` can improve the speed of programs that make *small* and
+/// `BufReader<R>` can improve the speed of programs that make *small* and
 /// *repeated* read calls to the same file or network socket. It does not
 /// help when reading very large amounts at once, or reading just one or a few
 /// times. It also provides no advantage when reading from a source that is
 /// already in memory, like a `Vec<u8>`.
 ///
-/// When the `BufReader` is dropped, the contents of its buffer will be
-/// discarded. Creating multiple instances of a `BufReader` on the same
+/// When the `BufReader<R>` is dropped, the contents of its buffer will be
+/// discarded. Creating multiple instances of a `BufReader<R>` on the same
 /// stream can cause data loss.
 ///
 /// [`Read`]: ../../std/io/trait.Read.html
@@ -56,7 +56,7 @@ pub struct BufReader<R> {
 }
 
 impl<R: Read> BufReader<R> {
-    /// Creates a new `BufReader` with a default buffer capacity. The default is currently 8 KB,
+    /// Creates a new `BufReader<R>` with a default buffer capacity. The default is currently 8 KB,
     /// but may change in the future.
     ///
     /// # Examples
@@ -76,7 +76,7 @@ impl<R: Read> BufReader<R> {
         BufReader::with_capacity(DEFAULT_BUF_SIZE, inner)
     }
 
-    /// Creates a new `BufReader` with the specified buffer capacity.
+    /// Creates a new `BufReader<R>` with the specified buffer capacity.
     ///
     /// # Examples
     ///
@@ -177,7 +177,7 @@ impl<R> BufReader<R> {
         &self.buf[self.pos..self.cap]
     }
 
-    /// Unwraps this `BufReader`, returning the underlying reader.
+    /// Unwraps this `BufReader<R>`, returning the underlying reader.
     ///
     /// Note that any leftover data in the internal buffer is lost.
     ///
@@ -304,7 +304,7 @@ impl<R: Seek> Seek for BufReader<R> {
     /// Seek to an offset, in bytes, in the underlying reader.
     ///
     /// The position used for seeking with `SeekFrom::Current(_)` is the
-    /// position the underlying reader would be at if the `BufReader` had no
+    /// position the underlying reader would be at if the `BufReader<R>` had no
     /// internal buffer.
     ///
     /// Seeking always discards the internal buffer, even if the seek position
@@ -355,16 +355,16 @@ impl<R: Seek> Seek for BufReader<R> {
 /// It can be excessively inefficient to work directly with something that
 /// implements [`Write`]. For example, every call to
 /// [`write`][`TcpStream::write`] on [`TcpStream`] results in a system call. A
-/// `BufWriter` keeps an in-memory buffer of data and writes it to an underlying
+/// `BufWriter<W>` keeps an in-memory buffer of data and writes it to an underlying
 /// writer in large, infrequent batches.
 ///
-/// `BufWriter` can improve the speed of programs that make *small* and
+/// `BufWriter<W>` can improve the speed of programs that make *small* and
 /// *repeated* write calls to the same file or network socket. It does not
 /// help when writing very large amounts at once, or writing just one or a few
 /// times. It also provides no advantage when writing to a destination that is
 /// in memory, like a `Vec<u8>`.
 ///
-/// It is critical to call [`flush`] before `BufWriter` is dropped. Though
+/// It is critical to call [`flush`] before `BufWriter<W>` is dropped. Though
 /// dropping will attempt to flush the the contents of the buffer, any errors
 /// that happen in the process will be ignored. Calling ['flush'] ensures that
 /// the buffer is empty and all errors have been observed.
@@ -386,7 +386,7 @@ impl<R: Seek> Seek for BufReader<R> {
 ///
 /// Because we're not buffering, we write each one in turn, incurring the
 /// overhead of a system call per byte written. We can fix this with a
-/// `BufWriter`:
+/// `BufWriter<W>`:
 ///
 /// ```no_run
 /// use std::io::prelude::*;
@@ -401,7 +401,7 @@ impl<R: Seek> Seek for BufReader<R> {
 /// stream.flush().unwrap();
 /// ```
 ///
-/// By wrapping the stream with a `BufWriter`, these ten writes are all grouped
+/// By wrapping the stream with a `BufWriter<W>`, these ten writes are all grouped
 /// together by the buffer and will all be written out in one system call when
 /// the `stream` is flushed.
 ///
@@ -448,7 +448,7 @@ pub struct BufWriter<W: Write> {
 pub struct IntoInnerError<W>(W, Error);
 
 impl<W: Write> BufWriter<W> {
-    /// Creates a new `BufWriter` with a default buffer capacity. The default is currently 8 KB,
+    /// Creates a new `BufWriter<W>` with a default buffer capacity. The default is currently 8 KB,
     /// but may change in the future.
     ///
     /// # Examples
@@ -464,7 +464,7 @@ impl<W: Write> BufWriter<W> {
         BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
     }
 
-    /// Creates a new `BufWriter` with the specified buffer capacity.
+    /// Creates a new `BufWriter<W>` with the specified buffer capacity.
     ///
     /// # Examples
     ///
@@ -565,7 +565,7 @@ impl<W: Write> BufWriter<W> {
         &self.buf
     }
 
-    /// Unwraps this `BufWriter`, returning the underlying writer.
+    /// Unwraps this `BufWriter<W>`, returning the underlying writer.
     ///
     /// The buffer is written out before returning the writer.
     ///

From 1b946106b7955d3dcde26719b9b62a5a2c4b78fe Mon Sep 17 00:00:00 2001
From: John Erickson <john.t.erickson@gmail.com>
Date: Mon, 12 Aug 2019 15:36:11 -0700
Subject: [PATCH 386/943] clarify that not all errors are observed

---
 src/libstd/io/buffered.rs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index 2dc7d6fe6d2ac..9593a1bae0a3c 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -366,8 +366,9 @@ impl<R: Seek> Seek for BufReader<R> {
 ///
 /// It is critical to call [`flush`] before `BufWriter<W>` is dropped. Though
 /// dropping will attempt to flush the the contents of the buffer, any errors
-/// that happen in the process will be ignored. Calling ['flush'] ensures that
-/// the buffer is empty and all errors have been observed.
+/// that happen in the process of dropping will be ignored. Calling ['flush']
+/// ensures that the buffer is empty and thus dropping will not even attempt
+/// file operations.
 ///
 /// # Examples
 ///

From 7bb2d8b0765e6737f43b501135d91bc8ab64db7a Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sat, 31 Aug 2019 15:43:24 +0100
Subject: [PATCH 387/943] Slightly clean up the error for recursive `async fn`

* Make it clear that type erasure is required, not just pointer
  indirection.
* Don't make the message specific to direct recursion.
---
 src/librustc_typeck/check/mod.rs                              | 4 ++--
 .../ui/async-await/recursive-async-impl-trait-type.stderr     | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a80550486d627..7855008a28221 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1420,8 +1420,8 @@ fn check_opaque_for_cycles<'tcx>(
                 tcx.sess, span, E0733,
                 "recursion in an `async fn` requires boxing",
             )
-            .span_label(span, "an `async fn` cannot invoke itself directly")
-            .note("a recursive `async fn` must be rewritten to return a boxed future.")
+            .span_label(span, "recursive `async fn`")
+            .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
             .emit();
         } else {
             let mut err = struct_span_err!(
diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
index 8781a9c444d0a..9ee014021804e 100644
--- a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
+++ b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
@@ -2,9 +2,9 @@ error[E0733]: recursion in an `async fn` requires boxing
   --> $DIR/recursive-async-impl-trait-type.rs:5:40
    |
 LL | async fn recursive_async_function() -> () {
-   |                                        ^^ an `async fn` cannot invoke itself directly
+   |                                        ^^ recursive `async fn`
    |
-   = note: a recursive `async fn` must be rewritten to return a boxed future.
+   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
 
 error: aborting due to previous error
 

From 877faf38440ada48b0c27100fa3c456b35bc5612 Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sat, 31 Aug 2019 15:44:09 +0100
Subject: [PATCH 388/943] Check impl trait substs when checking for recursive
 types

This prevents mutual `async fn` recursion
---
 src/librustc/ty/util.rs                       |  6 ++--
 ...utually-recursive-async-impl-trait-type.rs | 13 +++++++
 ...lly-recursive-async-impl-trait-type.stderr | 19 ++++++++++
 ...-impl-trait-type--through-non-recursize.rs | 25 +++++++++++++
 ...l-trait-type--through-non-recursize.stderr | 35 +++++++++++++++++++
 5 files changed, 96 insertions(+), 2 deletions(-)
 create mode 100644 src/test/ui/async-await/mutually-recursive-async-impl-trait-type.rs
 create mode 100644 src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr
 create mode 100644 src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.rs
 create mode 100644 src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr

diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 7a77418050cdb..a08c82a0ae82f 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -709,8 +709,10 @@ impl<'tcx> TyCtxt<'tcx> {
                 substs: SubstsRef<'tcx>,
             ) -> Option<Ty<'tcx>> {
                 if self.found_recursion {
-                    None
-                } else if self.seen_opaque_tys.insert(def_id) {
+                    return None;
+                }
+                let substs = substs.fold_with(self);
+                if self.seen_opaque_tys.insert(def_id) {
                     let generic_ty = self.tcx.type_of(def_id);
                     let concrete_ty = generic_ty.subst(self.tcx, substs);
                     let expanded_ty = self.fold_ty(concrete_ty);
diff --git a/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.rs b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.rs
new file mode 100644
index 0000000000000..bb2a61f03ce1f
--- /dev/null
+++ b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.rs
@@ -0,0 +1,13 @@
+// edition:2018
+// Test that impl trait does not allow creating recursive types that are
+// otherwise forbidden when using `async` and `await`.
+
+async fn rec_1() { //~ ERROR recursion in an `async fn`
+    rec_2().await;
+}
+
+async fn rec_2() { //~ ERROR recursion in an `async fn`
+    rec_1().await;
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr
new file mode 100644
index 0000000000000..9249308936e54
--- /dev/null
+++ b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr
@@ -0,0 +1,19 @@
+error[E0733]: recursion in an `async fn` requires boxing
+  --> $DIR/mutually-recursive-async-impl-trait-type.rs:5:18
+   |
+LL | async fn rec_1() {
+   |                  ^ recursive `async fn`
+   |
+   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
+
+error[E0733]: recursion in an `async fn` requires boxing
+  --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18
+   |
+LL | async fn rec_2() {
+   |                  ^ recursive `async fn`
+   |
+   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0733`.
diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.rs b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.rs
new file mode 100644
index 0000000000000..cfd9c0ec5b45b
--- /dev/null
+++ b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.rs
@@ -0,0 +1,25 @@
+// Test that impl trait does not allow creating recursive types that are
+// otherwise forbidden. Even when there's an opaque type in another crate
+// hiding this.
+
+fn id<T>(t: T) -> impl Sized { t }
+
+fn recursive_id() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+    id(recursive_id2())
+}
+
+fn recursive_id2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+    id(recursive_id())
+}
+
+fn wrap<T>(t: T) -> impl Sized { (t,) }
+
+fn recursive_wrap() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+    wrap(recursive_wrap2())
+}
+
+fn recursive_wrap2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+    wrap(recursive_wrap())
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr
new file mode 100644
index 0000000000000..7572c6c1bf057
--- /dev/null
+++ b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr
@@ -0,0 +1,35 @@
+error[E0720]: opaque type expands to a recursive type
+  --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:7:22
+   |
+LL | fn recursive_id() -> impl Sized {
+   |                      ^^^^^^^^^^ expands to a recursive type
+   |
+   = note: type resolves to itself
+
+error[E0720]: opaque type expands to a recursive type
+  --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:11:23
+   |
+LL | fn recursive_id2() -> impl Sized {
+   |                       ^^^^^^^^^^ expands to a recursive type
+   |
+   = note: type resolves to itself
+
+error[E0720]: opaque type expands to a recursive type
+  --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:17:24
+   |
+LL | fn recursive_wrap() -> impl Sized {
+   |                        ^^^^^^^^^^ expands to a recursive type
+   |
+   = note: expanded type is `((impl Sized,),)`
+
+error[E0720]: opaque type expands to a recursive type
+  --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:21:25
+   |
+LL | fn recursive_wrap2() -> impl Sized {
+   |                         ^^^^^^^^^^ expands to a recursive type
+   |
+   = note: expanded type is `((impl Sized,),)`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0720`.

From e2e1175ce25b6a69954b0ad3cdb15c1b684b1d92 Mon Sep 17 00:00:00 2001
From: Ivan Tham <pickfire@riseup.net>
Date: Sat, 31 Aug 2019 23:09:37 +0800
Subject: [PATCH 389/943] Update sync condvar doc style

---
 src/libstd/sync/condvar.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index aeff57716e86b..65ce19f2a1b3a 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -28,14 +28,14 @@ impl WaitTimeoutResult {
     /// once the boolean has been updated and notified.
     ///
     /// ```
-    /// use std::sync::{Arc, Mutex, Condvar};
+    /// use std::sync::{Arc, Condvar, Mutex};
     /// use std::thread;
     /// use std::time::Duration;
     ///
     /// let pair = Arc::new((Mutex::new(false), Condvar::new()));
     /// let pair2 = pair.clone();
     ///
-    /// thread::spawn(move|| {
+    /// thread::spawn(move || {
     ///     let (lock, cvar) = &*pair2;
     ///
     ///     // Let's wait 20 milliseconds before notifying the condvar.

From 823c3b984541b13c2083b7bd8025d8d679a2c13b Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Sat, 31 Aug 2019 17:01:56 +0200
Subject: [PATCH 390/943] Improve documentation around allocation accessors

---
 src/librustc/mir/interpret/allocation.rs | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index 8f47bf9d0fd5a..8e824aeb7916a 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -581,8 +581,10 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
 /// Run-length encoding of the undef mask.
 /// Used to copy parts of a mask multiple times to another allocation.
 pub struct AllocationDefinedness {
+    /// The lengths of ranges that are run-length encoded.
     ranges: smallvec::SmallVec::<[u64; 1]>,
-    first: bool,
+    /// The definedness of the first range.
+    initial: bool,
 }
 
 /// Transferring the definedness mask to other allocations.
@@ -606,9 +608,9 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
         // where each element toggles the state
 
         let mut ranges = smallvec::SmallVec::<[u64; 1]>::new();
-        let first = self.undef_mask.get(src.offset);
+        let initial = self.undef_mask.get(src.offset);
         let mut cur_len = 1;
-        let mut cur = first;
+        let mut cur = initial;
 
         for i in 1..size.bytes() {
             // FIXME: optimize to bitshift the current undef block's bits and read the top bit
@@ -623,7 +625,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
 
         ranges.push(cur_len);
 
-        AllocationDefinedness { ranges, first, }
+        AllocationDefinedness { ranges, initial, }
     }
 
     /// Apply multiple instances of the run-length encoding to the undef_mask.
@@ -640,7 +642,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
             self.undef_mask.set_range_inbounds(
                 dest.offset,
                 dest.offset + size * repeat,
-                defined.first,
+                defined.initial,
             );
             return;
         }
@@ -648,7 +650,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
         for mut j in 0..repeat {
             j *= size.bytes();
             j += dest.offset.bytes();
-            let mut cur = defined.first;
+            let mut cur = defined.initial;
             for range in &defined.ranges {
                 let old_j = j;
                 j += range;
@@ -725,9 +727,9 @@ impl<Tag: Copy, Extra> Allocation<Tag, Extra> {
                         // shift offsets from source allocation to destination allocation
                         offset + dest_offset - src.offset,
                         reloc,
-                        )
+                    )
                 })
-                );
+            );
         }
 
         AllocationRelocations {
@@ -735,6 +737,9 @@ impl<Tag: Copy, Extra> Allocation<Tag, Extra> {
         }
     }
 
+    /// Apply a relocation copy.
+    /// The affected range, as defined in the parameters to `prepare_relocation_copy` is expected
+    /// to be clear of relocations.
     pub fn mark_relocation_range(
         &mut self,
         relocations: AllocationRelocations<Tag>,

From 754a875e15f778ed5bdd49b4208956b3003949c4 Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sat, 31 Aug 2019 16:31:50 +0100
Subject: [PATCH 391/943] Add some more tests for underscore imports

---
 .../auxiliary/duplicate.rs                    |  0
 .../auxiliary/underscore-imports.rs           |  0
 .../basic.rs                                  |  0
 .../basic.stderr                              |  0
 src/test/ui/underscore-imports/cycle.rs       | 18 +++++++++++++++
 .../duplicate.rs                              |  0
 .../intercrate.rs                             |  0
 src/test/ui/underscore-imports/shadow.rs      | 23 +++++++++++++++++++
 src/test/ui/underscore-imports/shadow.stderr  | 13 +++++++++++
 .../unused-2018.rs                            |  0
 .../unused-2018.stderr                        |  0
 11 files changed, 54 insertions(+)
 rename src/test/ui/{rfc-2166-underscore-imports => underscore-imports}/auxiliary/duplicate.rs (100%)
 rename src/test/ui/{rfc-2166-underscore-imports => underscore-imports}/auxiliary/underscore-imports.rs (100%)
 rename src/test/ui/{rfc-2166-underscore-imports => underscore-imports}/basic.rs (100%)
 rename src/test/ui/{rfc-2166-underscore-imports => underscore-imports}/basic.stderr (100%)
 create mode 100644 src/test/ui/underscore-imports/cycle.rs
 rename src/test/ui/{rfc-2166-underscore-imports => underscore-imports}/duplicate.rs (100%)
 rename src/test/ui/{rfc-2166-underscore-imports => underscore-imports}/intercrate.rs (100%)
 create mode 100644 src/test/ui/underscore-imports/shadow.rs
 create mode 100644 src/test/ui/underscore-imports/shadow.stderr
 rename src/test/ui/{rfc-2166-underscore-imports => underscore-imports}/unused-2018.rs (100%)
 rename src/test/ui/{rfc-2166-underscore-imports => underscore-imports}/unused-2018.stderr (100%)

diff --git a/src/test/ui/rfc-2166-underscore-imports/auxiliary/duplicate.rs b/src/test/ui/underscore-imports/auxiliary/duplicate.rs
similarity index 100%
rename from src/test/ui/rfc-2166-underscore-imports/auxiliary/duplicate.rs
rename to src/test/ui/underscore-imports/auxiliary/duplicate.rs
diff --git a/src/test/ui/rfc-2166-underscore-imports/auxiliary/underscore-imports.rs b/src/test/ui/underscore-imports/auxiliary/underscore-imports.rs
similarity index 100%
rename from src/test/ui/rfc-2166-underscore-imports/auxiliary/underscore-imports.rs
rename to src/test/ui/underscore-imports/auxiliary/underscore-imports.rs
diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.rs b/src/test/ui/underscore-imports/basic.rs
similarity index 100%
rename from src/test/ui/rfc-2166-underscore-imports/basic.rs
rename to src/test/ui/underscore-imports/basic.rs
diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.stderr b/src/test/ui/underscore-imports/basic.stderr
similarity index 100%
rename from src/test/ui/rfc-2166-underscore-imports/basic.stderr
rename to src/test/ui/underscore-imports/basic.stderr
diff --git a/src/test/ui/underscore-imports/cycle.rs b/src/test/ui/underscore-imports/cycle.rs
new file mode 100644
index 0000000000000..bacf9b2d5a96a
--- /dev/null
+++ b/src/test/ui/underscore-imports/cycle.rs
@@ -0,0 +1,18 @@
+// Check that cyclic glob imports are allowed with underscore imports
+
+// check-pass
+
+mod x {
+    pub use crate::y::*;
+    pub use std::ops::Deref as _;
+}
+
+mod y {
+    pub use crate::x::*;
+    pub use std::ops::Deref as _;
+}
+
+pub fn main() {
+    use x::*;
+    (&0).deref();
+}
diff --git a/src/test/ui/rfc-2166-underscore-imports/duplicate.rs b/src/test/ui/underscore-imports/duplicate.rs
similarity index 100%
rename from src/test/ui/rfc-2166-underscore-imports/duplicate.rs
rename to src/test/ui/underscore-imports/duplicate.rs
diff --git a/src/test/ui/rfc-2166-underscore-imports/intercrate.rs b/src/test/ui/underscore-imports/intercrate.rs
similarity index 100%
rename from src/test/ui/rfc-2166-underscore-imports/intercrate.rs
rename to src/test/ui/underscore-imports/intercrate.rs
diff --git a/src/test/ui/underscore-imports/shadow.rs b/src/test/ui/underscore-imports/shadow.rs
new file mode 100644
index 0000000000000..325f2001b9ede
--- /dev/null
+++ b/src/test/ui/underscore-imports/shadow.rs
@@ -0,0 +1,23 @@
+// Check that underscore imports don't cause glob imports to be unshadowed
+
+mod a {
+    pub use std::ops::Deref as Shadow;
+}
+
+mod b {
+    pub use crate::a::*;
+    macro_rules! m {
+        ($i:ident) => { pub struct $i; }
+    }
+    m!(Shadow);
+}
+
+mod c {
+    use crate::b::Shadow as _; // Only imports the struct
+
+    fn f(x: &()) {
+        x.deref(); //~ ERROR no method named `deref` found
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/underscore-imports/shadow.stderr b/src/test/ui/underscore-imports/shadow.stderr
new file mode 100644
index 0000000000000..92adca2c70490
--- /dev/null
+++ b/src/test/ui/underscore-imports/shadow.stderr
@@ -0,0 +1,13 @@
+error[E0599]: no method named `deref` found for type `&()` in the current scope
+  --> $DIR/shadow.rs:19:11
+   |
+LL |         x.deref();
+   |           ^^^^^
+   |
+   = help: items from traits can only be used if the trait is in scope
+   = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
+           `use std::ops::Deref;`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/rfc-2166-underscore-imports/unused-2018.rs b/src/test/ui/underscore-imports/unused-2018.rs
similarity index 100%
rename from src/test/ui/rfc-2166-underscore-imports/unused-2018.rs
rename to src/test/ui/underscore-imports/unused-2018.rs
diff --git a/src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr b/src/test/ui/underscore-imports/unused-2018.stderr
similarity index 100%
rename from src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr
rename to src/test/ui/underscore-imports/unused-2018.stderr

From c4d0c285fe19a921e75002866b2cfdf1d0f59370 Mon Sep 17 00:00:00 2001
From: Julian Gehring <juliangehring@users.noreply.github.com>
Date: Sat, 31 Aug 2019 17:36:55 +0100
Subject: [PATCH 392/943] Fix word repetition in str documentation

Fixes a few repetitions of "like like" in the `trim*` methods documentation of `str`.
---
 src/libcore/str/mod.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index 752c372e93e3a..5e5b5593fd8a7 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -3558,7 +3558,7 @@ impl str {
     /// A string is a sequence of bytes. `start` in this context means the first
     /// position of that byte string; for a left-to-right language like English or
     /// Russian, this will be left side, and for right-to-left languages like
-    /// like Arabic or Hebrew, this will be the right side.
+    /// Arabic or Hebrew, this will be the right side.
     ///
     /// # Examples
     ///
@@ -3595,7 +3595,7 @@ impl str {
     /// A string is a sequence of bytes. `end` in this context means the last
     /// position of that byte string; for a left-to-right language like English or
     /// Russian, this will be right side, and for right-to-left languages like
-    /// like Arabic or Hebrew, this will be the left side.
+    /// Arabic or Hebrew, this will be the left side.
     ///
     /// # Examples
     ///
@@ -3762,7 +3762,7 @@ impl str {
     /// A string is a sequence of bytes. `start` in this context means the first
     /// position of that byte string; for a left-to-right language like English or
     /// Russian, this will be left side, and for right-to-left languages like
-    /// like Arabic or Hebrew, this will be the right side.
+    /// Arabic or Hebrew, this will be the right side.
     ///
     /// # Examples
     ///
@@ -3801,7 +3801,7 @@ impl str {
     /// A string is a sequence of bytes. `end` in this context means the last
     /// position of that byte string; for a left-to-right language like English or
     /// Russian, this will be right side, and for right-to-left languages like
-    /// like Arabic or Hebrew, this will be the left side.
+    /// Arabic or Hebrew, this will be the left side.
     ///
     /// # Examples
     ///

From f3c435eb780dec5c1d390a3b43cdfb4f1528d70d Mon Sep 17 00:00:00 2001
From: Andreas Molzer <andreas.molzer@gmx.de>
Date: Sat, 31 Aug 2019 21:21:29 +0200
Subject: [PATCH 393/943] Reorder AllocationDefinedness members

This improves the clarity of the documentation a bit since they can
reference each other when reading the member docs in sequence.
---
 src/librustc/mir/interpret/allocation.rs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index 8e824aeb7916a..db24c14083768 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -581,10 +581,11 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
 /// Run-length encoding of the undef mask.
 /// Used to copy parts of a mask multiple times to another allocation.
 pub struct AllocationDefinedness {
-    /// The lengths of ranges that are run-length encoded.
-    ranges: smallvec::SmallVec::<[u64; 1]>,
     /// The definedness of the first range.
     initial: bool,
+    /// The lengths of ranges that are run-length encoded.
+    /// The definedness of the ranges alternate starting with `initial`.
+    ranges: smallvec::SmallVec::<[u64; 1]>,
 }
 
 /// Transferring the definedness mask to other allocations.

From aee6cd937a3fff26a5d13f0a8570cafe5fb8a11c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 31 Aug 2019 13:40:20 -0700
Subject: [PATCH 394/943] Fix nll tests

---
 .../expect-fn-supply-fn.nll.stderr            | 45 ++++++++-----------
 .../ui/kindck/kindck-send-object1.nll.stderr  | 16 +++----
 2 files changed, 24 insertions(+), 37 deletions(-)

diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr
index 7e4ac4e8ce656..565c60e5216dd 100644
--- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr
@@ -1,53 +1,44 @@
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:30:5
    |
-LL |     with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
-   |     |
-   |     expected signature of `fn(fn(&'a u32), &i32) -> _`
-   |
-note: required by `with_closure_expecting_fn_with_free_region`
-  --> $DIR/expect-fn-supply-fn.rs:1:1
-   |
 LL | / fn with_closure_expecting_fn_with_free_region<F>(_: F)
 LL | |     where F: for<'a> FnOnce(fn(&'a u32), &i32)
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `with_closure_expecting_fn_with_free_region`
+...
+LL |       with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
+   |       |
+   |       expected signature of `fn(fn(&'a u32), &i32) -> _`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:37:5
    |
-LL |     with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
-   |     |
-   |     expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
-   |
-note: required by `with_closure_expecting_fn_with_bound_region`
-  --> $DIR/expect-fn-supply-fn.rs:6:1
-   |
 LL | / fn with_closure_expecting_fn_with_bound_region<F>(_: F)
 LL | |     where F: FnOnce(fn(&u32), &i32)
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `with_closure_expecting_fn_with_bound_region`
+...
+LL |       with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
+   |       |
+   |       expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:46:5
    |
-LL |     with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
-   |     |
-   |     expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
-   |
-note: required by `with_closure_expecting_fn_with_bound_region`
-  --> $DIR/expect-fn-supply-fn.rs:6:1
-   |
 LL | / fn with_closure_expecting_fn_with_bound_region<F>(_: F)
 LL | |     where F: FnOnce(fn(&u32), &i32)
 LL | | {
 LL | | }
-   | |_^
+   | |_- required by `with_closure_expecting_fn_with_bound_region`
+...
+LL |       with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
+   |       |
+   |       expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/kindck/kindck-send-object1.nll.stderr b/src/test/ui/kindck/kindck-send-object1.nll.stderr
index 998dc90456f14..c7d18cd8b8bb1 100644
--- a/src/test/ui/kindck/kindck-send-object1.nll.stderr
+++ b/src/test/ui/kindck/kindck-send-object1.nll.stderr
@@ -1,31 +1,27 @@
 error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely
   --> $DIR/kindck-send-object1.rs:10:5
    |
+LL | fn assert_send<T:Send+'static>() { }
+   | -------------------------------- required by `assert_send`
+...
 LL |     assert_send::<&'a dyn Dummy>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `(dyn Dummy + 'a)`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&'a (dyn Dummy + 'a)`
-note: required by `assert_send`
-  --> $DIR/kindck-send-object1.rs:5:1
-   |
-LL | fn assert_send<T:Send+'static>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely
   --> $DIR/kindck-send-object1.rs:29:5
    |
+LL | fn assert_send<T:Send+'static>() { }
+   | -------------------------------- required by `assert_send`
+...
 LL |     assert_send::<Box<dyn Dummy + 'a>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `(dyn Dummy + 'a)`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<(dyn Dummy + 'a)>`
    = note: required because it appears within the type `std::boxed::Box<(dyn Dummy + 'a)>`
-note: required by `assert_send`
-  --> $DIR/kindck-send-object1.rs:5:1
-   |
-LL | fn assert_send<T:Send+'static>() { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 

From 84567190e0d36f9a61f9bc833bd9fa559aeb0089 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 31 Aug 2019 13:42:53 -0700
Subject: [PATCH 395/943] Use saturating_sub

---
 src/librustc_errors/emitter.rs | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 02473cc86bdff..a0ce761cfa277 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -146,12 +146,12 @@ impl Margin {
             } else if self.label_right - self.span_left <= self.column_width {
                 // Attempt to fit the code window considering only the spans and labels.
                 let padding_left = (self.column_width - (self.label_right - self.span_left)) / 2;
-                self.computed_left = max(self.span_left, padding_left) - padding_left;
+                self.computed_left = self.span_left.saturating_sub(padding_left);
                 self.computed_right = self.computed_left + self.column_width;
             } else if self.span_right - self.span_left <= self.column_width {
                 // Attempt to fit the code window considering the spans and labels plus padding.
                 let padding_left = (self.column_width - (self.span_right - self.span_left)) / 5 * 2;
-                self.computed_left = max(self.span_left, padding_left) - padding_left;
+                self.computed_left = self.span_left.saturating_sub(padding_left);
                 self.computed_right = self.computed_left + self.column_width;
             } else { // Mostly give up but still don't show the full line.
                 self.computed_left = self.span_left;
@@ -1304,11 +1304,13 @@ impl EmitterWriter {
                 };
 
                 let column_width = if let Some(width) = self.terminal_width {
-                    max(width, code_offset) - code_offset
+                    width.saturating_sub(code_offset)
                 } else if self.ui_testing {
                     140
                 } else {
-                    term_size::dimensions().map(|(w, _)| w - code_offset).unwrap_or(std::usize::MAX)
+                    term_size::dimensions()
+                        .map(|(w, _)| w.saturating_sub(code_offset))
+                        .unwrap_or(std::usize::MAX)
                 };
 
                 let margin = Margin::new(

From 5e933b490b17de43b5c9b45b77088732f17b7ffd Mon Sep 17 00:00:00 2001
From: Alex Gaynor <alex.gaynor@gmail.com>
Date: Sat, 31 Aug 2019 15:13:16 -0400
Subject: [PATCH 396/943] Add x86_64-linux-kernel target

This adds a target specification for Linux kernel modules on x86_64, as well as base code that can be shared with other architectures.
---
 src/librustc_target/spec/linux_kernel_base.rs | 26 ++++++++++++++++
 src/librustc_target/spec/mod.rs               |  3 ++
 .../spec/x86_64_linux_kernel.rs               | 31 +++++++++++++++++++
 3 files changed, 60 insertions(+)
 create mode 100644 src/librustc_target/spec/linux_kernel_base.rs
 create mode 100644 src/librustc_target/spec/x86_64_linux_kernel.rs

diff --git a/src/librustc_target/spec/linux_kernel_base.rs b/src/librustc_target/spec/linux_kernel_base.rs
new file mode 100644
index 0000000000000..fae44836fa821
--- /dev/null
+++ b/src/librustc_target/spec/linux_kernel_base.rs
@@ -0,0 +1,26 @@
+use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, RelroLevel, TargetOptions};
+use std::default::Default;
+
+pub fn opts() -> TargetOptions {
+    let mut pre_link_args = LinkArgs::new();
+    pre_link_args.insert(
+        LinkerFlavor::Gcc,
+        vec!["-Wl,--as-needed".to_string(), "-Wl,-z,noexecstack".to_string()],
+    );
+
+    TargetOptions {
+        disable_redzone: true,
+        panic_strategy: PanicStrategy::Abort,
+        stack_probes: true,
+        eliminate_frame_pointer: false,
+        linker_is_gnu: true,
+        position_independent_executables: true,
+        needs_plt: true,
+        relro_level: RelroLevel::Full,
+        relocation_model: "static".to_string(),
+        target_family: Some("unix".to_string()),
+        pre_link_args,
+
+        ..Default::default()
+    }
+}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 539e28f7088e3..503d8a08b6f4f 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -53,6 +53,7 @@ mod freebsd_base;
 mod haiku_base;
 mod hermit_base;
 mod linux_base;
+mod linux_kernel_base;
 mod linux_musl_base;
 mod openbsd_base;
 mod netbsd_base;
@@ -386,6 +387,8 @@ supported_targets! {
     ("thumbv7neon-linux-androideabi", thumbv7neon_linux_androideabi),
     ("aarch64-linux-android", aarch64_linux_android),
 
+    ("x86_64-linux-kernel", x86_64_linux_kernel),
+
     ("aarch64-unknown-freebsd", aarch64_unknown_freebsd),
     ("armv6-unknown-freebsd", armv6_unknown_freebsd),
     ("armv7-unknown-freebsd", armv7_unknown_freebsd),
diff --git a/src/librustc_target/spec/x86_64_linux_kernel.rs b/src/librustc_target/spec/x86_64_linux_kernel.rs
new file mode 100644
index 0000000000000..a80b021208ed7
--- /dev/null
+++ b/src/librustc_target/spec/x86_64_linux_kernel.rs
@@ -0,0 +1,31 @@
+// This defines the amd64 target for the Linux Kernel. See the linux-kernel-base module for
+// generic Linux kernel options.
+
+use crate::spec::{LinkerFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::linux_kernel_base::opts();
+    base.cpu = "x86-64".to_string();
+    base.max_atomic_width = Some(64);
+    base.features =
+        "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float"
+            .to_string();
+    base.code_model = Some("kernel".to_string());
+    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
+
+    Ok(Target {
+        // FIXME: Some dispute, the linux-on-clang folks think this should use "Linux"
+        llvm_target: "x86_64-elf".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
+        target_os: "none".to_string(),
+        target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
+        arch: "x86_64".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+
+        options: base,
+    })
+}

From cab607edcfe556343aa4fcb3de6229a790fc5e72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 31 Aug 2019 18:34:50 -0700
Subject: [PATCH 397/943] Emit a single error on if expr with expectation and
 no else clause

---
 src/librustc_typeck/check/_match.rs           | 41 ++++++---
 src/test/ui/if/if-without-else-as-fn-expr.rs  |  6 --
 .../ui/if/if-without-else-as-fn-expr.stderr   | 83 ++-----------------
 src/test/ui/issues/issue-50577.rs             |  1 -
 src/test/ui/issues/issue-50577.stderr         | 15 +---
 5 files changed, 38 insertions(+), 108 deletions(-)

diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index efc37cc04b212..3983a3b820391 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -112,23 +112,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
 
             self.diverges.set(pats_diverge);
-            let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
-            all_arms_diverge &= self.diverges.get();
-
-            let span = expr.span;
-
-            if source_if {
+            let arm_ty = if source_if {
                 let then_expr = &arms[0].body;
                 match (i, if_no_else) {
-                    (0, _) => coercion.coerce(self, &self.misc(span), &arm.body, arm_ty),
-                    (_, true) => self.if_fallback_coercion(span, then_expr, &mut coercion),
+                    (0, _) => {
+                        let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
+                        all_arms_diverge &= self.diverges.get();
+                        coercion.coerce(self, &self.misc(expr.span), &arm.body, arm_ty);
+                        arm_ty
+                    }
+                    (_, true) => {
+                        if self.if_fallback_coercion(expr.span, then_expr, &mut coercion) {
+                            tcx.types.err
+                        } else {
+                            let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
+                            all_arms_diverge &= self.diverges.get();
+                            arm_ty
+                        }
+                    }
                     (_, _) => {
+                        let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
+                        all_arms_diverge &= self.diverges.get();
                         let then_ty = prior_arm_ty.unwrap();
-                        let cause = self.if_cause(span, then_expr, &arm.body, then_ty, arm_ty);
+                        let cause = self.if_cause(expr.span, then_expr, &arm.body, then_ty, arm_ty);
                         coercion.coerce(self, &cause, &arm.body, arm_ty);
+                        arm_ty
                     }
                 }
             } else {
+                let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
+                all_arms_diverge &= self.diverges.get();
                 let arm_span = if let hir::ExprKind::Block(blk, _) = &arm.body.node {
                     // Point at the block expr instead of the entire block
                     blk.expr.as_ref().map(|e| e.span).unwrap_or(arm.body.span)
@@ -139,7 +152,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // The reason for the first arm to fail is not that the match arms diverge,
                     // but rather that there's a prior obligation that doesn't hold.
                     0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)),
-                    _ => (span, ObligationCauseCode::MatchExpressionArm {
+                    _ => (expr.span, ObligationCauseCode::MatchExpressionArm {
                         arm_span,
                         source: match_src,
                         prior_arms: other_arms.clone(),
@@ -153,7 +166,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if other_arms.len() > 5 {
                     other_arms.remove(0);
                 }
-            }
+                arm_ty
+            };
             prior_arm_ty = Some(arm_ty);
         }
 
@@ -185,11 +199,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         then_expr: &'tcx hir::Expr,
         coercion: &mut CoerceMany<'tcx, '_, rustc::hir::Arm>,
-    ) {
+    ) -> bool {
         // If this `if` expr is the parent's function return expr,
         // the cause of the type coercion is the return type, point at it. (#25228)
         let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, span);
         let cause = self.cause(span, ObligationCauseCode::IfExpressionWithNoElse);
+        let mut error = false;
         coercion.coerce_forced_unit(self, &cause, &mut |err| {
             if let Some((span, msg)) = &ret_reason {
                 err.span_label(*span, msg.as_str());
@@ -200,7 +215,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             err.note("`if` expressions without `else` evaluate to `()`");
             err.help("consider adding an `else` block that evaluates to the expected type");
+            error = true;
         }, ret_reason.is_none());
+        error
     }
 
     fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, span: Span) -> Option<(Span, String)> {
diff --git a/src/test/ui/if/if-without-else-as-fn-expr.rs b/src/test/ui/if/if-without-else-as-fn-expr.rs
index 15892de83854c..826371be35f45 100644
--- a/src/test/ui/if/if-without-else-as-fn-expr.rs
+++ b/src/test/ui/if/if-without-else-as-fn-expr.rs
@@ -3,7 +3,6 @@ fn foo(bar: usize) -> usize {
         return 3;
     }
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
 }
 
 fn foo2(bar: usize) -> usize {
@@ -11,7 +10,6 @@ fn foo2(bar: usize) -> usize {
         return 3;
     };
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
     x
 }
 
@@ -20,7 +18,6 @@ fn foo3(bar: usize) -> usize {
         3
     }
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
 }
 
 fn foo_let(bar: usize) -> usize {
@@ -28,7 +25,6 @@ fn foo_let(bar: usize) -> usize {
         return 3;
     }
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
 }
 
 fn foo2_let(bar: usize) -> usize {
@@ -36,7 +32,6 @@ fn foo2_let(bar: usize) -> usize {
         return 3;
     };
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
     x
 }
 
@@ -45,7 +40,6 @@ fn foo3_let(bar: usize) -> usize {
         3
     }
     //~^^^ ERROR if may be missing an else clause
-    //~| ERROR mismatched types [E0308]
 }
 
 // FIXME(60254): deduplicate first error in favor of second.
diff --git a/src/test/ui/if/if-without-else-as-fn-expr.stderr b/src/test/ui/if/if-without-else-as-fn-expr.stderr
index 06600b1cb9aea..b49c2aa6319df 100644
--- a/src/test/ui/if/if-without-else-as-fn-expr.stderr
+++ b/src/test/ui/if/if-without-else-as-fn-expr.stderr
@@ -1,14 +1,3 @@
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:2:5
-   |
-LL | /     if bar % 5 == 0 {
-LL | |         return 3;
-LL | |     }
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
   --> $DIR/if-without-else-as-fn-expr.rs:2:5
    |
@@ -24,20 +13,8 @@ LL | |     }
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:10:20
-   |
-LL |       let x: usize = if bar % 5 == 0 {
-   |  ____________________^
-LL | |         return 3;
-LL | |     };
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
-  --> $DIR/if-without-else-as-fn-expr.rs:10:20
+  --> $DIR/if-without-else-as-fn-expr.rs:9:20
    |
 LL |       let x: usize = if bar % 5 == 0 {
    |  _________-__________^
@@ -52,19 +29,8 @@ LL | |     };
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:19:5
-   |
-LL | /     if bar % 5 == 0 {
-LL | |         3
-LL | |     }
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
-  --> $DIR/if-without-else-as-fn-expr.rs:19:5
+  --> $DIR/if-without-else-as-fn-expr.rs:17:5
    |
 LL |   fn foo3(bar: usize) -> usize {
    |                          ----- expected `usize` because of this return type
@@ -78,19 +44,8 @@ LL | |     }
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:27:5
-   |
-LL | /     if let 0 = 1 {
-LL | |         return 3;
-LL | |     }
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
-  --> $DIR/if-without-else-as-fn-expr.rs:27:5
+  --> $DIR/if-without-else-as-fn-expr.rs:24:5
    |
 LL |   fn foo_let(bar: usize) -> usize {
    |                             ----- expected `usize` because of this return type
@@ -104,20 +59,8 @@ LL | |     }
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:35:20
-   |
-LL |       let x: usize = if let 0 = 1 {
-   |  ____________________^
-LL | |         return 3;
-LL | |     };
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
-  --> $DIR/if-without-else-as-fn-expr.rs:35:20
+  --> $DIR/if-without-else-as-fn-expr.rs:31:20
    |
 LL |       let x: usize = if let 0 = 1 {
    |  _________-__________^
@@ -132,19 +75,8 @@ LL | |     };
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error[E0308]: mismatched types
-  --> $DIR/if-without-else-as-fn-expr.rs:44:5
-   |
-LL | /     if let 0 = 1 {
-LL | |         3
-LL | |     }
-   | |_____^ expected usize, found ()
-   |
-   = note: expected type `usize`
-              found type `()`
-
 error[E0317]: if may be missing an else clause
-  --> $DIR/if-without-else-as-fn-expr.rs:44:5
+  --> $DIR/if-without-else-as-fn-expr.rs:39:5
    |
 LL |   fn foo3_let(bar: usize) -> usize {
    |                              ----- expected `usize` because of this return type
@@ -158,7 +90,6 @@ LL | |     }
    = note: `if` expressions without `else` evaluate to `()`
    = help: consider adding an `else` block that evaluates to the expected type
 
-error: aborting due to 12 previous errors
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0308, E0317.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0317`.
diff --git a/src/test/ui/issues/issue-50577.rs b/src/test/ui/issues/issue-50577.rs
index bf892a8daa27f..f0f1dc6c28667 100644
--- a/src/test/ui/issues/issue-50577.rs
+++ b/src/test/ui/issues/issue-50577.rs
@@ -2,6 +2,5 @@ fn main() {
     enum Foo {
         Drop = assert_eq!(1, 1)
         //~^ ERROR if may be missing an else clause
-        //~| ERROR mismatched types [E0308]
     }
 }
diff --git a/src/test/ui/issues/issue-50577.stderr b/src/test/ui/issues/issue-50577.stderr
index 413c8c5c80b52..0c3ba2ea4f94d 100644
--- a/src/test/ui/issues/issue-50577.stderr
+++ b/src/test/ui/issues/issue-50577.stderr
@@ -1,13 +1,3 @@
-error[E0308]: mismatched types
-  --> $DIR/issue-50577.rs:3:16
-   |
-LL |         Drop = assert_eq!(1, 1)
-   |                ^^^^^^^^^^^^^^^^ expected isize, found ()
-   |
-   = note: expected type `isize`
-              found type `()`
-   = 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[E0317]: if may be missing an else clause
   --> $DIR/issue-50577.rs:3:16
    |
@@ -23,7 +13,6 @@ LL |         Drop = assert_eq!(1, 1)
    = help: consider adding an `else` block that evaluates to the expected type
    = 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 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0308, E0317.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0317`.

From aae2b245e4c3958ca37d6eaa58b89d955d0b66e7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 31 Aug 2019 18:42:13 -0700
Subject: [PATCH 398/943] deduplicate code

---
 src/librustc_typeck/check/_match.rs | 40 ++++++++++++-----------------
 1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 3983a3b820391..63d059bdf2a80 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -112,36 +112,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
 
             self.diverges.set(pats_diverge);
-            let arm_ty = if source_if {
+            let arm_ty = if source_if && if_no_else && i != 0 && self.if_fallback_coercion(
+                expr.span,
+                &arms[0].body,
+                &mut coercion,
+            ) {
+                    tcx.types.err
+            } else {
+                // Only call this if this is not an `if` expr with an expected type and no `else`
+                // clause to avoid duplicated type errors. (#60254)
+                let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
+                all_arms_diverge &= self.diverges.get();
+                arm_ty
+            };
+            if source_if {
                 let then_expr = &arms[0].body;
                 match (i, if_no_else) {
-                    (0, _) => {
-                        let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
-                        all_arms_diverge &= self.diverges.get();
-                        coercion.coerce(self, &self.misc(expr.span), &arm.body, arm_ty);
-                        arm_ty
-                    }
-                    (_, true) => {
-                        if self.if_fallback_coercion(expr.span, then_expr, &mut coercion) {
-                            tcx.types.err
-                        } else {
-                            let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
-                            all_arms_diverge &= self.diverges.get();
-                            arm_ty
-                        }
-                    }
+                    (0, _) => coercion.coerce(self, &self.misc(expr.span), &arm.body, arm_ty),
+                    (_, true) => {} // Handled above to avoid duplicated type errors (#60254).
                     (_, _) => {
-                        let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
-                        all_arms_diverge &= self.diverges.get();
                         let then_ty = prior_arm_ty.unwrap();
                         let cause = self.if_cause(expr.span, then_expr, &arm.body, then_ty, arm_ty);
                         coercion.coerce(self, &cause, &arm.body, arm_ty);
-                        arm_ty
                     }
                 }
             } else {
-                let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
-                all_arms_diverge &= self.diverges.get();
                 let arm_span = if let hir::ExprKind::Block(blk, _) = &arm.body.node {
                     // Point at the block expr instead of the entire block
                     blk.expr.as_ref().map(|e| e.span).unwrap_or(arm.body.span)
@@ -166,8 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if other_arms.len() > 5 {
                     other_arms.remove(0);
                 }
-                arm_ty
-            };
+            }
             prior_arm_ty = Some(arm_ty);
         }
 

From 6ed50f4777b65f117648dc2f524d684424c2730d Mon Sep 17 00:00:00 2001
From: Joe Ranweiler <joe@lemma.co>
Date: Sat, 31 Aug 2019 20:00:08 -0700
Subject: [PATCH 399/943] Rename test locals to work around LLDB bug

LLDB's expression parser can't unambiguously resolve local variables in
some cases, as described in #47938. Work around this by using names that
don't shadow direct submodules of `core`.
---
 src/test/debuginfo/boxed-struct.rs | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/test/debuginfo/boxed-struct.rs b/src/test/debuginfo/boxed-struct.rs
index c0ff90c3ffb9b..8709fb681704b 100644
--- a/src/test/debuginfo/boxed-struct.rs
+++ b/src/test/debuginfo/boxed-struct.rs
@@ -8,11 +8,11 @@
 
 // gdb-command:run
 
-// gdb-command:print *unique
+// gdb-command:print *boxed_with_padding
 // gdbg-check:$1 = {x = 99, y = 999, z = 9999, w = 99999}
 // gdbr-check:$1 = boxed_struct::StructWithSomePadding {x: 99, y: 999, z: 9999, w: 99999}
 
-// gdb-command:print *unique_dtor
+// gdb-command:print *boxed_with_dtor
 // gdbg-check:$2 = {x = 77, y = 777, z = 7777, w = 77777}
 // gdbr-check:$2 = boxed_struct::StructWithDestructor {x: 77, y: 777, z: 7777, w: 77777}
 
@@ -21,13 +21,13 @@
 
 // lldb-command:run
 
-// lldb-command:print *unique
+// lldb-command:print *boxed_with_padding
 // lldbg-check:[...]$0 = StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 }
-// lldbr-check:(boxed_struct::StructWithSomePadding) *unique = StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 }
+// lldbr-check:(boxed_struct::StructWithSomePadding) *boxed_with_padding = StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 }
 
-// lldb-command:print *unique_dtor
+// lldb-command:print *boxed_with_dtor
 // lldbg-check:[...]$1 = StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 }
-// lldbr-check:(boxed_struct::StructWithDestructor) *unique_dtor = StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 }
+// lldbr-check:(boxed_struct::StructWithDestructor) *boxed_with_dtor = StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 }
 
 #![allow(unused_variables)]
 #![feature(box_syntax)]
@@ -54,9 +54,9 @@ impl Drop for StructWithDestructor {
 
 fn main() {
 
-    let unique: Box<_> = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
+    let boxed_with_padding: Box<_> = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
 
-    let unique_dtor: Box<_> = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
+    let boxed_with_dtor: Box<_> = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
     zzz(); // #break
 }
 

From f0b30c7ded69123cffe26b54fb1feedf45d1c5a8 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403@users.noreply.github.com>
Date: Sun, 1 Sep 2019 08:49:26 +0200
Subject: [PATCH 400/943] remove the unstable rustdoc parameter --linker

use the code generation parameter -Clinker (same parameter as rustc)
to control what linker to use for building the rustdoc test executables.

closes: #63816
---
 src/bootstrap/bin/rustdoc.rs             |  5 ++++-
 src/doc/rustdoc/src/unstable-features.md | 13 -------------
 src/librustdoc/config.rs                 |  5 -----
 src/librustdoc/lib.rs                    |  3 ---
 src/librustdoc/test.rs                   |  3 ---
 src/test/run-make-fulldeps/tools.mk      |  2 +-
 src/tools/compiletest/src/runtest.rs     |  6 +-----
 7 files changed, 6 insertions(+), 31 deletions(-)

diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs
index 766a3463ecd8b..a13ff69a7b56f 100644
--- a/src/bootstrap/bin/rustdoc.rs
+++ b/src/bootstrap/bin/rustdoc.rs
@@ -5,6 +5,7 @@
 use std::env;
 use std::process::Command;
 use std::path::PathBuf;
+use std::ffi::OsString;
 
 fn main() {
     let args = env::args_os().skip(1).collect::<Vec<_>>();
@@ -44,7 +45,9 @@ fn main() {
         cmd.arg("-Z").arg("force-unstable-if-unmarked");
     }
     if let Some(linker) = env::var_os("RUSTC_TARGET_LINKER") {
-        cmd.arg("--linker").arg(linker).arg("-Z").arg("unstable-options");
+        let mut arg = OsString::from("-Clinker=");
+        arg.push(&linker);
+        cmd.arg(arg);
     }
 
     // Bootstrap's Cargo-command builder sets this variable to the current Rust version; let's pick
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index 6e32468b64dee..993fc8412836e 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -311,19 +311,6 @@ When `rustdoc` receives this flag, it will print an extra "Version (version)" in
 the crate root's docs. You can use this flag to differentiate between different versions of your
 library's documentation.
 
-### `--linker`: control the linker used for documentation tests
-
-Using this flag looks like this:
-
-```bash
-$ rustdoc --test src/lib.rs -Z unstable-options --linker foo
-$ rustdoc --test README.md -Z unstable-options --linker foo
-```
-
-When `rustdoc` runs your documentation tests, it needs to compile and link the tests as executables
-before running them. This flag can be used to change the linker used on these executables. It's
-equivalent to passing `-C linker=foo` to `rustc`.
-
 ### `--sort-modules-by-appearance`: control how items on module pages are sorted
 
 Using this flag looks like this:
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 30b1706f29464..d261408fc148a 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -60,8 +60,6 @@ pub struct Options {
     pub edition: Edition,
     /// The path to the sysroot. Used during the compilation process.
     pub maybe_sysroot: Option<PathBuf>,
-    /// Linker to use when building doctests.
-    pub linker: Option<PathBuf>,
     /// Lint information passed over the command-line.
     pub lint_opts: Vec<(String, Level)>,
     /// Whether to ask rustc to describe the lints it knows. Practically speaking, this will not be
@@ -130,7 +128,6 @@ impl fmt::Debug for Options {
             .field("target", &self.target)
             .field("edition", &self.edition)
             .field("maybe_sysroot", &self.maybe_sysroot)
-            .field("linker", &self.linker)
             .field("lint_opts", &self.lint_opts)
             .field("describe_lints", &self.describe_lints)
             .field("lint_cap", &self.lint_cap)
@@ -454,7 +451,6 @@ impl Options {
         let playground_url = matches.opt_str("playground-url");
         let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from);
         let display_warnings = matches.opt_present("display-warnings");
-        let linker = matches.opt_str("linker").map(PathBuf::from);
         let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
         let resource_suffix = matches.opt_str("resource-suffix").unwrap_or_default();
         let enable_minification = !matches.opt_present("disable-minification");
@@ -489,7 +485,6 @@ impl Options {
             target,
             edition,
             maybe_sysroot,
-            linker,
             lint_opts,
             describe_lints,
             lint_cap,
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 87dac0f226896..dfa0db0d23b74 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -242,9 +242,6 @@ fn opts() -> Vec<RustcOptGroup> {
         unstable("crate-version", |o| {
             o.optopt("", "crate-version", "crate version to print into documentation", "VERSION")
         }),
-        unstable("linker", |o| {
-            o.optopt("", "linker", "linker used for building executable test code", "PATH")
-        }),
         unstable("sort-modules-by-appearance", |o| {
             o.optflag("", "sort-modules-by-appearance", "sort modules by where they appear in the \
                                                          program, rather than alphabetically")
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 31c0b85a481f5..41df1ff8cd04e 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -266,9 +266,6 @@ fn run_test(
     for codegen_options_str in &options.codegen_options_strs {
         compiler.arg("-C").arg(&codegen_options_str);
     }
-    if let Some(linker) = options.linker {
-        compiler.arg(&format!("-C linker={:?}", linker));
-    }
     if no_run {
         compiler.arg("--emit=metadata");
     }
diff --git a/src/test/run-make-fulldeps/tools.mk b/src/test/run-make-fulldeps/tools.mk
index 3b4df73cdfd6d..9a113b7fa6370 100644
--- a/src/test/run-make-fulldeps/tools.mk
+++ b/src/test/run-make-fulldeps/tools.mk
@@ -12,7 +12,7 @@ RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS)
 RUSTDOC := $(BARE_RUSTDOC) -L $(TARGET_RPATH_DIR)
 ifdef RUSTC_LINKER
 RUSTC := $(RUSTC) -Clinker=$(RUSTC_LINKER)
-RUSTDOC := $(RUSTDOC) --linker $(RUSTC_LINKER) -Z unstable-options
+RUSTDOC := $(RUSTDOC) -Clinker=$(RUSTC_LINKER)
 endif
 #CC := $(CC) -L $(TMPDIR)
 HTMLDOCCK := $(PYTHON) $(S)/src/etc/htmldocck.py
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 3da6be74129f4..03c5177ee5202 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1603,11 +1603,7 @@ impl<'test> TestCx<'test> {
             .args(&self.props.compile_flags);
 
         if let Some(ref linker) = self.config.linker {
-            rustdoc
-                .arg("--linker")
-                .arg(linker)
-                .arg("-Z")
-                .arg("unstable-options");
+            rustdoc.arg(format!("-Clinker={}", linker));
         }
 
         self.compose_and_run_compiler(rustdoc, None)

From e5530519502baf3ae37fa94eda27c2461d8c94aa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 1 Sep 2019 00:08:44 -0700
Subject: [PATCH 401/943] review comment

---
 src/librustc/traits/error_reporting.rs                         | 3 +--
 ...-ctor-passed-as-arg-where-it-should-have-been-called.stderr | 2 +-
 ...-ctor-passed-as-arg-where-it-should-have-been-called.stderr | 2 +-
 3 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 181efeb2f985b..b38e1f5f83937 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -992,8 +992,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         })) = self.tcx.hir().get_if_local(def_id) {
                             let body = self.tcx.hir().body(*body_id);
                             err.help(&format!(
-                                "it looks like you forgot to use parentheses to \
-                                 call the function: `{}({})`",
+                                "use parentheses to call the function: `{}({})`",
                                 ident,
                                 body.params.iter()
                                     .map(|arg| match &arg.pat.node {
diff --git a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index 5735f725dc380..3141b1b65f9ba 100644
--- a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -7,7 +7,7 @@ LL | fn bar(f: impl Future<Output=()>) {}
 LL |     bar(foo);
    |     ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
    |
-   = help: it looks like you forgot to use parentheses to call the function: `foo()`
+   = help: use parentheses to call the function: `foo()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index 2e4505c740588..2cc4653fabe2d 100644
--- a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -7,7 +7,7 @@ LL | fn bar(f: impl T<O=()>) {}
 LL |     bar(foo);
    |     ^^^ the trait `T` is not implemented for `fn() -> impl T {foo}`
    |
-   = help: it looks like you forgot to use parentheses to call the function: `foo()`
+   = help: use parentheses to call the function: `foo()`
 
 error: aborting due to previous error
 

From a9ce33c059d0a91fb12a79d75aa1a868d76bf6f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 1 Sep 2019 02:22:42 -0700
Subject: [PATCH 402/943] Account for arbitrary self types in E0599

---
 src/librustc/ty/context.rs                    | 18 +++++
 src/librustc_typeck/check/expr.rs             | 72 +++++++++++++------
 src/librustc_typeck/check/method/mod.rs       |  2 +-
 src/librustc_typeck/check/method/suggest.rs   |  9 +--
 src/librustc_typeck/check/mod.rs              |  2 +-
 .../no-method-suggested-traits.stderr         |  8 +++
 .../point-at-arbitrary-self-type-method.rs    |  9 +++
 ...point-at-arbitrary-self-type-method.stderr | 15 ++++
 ...int-at-arbitrary-self-type-trait-method.rs | 10 +++
 ...at-arbitrary-self-type-trait-method.stderr | 18 +++++
 src/test/ui/traits/trait-item-privacy.stderr  |  7 ++
 11 files changed, 144 insertions(+), 26 deletions(-)
 create mode 100644 src/test/ui/self/point-at-arbitrary-self-type-method.rs
 create mode 100644 src/test/ui/self/point-at-arbitrary-self-type-method.stderr
 create mode 100644 src/test/ui/self/point-at-arbitrary-self-type-trait-method.rs
 create mode 100644 src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr

diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index e240e0df8b948..f355e231914d2 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2402,6 +2402,24 @@ impl<'tcx> TyCtxt<'tcx> {
         self.mk_generic_adt(def_id, ty)
     }
 
+    #[inline]
+    pub fn mk_pin(self, ty: Ty<'tcx>) -> Ty<'tcx> {
+        let def_id = self.require_lang_item(lang_items::PinTypeLangItem, None);
+        self.mk_generic_adt(def_id, ty)
+    }
+
+    #[inline]
+    pub fn mk_rc(self, ty: Ty<'tcx>) -> Ty<'tcx> {
+        let def_id = self.require_lang_item(lang_items::Rc, None);
+        self.mk_generic_adt(def_id, ty)
+    }
+
+    #[inline]
+    pub fn mk_arc(self, ty: Ty<'tcx>) -> Ty<'tcx> {
+        let def_id = self.require_lang_item(lang_items::Arc, None);
+        self.mk_generic_adt(def_id, ty)
+    }
+
     #[inline]
     pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
         let def_id = self.require_lang_item(lang_items::MaybeUninitLangItem, None);
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index a53fb12367d0e..efff8bcdacbcf 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -12,7 +12,7 @@ use crate::check::fatally_break_rust;
 use crate::check::report_unexpected_variant_res;
 use crate::check::Needs;
 use crate::check::TupleArgumentsFlag::DontTupleArguments;
-use crate::check::method::SelfSource;
+use crate::check::method::{probe, SelfSource};
 use crate::util::common::ErrorReported;
 use crate::util::nodemap::FxHashMap;
 use crate::astconv::AstConv as _;
@@ -775,35 +775,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // no need to check for bot/err -- callee does that
         let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
 
-        let method = match self.lookup_method(rcvr_t,
-                                              segment,
-                                              span,
-                                              expr,
-                                              rcvr) {
+        let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| {
+            if let Ok(pick) = self.lookup_probe(
+                span,
+                segment.ident,
+                new_rcvr_t,
+                rcvr,
+                probe::ProbeScope::AllTraits,
+            ) {
+                err.span_label(
+                    pick.item.ident.span,
+                    &format!("the method is available for `{}` here", new_rcvr_t),
+                );
+            }
+        };
+
+        let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) {
             Ok(method) => {
                 self.write_method_call(expr.hir_id, method);
                 Ok(method)
             }
             Err(error) => {
                 if segment.ident.name != kw::Invalid {
-                    self.report_method_error(span,
-                                             rcvr_t,
-                                             segment.ident,
-                                             SelfSource::MethodCall(rcvr),
-                                             error,
-                                             Some(args));
+                    if let Some(mut err) = self.report_method_error(
+                        span,
+                        rcvr_t,
+                        segment.ident,
+                        SelfSource::MethodCall(rcvr),
+                        error,
+                        Some(args),
+                    ) {
+                        if let ty::Adt(..) = rcvr_t.sty {
+                            // Try alternative arbitrary self types that could fulfill this call.
+                            // FIXME: probe for all types that *could* be arbitrary self-types, not
+                            // just this whitelist.
+                            let box_rcvr_t = self.tcx.mk_box(rcvr_t);
+                            try_alt_rcvr(&mut err, box_rcvr_t);
+                            let pin_rcvr_t = self.tcx.mk_pin(rcvr_t);
+                            try_alt_rcvr(&mut err, pin_rcvr_t);
+                            let arc_rcvr_t = self.tcx.mk_arc(rcvr_t);
+                            try_alt_rcvr(&mut err, arc_rcvr_t);
+                            let rc_rcvr_t = self.tcx.mk_rc(rcvr_t);
+                            try_alt_rcvr(&mut err, rc_rcvr_t);
+                        }
+                        err.emit();
+                    }
                 }
                 Err(())
             }
         };
 
         // Call the generic checker.
-        self.check_method_argument_types(span,
-                                         expr.span,
-                                         method,
-                                         &args[1..],
-                                         DontTupleArguments,
-                                         expected)
+        self.check_method_argument_types(
+            span,
+            expr.span,
+            method,
+            &args[1..],
+            DontTupleArguments,
+            expected,
+        )
     }
 
     fn check_expr_cast(
@@ -1466,8 +1496,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let struct_variant_def = def.non_enum_variant();
             let field_names = self.available_field_names(struct_variant_def);
             if !field_names.is_empty() {
-                err.note(&format!("available fields are: {}",
-                                    self.name_series_display(field_names)));
+                err.note(&format!(
+                    "available fields are: {}",
+                    self.name_series_display(field_names),
+                ));
             }
         }
     }
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index a7e4f8e5c6289..1509c0f8a2196 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -245,7 +245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         Ok(result.callee)
     }
 
-    fn lookup_probe(
+    pub fn lookup_probe(
         &self,
         span: Span,
         method_name: ast::Ident,
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 440e7e5d0e314..72e6f59715960 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -69,12 +69,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         source: SelfSource<'b>,
         error: MethodError<'tcx>,
         args: Option<&'tcx [hir::Expr]>,
-    ) {
+    ) -> Option<DiagnosticBuilder<'_>> {
         let orig_span = span;
         let mut span = span;
         // Avoid suggestions when we don't know what's going on.
         if rcvr_ty.references_error() {
-            return;
+            return None;
         }
 
         let print_disambiguation_help = |
@@ -314,7 +314,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             _ => {}
                         }
                         err.emit();
-                        return;
+                        return None;
                     } else {
                         span = item_name.span;
                         let mut err = struct_span_err!(
@@ -529,7 +529,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     );
                 }
 
-                err.emit();
+                return Some(err);
             }
 
             MethodError::Ambiguity(sources) => {
@@ -573,6 +573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 bug!("no return type expectations but got BadReturnType")
             }
         }
+        None
     }
 
     fn suggest_use_candidates(&self,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a80550486d627..2d9cacea68f31 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3580,7 +3580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     SelfSource::QPath(qself),
                     error,
                     None,
-                );
+                ).map(|mut e| e.emit());
             }
             result
         });
diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
index d980d7cccadd5..002b60f9f258d 100644
--- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr
+++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
@@ -49,6 +49,14 @@ LL | use foo::Bar;
 error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&char>>` in the current scope
   --> $DIR/no-method-suggested-traits.rs:32:43
    |
+LL |         fn method(&self) {}
+   |            ------
+   |            |
+   |            the method is available for `std::boxed::Box<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
+   |            the method is available for `std::pin::Pin<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
+   |            the method is available for `std::sync::Arc<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
+   |            the method is available for `std::rc::Rc<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
+...
 LL |     std::rc::Rc::new(&mut Box::new(&'a')).method();
    |                                           ^^^^^^
    |
diff --git a/src/test/ui/self/point-at-arbitrary-self-type-method.rs b/src/test/ui/self/point-at-arbitrary-self-type-method.rs
new file mode 100644
index 0000000000000..0f7deeacad292
--- /dev/null
+++ b/src/test/ui/self/point-at-arbitrary-self-type-method.rs
@@ -0,0 +1,9 @@
+struct A;
+
+impl A {
+    fn foo(self: Box<Self>) {}
+}
+
+fn main() {
+    A.foo(); //~ ERROR E0599
+}
diff --git a/src/test/ui/self/point-at-arbitrary-self-type-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr
new file mode 100644
index 0000000000000..06dad7caa6735
--- /dev/null
+++ b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr
@@ -0,0 +1,15 @@
+error[E0599]: no method named `foo` found for type `A` in the current scope
+  --> $DIR/point-at-arbitrary-self-type-method.rs:8:7
+   |
+LL | struct A;
+   | --------- method `foo` not found for this
+...
+LL |     fn foo(self: Box<Self>) {}
+   |        --- the method is available for `std::boxed::Box<A>` here
+...
+LL |     A.foo();
+   |       ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.rs b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.rs
new file mode 100644
index 0000000000000..53d992771186f
--- /dev/null
+++ b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.rs
@@ -0,0 +1,10 @@
+trait B { fn foo(self: Box<Self>); }
+struct A;
+
+impl B for A {
+    fn foo(self: Box<Self>) {}
+}
+
+fn main() {
+    A.foo() //~ ERROR E0599
+}
diff --git a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr
new file mode 100644
index 0000000000000..90cd3b8074580
--- /dev/null
+++ b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr
@@ -0,0 +1,18 @@
+error[E0599]: no method named `foo` found for type `A` in the current scope
+  --> $DIR/point-at-arbitrary-self-type-trait-method.rs:9:7
+   |
+LL | trait B { fn foo(self: Box<Self>); }
+   |              --- the method is available for `std::boxed::Box<A>` here
+LL | struct A;
+   | --------- method `foo` not found for this
+...
+LL |     A.foo()
+   |       ^^^
+   |
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the following trait defines an item `foo`, perhaps you need to implement it:
+           candidate #1: `B`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr
index de699a69fa8bc..ce2919c8e7741 100644
--- a/src/test/ui/traits/trait-item-privacy.stderr
+++ b/src/test/ui/traits/trait-item-privacy.stderr
@@ -17,6 +17,13 @@ error[E0599]: no method named `b` found for type `S` in the current scope
 LL | struct S;
    | --------- method `b` not found for this
 ...
+LL |         fn b(&self) { }
+   |            -
+   |            |
+   |            the method is available for `std::boxed::Box<S>` here
+   |            the method is available for `std::sync::Arc<S>` here
+   |            the method is available for `std::rc::Rc<S>` here
+...
 LL |     S.b();
    |       ^
    |

From 84ccbe2076cf37bc13c32a89ccc57a57281b8708 Mon Sep 17 00:00:00 2001
From: Philipp Hansch <dev@phansch.net>
Date: Sun, 1 Sep 2019 12:15:33 +0200
Subject: [PATCH 403/943] librustc_errors: Extract sugg/subst handling into
 method

An initial refactoring before working on #61809.

This moves the whole block into a method so that it can be reused in the
annotate-snippet output. It's already used in the new emitter, but
there's no UI tests with suggestions included in this PR.

A first look at some UI tests with suggestions showed that there's some
more work to do in [annotate-snippet-rs][annotate-snippet-rs] before the
new output is closer to the current one.
---
 .../annotate_snippet_emitter_writer.rs        |  4 +-
 src/librustc_errors/emitter.rs                | 40 ++++++++++++++-----
 2 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs
index 255af3122e70c..3bed5d81dc514 100644
--- a/src/librustc_errors/annotate_snippet_emitter_writer.rs
+++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs
@@ -30,10 +30,8 @@ pub struct AnnotateSnippetEmitterWriter {
 impl Emitter for AnnotateSnippetEmitterWriter {
     /// The entry point for the diagnostics generation
     fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
-        let primary_span = db.span.clone();
         let children = db.children.clone();
-        // FIXME(#59346): Collect suggestions (see emitter.rs)
-        let suggestions: &[_] = &[];
+        let (primary_span, suggestions) = self.primary_span_formatted(&db);
 
         // FIXME(#59346): Add `fix_multispans_in_std_macros` function from emitter.rs
 
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 77d373e7a8ca8..0a9c927ef40a1 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -191,16 +191,25 @@ pub trait Emitter {
     fn should_show_explain(&self) -> bool {
         true
     }
-}
 
-impl Emitter for EmitterWriter {
-    fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
+    /// Formats the substitutions of the primary_span
+    ///
+    /// The are a lot of conditions to this method, but in short:
+    ///
+    /// * If the current `Diagnostic` has only one visible `CodeSuggestion`,
+    ///   we format the `help` suggestion depending on the content of the
+    ///   substitutions. In that case, we return the modified span only.
+    ///
+    /// * If the current `Diagnostic` has multiple suggestions,
+    ///   we return the original `primary_span` and the original suggestions.
+    fn primary_span_formatted<'a>(
+        &mut self,
+        db: &'a DiagnosticBuilder<'_>
+    ) -> (MultiSpan, &'a [CodeSuggestion]) {
         let mut primary_span = db.span.clone();
-        let mut children = db.children.clone();
-        let mut suggestions: &[_] = &[];
-
         if let Some((sugg, rest)) = db.suggestions.split_first() {
             if rest.is_empty() &&
+               // ^ if there is only one suggestion
                // don't display multi-suggestions as labels
                sugg.substitutions.len() == 1 &&
                // don't display multipart suggestions as labels
@@ -216,21 +225,34 @@ impl Emitter for EmitterWriter {
             {
                 let substitution = &sugg.substitutions[0].parts[0].snippet.trim();
                 let msg = if substitution.len() == 0 || sugg.style.hide_inline() {
-                    // This substitution is only removal or we explicitly don't want to show the
-                    // code inline, don't show it
+                    // This substitution is only removal OR we explicitly don't want to show the
+                    // code inline (`hide_inline`). Therefore, we don't show the substitution.
                     format!("help: {}", sugg.msg)
                 } else {
+                    // Show the default suggestion text with the substitution
                     format!("help: {}: `{}`", sugg.msg, substitution)
                 };
                 primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg);
+
+                // We return only the modified primary_span
+                (primary_span, &[])
             } else {
                 // if there are multiple suggestions, print them all in full
                 // to be consistent. We could try to figure out if we can
                 // make one (or the first one) inline, but that would give
                 // undue importance to a semi-random suggestion
-                suggestions = &db.suggestions;
+                (primary_span, &db.suggestions)
             }
+        } else {
+            (primary_span, &db.suggestions)
         }
+    }
+}
+
+impl Emitter for EmitterWriter {
+    fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
+        let mut children = db.children.clone();
+        let (mut primary_span, suggestions) = self.primary_span_formatted(&db);
 
         self.fix_multispans_in_std_macros(&mut primary_span,
                                           &mut children,

From 35c9e5f1229d8b634ebd98c49e35c74e237e17f7 Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Sun, 1 Sep 2019 22:05:50 +0900
Subject: [PATCH 404/943] Fix const_err with `-(-0.0)`

---
 src/librustc_mir/transform/const_prop.rs | 14 +-------------
 src/test/ui/consts/const-err2.rs         |  1 -
 src/test/ui/consts/const-err2.stderr     | 20 +++++++-------------
 src/test/ui/consts/issue-64059.rs        |  5 +++++
 4 files changed, 13 insertions(+), 27 deletions(-)
 create mode 100644 src/test/ui/consts/issue-64059.rs

diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index f261fdc268b5b..00118c05c9451 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -6,7 +6,7 @@ use std::cell::Cell;
 use rustc::hir::def::DefKind;
 use rustc::mir::{
     AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue,
-    Local, NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind,
+    Local, NullOp, StatementKind, Statement, LocalKind, Static, StaticKind,
     TerminatorKind, Terminator,  ClearCrossCrate, SourceInfo, BinOp, ProjectionElem,
     SourceScope, SourceScopeLocalData, LocalDecl,
 };
@@ -407,18 +407,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 let arg = self.eval_operand(arg, source_info)?;
                 let val = self.use_ecx(source_info, |this| {
                     let prim = this.ecx.read_immediate(arg)?;
-                    match op {
-                        UnOp::Neg => {
-                            // Need to do overflow check here: For actual CTFE, MIR
-                            // generation emits code that does this before calling the op.
-                            if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
-                                throw_panic!(OverflowNeg)
-                            }
-                        }
-                        UnOp::Not => {
-                            // Cannot overflow
-                        }
-                    }
                     // Now run the actual operation.
                     this.ecx.unary_op(op, prim)
                 })?;
diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs
index a5f685a159b39..5aab1972a9bd5 100644
--- a/src/test/ui/consts/const-err2.rs
+++ b/src/test/ui/consts/const-err2.rs
@@ -13,7 +13,6 @@ fn black_box<T>(_: T) {
 
 fn main() {
     let a = -std::i8::MIN;
-    //~^ ERROR const_err
     let b = 200u8 + 200u8 + 200u8;
     //~^ ERROR const_err
     let c = 200u8 * 4;
diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr
index 659c3afc618a9..63d037764a13d 100644
--- a/src/test/ui/consts/const-err2.stderr
+++ b/src/test/ui/consts/const-err2.stderr
@@ -1,8 +1,8 @@
 error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:15:13
+  --> $DIR/const-err2.rs:16:13
    |
-LL |     let a = -std::i8::MIN;
-   |             ^^^^^^^^^^^^^ attempt to negate with overflow
+LL |     let b = 200u8 + 200u8 + 200u8;
+   |             ^^^^^^^^^^^^^ attempt to add with overflow
    |
 note: lint level defined here
   --> $DIR/const-err2.rs:8:9
@@ -11,28 +11,22 @@ LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:17:13
-   |
-LL |     let b = 200u8 + 200u8 + 200u8;
-   |             ^^^^^^^^^^^^^ attempt to add with overflow
-
-error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:19:13
+  --> $DIR/const-err2.rs:18:13
    |
 LL |     let c = 200u8 * 4;
    |             ^^^^^^^^^ attempt to multiply with overflow
 
 error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:21:13
+  --> $DIR/const-err2.rs:20:13
    |
 LL |     let d = 42u8 - (42u8 + 1);
    |             ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
 
 error: index out of bounds: the len is 1 but the index is 1
-  --> $DIR/const-err2.rs:23:14
+  --> $DIR/const-err2.rs:22:14
    |
 LL |     let _e = [5u8][1];
    |              ^^^^^^^^
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/consts/issue-64059.rs b/src/test/ui/consts/issue-64059.rs
new file mode 100644
index 0000000000000..c4c895fef66cf
--- /dev/null
+++ b/src/test/ui/consts/issue-64059.rs
@@ -0,0 +1,5 @@
+// run-pass
+
+fn main() {
+    let _ = -(-0.0);
+}

From 0c9aeba5f44b9ddb259154484d2ed6c270da6211 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sun, 1 Sep 2019 10:09:45 -0400
Subject: [PATCH 405/943] Remove no-prefer-dynamic from valgrind tests

---
 src/test/run-pass-valgrind/cast-enum-with-dtor.rs     | 2 --
 src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs | 2 --
 src/test/run-pass-valgrind/cleanup-stdin.rs           | 2 --
 src/test/run-pass-valgrind/down-with-thread-dtors.rs  | 1 -
 src/test/run-pass-valgrind/dst-dtor-1.rs              | 2 --
 src/test/run-pass-valgrind/dst-dtor-2.rs              | 2 --
 src/test/run-pass-valgrind/dst-dtor-3.rs              | 2 --
 src/test/run-pass-valgrind/dst-dtor-4.rs              | 2 --
 src/test/run-pass-valgrind/exit-flushes.rs            | 1 -
 src/test/run-pass-valgrind/osx-frameworks.rs          | 1 -
 10 files changed, 17 deletions(-)

diff --git a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
index 42445b9056f9d..93c47d32f92a1 100644
--- a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
+++ b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
@@ -1,5 +1,3 @@
-// no-prefer-dynamic
-
 #![allow(dead_code)]
 
 // check dtor calling order when casting enums.
diff --git a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
index 925ffe75fe785..fb2b4d476355e 100644
--- a/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
+++ b/src/test/run-pass-valgrind/cleanup-auto-borrow-obj.rs
@@ -1,5 +1,3 @@
-// no-prefer-dynamic
-
 // This would previously leak the Box<Trait> because we wouldn't
 // schedule cleanups when auto borrowing trait objects.
 // This program should be valgrind clean.
diff --git a/src/test/run-pass-valgrind/cleanup-stdin.rs b/src/test/run-pass-valgrind/cleanup-stdin.rs
index 3505074293264..cf8f81cf5aa7c 100644
--- a/src/test/run-pass-valgrind/cleanup-stdin.rs
+++ b/src/test/run-pass-valgrind/cleanup-stdin.rs
@@ -1,5 +1,3 @@
-// no-prefer-dynamic
-
 fn main() {
     let _ = std::io::stdin();
     let _ = std::io::stdout();
diff --git a/src/test/run-pass-valgrind/down-with-thread-dtors.rs b/src/test/run-pass-valgrind/down-with-thread-dtors.rs
index c3567a9b20097..8531b8d832604 100644
--- a/src/test/run-pass-valgrind/down-with-thread-dtors.rs
+++ b/src/test/run-pass-valgrind/down-with-thread-dtors.rs
@@ -1,4 +1,3 @@
-// no-prefer-dynamic
 // ignore-emscripten
 
 thread_local!(static FOO: Foo = Foo);
diff --git a/src/test/run-pass-valgrind/dst-dtor-1.rs b/src/test/run-pass-valgrind/dst-dtor-1.rs
index 7533a7bd2353b..5b8433f614567 100644
--- a/src/test/run-pass-valgrind/dst-dtor-1.rs
+++ b/src/test/run-pass-valgrind/dst-dtor-1.rs
@@ -1,5 +1,3 @@
-// no-prefer-dynamic
-
 static mut DROP_RAN: bool = false;
 
 struct Foo;
diff --git a/src/test/run-pass-valgrind/dst-dtor-2.rs b/src/test/run-pass-valgrind/dst-dtor-2.rs
index ebf0c17fecb56..991fe00950bba 100644
--- a/src/test/run-pass-valgrind/dst-dtor-2.rs
+++ b/src/test/run-pass-valgrind/dst-dtor-2.rs
@@ -1,5 +1,3 @@
-// no-prefer-dynamic
-
 static mut DROP_RAN: isize = 0;
 
 struct Foo;
diff --git a/src/test/run-pass-valgrind/dst-dtor-3.rs b/src/test/run-pass-valgrind/dst-dtor-3.rs
index e15908dfcc31f..f0c2dda5ab05b 100644
--- a/src/test/run-pass-valgrind/dst-dtor-3.rs
+++ b/src/test/run-pass-valgrind/dst-dtor-3.rs
@@ -1,5 +1,3 @@
-// no-prefer-dynamic
-
 #![feature(unsized_tuple_coercion)]
 
 static mut DROP_RAN: bool = false;
diff --git a/src/test/run-pass-valgrind/dst-dtor-4.rs b/src/test/run-pass-valgrind/dst-dtor-4.rs
index 52bf0c364b24d..ad6d46f7c0886 100644
--- a/src/test/run-pass-valgrind/dst-dtor-4.rs
+++ b/src/test/run-pass-valgrind/dst-dtor-4.rs
@@ -1,5 +1,3 @@
-// no-prefer-dynamic
-
 #![feature(unsized_tuple_coercion)]
 
 static mut DROP_RAN: isize = 0;
diff --git a/src/test/run-pass-valgrind/exit-flushes.rs b/src/test/run-pass-valgrind/exit-flushes.rs
index cd5edb84bdfe4..a68c6f3355644 100644
--- a/src/test/run-pass-valgrind/exit-flushes.rs
+++ b/src/test/run-pass-valgrind/exit-flushes.rs
@@ -1,4 +1,3 @@
-// no-prefer-dynamic
 // ignore-cloudabi
 // ignore-emscripten
 // ignore-sgx no processes
diff --git a/src/test/run-pass-valgrind/osx-frameworks.rs b/src/test/run-pass-valgrind/osx-frameworks.rs
index 4ea804a184474..ea1403645a515 100644
--- a/src/test/run-pass-valgrind/osx-frameworks.rs
+++ b/src/test/run-pass-valgrind/osx-frameworks.rs
@@ -1,4 +1,3 @@
-// no-prefer-dynamic
 // pretty-expanded FIXME #23616
 
 #![feature(rustc_private)]

From 3a6aadaa8c915c3dea42c0b1fb6d96f227166148 Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Mon, 2 Sep 2019 01:05:38 +0900
Subject: [PATCH 406/943] Add `opt-level` check

---
 src/librustc_mir/transform/const_prop.rs      |  16 ++-
 src/test/ui/consts/const-err2.rs              |   3 -
 src/test/ui/consts/const-err2.stderr          |  28 +---
 .../ui/consts/const-eval/promoted_errors.rs   |   1 -
 .../consts/const-eval/promoted_errors.stderr  |  30 ++---
 ...t-method-self-inherit-builtin-trait.stderr |   6 +
 src/test/ui/issues/issue-8460-const.rs        |  10 --
 src/test/ui/issues/issue-8460-const.stderr    | 120 +++++-------------
 8 files changed, 67 insertions(+), 147 deletions(-)
 create mode 100644 src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr

diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 00118c05c9451..37e14004ce841 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -6,7 +6,7 @@ use std::cell::Cell;
 use rustc::hir::def::DefKind;
 use rustc::mir::{
     AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue,
-    Local, NullOp, StatementKind, Statement, LocalKind, Static, StaticKind,
+    Local, NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind,
     TerminatorKind, Terminator,  ClearCrossCrate, SourceInfo, BinOp, ProjectionElem,
     SourceScope, SourceScopeLocalData, LocalDecl,
 };
@@ -405,8 +405,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 }
 
                 let arg = self.eval_operand(arg, source_info)?;
+                let is_release_mode = self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2;
                 let val = self.use_ecx(source_info, |this| {
                     let prim = this.ecx.read_immediate(arg)?;
+                    match op {
+                        UnOp::Neg => {
+                            if is_release_mode
+                            && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
+                                throw_panic!(OverflowNeg)
+                            }
+                        }
+                        UnOp::Not => {
+                            // Cannot overflow
+                        }
+                    }
                     // Now run the actual operation.
                     this.ecx.unary_op(op, prim)
                 })?;
@@ -473,7 +485,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                         Scalar::from_bool(overflow).into(),
                     )
                 } else {
-                    if overflow {
+                    if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 && overflow {
                         let err = err_panic!(Overflow(op)).into();
                         let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
                         return None;
diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs
index 5aab1972a9bd5..6da6addf60a1c 100644
--- a/src/test/ui/consts/const-err2.rs
+++ b/src/test/ui/consts/const-err2.rs
@@ -14,11 +14,8 @@ fn black_box<T>(_: T) {
 fn main() {
     let a = -std::i8::MIN;
     let b = 200u8 + 200u8 + 200u8;
-    //~^ ERROR const_err
     let c = 200u8 * 4;
-    //~^ ERROR const_err
     let d = 42u8 - (42u8 + 1);
-    //~^ ERROR const_err
     let _e = [5u8][1];
     //~^ ERROR const_err
     black_box(a);
diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr
index 63d037764a13d..30855fd215ff3 100644
--- a/src/test/ui/consts/const-err2.stderr
+++ b/src/test/ui/consts/const-err2.stderr
@@ -1,8 +1,8 @@
-error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:16:13
+error: index out of bounds: the len is 1 but the index is 1
+  --> $DIR/const-err2.rs:19:14
    |
-LL |     let b = 200u8 + 200u8 + 200u8;
-   |             ^^^^^^^^^^^^^ attempt to add with overflow
+LL |     let _e = [5u8][1];
+   |              ^^^^^^^^
    |
 note: lint level defined here
   --> $DIR/const-err2.rs:8:9
@@ -10,23 +10,5 @@ note: lint level defined here
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:18:13
-   |
-LL |     let c = 200u8 * 4;
-   |             ^^^^^^^^^ attempt to multiply with overflow
-
-error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:20:13
-   |
-LL |     let d = 42u8 - (42u8 + 1);
-   |             ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
-
-error: index out of bounds: the len is 1 but the index is 1
-  --> $DIR/const-err2.rs:22:14
-   |
-LL |     let _e = [5u8][1];
-   |              ^^^^^^^^
-
-error: aborting due to 4 previous errors
+error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs
index cd989731452b3..a9a7a66fe614f 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors.rs
@@ -5,7 +5,6 @@
 fn main() {
     println!("{}", 0u32 - 1);
     let _x = 0u32 - 1;
-    //~^ ERROR this expression will panic at runtime [const_err]
     println!("{}", 1/(1-1));
     //~^ ERROR attempt to divide by zero [const_err]
     //~| ERROR reaching this expression at runtime will panic or abort [const_err]
diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr
index 40d5c73e86679..3940fa13d7892 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.stderr
@@ -1,8 +1,8 @@
-error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:7:14
+error: attempt to divide by zero
+  --> $DIR/promoted_errors.rs:8:20
    |
-LL |     let _x = 0u32 - 1;
-   |              ^^^^^^^^ attempt to subtract with overflow
+LL |     println!("{}", 1/(1-1));
+   |                    ^^^^^^^
    |
 note: lint level defined here
   --> $DIR/promoted_errors.rs:3:9
@@ -10,53 +10,47 @@ note: lint level defined here
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
-error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:9:20
-   |
-LL |     println!("{}", 1/(1-1));
-   |                    ^^^^^^^
-
 error: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:9:20
+  --> $DIR/promoted_errors.rs:8:20
    |
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:12:14
+  --> $DIR/promoted_errors.rs:11:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:12:14
+  --> $DIR/promoted_errors.rs:11:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:15:20
+  --> $DIR/promoted_errors.rs:14:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^
 
 error: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:15:20
+  --> $DIR/promoted_errors.rs:14:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:18:14
+  --> $DIR/promoted_errors.rs:17:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:18:14
+  --> $DIR/promoted_errors.rs:17:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
-error: aborting due to 9 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr
new file mode 100644
index 0000000000000..5160c9e72a9c4
--- /dev/null
+++ b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr
@@ -0,0 +1,6 @@
+error: failed to remove $TEST_BUILD_DIR/issues/issue-8171-default-method-self-inherit-builtin-trait/issue-8171-default-method-self-inherit-builtin-trait.issue_8171_default_method_self_inherit_builtin_trait.7rcbfp3g-cgu.0.rcgu.o: 指定されたパスが見つかりません。 (os error 3)
+
+error: failed to remove $TEST_BUILD_DIR/issues/issue-8171-default-method-self-inherit-builtin-trait/issue-8171-default-method-self-inherit-builtin-trait.issue_8171_default_method_self_inherit_builtin_trait.7rcbfp3g-cgu.1.rcgu.o: 指定されたパスが見つかりません。 (os error 3)
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/issues/issue-8460-const.rs b/src/test/ui/issues/issue-8460-const.rs
index 611d280f774c0..6a5b98fa9b190 100644
--- a/src/test/ui/issues/issue-8460-const.rs
+++ b/src/test/ui/issues/issue-8460-const.rs
@@ -6,19 +6,14 @@ use std::thread;
 fn main() {
     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
     //~^ ERROR attempt to divide by zero
     //~| ERROR this expression will panic at runtime
@@ -36,19 +31,14 @@ fn main() {
     //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with a divisor of zero
     //~| ERROR this expression will panic at runtime
diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr
index 31b1da4f804ab..b9fbf0bdaa609 100644
--- a/src/test/ui/issues/issue-8460-const.stderr
+++ b/src/test/ui/issues/issue-8460-const.stderr
@@ -10,239 +10,179 @@ note: lint level defined here
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:7:36
-   |
-LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^^^ attempt to divide with overflow
-
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:10:36
+  --> $DIR/issue-8460-const.rs:9:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:10:36
-   |
-LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^ attempt to divide with overflow
-
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:13:36
+  --> $DIR/issue-8460-const.rs:11:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:13:36
-   |
-LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
-
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:16:36
+  --> $DIR/issue-8460-const.rs:13:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:16:36
-   |
-LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
-
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:19:36
+  --> $DIR/issue-8460-const.rs:15:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:19:36
-   |
-LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
-
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:22:36
+  --> $DIR/issue-8460-const.rs:17:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:22:36
+  --> $DIR/issue-8460-const.rs:17:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:25:36
+  --> $DIR/issue-8460-const.rs:20:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:25:36
+  --> $DIR/issue-8460-const.rs:20:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:28:36
+  --> $DIR/issue-8460-const.rs:23:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:28:36
+  --> $DIR/issue-8460-const.rs:23:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:31:36
+  --> $DIR/issue-8460-const.rs:26:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:31:36
+  --> $DIR/issue-8460-const.rs:26:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:34:36
+  --> $DIR/issue-8460-const.rs:29:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:34:36
+  --> $DIR/issue-8460-const.rs:29:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:37:36
+  --> $DIR/issue-8460-const.rs:32:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:37:36
-   |
-LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:40:36
+  --> $DIR/issue-8460-const.rs:34:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:40:36
-   |
-LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:43:36
+  --> $DIR/issue-8460-const.rs:36:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:43:36
-   |
-LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:46:36
+  --> $DIR/issue-8460-const.rs:38:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:46:36
-   |
-LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:49:36
+  --> $DIR/issue-8460-const.rs:40:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:49:36
-   |
-LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:52:36
+  --> $DIR/issue-8460-const.rs:42:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:52:36
+  --> $DIR/issue-8460-const.rs:42:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:55:36
+  --> $DIR/issue-8460-const.rs:45:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:55:36
+  --> $DIR/issue-8460-const.rs:45:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:58:36
+  --> $DIR/issue-8460-const.rs:48:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:58:36
+  --> $DIR/issue-8460-const.rs:48:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:61:36
+  --> $DIR/issue-8460-const.rs:51:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:61:36
+  --> $DIR/issue-8460-const.rs:51:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:64:36
+  --> $DIR/issue-8460-const.rs:54:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:64:36
+  --> $DIR/issue-8460-const.rs:54:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
-error: aborting due to 40 previous errors
+error: aborting due to 30 previous errors
 

From ab12dfeb164fb06d19ce24acd8268eebfd6440fa Mon Sep 17 00:00:00 2001
From: Guanqun Lu <guanqun.lu@gmail.com>
Date: Mon, 2 Sep 2019 00:38:05 +0800
Subject: [PATCH 407/943] following the same style

---
 src/tools/compiletest/src/main.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index bde49ff391c8c..467b7771c152e 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -335,7 +335,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         runtool: matches.opt_str("runtool"),
         host_rustcflags: matches.opt_str("host-rustcflags"),
         target_rustcflags: matches.opt_str("target-rustcflags"),
-        target: target,
+        target,
         host: opt_str2(matches.opt_str("host")),
         cdb,
         gdb,
@@ -345,7 +345,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         lldb_native_rust,
         llvm_version: matches.opt_str("llvm-version"),
         system_llvm: matches.opt_present("system-llvm"),
-        android_cross_path: android_cross_path,
+        android_cross_path,
         adb_path: opt_str2(matches.opt_str("adb-path")),
         adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")),
         adb_device_status: opt_str2(matches.opt_str("target")).contains("android")

From 7fdcbce499990498bca38ebce6b215206dcbb591 Mon Sep 17 00:00:00 2001
From: limira <20672976+limira@users.noreply.github.com>
Date: Mon, 2 Sep 2019 00:14:58 +0700
Subject: [PATCH 408/943] Replace file_stem by file_name in rustdoc markdown

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

diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index a30fc05f36acd..401bd5f6e66c1 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -43,7 +43,7 @@ pub fn render(
     edition: Edition
 ) -> i32 {
     let mut output = options.output;
-    output.push(input.file_stem().unwrap());
+    output.push(input.file_name().unwrap());
     output.set_extension("html");
 
     let mut css = String::new();

From 4a0872b37efbd982aed7e29f166e4ccb095f5779 Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Mon, 2 Sep 2019 02:18:16 +0900
Subject: [PATCH 409/943] Add `overflow_check` check

---
 src/librustc_mir/transform/const_prop.rs                  | 8 ++++++--
 ...-8171-default-method-self-inherit-builtin-trait.stderr | 6 ------
 2 files changed, 6 insertions(+), 8 deletions(-)
 delete mode 100644 src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr

diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 37e14004ce841..b43323687cda3 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -405,11 +405,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 }
 
                 let arg = self.eval_operand(arg, source_info)?;
-                let is_release_mode = self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2;
+                let is_release_mode = self.tcx.sess.overflow_checks();
                 let val = self.use_ecx(source_info, |this| {
                     let prim = this.ecx.read_immediate(arg)?;
                     match op {
                         UnOp::Neg => {
+                            // We don't have to check overflow here when we already
+                            // check it in release mode.
                             if is_release_mode
                             && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
                                 throw_panic!(OverflowNeg)
@@ -485,7 +487,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                         Scalar::from_bool(overflow).into(),
                     )
                 } else {
-                    if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 && overflow {
+                    // We don't have to check overflow here when we already
+                    // check it in release mode.
+                    if self.tcx.sess.overflow_checks() && overflow {
                         let err = err_panic!(Overflow(op)).into();
                         let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
                         return None;
diff --git a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr
deleted file mode 100644
index 5160c9e72a9c4..0000000000000
--- a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr
+++ /dev/null
@@ -1,6 +0,0 @@
-error: failed to remove $TEST_BUILD_DIR/issues/issue-8171-default-method-self-inherit-builtin-trait/issue-8171-default-method-self-inherit-builtin-trait.issue_8171_default_method_self_inherit_builtin_trait.7rcbfp3g-cgu.0.rcgu.o: 指定されたパスが見つかりません。 (os error 3)
-
-error: failed to remove $TEST_BUILD_DIR/issues/issue-8171-default-method-self-inherit-builtin-trait/issue-8171-default-method-self-inherit-builtin-trait.issue_8171_default_method_self_inherit_builtin_trait.7rcbfp3g-cgu.1.rcgu.o: 指定されたパスが見つかりません。 (os error 3)
-
-error: aborting due to 2 previous errors
-

From f53c2179ba2ae35bd241a28027fb703aec89139b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 1 Sep 2019 10:49:07 -0700
Subject: [PATCH 410/943] review comments

---
 src/librustc_typeck/check/_match.rs | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 63d059bdf2a80..7427ae9ce8de3 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -117,14 +117,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 &arms[0].body,
                 &mut coercion,
             ) {
-                    tcx.types.err
+                tcx.types.err
             } else {
                 // Only call this if this is not an `if` expr with an expected type and no `else`
                 // clause to avoid duplicated type errors. (#60254)
-                let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
-                all_arms_diverge &= self.diverges.get();
-                arm_ty
+                self.check_expr_with_expectation(&arm.body, expected)
             };
+            all_arms_diverge &= self.diverges.get();
             if source_if {
                 let then_expr = &arms[0].body;
                 match (i, if_no_else) {
@@ -188,6 +187,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Handle the fallback arm of a desugared if(-let) like a missing else.
+    ///
+    /// Returns `true` if there was an error forcing the coercion to the `()` type.
     fn if_fallback_coercion(
         &self,
         span: Span,

From 8e9825aeb9bce905ed230733bf2a5b4b07f25eb9 Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Mon, 2 Sep 2019 03:06:11 +0900
Subject: [PATCH 411/943] Fix overflow_check

---
 src/librustc_mir/transform/const_prop.rs      |  14 +-
 src/test/ui/consts/const-err2.rs              |   4 +
 src/test/ui/consts/const-err2.stderr          |  34 ++++-
 .../ui/consts/const-eval/promoted_errors.rs   |   1 +
 .../consts/const-eval/promoted_errors.stderr  |  30 +++--
 src/test/ui/consts/issue-64059.rs             |   3 +-
 src/test/ui/consts/issue-64059.stderr         |  10 ++
 src/test/ui/issues/issue-8460-const.rs        |  10 ++
 src/test/ui/issues/issue-8460-const.stderr    | 120 +++++++++++++-----
 9 files changed, 170 insertions(+), 56 deletions(-)
 create mode 100644 src/test/ui/consts/issue-64059.stderr

diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index b43323687cda3..091e68cd0669c 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -405,14 +405,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 }
 
                 let arg = self.eval_operand(arg, source_info)?;
-                let is_release_mode = self.tcx.sess.overflow_checks();
+                let oflo_check = self.tcx.sess.overflow_checks();
                 let val = self.use_ecx(source_info, |this| {
                     let prim = this.ecx.read_immediate(arg)?;
                     match op {
                         UnOp::Neg => {
-                            // We don't have to check overflow here when we already
-                            // check it in release mode.
-                            if is_release_mode
+                            // We check overflow in debug mode already
+                            // so should only check in release mode.
+                            if !oflo_check
                             && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
                                 throw_panic!(OverflowNeg)
                             }
@@ -487,9 +487,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                         Scalar::from_bool(overflow).into(),
                     )
                 } else {
-                    // We don't have to check overflow here when we already
-                    // check it in release mode.
-                    if self.tcx.sess.overflow_checks() && overflow {
+                    // We check overflow in debug mode already
+                    // so should only check in release mode.
+                    if !self.tcx.sess.overflow_checks() && overflow {
                         let err = err_panic!(Overflow(op)).into();
                         let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
                         return None;
diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs
index 6da6addf60a1c..a5f685a159b39 100644
--- a/src/test/ui/consts/const-err2.rs
+++ b/src/test/ui/consts/const-err2.rs
@@ -13,9 +13,13 @@ fn black_box<T>(_: T) {
 
 fn main() {
     let a = -std::i8::MIN;
+    //~^ ERROR const_err
     let b = 200u8 + 200u8 + 200u8;
+    //~^ ERROR const_err
     let c = 200u8 * 4;
+    //~^ ERROR const_err
     let d = 42u8 - (42u8 + 1);
+    //~^ ERROR const_err
     let _e = [5u8][1];
     //~^ ERROR const_err
     black_box(a);
diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr
index 30855fd215ff3..659c3afc618a9 100644
--- a/src/test/ui/consts/const-err2.stderr
+++ b/src/test/ui/consts/const-err2.stderr
@@ -1,8 +1,8 @@
-error: index out of bounds: the len is 1 but the index is 1
-  --> $DIR/const-err2.rs:19:14
+error: this expression will panic at runtime
+  --> $DIR/const-err2.rs:15:13
    |
-LL |     let _e = [5u8][1];
-   |              ^^^^^^^^
+LL |     let a = -std::i8::MIN;
+   |             ^^^^^^^^^^^^^ attempt to negate with overflow
    |
 note: lint level defined here
   --> $DIR/const-err2.rs:8:9
@@ -10,5 +10,29 @@ note: lint level defined here
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
-error: aborting due to previous error
+error: this expression will panic at runtime
+  --> $DIR/const-err2.rs:17:13
+   |
+LL |     let b = 200u8 + 200u8 + 200u8;
+   |             ^^^^^^^^^^^^^ attempt to add with overflow
+
+error: this expression will panic at runtime
+  --> $DIR/const-err2.rs:19:13
+   |
+LL |     let c = 200u8 * 4;
+   |             ^^^^^^^^^ attempt to multiply with overflow
+
+error: this expression will panic at runtime
+  --> $DIR/const-err2.rs:21:13
+   |
+LL |     let d = 42u8 - (42u8 + 1);
+   |             ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+
+error: index out of bounds: the len is 1 but the index is 1
+  --> $DIR/const-err2.rs:23:14
+   |
+LL |     let _e = [5u8][1];
+   |              ^^^^^^^^
+
+error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs
index a9a7a66fe614f..cd989731452b3 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors.rs
@@ -5,6 +5,7 @@
 fn main() {
     println!("{}", 0u32 - 1);
     let _x = 0u32 - 1;
+    //~^ ERROR this expression will panic at runtime [const_err]
     println!("{}", 1/(1-1));
     //~^ ERROR attempt to divide by zero [const_err]
     //~| ERROR reaching this expression at runtime will panic or abort [const_err]
diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr
index 3940fa13d7892..40d5c73e86679 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.stderr
@@ -1,8 +1,8 @@
-error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:8:20
+error: this expression will panic at runtime
+  --> $DIR/promoted_errors.rs:7:14
    |
-LL |     println!("{}", 1/(1-1));
-   |                    ^^^^^^^
+LL |     let _x = 0u32 - 1;
+   |              ^^^^^^^^ attempt to subtract with overflow
    |
 note: lint level defined here
   --> $DIR/promoted_errors.rs:3:9
@@ -10,47 +10,53 @@ note: lint level defined here
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
+error: attempt to divide by zero
+  --> $DIR/promoted_errors.rs:9:20
+   |
+LL |     println!("{}", 1/(1-1));
+   |                    ^^^^^^^
+
 error: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:8:20
+  --> $DIR/promoted_errors.rs:9:20
    |
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:11:14
+  --> $DIR/promoted_errors.rs:12:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:11:14
+  --> $DIR/promoted_errors.rs:12:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:14:20
+  --> $DIR/promoted_errors.rs:15:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^
 
 error: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:14:20
+  --> $DIR/promoted_errors.rs:15:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:17:14
+  --> $DIR/promoted_errors.rs:18:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:17:14
+  --> $DIR/promoted_errors.rs:18:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/consts/issue-64059.rs b/src/test/ui/consts/issue-64059.rs
index c4c895fef66cf..30b8744cb7fa7 100644
--- a/src/test/ui/consts/issue-64059.rs
+++ b/src/test/ui/consts/issue-64059.rs
@@ -1,5 +1,4 @@
-// run-pass
-
 fn main() {
     let _ = -(-0.0);
+    //~^ ERROR: this expression will panic at runtime
 }
diff --git a/src/test/ui/consts/issue-64059.stderr b/src/test/ui/consts/issue-64059.stderr
new file mode 100644
index 0000000000000..6f27653421bd6
--- /dev/null
+++ b/src/test/ui/consts/issue-64059.stderr
@@ -0,0 +1,10 @@
+error: this expression will panic at runtime
+  --> $DIR/issue-64059.rs:2:13
+   |
+LL |     let _ = -(-0.0);
+   |             ^^^^^^^ attempt to negate with overflow
+   |
+   = note: `#[deny(const_err)]` on by default
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issues/issue-8460-const.rs b/src/test/ui/issues/issue-8460-const.rs
index 6a5b98fa9b190..611d280f774c0 100644
--- a/src/test/ui/issues/issue-8460-const.rs
+++ b/src/test/ui/issues/issue-8460-const.rs
@@ -6,14 +6,19 @@ use std::thread;
 fn main() {
     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
     //~^ ERROR attempt to divide by zero
     //~| ERROR this expression will panic at runtime
@@ -31,14 +36,19 @@ fn main() {
     //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with a divisor of zero
     //~| ERROR this expression will panic at runtime
diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr
index b9fbf0bdaa609..31b1da4f804ab 100644
--- a/src/test/ui/issues/issue-8460-const.stderr
+++ b/src/test/ui/issues/issue-8460-const.stderr
@@ -10,179 +10,239 @@ note: lint level defined here
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:7:36
+   |
+LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^^^ attempt to divide with overflow
+
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:9:36
+  --> $DIR/issue-8460-const.rs:10:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:10:36
+   |
+LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^ attempt to divide with overflow
+
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:11:36
+  --> $DIR/issue-8460-const.rs:13:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: attempt to divide with overflow
+error: this expression will panic at runtime
   --> $DIR/issue-8460-const.rs:13:36
    |
+LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const.rs:16:36
+   |
 LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:16:36
+   |
+LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
+
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:15:36
+  --> $DIR/issue-8460-const.rs:19:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:19:36
+   |
+LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
+
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:17:36
+  --> $DIR/issue-8460-const.rs:22:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:17:36
+  --> $DIR/issue-8460-const.rs:22:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:20:36
+  --> $DIR/issue-8460-const.rs:25:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:20:36
+  --> $DIR/issue-8460-const.rs:25:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:23:36
+  --> $DIR/issue-8460-const.rs:28:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:23:36
+  --> $DIR/issue-8460-const.rs:28:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:26:36
+  --> $DIR/issue-8460-const.rs:31:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:26:36
+  --> $DIR/issue-8460-const.rs:31:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:29:36
+  --> $DIR/issue-8460-const.rs:34:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:29:36
+  --> $DIR/issue-8460-const.rs:34:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:32:36
+  --> $DIR/issue-8460-const.rs:37:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:37:36
+   |
+LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:34:36
+  --> $DIR/issue-8460-const.rs:40:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:40:36
+   |
+LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:36:36
+  --> $DIR/issue-8460-const.rs:43:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:43:36
+   |
+LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:38:36
+  --> $DIR/issue-8460-const.rs:46:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:46:36
+   |
+LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:40:36
+  --> $DIR/issue-8460-const.rs:49:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:49:36
+   |
+LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:42:36
+  --> $DIR/issue-8460-const.rs:52:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:42:36
+  --> $DIR/issue-8460-const.rs:52:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:45:36
+  --> $DIR/issue-8460-const.rs:55:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:45:36
+  --> $DIR/issue-8460-const.rs:55:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:48:36
+  --> $DIR/issue-8460-const.rs:58:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:48:36
+  --> $DIR/issue-8460-const.rs:58:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:51:36
+  --> $DIR/issue-8460-const.rs:61:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:51:36
+  --> $DIR/issue-8460-const.rs:61:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:54:36
+  --> $DIR/issue-8460-const.rs:64:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:54:36
+  --> $DIR/issue-8460-const.rs:64:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
-error: aborting due to 30 previous errors
+error: aborting due to 40 previous errors
 

From 141f5a7558289acb6c7aaf9c6500eb9f6dbeec1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 1 Sep 2019 11:20:33 -0700
Subject: [PATCH 412/943] review comments

---
 src/librustc/ty/context.rs        | 16 +-----
 src/librustc_typeck/check/expr.rs | 94 ++++++++++++++++++-------------
 2 files changed, 57 insertions(+), 53 deletions(-)

diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index f355e231914d2..17c9e520bcea2 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2403,20 +2403,8 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     #[inline]
-    pub fn mk_pin(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let def_id = self.require_lang_item(lang_items::PinTypeLangItem, None);
-        self.mk_generic_adt(def_id, ty)
-    }
-
-    #[inline]
-    pub fn mk_rc(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let def_id = self.require_lang_item(lang_items::Rc, None);
-        self.mk_generic_adt(def_id, ty)
-    }
-
-    #[inline]
-    pub fn mk_arc(self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        let def_id = self.require_lang_item(lang_items::Arc, None);
+    pub fn mk_lang_item(self, ty: Ty<'tcx>, item: lang_items::LangItem)  -> Ty<'tcx> {
+        let def_id = self.require_lang_item(item, None);
         self.mk_generic_adt(def_id, ty)
     }
 
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index efff8bcdacbcf..fbaa9904d8303 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -12,7 +12,7 @@ use crate::check::fatally_break_rust;
 use crate::check::report_unexpected_variant_res;
 use crate::check::Needs;
 use crate::check::TupleArgumentsFlag::DontTupleArguments;
-use crate::check::method::{probe, SelfSource};
+use crate::check::method::{probe, SelfSource, MethodError};
 use crate::util::common::ErrorReported;
 use crate::util::nodemap::FxHashMap;
 use crate::astconv::AstConv as _;
@@ -29,6 +29,7 @@ use rustc::hir::def::{CtorKind, Res, DefKind};
 use rustc::hir::ptr::P;
 use rustc::infer;
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc::middle::lang_items;
 use rustc::mir::interpret::GlobalId;
 use rustc::ty;
 use rustc::ty::adjustment::{
@@ -775,21 +776,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // no need to check for bot/err -- callee does that
         let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t);
 
-        let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| {
-            if let Ok(pick) = self.lookup_probe(
-                span,
-                segment.ident,
-                new_rcvr_t,
-                rcvr,
-                probe::ProbeScope::AllTraits,
-            ) {
-                err.span_label(
-                    pick.item.ident.span,
-                    &format!("the method is available for `{}` here", new_rcvr_t),
-                );
-            }
-        };
-
         let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) {
             Ok(method) => {
                 self.write_method_call(expr.hir_id, method);
@@ -797,29 +783,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             Err(error) => {
                 if segment.ident.name != kw::Invalid {
-                    if let Some(mut err) = self.report_method_error(
-                        span,
-                        rcvr_t,
-                        segment.ident,
-                        SelfSource::MethodCall(rcvr),
-                        error,
-                        Some(args),
-                    ) {
-                        if let ty::Adt(..) = rcvr_t.sty {
-                            // Try alternative arbitrary self types that could fulfill this call.
-                            // FIXME: probe for all types that *could* be arbitrary self-types, not
-                            // just this whitelist.
-                            let box_rcvr_t = self.tcx.mk_box(rcvr_t);
-                            try_alt_rcvr(&mut err, box_rcvr_t);
-                            let pin_rcvr_t = self.tcx.mk_pin(rcvr_t);
-                            try_alt_rcvr(&mut err, pin_rcvr_t);
-                            let arc_rcvr_t = self.tcx.mk_arc(rcvr_t);
-                            try_alt_rcvr(&mut err, arc_rcvr_t);
-                            let rc_rcvr_t = self.tcx.mk_rc(rcvr_t);
-                            try_alt_rcvr(&mut err, rc_rcvr_t);
-                        }
-                        err.emit();
-                    }
+                    self.report_extended_method_error(segment, span, args, rcvr_t, error);
                 }
                 Err(())
             }
@@ -836,6 +800,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         )
     }
 
+    fn report_extended_method_error(
+        &self,
+        segment: &hir::PathSegment,
+        span: Span,
+        args: &'tcx [hir::Expr],
+        rcvr_t: Ty<'tcx>,
+        error: MethodError<'tcx>
+    ) {
+        let rcvr = &args[0];
+        let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| {
+            if let Ok(pick) = self.lookup_probe(
+                span,
+                segment.ident,
+                new_rcvr_t,
+                rcvr,
+                probe::ProbeScope::AllTraits,
+            ) {
+                err.span_label(
+                    pick.item.ident.span,
+                    &format!("the method is available for `{}` here", new_rcvr_t),
+                );
+            }
+        };
+
+        if let Some(mut err) = self.report_method_error(
+            span,
+            rcvr_t,
+            segment.ident,
+            SelfSource::MethodCall(rcvr),
+            error,
+            Some(args),
+        ) {
+            if let ty::Adt(..) = rcvr_t.sty {
+                // Try alternative arbitrary self types that could fulfill this call.
+                // FIXME: probe for all types that *could* be arbitrary self-types, not
+                // just this whitelist.
+                let box_rcvr_t = self.tcx.mk_box(rcvr_t);
+                try_alt_rcvr(&mut err, box_rcvr_t);
+                let pin_rcvr_t = self.tcx.mk_lang_item(
+                    rcvr_t,
+                    lang_items::PinTypeLangItem,
+                );
+                try_alt_rcvr(&mut err, pin_rcvr_t);
+                let arc_rcvr_t = self.tcx.mk_lang_item(rcvr_t, lang_items::Arc);
+                try_alt_rcvr(&mut err, arc_rcvr_t);
+                let rc_rcvr_t = self.tcx.mk_lang_item(rcvr_t, lang_items::Rc);
+                try_alt_rcvr(&mut err, rc_rcvr_t);
+            }
+            err.emit();
+        }
+    }
+
     fn check_expr_cast(
         &self,
         e: &'tcx hir::Expr,

From 0cd9c1623fb5858990892fed2fbf7c06e7b25f22 Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Mon, 2 Sep 2019 03:40:35 +0900
Subject: [PATCH 413/943] Fix condition and tests' flags

---
 src/librustc_mir/transform/const_prop.rs      |   1 +
 src/test/ui/consts/const-err2.rs              |   2 +
 src/test/ui/consts/const-err2.stderr          |  28 ++--
 .../ui/consts/const-eval/promoted_errors.rs   |   5 +-
 .../consts/const-eval/promoted_errors.stderr  |  32 +++--
 src/test/ui/consts/issue-64059.rs             |   4 +-
 src/test/ui/consts/issue-64059.stderr         |  10 --
 src/test/ui/issues/issue-8460-const.rs        |  12 +-
 src/test/ui/issues/issue-8460-const.stderr    | 122 +++++-------------
 9 files changed, 75 insertions(+), 141 deletions(-)
 delete mode 100644 src/test/ui/consts/issue-64059.stderr

diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 091e68cd0669c..e4b186736e2a1 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -413,6 +413,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                             // We check overflow in debug mode already
                             // so should only check in release mode.
                             if !oflo_check
+                            && prim.layout.ty.is_signed()
                             && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
                                 throw_panic!(OverflowNeg)
                             }
diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs
index a5f685a159b39..cd6ac47bd92a8 100644
--- a/src/test/ui/consts/const-err2.rs
+++ b/src/test/ui/consts/const-err2.rs
@@ -5,6 +5,8 @@
 
 #![feature(rustc_attrs)]
 #![allow(exceeding_bitshifts)]
+// compile-flags: -C overflow-checks=on -O
+
 #![deny(const_err)]
 
 fn black_box<T>(_: T) {
diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr
index 659c3afc618a9..ecfced7f0db8b 100644
--- a/src/test/ui/consts/const-err2.stderr
+++ b/src/test/ui/consts/const-err2.stderr
@@ -1,35 +1,35 @@
-error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:15:13
+error: attempt to negate with overflow
+  --> $DIR/const-err2.rs:17:13
    |
 LL |     let a = -std::i8::MIN;
-   |             ^^^^^^^^^^^^^ attempt to negate with overflow
+   |             ^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/const-err2.rs:8:9
+  --> $DIR/const-err2.rs:10:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:17:13
+error: attempt to add with overflow
+  --> $DIR/const-err2.rs:19:13
    |
 LL |     let b = 200u8 + 200u8 + 200u8;
-   |             ^^^^^^^^^^^^^ attempt to add with overflow
+   |             ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:19:13
+error: attempt to multiply with overflow
+  --> $DIR/const-err2.rs:21:13
    |
 LL |     let c = 200u8 * 4;
-   |             ^^^^^^^^^ attempt to multiply with overflow
+   |             ^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:21:13
+error: attempt to subtract with overflow
+  --> $DIR/const-err2.rs:23:13
    |
 LL |     let d = 42u8 - (42u8 + 1);
-   |             ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
+   |             ^^^^^^^^^^^^^^^^^
 
 error: index out of bounds: the len is 1 but the index is 1
-  --> $DIR/const-err2.rs:23:14
+  --> $DIR/const-err2.rs:25:14
    |
 LL |     let _e = [5u8][1];
    |              ^^^^^^^^
diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs
index cd989731452b3..7adb394144bdd 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors.rs
@@ -1,11 +1,12 @@
-// compile-flags: -O
+// compile-flags: -C overflow-checks=on -O
 
 #![deny(const_err)]
 
 fn main() {
     println!("{}", 0u32 - 1);
+    //~^ ERROR attempt to subtract with overflow
     let _x = 0u32 - 1;
-    //~^ ERROR this expression will panic at runtime [const_err]
+    //~^ ERROR attempt to subtract with overflow
     println!("{}", 1/(1-1));
     //~^ ERROR attempt to divide by zero [const_err]
     //~| ERROR reaching this expression at runtime will panic or abort [const_err]
diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr
index 40d5c73e86679..fe63d0800dd7c 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.stderr
@@ -1,8 +1,8 @@
-error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:7:14
+error: attempt to subtract with overflow
+  --> $DIR/promoted_errors.rs:6:20
    |
-LL |     let _x = 0u32 - 1;
-   |              ^^^^^^^^ attempt to subtract with overflow
+LL |     println!("{}", 0u32 - 1);
+   |                    ^^^^^^^^
    |
 note: lint level defined here
   --> $DIR/promoted_errors.rs:3:9
@@ -10,53 +10,59 @@ note: lint level defined here
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
+error: attempt to subtract with overflow
+  --> $DIR/promoted_errors.rs:8:14
+   |
+LL |     let _x = 0u32 - 1;
+   |              ^^^^^^^^
+
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:9:20
+  --> $DIR/promoted_errors.rs:10:20
    |
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^
 
 error: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:9:20
+  --> $DIR/promoted_errors.rs:10:20
    |
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:12:14
+  --> $DIR/promoted_errors.rs:13:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:12:14
+  --> $DIR/promoted_errors.rs:13:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:15:20
+  --> $DIR/promoted_errors.rs:16:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^
 
 error: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:15:20
+  --> $DIR/promoted_errors.rs:16:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:18:14
+  --> $DIR/promoted_errors.rs:19:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:18:14
+  --> $DIR/promoted_errors.rs:19:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
-error: aborting due to 9 previous errors
+error: aborting due to 10 previous errors
 
diff --git a/src/test/ui/consts/issue-64059.rs b/src/test/ui/consts/issue-64059.rs
index 30b8744cb7fa7..38911c3dcf692 100644
--- a/src/test/ui/consts/issue-64059.rs
+++ b/src/test/ui/consts/issue-64059.rs
@@ -1,4 +1,6 @@
+// compile-flags: -C overflow-checks=on -O
+// run-pass
+
 fn main() {
     let _ = -(-0.0);
-    //~^ ERROR: this expression will panic at runtime
 }
diff --git a/src/test/ui/consts/issue-64059.stderr b/src/test/ui/consts/issue-64059.stderr
deleted file mode 100644
index 6f27653421bd6..0000000000000
--- a/src/test/ui/consts/issue-64059.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: this expression will panic at runtime
-  --> $DIR/issue-64059.rs:2:13
-   |
-LL |     let _ = -(-0.0);
-   |             ^^^^^^^ attempt to negate with overflow
-   |
-   = note: `#[deny(const_err)]` on by default
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/issues/issue-8460-const.rs b/src/test/ui/issues/issue-8460-const.rs
index 611d280f774c0..c3f53e3298b2b 100644
--- a/src/test/ui/issues/issue-8460-const.rs
+++ b/src/test/ui/issues/issue-8460-const.rs
@@ -1,3 +1,5 @@
+// compile-flags: -C overflow-checks=on -O
+
 #![deny(const_err)]
 
 use std::{isize, i8, i16, i32, i64};
@@ -6,19 +8,14 @@ use std::thread;
 fn main() {
     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
     //~^ ERROR attempt to divide by zero
     //~| ERROR this expression will panic at runtime
@@ -36,19 +33,14 @@ fn main() {
     //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
-    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with a divisor of zero
     //~| ERROR this expression will panic at runtime
diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr
index 31b1da4f804ab..914323227ddd2 100644
--- a/src/test/ui/issues/issue-8460-const.stderr
+++ b/src/test/ui/issues/issue-8460-const.stderr
@@ -1,248 +1,188 @@
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:7:36
+  --> $DIR/issue-8460-const.rs:9:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/issue-8460-const.rs:1:9
+  --> $DIR/issue-8460-const.rs:3:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:7:36
-   |
-LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^^^ attempt to divide with overflow
-
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:10:36
+  --> $DIR/issue-8460-const.rs:11:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:10:36
-   |
-LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^ attempt to divide with overflow
-
 error: attempt to divide with overflow
   --> $DIR/issue-8460-const.rs:13:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:13:36
-   |
-LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
-
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:16:36
+  --> $DIR/issue-8460-const.rs:15:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:16:36
-   |
-LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
-
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:19:36
+  --> $DIR/issue-8460-const.rs:17:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:19:36
-   |
-LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
-
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:22:36
+  --> $DIR/issue-8460-const.rs:19:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:22:36
+  --> $DIR/issue-8460-const.rs:19:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:25:36
+  --> $DIR/issue-8460-const.rs:22:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:25:36
+  --> $DIR/issue-8460-const.rs:22:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:28:36
+  --> $DIR/issue-8460-const.rs:25:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:28:36
+  --> $DIR/issue-8460-const.rs:25:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:31:36
+  --> $DIR/issue-8460-const.rs:28:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:31:36
+  --> $DIR/issue-8460-const.rs:28:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:34:36
+  --> $DIR/issue-8460-const.rs:31:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:34:36
+  --> $DIR/issue-8460-const.rs:31:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:37:36
+  --> $DIR/issue-8460-const.rs:34:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:37:36
-   |
-LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:40:36
+  --> $DIR/issue-8460-const.rs:36:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:40:36
-   |
-LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:43:36
+  --> $DIR/issue-8460-const.rs:38:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:43:36
-   |
-LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:46:36
+  --> $DIR/issue-8460-const.rs:40:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:46:36
-   |
-LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:49:36
+  --> $DIR/issue-8460-const.rs:42:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:49:36
-   |
-LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
-   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
-
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:52:36
+  --> $DIR/issue-8460-const.rs:44:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:52:36
+  --> $DIR/issue-8460-const.rs:44:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:55:36
+  --> $DIR/issue-8460-const.rs:47:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:55:36
+  --> $DIR/issue-8460-const.rs:47:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:58:36
+  --> $DIR/issue-8460-const.rs:50:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:58:36
+  --> $DIR/issue-8460-const.rs:50:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:61:36
+  --> $DIR/issue-8460-const.rs:53:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:61:36
+  --> $DIR/issue-8460-const.rs:53:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:64:36
+  --> $DIR/issue-8460-const.rs:56:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:64:36
+  --> $DIR/issue-8460-const.rs:56:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
-error: aborting due to 40 previous errors
+error: aborting due to 30 previous errors
 

From a937d8cdeb56ed72897ecf14469f89f18814554c Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Mon, 2 Sep 2019 05:01:39 +0900
Subject: [PATCH 414/943] Fix tests again

---
 src/test/ui/consts/const-err2.rs              |   3 +-
 src/test/ui/consts/const-err2.stderr          |  28 +--
 src/test/ui/consts/const-err3.rs              |  30 +++
 src/test/ui/consts/const-err3.stderr          |  38 ++++
 .../ui/consts/const-eval/promoted_errors.rs   |   5 +-
 .../consts/const-eval/promoted_errors.stderr  |  32 ++-
 .../ui/consts/const-eval/promoted_errors2.rs  |  22 ++
 .../consts/const-eval/promoted_errors2.stderr |  68 +++++++
 src/test/ui/consts/issue-64059-2.rs           |   6 +
 src/test/ui/consts/issue-64059.rs             |   1 -
 src/test/ui/issues/issue-8460-const.rs        |  12 +-
 src/test/ui/issues/issue-8460-const.stderr    | 122 +++++++++---
 src/test/ui/issues/issue-8460-const2.rs       |  59 ++++++
 src/test/ui/issues/issue-8460-const2.stderr   | 188 ++++++++++++++++++
 14 files changed, 542 insertions(+), 72 deletions(-)
 create mode 100644 src/test/ui/consts/const-err3.rs
 create mode 100644 src/test/ui/consts/const-err3.stderr
 create mode 100644 src/test/ui/consts/const-eval/promoted_errors2.rs
 create mode 100644 src/test/ui/consts/const-eval/promoted_errors2.stderr
 create mode 100644 src/test/ui/consts/issue-64059-2.rs
 create mode 100644 src/test/ui/issues/issue-8460-const2.rs
 create mode 100644 src/test/ui/issues/issue-8460-const2.stderr

diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs
index cd6ac47bd92a8..ecbcc2a4b496f 100644
--- a/src/test/ui/consts/const-err2.rs
+++ b/src/test/ui/consts/const-err2.rs
@@ -5,7 +5,6 @@
 
 #![feature(rustc_attrs)]
 #![allow(exceeding_bitshifts)]
-// compile-flags: -C overflow-checks=on -O
 
 #![deny(const_err)]
 
@@ -23,7 +22,7 @@ fn main() {
     let d = 42u8 - (42u8 + 1);
     //~^ ERROR const_err
     let _e = [5u8][1];
-    //~^ ERROR const_err
+    //~^ ERROR index out of bounds
     black_box(a);
     black_box(b);
     black_box(c);
diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr
index ecfced7f0db8b..1d84d44dc27b3 100644
--- a/src/test/ui/consts/const-err2.stderr
+++ b/src/test/ui/consts/const-err2.stderr
@@ -1,35 +1,35 @@
-error: attempt to negate with overflow
-  --> $DIR/const-err2.rs:17:13
+error: this expression will panic at runtime
+  --> $DIR/const-err2.rs:16:13
    |
 LL |     let a = -std::i8::MIN;
-   |             ^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^ attempt to negate with overflow
    |
 note: lint level defined here
-  --> $DIR/const-err2.rs:10:9
+  --> $DIR/const-err2.rs:9:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
-error: attempt to add with overflow
-  --> $DIR/const-err2.rs:19:13
+error: this expression will panic at runtime
+  --> $DIR/const-err2.rs:18:13
    |
 LL |     let b = 200u8 + 200u8 + 200u8;
-   |             ^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^ attempt to add with overflow
 
-error: attempt to multiply with overflow
-  --> $DIR/const-err2.rs:21:13
+error: this expression will panic at runtime
+  --> $DIR/const-err2.rs:20:13
    |
 LL |     let c = 200u8 * 4;
-   |             ^^^^^^^^^
+   |             ^^^^^^^^^ attempt to multiply with overflow
 
-error: attempt to subtract with overflow
-  --> $DIR/const-err2.rs:23:13
+error: this expression will panic at runtime
+  --> $DIR/const-err2.rs:22:13
    |
 LL |     let d = 42u8 - (42u8 + 1);
-   |             ^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
 
 error: index out of bounds: the len is 1 but the index is 1
-  --> $DIR/const-err2.rs:25:14
+  --> $DIR/const-err2.rs:24:14
    |
 LL |     let _e = [5u8][1];
    |              ^^^^^^^^
diff --git a/src/test/ui/consts/const-err3.rs b/src/test/ui/consts/const-err3.rs
new file mode 100644
index 0000000000000..a9cf04cda7a5a
--- /dev/null
+++ b/src/test/ui/consts/const-err3.rs
@@ -0,0 +1,30 @@
+// needed because negating int::MIN will behave differently between
+// optimized compilation and unoptimized compilation and thus would
+// lead to different lints being emitted
+// compile-flags: -C overflow-checks=on -O
+
+#![feature(rustc_attrs)]
+#![allow(exceeding_bitshifts)]
+
+#![deny(const_err)]
+
+fn black_box<T>(_: T) {
+    unimplemented!()
+}
+
+fn main() {
+    let a = -std::i8::MIN;
+    //~^ ERROR const_err
+    let b = 200u8 + 200u8 + 200u8;
+    //~^ ERROR const_err
+    let c = 200u8 * 4;
+    //~^ ERROR const_err
+    let d = 42u8 - (42u8 + 1);
+    //~^ ERROR const_err
+    let _e = [5u8][1];
+    //~^ ERROR const_err
+    black_box(a);
+    black_box(b);
+    black_box(c);
+    black_box(d);
+}
diff --git a/src/test/ui/consts/const-err3.stderr b/src/test/ui/consts/const-err3.stderr
new file mode 100644
index 0000000000000..0602707be7040
--- /dev/null
+++ b/src/test/ui/consts/const-err3.stderr
@@ -0,0 +1,38 @@
+error: attempt to negate with overflow
+  --> $DIR/const-err3.rs:16:13
+   |
+LL |     let a = -std::i8::MIN;
+   |             ^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/const-err3.rs:9:9
+   |
+LL | #![deny(const_err)]
+   |         ^^^^^^^^^
+
+error: attempt to add with overflow
+  --> $DIR/const-err3.rs:18:13
+   |
+LL |     let b = 200u8 + 200u8 + 200u8;
+   |             ^^^^^^^^^^^^^
+
+error: attempt to multiply with overflow
+  --> $DIR/const-err3.rs:20:13
+   |
+LL |     let c = 200u8 * 4;
+   |             ^^^^^^^^^
+
+error: attempt to subtract with overflow
+  --> $DIR/const-err3.rs:22:13
+   |
+LL |     let d = 42u8 - (42u8 + 1);
+   |             ^^^^^^^^^^^^^^^^^
+
+error: index out of bounds: the len is 1 but the index is 1
+  --> $DIR/const-err3.rs:24:14
+   |
+LL |     let _e = [5u8][1];
+   |              ^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs
index 7adb394144bdd..45941398f4b66 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors.rs
@@ -1,12 +1,11 @@
-// compile-flags: -C overflow-checks=on -O
+// compile-flags: -O
 
 #![deny(const_err)]
 
 fn main() {
     println!("{}", 0u32 - 1);
-    //~^ ERROR attempt to subtract with overflow
     let _x = 0u32 - 1;
-    //~^ ERROR attempt to subtract with overflow
+    //~^ ERROR const_err
     println!("{}", 1/(1-1));
     //~^ ERROR attempt to divide by zero [const_err]
     //~| ERROR reaching this expression at runtime will panic or abort [const_err]
diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr
index fe63d0800dd7c..40d5c73e86679 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.stderr
+++ b/src/test/ui/consts/const-eval/promoted_errors.stderr
@@ -1,8 +1,8 @@
-error: attempt to subtract with overflow
-  --> $DIR/promoted_errors.rs:6:20
+error: this expression will panic at runtime
+  --> $DIR/promoted_errors.rs:7:14
    |
-LL |     println!("{}", 0u32 - 1);
-   |                    ^^^^^^^^
+LL |     let _x = 0u32 - 1;
+   |              ^^^^^^^^ attempt to subtract with overflow
    |
 note: lint level defined here
   --> $DIR/promoted_errors.rs:3:9
@@ -10,59 +10,53 @@ note: lint level defined here
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
-error: attempt to subtract with overflow
-  --> $DIR/promoted_errors.rs:8:14
-   |
-LL |     let _x = 0u32 - 1;
-   |              ^^^^^^^^
-
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:10:20
+  --> $DIR/promoted_errors.rs:9:20
    |
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^
 
 error: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:10:20
+  --> $DIR/promoted_errors.rs:9:20
    |
 LL |     println!("{}", 1/(1-1));
    |                    ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:13:14
+  --> $DIR/promoted_errors.rs:12:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:13:14
+  --> $DIR/promoted_errors.rs:12:14
    |
 LL |     let _x = 1/(1-1);
    |              ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:16:20
+  --> $DIR/promoted_errors.rs:15:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^
 
 error: reaching this expression at runtime will panic or abort
-  --> $DIR/promoted_errors.rs:16:20
+  --> $DIR/promoted_errors.rs:15:20
    |
 LL |     println!("{}", 1/(false as u32));
    |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/promoted_errors.rs:19:14
+  --> $DIR/promoted_errors.rs:18:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/promoted_errors.rs:19:14
+  --> $DIR/promoted_errors.rs:18:14
    |
 LL |     let _x = 1/(false as u32);
    |              ^^^^^^^^^^^^^^^^ attempt to divide by zero
 
-error: aborting due to 10 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/consts/const-eval/promoted_errors2.rs b/src/test/ui/consts/const-eval/promoted_errors2.rs
new file mode 100644
index 0000000000000..7adb394144bdd
--- /dev/null
+++ b/src/test/ui/consts/const-eval/promoted_errors2.rs
@@ -0,0 +1,22 @@
+// compile-flags: -C overflow-checks=on -O
+
+#![deny(const_err)]
+
+fn main() {
+    println!("{}", 0u32 - 1);
+    //~^ ERROR attempt to subtract with overflow
+    let _x = 0u32 - 1;
+    //~^ ERROR attempt to subtract with overflow
+    println!("{}", 1/(1-1));
+    //~^ ERROR attempt to divide by zero [const_err]
+    //~| ERROR reaching this expression at runtime will panic or abort [const_err]
+    let _x = 1/(1-1);
+    //~^ ERROR const_err
+    //~| ERROR const_err
+    println!("{}", 1/(false as u32));
+    //~^ ERROR attempt to divide by zero [const_err]
+    //~| ERROR reaching this expression at runtime will panic or abort [const_err]
+    let _x = 1/(false as u32);
+    //~^ ERROR const_err
+    //~| ERROR const_err
+}
diff --git a/src/test/ui/consts/const-eval/promoted_errors2.stderr b/src/test/ui/consts/const-eval/promoted_errors2.stderr
new file mode 100644
index 0000000000000..2819e6e8fdbe0
--- /dev/null
+++ b/src/test/ui/consts/const-eval/promoted_errors2.stderr
@@ -0,0 +1,68 @@
+error: attempt to subtract with overflow
+  --> $DIR/promoted_errors2.rs:6:20
+   |
+LL |     println!("{}", 0u32 - 1);
+   |                    ^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/promoted_errors2.rs:3:9
+   |
+LL | #![deny(const_err)]
+   |         ^^^^^^^^^
+
+error: attempt to subtract with overflow
+  --> $DIR/promoted_errors2.rs:8:14
+   |
+LL |     let _x = 0u32 - 1;
+   |              ^^^^^^^^
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:10:20
+   |
+LL |     println!("{}", 1/(1-1));
+   |                    ^^^^^^^
+
+error: reaching this expression at runtime will panic or abort
+  --> $DIR/promoted_errors2.rs:10:20
+   |
+LL |     println!("{}", 1/(1-1));
+   |                    ^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:13:14
+   |
+LL |     let _x = 1/(1-1);
+   |              ^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/promoted_errors2.rs:13:14
+   |
+LL |     let _x = 1/(1-1);
+   |              ^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:16:20
+   |
+LL |     println!("{}", 1/(false as u32));
+   |                    ^^^^^^^^^^^^^^^^
+
+error: reaching this expression at runtime will panic or abort
+  --> $DIR/promoted_errors2.rs:16:20
+   |
+LL |     println!("{}", 1/(false as u32));
+   |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:19:14
+   |
+LL |     let _x = 1/(false as u32);
+   |              ^^^^^^^^^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/promoted_errors2.rs:19:14
+   |
+LL |     let _x = 1/(false as u32);
+   |              ^^^^^^^^^^^^^^^^ attempt to divide by zero
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/ui/consts/issue-64059-2.rs b/src/test/ui/consts/issue-64059-2.rs
new file mode 100644
index 0000000000000..38911c3dcf692
--- /dev/null
+++ b/src/test/ui/consts/issue-64059-2.rs
@@ -0,0 +1,6 @@
+// compile-flags: -C overflow-checks=on -O
+// run-pass
+
+fn main() {
+    let _ = -(-0.0);
+}
diff --git a/src/test/ui/consts/issue-64059.rs b/src/test/ui/consts/issue-64059.rs
index 38911c3dcf692..c4c895fef66cf 100644
--- a/src/test/ui/consts/issue-64059.rs
+++ b/src/test/ui/consts/issue-64059.rs
@@ -1,4 +1,3 @@
-// compile-flags: -C overflow-checks=on -O
 // run-pass
 
 fn main() {
diff --git a/src/test/ui/issues/issue-8460-const.rs b/src/test/ui/issues/issue-8460-const.rs
index c3f53e3298b2b..611d280f774c0 100644
--- a/src/test/ui/issues/issue-8460-const.rs
+++ b/src/test/ui/issues/issue-8460-const.rs
@@ -1,5 +1,3 @@
-// compile-flags: -C overflow-checks=on -O
-
 #![deny(const_err)]
 
 use std::{isize, i8, i16, i32, i64};
@@ -8,14 +6,19 @@ use std::thread;
 fn main() {
     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
     //~^ ERROR attempt to divide with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
     //~^ ERROR attempt to divide by zero
     //~| ERROR this expression will panic at runtime
@@ -33,14 +36,19 @@ fn main() {
     //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with overflow
+    //~| ERROR this expression will panic at runtime
     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
     //~^ ERROR attempt to calculate the remainder with a divisor of zero
     //~| ERROR this expression will panic at runtime
diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr
index 914323227ddd2..31b1da4f804ab 100644
--- a/src/test/ui/issues/issue-8460-const.stderr
+++ b/src/test/ui/issues/issue-8460-const.stderr
@@ -1,188 +1,248 @@
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:9:36
+  --> $DIR/issue-8460-const.rs:7:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/issue-8460-const.rs:3:9
+  --> $DIR/issue-8460-const.rs:1:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:7:36
+   |
+LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^^^ attempt to divide with overflow
+
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:11:36
+  --> $DIR/issue-8460-const.rs:10:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:10:36
+   |
+LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^ attempt to divide with overflow
+
 error: attempt to divide with overflow
   --> $DIR/issue-8460-const.rs:13:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:13:36
+   |
+LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
+
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:15:36
+  --> $DIR/issue-8460-const.rs:16:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:16:36
+   |
+LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
+
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:17:36
+  --> $DIR/issue-8460-const.rs:19:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
-error: attempt to divide by zero
+error: this expression will panic at runtime
   --> $DIR/issue-8460-const.rs:19:36
    |
+LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const.rs:22:36
+   |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:19:36
+  --> $DIR/issue-8460-const.rs:22:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:22:36
+  --> $DIR/issue-8460-const.rs:25:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:22:36
+  --> $DIR/issue-8460-const.rs:25:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:25:36
+  --> $DIR/issue-8460-const.rs:28:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:25:36
+  --> $DIR/issue-8460-const.rs:28:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:28:36
+  --> $DIR/issue-8460-const.rs:31:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:28:36
+  --> $DIR/issue-8460-const.rs:31:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:31:36
+  --> $DIR/issue-8460-const.rs:34:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:31:36
+  --> $DIR/issue-8460-const.rs:34:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:34:36
+  --> $DIR/issue-8460-const.rs:37:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:37:36
+   |
+LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:36:36
+  --> $DIR/issue-8460-const.rs:40:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:40:36
+   |
+LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:38:36
+  --> $DIR/issue-8460-const.rs:43:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:43:36
+   |
+LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:40:36
+  --> $DIR/issue-8460-const.rs:46:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:46:36
+   |
+LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:42:36
+  --> $DIR/issue-8460-const.rs:49:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const.rs:49:36
+   |
+LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
+
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:44:36
+  --> $DIR/issue-8460-const.rs:52:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:44:36
+  --> $DIR/issue-8460-const.rs:52:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:47:36
+  --> $DIR/issue-8460-const.rs:55:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:47:36
+  --> $DIR/issue-8460-const.rs:55:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:50:36
+  --> $DIR/issue-8460-const.rs:58:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:50:36
+  --> $DIR/issue-8460-const.rs:58:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:53:36
+  --> $DIR/issue-8460-const.rs:61:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:53:36
+  --> $DIR/issue-8460-const.rs:61:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:56:36
+  --> $DIR/issue-8460-const.rs:64:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:56:36
+  --> $DIR/issue-8460-const.rs:64:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
-error: aborting due to 30 previous errors
+error: aborting due to 40 previous errors
 
diff --git a/src/test/ui/issues/issue-8460-const2.rs b/src/test/ui/issues/issue-8460-const2.rs
new file mode 100644
index 0000000000000..c3f53e3298b2b
--- /dev/null
+++ b/src/test/ui/issues/issue-8460-const2.rs
@@ -0,0 +1,59 @@
+// compile-flags: -C overflow-checks=on -O
+
+#![deny(const_err)]
+
+use std::{isize, i8, i16, i32, i64};
+use std::thread;
+
+fn main() {
+    assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+}
diff --git a/src/test/ui/issues/issue-8460-const2.stderr b/src/test/ui/issues/issue-8460-const2.stderr
new file mode 100644
index 0000000000000..b688ec1367794
--- /dev/null
+++ b/src/test/ui/issues/issue-8460-const2.stderr
@@ -0,0 +1,188 @@
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:9:36
+   |
+LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/issue-8460-const2.rs:3:9
+   |
+LL | #![deny(const_err)]
+   |         ^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:11:36
+   |
+LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:13:36
+   |
+LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:15:36
+   |
+LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:17:36
+   |
+LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:19:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+   |                                    ^^^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:19:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+   |                                    ^^^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:22:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+   |                                    ^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:22:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+   |                                    ^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:25:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:25:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:28:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:28:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:31:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:31:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to divide by zero
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:34:36
+   |
+LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:36:36
+   |
+LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:38:36
+   |
+LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:40:36
+   |
+LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:42:36
+   |
+LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:44:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+   |                                    ^^^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:44:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+   |                                    ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:47:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+   |                                    ^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:47:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+   |                                    ^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:50:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:50:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:53:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:53:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:56:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:56:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: aborting due to 30 previous errors
+

From 4dec571ec69e14673b4e185e9881e4b71cd42aaa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 1 Sep 2019 15:09:05 -0700
Subject: [PATCH 415/943] Be accurate on `format!` parse error expectations

---
 src/libsyntax_ext/format.rs                      | 16 ++++++++++++----
 src/test/ui/codemap_tests/bad-format-args.rs     |  2 +-
 src/test/ui/codemap_tests/bad-format-args.stderr |  4 ++--
 src/test/ui/type/ascription/issue-54516.rs       |  2 +-
 src/test/ui/type/ascription/issue-54516.stderr   |  4 ++--
 5 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 47394c02b4186..d9ca693aca504 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -138,15 +138,23 @@ fn parse_args<'a>(
     }
 
     let fmtstr = p.parse_expr()?;
+    let mut first = true;
     let mut named = false;
 
     while p.token != token::Eof {
         if !p.eat(&token::Comma) {
-            let mut err = ecx.struct_span_err(p.token.span, "expected token: `,`");
-            err.span_label(p.token.span, "expected `,`");
-            p.maybe_annotate_with_ascription(&mut err, false);
-            return Err(err);
+            if first {
+                // After `format!(""` we always expect *only* a comma...
+                let mut err = ecx.struct_span_err(p.token.span, "expected token: `,`");
+                err.span_label(p.token.span, "expected `,`");
+                p.maybe_annotate_with_ascription(&mut err, false);
+                return Err(err);
+            } else {
+                // ...after that delegate to `expect` to also include the other expected tokens.
+                return Err(p.expect(&token::Comma).err().unwrap());
+            }
         }
+        first = false;
         if p.token == token::Eof {
             break;
         } // accept trailing commas
diff --git a/src/test/ui/codemap_tests/bad-format-args.rs b/src/test/ui/codemap_tests/bad-format-args.rs
index 9f90185774467..dff248344a53d 100644
--- a/src/test/ui/codemap_tests/bad-format-args.rs
+++ b/src/test/ui/codemap_tests/bad-format-args.rs
@@ -1,5 +1,5 @@
 fn main() {
     format!(); //~ ERROR requires at least a format string argument
     format!("" 1); //~ ERROR expected token: `,`
-    format!("", 1 1); //~ ERROR expected token: `,`
+    format!("", 1 1); //~ ERROR expected one of
 }
diff --git a/src/test/ui/codemap_tests/bad-format-args.stderr b/src/test/ui/codemap_tests/bad-format-args.stderr
index 5b01314d8ad4f..3372ef6dea1fc 100644
--- a/src/test/ui/codemap_tests/bad-format-args.stderr
+++ b/src/test/ui/codemap_tests/bad-format-args.stderr
@@ -12,11 +12,11 @@ error: expected token: `,`
 LL |     format!("" 1);
    |                ^ expected `,`
 
-error: expected token: `,`
+error: expected one of `,`, `.`, `?`, or an operator, found `1`
   --> $DIR/bad-format-args.rs:4:19
    |
 LL |     format!("", 1 1);
-   |                   ^ expected `,`
+   |                   ^ expected one of `,`, `.`, `?`, or an operator here
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/type/ascription/issue-54516.rs b/src/test/ui/type/ascription/issue-54516.rs
index 6d65760e299b5..b53bfe5df03f3 100644
--- a/src/test/ui/type/ascription/issue-54516.rs
+++ b/src/test/ui/type/ascription/issue-54516.rs
@@ -2,5 +2,5 @@ use std::collections::BTreeMap;
 
 fn main() {
     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
-    //~^ ERROR expected token: `,`
+    //~^ ERROR expected one of
 }
diff --git a/src/test/ui/type/ascription/issue-54516.stderr b/src/test/ui/type/ascription/issue-54516.stderr
index a846f3bc320e6..97942904a0ffa 100644
--- a/src/test/ui/type/ascription/issue-54516.stderr
+++ b/src/test/ui/type/ascription/issue-54516.stderr
@@ -1,8 +1,8 @@
-error: expected token: `,`
+error: expected one of `!`, `,`, or `::`, found `(`
   --> $DIR/issue-54516.rs:4:58
    |
 LL |     println!("{}", std::mem:size_of::<BTreeMap<u32, u32>>());
-   |                            -                             ^ expected `,`
+   |                            -                             ^ expected one of `!`, `,`, or `::` here
    |                            |
    |                            help: maybe write a path separator here: `::`
    |

From db576f8103ed0cdda4e77d977c1eab8456233e11 Mon Sep 17 00:00:00 2001
From: Baoshan Pang <baoshan.pang@windriver.com>
Date: Sun, 1 Sep 2019 17:56:36 -0700
Subject: [PATCH 416/943] vxWorks: set DEFAULT_MIN_STACK_SIZE to 256K and use
 min_stack to pass initial stack size to rtpSpawn

---
 src/libstd/sys/vxworks/process/process_vxworks.rs | 6 ++++--
 src/libstd/sys/vxworks/thread.rs                  | 4 +++-
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/libstd/sys/vxworks/process/process_vxworks.rs b/src/libstd/sys/vxworks/process/process_vxworks.rs
index b07966fa20626..12aa779746866 100644
--- a/src/libstd/sys/vxworks/process/process_vxworks.rs
+++ b/src/libstd/sys/vxworks/process/process_vxworks.rs
@@ -1,3 +1,5 @@
+// Copyright (c) 2019 Wind River Systems, Inc.
+
 use crate::io::{self, Error, ErrorKind};
 use libc::{self, c_int, c_char};
 use libc::{RTP_ID};
@@ -5,6 +7,7 @@ use crate::sys;
 use crate::sys::cvt;
 use crate::sys::process::rtp;
 use crate::sys::process::process_common::*;
+use crate::sys_common::thread;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Command
@@ -57,8 +60,7 @@ impl Command {
                 self.get_argv().as_ptr() as *const _, // argv
                 *sys::os::environ() as *const *const c_char,
                 100 as c_int,                         // initial priority
-                0x16000,                                    // initial stack size. 0 defaults
-                                                      // to 0x4000 in 32 bit and 0x8000 in 64 bit
+                thread::min_stack(),                  // initial stack size.
                 0,                                    // options
                 0                                     // task options
             );
diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs
index ef896f6a6e8cf..f9305afdeb6d1 100644
--- a/src/libstd/sys/vxworks/thread.rs
+++ b/src/libstd/sys/vxworks/thread.rs
@@ -1,3 +1,5 @@
+// Copyright (c) 2019 Wind River Systems, Inc.
+
 use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;
@@ -8,7 +10,7 @@ use crate::time::Duration;
 
 use crate::sys_common::thread::*;
 
-pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
+pub const DEFAULT_MIN_STACK_SIZE: usize = 0x40000; // 256K
 
 pub struct Thread {
     id: libc::pthread_t,

From 334d4657322a95b4160e03fecc815fc38ac56e82 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 1 Sep 2019 20:13:59 -0700
Subject: [PATCH 417/943] Point at appropriate arm on type error on
 if/else/match with one non-! arm

---
 src/librustc_typeck/check/mod.rs              | 43 ++++++++++++++++---
 ...-to-type-err-cause-on-impl-trait-return.rs |  2 +-
 ...type-err-cause-on-impl-trait-return.stderr | 20 ++++-----
 3 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a80550486d627..4a0b3879cb991 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3687,6 +3687,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
+    /// expression's `Span`, otherwise return `expr.span`. This is done to give bettern errors
+    /// when given code like the following:
+    /// ```text
+    /// if false { return 0i32; } else { 1u32 }
+    /// //                               ^^^^ point at this instead of the whole `if` expression
+    /// ```
+    fn get_expr_coercion_span(&self, expr: &hir::Expr) -> syntax_pos::Span {
+        if let hir::ExprKind::Match(_, arms, _) = &expr.node {
+            let arm_spans: Vec<Span> = arms.iter().filter_map(|arm| {
+                self.in_progress_tables
+                    .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
+                    .and_then(|arm_ty| {
+                        if arm_ty.is_never() {
+                            None
+                        } else {
+                            Some(match &arm.body.node {
+                                // Point at the tail expression when possible.
+                                hir::ExprKind::Block(block, _) => block.expr
+                                    .as_ref()
+                                    .map(|e| e.span)
+                                    .unwrap_or(block.span),
+                                _ => arm.body.span,
+                            })
+                        }
+                    })
+            }).collect();
+            if arm_spans.len() == 1 {
+                return arm_spans[0];
+            }
+        }
+        expr.span
+    }
+
     fn check_block_with_expected(
         &self,
         blk: &'tcx hir::Block,
@@ -3746,12 +3780,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let coerce = ctxt.coerce.as_mut().unwrap();
             if let Some(tail_expr_ty) = tail_expr_ty {
                 let tail_expr = tail_expr.unwrap();
-                let cause = self.cause(tail_expr.span,
-                                       ObligationCauseCode::BlockTailExpression(blk.hir_id));
-                coerce.coerce(self,
-                              &cause,
-                              tail_expr,
-                              tail_expr_ty);
+                let span = self.get_expr_coercion_span(tail_expr);
+                let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
+                coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
             } else {
                 // Subtle: if there is no explicit tail expression,
                 // that is typically equivalent to a tail expression
diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
index 95b40368143ef..d416db628c03f 100644
--- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
+++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
@@ -17,10 +17,10 @@ fn bar() -> impl std::fmt::Display {
 
 fn baz() -> impl std::fmt::Display {
     if false {
-    //~^ ERROR mismatched types
         return 0i32;
     } else {
         1u32
+        //~^ ERROR mismatched types
     }
 }
 
diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
index ee1e36081e778..47644d66d1a2c 100644
--- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
+++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
@@ -29,18 +29,16 @@ LL |         return 1u32;
               found type `u32`
 
 error[E0308]: mismatched types
-  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:19:5
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:22:9
    |
-LL |   fn baz() -> impl std::fmt::Display {
-   |               ---------------------- expected because this return type...
-LL | /     if false {
-LL | |
-LL | |         return 0i32;
-   | |                ---- ...is found to be `i32` here
-LL | |     } else {
-LL | |         1u32
-LL | |     }
-   | |_____^ expected i32, found u32
+LL | fn baz() -> impl std::fmt::Display {
+   |             ---------------------- expected because this return type...
+LL |     if false {
+LL |         return 0i32;
+   |                ---- ...is found to be `i32` here
+LL |     } else {
+LL |         1u32
+   |         ^^^^ expected i32, found u32
    |
    = note: expected type `i32`
               found type `u32`

From b0bb3017c12d8e2cafb6a9852a10e12dc8e044e9 Mon Sep 17 00:00:00 2001
From: Michael Woerister <michaelwoerister@posteo>
Date: Mon, 2 Sep 2019 13:50:44 +0200
Subject: [PATCH 418/943] Update xLTO compatibility table in rustc book.

---
 src/doc/rustc/src/linker-plugin-lto.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md
index 2ae726c4ba61d..6f1bbe60569fd 100644
--- a/src/doc/rustc/src/linker-plugin-lto.md
+++ b/src/doc/rustc/src/linker-plugin-lto.md
@@ -105,5 +105,6 @@ The following table shows known good combinations of toolchain versions.
 | Rust 1.34 |     ✗     |     ✓     |
 | Rust 1.35 |     ✗     |     ✓     |
 | Rust 1.36 |     ✗     |     ✓     |
+| Rust 1.37 |     ✗     |     ✓     |
 
 Note that the compatibility policy for this feature might change in the future.

From a80ab3a2f85240ec2f9bda00f7cae1abc50865ef Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Sat, 24 Aug 2019 23:45:47 +0200
Subject: [PATCH 419/943] Generate version file if it doesn't exist

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

diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 6805474aa049f..7983c973cf1ec 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -375,7 +375,7 @@ impl Step for Standalone {
                up_to_date(&footer, &html) &&
                up_to_date(&favicon, &html) &&
                up_to_date(&full_toc, &html) &&
-               up_to_date(&version_info, &html) &&
+               (builder.config.dry_run || up_to_date(&version_info, &html)) &&
                (builder.config.dry_run || up_to_date(&rustdoc, &html)) {
                 continue
             }

From 991f4366336820a61dd7f22e849c57d4a64b41ea Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Mon, 2 Sep 2019 15:58:05 +0200
Subject: [PATCH 420/943] Fix regex replacement in theme detection

---
 src/librustdoc/html/static/storage.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js
index 40a6a156972f6..eae998ca3ecbf 100644
--- a/src/librustdoc/html/static/storage.js
+++ b/src/librustdoc/html/static/storage.js
@@ -119,7 +119,7 @@ function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
 
 function getSystemValue() {
     var property = getComputedStyle(document.documentElement).getPropertyValue('content');
-    return property.replace(/\"\'/g, "");
+    return property.replace(/[\"\']/g, "");
 }
 
 switchTheme(currentTheme, mainTheme,

From bf44f12d66b011bf14c4bbe4a652a853ef3e52cb Mon Sep 17 00:00:00 2001
From: nathanwhit <nathan.whitaker01@gmail.com>
Date: Mon, 2 Sep 2019 12:00:55 -0400
Subject: [PATCH 421/943] Ignore check-run-results tests for wasm32-bare

Ignores run-pass tests with the `check-run-results` flag enabled for the
wasm32-bare ("wasm32-unknown-unknown") target, as it does not support
printing to stdout/stderr.
---
 src/tools/compiletest/src/header.rs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index dcd4f14f354d1..3ba8cffe2b559 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -137,6 +137,11 @@ impl EarlyProps {
                    config.parse_needs_sanitizer_support(ln) {
                     props.ignore = Ignore::Ignore;
                 }
+
+                if config.target == "wasm32-unknown-unknown" && config.parse_check_run_results(ln) {
+                    props.ignore = Ignore::Ignore;
+                }
+
             }
 
             if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoGdbLldb) &&

From dd870d742244fc8c9399bfac6f91e15a51d02d08 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 2 Sep 2019 10:19:09 -0700
Subject: [PATCH 422/943] fix typo

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

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 4a0b3879cb991..2cfe080771456 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3688,7 +3688,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
-    /// expression's `Span`, otherwise return `expr.span`. This is done to give bettern errors
+    /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
     /// when given code like the following:
     /// ```text
     /// if false { return 0i32; } else { 1u32 }

From 46877e289087c67d03572019fca9792d95e55e0c Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wwiser@gmail.com>
Date: Wed, 28 Aug 2019 20:18:25 -0400
Subject: [PATCH 423/943] Fix const eval bug breaking run-pass tests in Miri

PR #63580 broke miri's ability to run the run-pass test suite with MIR
optimizations enabled. The issue was that we weren't properly handling
the substs and DefId associated with a Promoted value. This didn't break
anything in rustc because in rustc this code runs before the Inliner
pass which is where the DefId and substs can diverge from their initial
values. It broke Miri though because it ran this code again after
running the optimization pass.
---
 src/librustc_mir/interpret/place.rs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 23c9e7fdf67ce..f358bb00f4d12 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -585,8 +585,9 @@ where
         use rustc::mir::StaticKind;
 
         Ok(match place_static.kind {
-            StaticKind::Promoted(promoted, _) => {
-                let instance = self.frame().instance;
+            StaticKind::Promoted(promoted, promoted_substs) => {
+                let substs = self.subst_from_frame_and_normalize_erasing_regions(promoted_substs);
+                let instance = ty::Instance::new(place_static.def_id, substs);
                 self.const_eval_raw(GlobalId {
                     instance,
                     promoted: Some(promoted),

From dd323f8a72327aba0b4771ea08a8b007bba995ca Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 2 Sep 2019 17:28:37 -0400
Subject: [PATCH 424/943] Emit error on intrinsic to fn ptr casts

---
 src/librustc/infer/error_reporting/mod.rs |  3 +++
 src/librustc/ty/error.rs                  |  5 +++++
 src/librustc/ty/structural_impls.rs       |  2 ++
 src/librustc_typeck/check/cast.rs         |  4 ++++
 src/librustc_typeck/check/coercion.rs     |  6 ++++++
 src/test/ui/reify-intrinsic.rs            | 15 +++++++++++++++
 src/test/ui/reify-intrinsic.stderr        | 22 ++++++++++++++++++++++
 7 files changed, 57 insertions(+)
 create mode 100644 src/test/ui/reify-intrinsic.rs
 create mode 100644 src/test/ui/reify-intrinsic.stderr

diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 9be73cf3c6d16..e684ccfeeb7ed 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1636,6 +1636,9 @@ impl<'tcx> ObligationCause<'tcx> {
                 TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_generator() => {
                     Error0644("closure/generator type that references itself")
                 }
+                TypeError::IntrinsicCast => {
+                    Error0308("cannot coerce intrinsics to function pointers")
+                }
                 _ => Error0308("mismatched types"),
             },
         }
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index c70006b68d69a..fe8f94ab1d314 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -46,6 +46,8 @@ pub enum TypeError<'tcx> {
     ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>),
 
     ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>),
+
+    IntrinsicCast,
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)]
@@ -179,6 +181,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             ConstMismatch(ref values) => {
                 write!(f, "expected `{}`, found `{}`", values.expected, values.found)
             }
+            IntrinsicCast => {
+                write!(f, "cannot coerce intrinsics to function pointers")
+            }
         }
     }
 }
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 649a5244728ba..ec7cf1a13c596 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -748,6 +748,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> {
             Sorts(ref x) => return tcx.lift(x).map(Sorts),
             ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch),
             ConstMismatch(ref x) => return tcx.lift(x).map(ConstMismatch),
+            IntrinsicCast => IntrinsicCast,
         })
     }
 }
@@ -1338,6 +1339,7 @@ EnumTypeFoldableImpl! {
         (ty::error::TypeError::Sorts)(x),
         (ty::error::TypeError::ExistentialMismatch)(x),
         (ty::error::TypeError::ConstMismatch)(x),
+        (ty::error::TypeError::IntrinsicCast),
     }
 }
 
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 55e7a10f1aaa4..c216cc92b1e58 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -40,6 +40,7 @@ use rustc::ty::{self, Ty, TypeFoldable, TypeAndMut};
 use rustc::ty::subst::SubstsRef;
 use rustc::ty::adjustment::AllowTwoPhase;
 use rustc::ty::cast::{CastKind, CastTy};
+use rustc::ty::error::TypeError;
 use rustc::middle::lang_items;
 use syntax::ast;
 use syntax_pos::Span;
@@ -461,6 +462,9 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                                              self.expr_ty,
                                              fcx.tcx.mk_fn_ptr(f),
                                              AllowTwoPhase::No);
+                    if let Err(TypeError::IntrinsicCast) = res {
+                        return Err(CastError::IllegalCast);
+                    }
                     if res.is_err() {
                         return Err(CastError::NonScalar);
                     }
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 61b9c2a15ba16..f2e1a6e29d6fc 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -70,6 +70,7 @@ use std::ops::Deref;
 use syntax::feature_gate;
 use syntax::symbol::sym;
 use syntax_pos;
+use rustc_target::spec::abi::Abi;
 
 struct Coerce<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
@@ -689,6 +690,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         match b.sty {
             ty::FnPtr(_) => {
                 let a_sig = a.fn_sig(self.tcx);
+                // Intrinsics are not coercible to function pointers
+                if a_sig.abi() == Abi::RustIntrinsic ||
+                   a_sig.abi() == Abi::PlatformIntrinsic {
+                   return Err(TypeError::IntrinsicCast);
+                }
                 let InferOk { value: a_sig, mut obligations } =
                     self.normalize_associated_types_in_as_infer_ok(self.cause.span, &a_sig);
 
diff --git a/src/test/ui/reify-intrinsic.rs b/src/test/ui/reify-intrinsic.rs
new file mode 100644
index 0000000000000..09baa059e5567
--- /dev/null
+++ b/src/test/ui/reify-intrinsic.rs
@@ -0,0 +1,15 @@
+// check-fail
+
+#![feature(intrinsics)]
+
+fn a() {
+    let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::transmute;
+    //~^ ERROR cannot coerce
+}
+
+fn b() {
+    let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize;
+    //~^ ERROR casting
+}
+
+fn main() {}
diff --git a/src/test/ui/reify-intrinsic.stderr b/src/test/ui/reify-intrinsic.stderr
new file mode 100644
index 0000000000000..4a1bd77cf7ee9
--- /dev/null
+++ b/src/test/ui/reify-intrinsic.stderr
@@ -0,0 +1,22 @@
+error[E0308]: cannot coerce intrinsics to function pointers
+  --> $DIR/reify-intrinsic.rs:6:64
+   |
+LL |     let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::transmute;
+   |                                                                ^^^^^^^^^^^^^^^^^^^
+   |                                                                |
+   |                                                                cannot coerce intrinsics to function pointers
+   |                                                                help: use parentheses to call this function: `std::mem::transmute(...)`
+   |
+   = note: expected type `unsafe extern "rust-intrinsic" fn(isize) -> usize`
+              found type `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}`
+
+error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid
+  --> $DIR/reify-intrinsic.rs:11:13
+   |
+LL |     let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0606.
+For more information about an error, try `rustc --explain E0308`.

From c430d743e90967e621e27cdbb8bd64de67969ca6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 2 Sep 2019 17:37:50 -0700
Subject: [PATCH 425/943] Add match test cases

---
 ...-to-type-err-cause-on-impl-trait-return.rs | 29 +++++++++++
 ...type-err-cause-on-impl-trait-return.stderr | 48 ++++++++++++++++++-
 2 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
index d416db628c03f..58109be447e07 100644
--- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
+++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
@@ -33,4 +33,33 @@ fn qux() -> impl std::fmt::Display {
     }
 }
 
+fn bat() -> impl std::fmt::Display {
+    match 13 {
+        0 => return 0i32,
+        _ => 1u32,
+        //~^ ERROR mismatched types
+    }
+}
+
+fn can() -> impl std::fmt::Display {
+    match 13 {
+    //~^ ERROR mismatched types
+        0 => return 0i32,
+        1 => 1u32,
+        _ => 2u32,
+    }
+}
+
+fn cat() -> impl std::fmt::Display {
+    match 13 {
+        0 => {
+            return 0i32;
+        }
+        _ => {
+            1u32
+            //~^ ERROR mismatched types
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
index 47644d66d1a2c..314ff84ae3c46 100644
--- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
+++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
@@ -59,6 +59,52 @@ LL | |     }
    = note: expected type `i32`
               found type `u32`
 
-error: aborting due to 4 previous errors
+error[E0308]: mismatched types
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:39:14
+   |
+LL | fn bat() -> impl std::fmt::Display {
+   |             ---------------------- expected because this return type...
+LL |     match 13 {
+LL |         0 => return 0i32,
+   |                     ---- ...is found to be `i32` here
+LL |         _ => 1u32,
+   |              ^^^^ expected i32, found u32
+   |
+   = note: expected type `i32`
+              found type `u32`
+
+error[E0308]: mismatched types
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:45:5
+   |
+LL |   fn can() -> impl std::fmt::Display {
+   |               ---------------------- expected because this return type...
+LL | /     match 13 {
+LL | |
+LL | |         0 => return 0i32,
+   | |                     ---- ...is found to be `i32` here
+LL | |         1 => 1u32,
+LL | |         _ => 2u32,
+LL | |     }
+   | |_____^ expected i32, found u32
+   |
+   = note: expected type `i32`
+              found type `u32`
+
+error[E0308]: mismatched types
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:59:13
+   |
+LL | fn cat() -> impl std::fmt::Display {
+   |             ---------------------- expected because this return type...
+...
+LL |             return 0i32;
+   |                    ---- ...is found to be `i32` here
+...
+LL |             1u32
+   |             ^^^^ expected i32, found u32
+   |
+   = note: expected type `i32`
+              found type `u32`
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0308`.

From 37f5cc22391e693523e8320a1d5c214610790911 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 2 Sep 2019 18:03:54 -0700
Subject: [PATCH 426/943] Do not complain about unconstrained params when Self
 is Ty Error

---
 .../constrained_generic_params.rs              | 18 ++++++++----------
 src/librustc_typeck/impl_wf_check.rs           |  4 ++++
 src/test/ui/issues/issue-36836.rs              |  5 +++++
 src/test/ui/issues/issue-36836.stderr          |  9 +++++++++
 4 files changed, 26 insertions(+), 10 deletions(-)
 create mode 100644 src/test/ui/issues/issue-36836.rs
 create mode 100644 src/test/ui/issues/issue-36836.stderr

diff --git a/src/librustc_typeck/constrained_generic_params.rs b/src/librustc_typeck/constrained_generic_params.rs
index 79a04b9423a8e..c95f81506cd59 100644
--- a/src/librustc_typeck/constrained_generic_params.rs
+++ b/src/librustc_typeck/constrained_generic_params.rs
@@ -20,10 +20,10 @@ impl From<ty::ParamConst> for Parameter {
 }
 
 /// Returns the set of parameters constrained by the impl header.
-pub fn parameters_for_impl<'tcx>(impl_self_ty: Ty<'tcx>,
-                                 impl_trait_ref: Option<ty::TraitRef<'tcx>>)
-                                 -> FxHashSet<Parameter>
-{
+pub fn parameters_for_impl<'tcx>(
+    impl_self_ty: Ty<'tcx>,
+    impl_trait_ref: Option<ty::TraitRef<'tcx>>,
+) -> FxHashSet<Parameter> {
     let vec = match impl_trait_ref {
         Some(tr) => parameters_for(&tr, false),
         None => parameters_for(&impl_self_ty, false),
@@ -36,12 +36,10 @@ pub fn parameters_for_impl<'tcx>(impl_self_ty: Ty<'tcx>,
 /// uniquely determined by `t` (see RFC 447). If it is true, return the list
 /// of parameters whose values are needed in order to constrain `ty` - these
 /// differ, with the latter being a superset, in the presence of projections.
-pub fn parameters_for<'tcx, T>(t: &T,
-                               include_nonconstraining: bool)
-                               -> Vec<Parameter>
-    where T: TypeFoldable<'tcx>
-{
-
+pub fn parameters_for<'tcx, T: TypeFoldable<'tcx>>(
+    t: &T,
+    include_nonconstraining: bool,
+) -> Vec<Parameter> {
     let mut collector = ParameterCollector {
         parameters: vec![],
         include_nonconstraining,
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index fcfd9adef54df..8e69fbd9a79ef 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -99,6 +99,10 @@ fn enforce_impl_params_are_constrained(
 ) {
     // Every lifetime used in an associated type must be constrained.
     let impl_self_ty = tcx.type_of(impl_def_id);
+    if impl_self_ty.sty == ty::Error {
+        // Don't complain about unconstrained type params when self ty doesn't exist. (#36836)
+        return;
+    }
     let impl_generics = tcx.generics_of(impl_def_id);
     let impl_predicates = tcx.predicates_of(impl_def_id);
     let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
diff --git a/src/test/ui/issues/issue-36836.rs b/src/test/ui/issues/issue-36836.rs
new file mode 100644
index 0000000000000..56d5a7cca4566
--- /dev/null
+++ b/src/test/ui/issues/issue-36836.rs
@@ -0,0 +1,5 @@
+trait Foo {}
+
+impl<T> Foo for Bar<T> {} //~ ERROR cannot find type `Bar` in this scope
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-36836.stderr b/src/test/ui/issues/issue-36836.stderr
new file mode 100644
index 0000000000000..bfda9b0bbdd7e
--- /dev/null
+++ b/src/test/ui/issues/issue-36836.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `Bar` in this scope
+  --> $DIR/issue-36836.rs:3:17
+   |
+LL | impl<T> Foo for Bar<T> {}
+   |                 ^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.

From 3ea932ab0e622104c97d3818350388de3012c833 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 2 Sep 2019 18:21:58 -0700
Subject: [PATCH 427/943] Refer to "`self` type" instead of "receiver type"

---
 src/librustc/infer/error_reporting/mod.rs     |  2 +-
 src/librustc/traits/object_safety.rs          | 16 ++--
 src/librustc_typeck/check/wfcheck.rs          | 36 ++++-----
 src/librustc_typeck/error_codes.rs            | 78 ++++++++++++++++++-
 src/test/ui/did_you_mean/issue-40006.stderr   |  2 +-
 src/test/ui/error-codes/E0033-teach.rs        |  2 +-
 src/test/ui/error-codes/E0033-teach.stderr    |  2 +-
 src/test/ui/error-codes/E0033.rs              |  2 +-
 src/test/ui/error-codes/E0033.stderr          |  2 +-
 .../explicit-self-lifetime-mismatch.rs        |  4 +-
 .../explicit-self-lifetime-mismatch.stderr    |  4 +-
 src/test/ui/issues/issue-17740.rs             |  4 +-
 src/test/ui/issues/issue-17740.stderr         |  4 +-
 src/test/ui/issues/issue-17905-2.rs           |  4 +-
 src/test/ui/issues/issue-17905-2.stderr       |  4 +-
 src/test/ui/issues/issue-19380.stderr         |  2 +-
 src/test/ui/issues/issue-56806.rs             |  5 +-
 src/test/ui/issues/issue-56806.stderr         |  5 +-
 .../object-safety-no-static.stderr            |  2 +-
 src/test/ui/resolve/issue-3907-2.stderr       |  2 +-
 src/test/ui/span/issue-27522.rs               |  2 +-
 src/test/ui/span/issue-27522.stderr           |  5 +-
 src/test/ui/traits/trait-object-safety.stderr |  4 +-
 src/test/ui/ufcs/ufcs-explicit-self-bad.rs    | 14 ++--
 .../ui/ufcs/ufcs-explicit-self-bad.stderr     | 23 +++---
 25 files changed, 155 insertions(+), 75 deletions(-)

diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 9be73cf3c6d16..baaccea16cb9b 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1627,7 +1627,7 @@ impl<'tcx> ObligationCause<'tcx> {
             MainFunctionType => Error0580("main function has wrong type"),
             StartFunctionType => Error0308("start function has wrong type"),
             IntrinsicType => Error0308("intrinsic has wrong type"),
-            MethodReceiver => Error0308("mismatched method receiver"),
+            MethodReceiver => Error0308("mismatched `self` parameter type"),
 
             // In the case where we have no more specific thing to
             // say, also take a look at the error code, maybe we can
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 7ea7bf0257cf7..aac722b56a983 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -47,13 +47,15 @@ impl ObjectSafetyViolation {
                 "the trait cannot use `Self` as a type parameter \
                  in the supertraits or where-clauses".into(),
             ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) =>
-                format!("method `{}` has no receiver", name).into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) =>
-                format!("method `{}` references the `Self` type \
-                         in its arguments or return type", name).into(),
-            ObjectSafetyViolation::Method(name,
-                                            MethodViolationCode::WhereClauseReferencesSelf(_)) =>
-                format!("method `{}` references the `Self` type in where clauses", name).into(),
+                format!("associated function `{}` has no `self` parameter", name).into(),
+            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) => format!(
+                "method `{}` references the `Self` type in its arguments or return type",
+                name,
+            ).into(),
+            ObjectSafetyViolation::Method(
+                name,
+                MethodViolationCode::WhereClauseReferencesSelf(_),
+            ) => format!("method `{}` references the `Self` type in where clauses", name).into(),
             ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
                 format!("method `{}` has generic type parameters", name).into(),
             ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver) =>
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index f95b3e44bf0f7..ac8ee43dd0801 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -762,19 +762,19 @@ fn check_opaque_types<'fcx, 'tcx>(
     substituted_predicates
 }
 
+const HELP_FOR_SELF_TYPE: &str =
+    "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
+     `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
+     of the previous types except `Self`)";
+
 fn check_method_receiver<'fcx, 'tcx>(
     fcx: &FnCtxt<'fcx, 'tcx>,
     method_sig: &hir::MethodSig,
     method: &ty::AssocItem,
     self_ty: Ty<'tcx>,
 ) {
-    const HELP_FOR_SELF_TYPE: &str =
-        "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
-         `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
-         of the previous types except `Self`)";
     // Check that the method has a valid receiver type, given the type `Self`.
-    debug!("check_method_receiver({:?}, self_ty={:?})",
-           method, self_ty);
+    debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty);
 
     if !method.method_has_self_argument {
         return;
@@ -805,12 +805,7 @@ fn check_method_receiver<'fcx, 'tcx>(
     if fcx.tcx.features().arbitrary_self_types {
         if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {
             // Report error; `arbitrary_self_types` was enabled.
-            fcx.tcx.sess.diagnostic().mut_span_err(
-                span, &format!("invalid method receiver type: {:?}", receiver_ty)
-            ).note("type of `self` must be `Self` or a type that dereferences to it")
-            .help(HELP_FOR_SELF_TYPE)
-            .code(DiagnosticId::Error("E0307".into()))
-            .emit();
+            e0307(fcx, span, receiver_ty);
         }
     } else {
         if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) {
@@ -830,17 +825,22 @@ fn check_method_receiver<'fcx, 'tcx>(
                 .emit();
             } else {
                 // Report error; would not have worked with `arbitrary_self_types`.
-                fcx.tcx.sess.diagnostic().mut_span_err(
-                    span, &format!("invalid method receiver type: {:?}", receiver_ty)
-                ).note("type must be `Self` or a type that dereferences to it")
-                .help(HELP_FOR_SELF_TYPE)
-                .code(DiagnosticId::Error("E0307".into()))
-                .emit();
+                e0307(fcx, span, receiver_ty);
             }
         }
     }
 }
 
+fn e0307(fcx: &FnCtxt<'fcx, 'tcx>, span: Span, receiver_ty: Ty<'_>) {
+    fcx.tcx.sess.diagnostic().mut_span_err(
+        span,
+        &format!("invalid `self` parameter type: {:?}", receiver_ty)
+    ).note("type of `self` must be `Self` or a type that dereferences to it")
+    .help(HELP_FOR_SELF_TYPE)
+    .code(DiagnosticId::Error("E0307".into()))
+    .emit();
+}
+
 /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
 /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
 /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index b52183d4b1b56..ae0f17892959d 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -2425,6 +2425,83 @@ struct Bar<S, T> { x: Foo<S, T> }
 ```
 "##,
 
+E0307: r##"
+This error indicates that the `self` parameter in a method has an invalid
+"reciever type".
+
+Methods take a special first parameter, of which there are three variants:
+`self`, `&self`, and `&mut self`. The type `Self` acts as an alias to the
+type of the current trait implementor, or "receiver type". Besides the
+already mentioned `Self`, `&Self` and `&mut Self` valid receiver types, the
+following are also valid, if less common: `self: Box<Self>`,
+`self: Rc<Self>`, `self: Arc<Self>`, and `self: Pin<P>` (where P is one of
+the previous types except `Self`).
+
+```
+# struct Foo;
+trait Trait {
+    fn foo(&self);
+//         ^^^^^ this let's you refer to the type that implements this trait
+}
+impl Trait for Foo {
+//             ^^^ this is the "receiver type"
+    fn foo(&self) {}
+//         ^^^^^ this is of type `Foo`
+}
+```
+
+The above is equivalent to:
+
+```
+# struct Foo;
+# trait Trait {
+#     fn foo(&self);
+# }
+impl Trait for Foo {
+    fn foo(&self: &Foo) {}
+}
+```
+
+When using an invalid reciver type, like in the following example,
+
+```compile_fail,E0307
+# struct Foo;
+# struct Bar;
+# trait Trait {
+#     fn foo(&self);
+# }
+impl Trait for Struct {
+    fn foo(&self: &Bar) {}
+}
+```
+
+The nightly feature [Arbintrary self types][AST] extends the accepted
+receiver type to also include any type that can dereference to `Self`:
+
+```
+#![feature(arbitrary_self_types)]
+
+struct Foo;
+struct Bar;
+
+// Because you can dereference `Bar` into `Foo`...
+impl std::ops::Deref for Bar {
+    type Target = Foo;
+
+    fn deref(&self) -> &Foo {
+        &Foo
+    }
+}
+
+impl Foo {
+    fn foo(self: Bar) {}
+//         ^^^^^^^^^ ...it can be used as the receiver type
+}
+```
+
+[AST]: https://doc.rust-lang.org/unstable-book/language-features/arbitrary-self-types.html
+"##,
+
 E0321: r##"
 A cross-crate opt-out trait was implemented on something which wasn't a struct
 or enum type. Erroneous code example:
@@ -4851,7 +4928,6 @@ register_diagnostics! {
 //  E0247,
 //  E0248, // value used as a type, now reported earlier during resolution as E0412
 //  E0249,
-    E0307, // invalid method `self` type
 //  E0319, // trait impls for defaulted traits allowed just for structs/enums
 //  E0372, // coherence not object safe
     E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr
index 87e48cd1e1cd9..6f219a6e0b1fe 100644
--- a/src/test/ui/did_you_mean/issue-40006.stderr
+++ b/src/test/ui/did_you_mean/issue-40006.stderr
@@ -62,7 +62,7 @@ error[E0038]: the trait `X` cannot be made into an object
 LL | impl dyn X {
    |      ^^^^^ the trait `X` cannot be made into an object
    |
-   = note: method `xxx` has no receiver
+   = note: associated function `xxx` has no `self` parameter
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/error-codes/E0033-teach.rs b/src/test/ui/error-codes/E0033-teach.rs
index 6a27b07fa8b77..9b5e719781281 100644
--- a/src/test/ui/error-codes/E0033-teach.rs
+++ b/src/test/ui/error-codes/E0033-teach.rs
@@ -8,7 +8,7 @@ fn main() {
     let trait_obj: &dyn SomeTrait = SomeTrait;
     //~^ ERROR expected value, found trait `SomeTrait`
     //~| ERROR E0038
-    //~| method `foo` has no receiver
+    //~| associated function `foo` has no `self` parameter
 
     let &invalid = trait_obj;
     //~^ ERROR E0033
diff --git a/src/test/ui/error-codes/E0033-teach.stderr b/src/test/ui/error-codes/E0033-teach.stderr
index fb630de7fc147..1d4c2d788a43b 100644
--- a/src/test/ui/error-codes/E0033-teach.stderr
+++ b/src/test/ui/error-codes/E0033-teach.stderr
@@ -10,7 +10,7 @@ error[E0038]: the trait `SomeTrait` cannot be made into an object
 LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
    |                    ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
    |
-   = note: method `foo` has no receiver
+   = note: associated function `foo` has no `self` parameter
 
 error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
   --> $DIR/E0033-teach.rs:13:9
diff --git a/src/test/ui/error-codes/E0033.rs b/src/test/ui/error-codes/E0033.rs
index 582600e110ba0..86dacfd1a47ba 100644
--- a/src/test/ui/error-codes/E0033.rs
+++ b/src/test/ui/error-codes/E0033.rs
@@ -6,7 +6,7 @@ fn main() {
     let trait_obj: &dyn SomeTrait = SomeTrait;
     //~^ ERROR expected value, found trait `SomeTrait`
     //~| ERROR E0038
-    //~| method `foo` has no receiver
+    //~| associated function `foo` has no `self` parameter
 
     let &invalid = trait_obj;
     //~^ ERROR E0033
diff --git a/src/test/ui/error-codes/E0033.stderr b/src/test/ui/error-codes/E0033.stderr
index fe9f45d86a6a0..803d7917e5638 100644
--- a/src/test/ui/error-codes/E0033.stderr
+++ b/src/test/ui/error-codes/E0033.stderr
@@ -10,7 +10,7 @@ error[E0038]: the trait `SomeTrait` cannot be made into an object
 LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
    |                    ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
    |
-   = note: method `foo` has no receiver
+   = note: associated function `foo` has no `self` parameter
 
 error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
   --> $DIR/E0033.rs:11:9
diff --git a/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs b/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs
index 82c64bcf6a767..9ab8e13893bc7 100644
--- a/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs
+++ b/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs
@@ -6,11 +6,11 @@ struct Foo<'a,'b> {
 impl<'a,'b> Foo<'a,'b> {
     fn bar(self:
            Foo<'b,'a>
-    //~^ ERROR mismatched method receiver
+    //~^ ERROR mismatched `self` parameter type
     //~| expected type `Foo<'a, 'b>`
     //~| found type `Foo<'b, 'a>`
     //~| lifetime mismatch
-    //~| ERROR mismatched method receiver
+    //~| ERROR mismatched `self` parameter type
     //~| expected type `Foo<'a, 'b>`
     //~| found type `Foo<'b, 'a>`
     //~| lifetime mismatch
diff --git a/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr b/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr
index e6f9eded9a4f3..4bf2d573d4f96 100644
--- a/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr
+++ b/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr
@@ -1,4 +1,4 @@
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/explicit-self-lifetime-mismatch.rs:8:12
    |
 LL |            Foo<'b,'a>
@@ -17,7 +17,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
 LL | impl<'a,'b> Foo<'a,'b> {
    |      ^^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/explicit-self-lifetime-mismatch.rs:8:12
    |
 LL |            Foo<'b,'a>
diff --git a/src/test/ui/issues/issue-17740.rs b/src/test/ui/issues/issue-17740.rs
index c131b895849ae..b47568400c3b7 100644
--- a/src/test/ui/issues/issue-17740.rs
+++ b/src/test/ui/issues/issue-17740.rs
@@ -4,11 +4,11 @@ struct Foo<'a> {
 
 impl <'a> Foo<'a>{
     fn bar(self: &mut Foo) {
-    //~^ mismatched method receiver
+    //~^ mismatched `self` parameter type
     //~| expected type `Foo<'a>`
     //~| found type `Foo<'_>`
     //~| lifetime mismatch
-    //~| mismatched method receiver
+    //~| mismatched `self` parameter type
     //~| expected type `Foo<'a>`
     //~| found type `Foo<'_>`
     //~| lifetime mismatch
diff --git a/src/test/ui/issues/issue-17740.stderr b/src/test/ui/issues/issue-17740.stderr
index 7ab0fa4d818b0..b8a0a0676319a 100644
--- a/src/test/ui/issues/issue-17740.stderr
+++ b/src/test/ui/issues/issue-17740.stderr
@@ -1,4 +1,4 @@
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/issue-17740.rs:6:18
    |
 LL |     fn bar(self: &mut Foo) {
@@ -23,7 +23,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
 LL | impl <'a> Foo<'a>{
    |       ^^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/issue-17740.rs:6:18
    |
 LL |     fn bar(self: &mut Foo) {
diff --git a/src/test/ui/issues/issue-17905-2.rs b/src/test/ui/issues/issue-17905-2.rs
index 259d945018938..44279cc867b46 100644
--- a/src/test/ui/issues/issue-17905-2.rs
+++ b/src/test/ui/issues/issue-17905-2.rs
@@ -6,8 +6,8 @@ impl Pair<
     isize
 > {
     fn say(self: &Pair<&str, isize>) {
-//~^ ERROR mismatched method receiver
-//~| ERROR mismatched method receiver
+//~^ ERROR mismatched `self` parameter type
+//~| ERROR mismatched `self` parameter type
         println!("{:?}", self);
     }
 }
diff --git a/src/test/ui/issues/issue-17905-2.stderr b/src/test/ui/issues/issue-17905-2.stderr
index e3909e0c1253f..585bc9c14883b 100644
--- a/src/test/ui/issues/issue-17905-2.stderr
+++ b/src/test/ui/issues/issue-17905-2.stderr
@@ -1,4 +1,4 @@
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/issue-17905-2.rs:8:18
    |
 LL |     fn say(self: &Pair<&str, isize>) {
@@ -21,7 +21,7 @@ note: ...does not necessarily outlive the lifetime '_ as defined on the impl at
 LL |     &str,
    |     ^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/issue-17905-2.rs:8:18
    |
 LL |     fn say(self: &Pair<&str, isize>) {
diff --git a/src/test/ui/issues/issue-19380.stderr b/src/test/ui/issues/issue-19380.stderr
index 27e3ff57bf9ab..d70a7c2b5299c 100644
--- a/src/test/ui/issues/issue-19380.stderr
+++ b/src/test/ui/issues/issue-19380.stderr
@@ -4,7 +4,7 @@ error[E0038]: the trait `Qiz` cannot be made into an object
 LL |   foos: &'static [&'static (dyn Qiz + 'static)]
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object
    |
-   = note: method `qiz` has no receiver
+   = note: associated function `qiz` has no `self` parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-56806.rs b/src/test/ui/issues/issue-56806.rs
index b6454e578e6af..b1dac26d65a15 100644
--- a/src/test/ui/issues/issue-56806.rs
+++ b/src/test/ui/issues/issue-56806.rs
@@ -1,7 +1,6 @@
 pub trait Trait {
     fn dyn_instead_of_self(self: Box<dyn Trait>);
-    //~^ ERROR invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)>
+    //~^ ERROR invalid `self` parameter type
 }
 
-pub fn main() {
-}
+pub fn main() {}
diff --git a/src/test/ui/issues/issue-56806.stderr b/src/test/ui/issues/issue-56806.stderr
index fae6a26720f36..a4f9aadcfef3e 100644
--- a/src/test/ui/issues/issue-56806.stderr
+++ b/src/test/ui/issues/issue-56806.stderr
@@ -1,11 +1,12 @@
-error[E0307]: invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)>
+error[E0307]: invalid `self` parameter type: std::boxed::Box<(dyn Trait + 'static)>
   --> $DIR/issue-56806.rs:2:34
    |
 LL |     fn dyn_instead_of_self(self: Box<dyn Trait>);
    |                                  ^^^^^^^^^^^^^^
    |
-   = note: type must be `Self` or a type that dereferences to it
+   = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0307`.
diff --git a/src/test/ui/object-safety/object-safety-no-static.stderr b/src/test/ui/object-safety/object-safety-no-static.stderr
index da8dd657c2a9d..c189c358b4223 100644
--- a/src/test/ui/object-safety/object-safety-no-static.stderr
+++ b/src/test/ui/object-safety/object-safety-no-static.stderr
@@ -4,7 +4,7 @@ error[E0038]: the trait `Foo` cannot be made into an object
 LL | fn foo_implicit<T:Foo+'static>(b: Box<T>) -> Box<dyn Foo + 'static> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
    |
-   = note: method `foo` has no receiver
+   = note: associated function `foo` has no `self` parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr
index 968c1f3e463d0..63ac11dc8ae01 100644
--- a/src/test/ui/resolve/issue-3907-2.stderr
+++ b/src/test/ui/resolve/issue-3907-2.stderr
@@ -4,7 +4,7 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
 LL | fn bar(_x: Foo) {}
    | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
    |
-   = note: method `bar` has no receiver
+   = note: associated function `bar` has no `self` parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/issue-27522.rs b/src/test/ui/span/issue-27522.rs
index 5c9893f64a6ee..7a0cfb679ed67 100644
--- a/src/test/ui/span/issue-27522.rs
+++ b/src/test/ui/span/issue-27522.rs
@@ -3,7 +3,7 @@
 struct SomeType {}
 
 trait Foo {
-    fn handler(self: &SomeType); //~ ERROR invalid method receiver type
+    fn handler(self: &SomeType); //~ ERROR invalid `self` parameter type
 }
 
 fn main() {}
diff --git a/src/test/ui/span/issue-27522.stderr b/src/test/ui/span/issue-27522.stderr
index 88dfee1cada3f..8a254a9685543 100644
--- a/src/test/ui/span/issue-27522.stderr
+++ b/src/test/ui/span/issue-27522.stderr
@@ -1,11 +1,12 @@
-error[E0307]: invalid method receiver type: &SomeType
+error[E0307]: invalid `self` parameter type: &SomeType
   --> $DIR/issue-27522.rs:6:22
    |
 LL |     fn handler(self: &SomeType);
    |                      ^^^^^^^^^
    |
-   = note: type must be `Self` or a type that dereferences to it
+   = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0307`.
diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr
index 68edc17870534..7f6bc0ebb70e5 100644
--- a/src/test/ui/traits/trait-object-safety.stderr
+++ b/src/test/ui/traits/trait-object-safety.stderr
@@ -4,7 +4,7 @@ error[E0038]: the trait `Tr` cannot be made into an object
 LL |     let _: &dyn Tr = &St;
    |                      ^^^ the trait `Tr` cannot be made into an object
    |
-   = note: method `foo` has no receiver
+   = note: associated function `foo` has no `self` parameter
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St`
 
 error[E0038]: the trait `Tr` cannot be made into an object
@@ -13,7 +13,7 @@ error[E0038]: the trait `Tr` cannot be made into an object
 LL |     let _: &dyn Tr = &St;
    |            ^^^^^^^ the trait `Tr` cannot be made into an object
    |
-   = note: method `foo` has no receiver
+   = note: associated function `foo` has no `self` parameter
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/ufcs/ufcs-explicit-self-bad.rs b/src/test/ui/ufcs/ufcs-explicit-self-bad.rs
index c6ff94a5e7606..bdb8e197fbe49 100644
--- a/src/test/ui/ufcs/ufcs-explicit-self-bad.rs
+++ b/src/test/ui/ufcs/ufcs-explicit-self-bad.rs
@@ -6,7 +6,7 @@ struct Foo {
 
 impl Foo {
     fn foo(self: isize, x: isize) -> isize {
-        //~^ ERROR invalid method receiver type
+        //~^ ERROR invalid `self` parameter type
         self.f + x
     }
 }
@@ -17,11 +17,11 @@ struct Bar<T> {
 
 impl<T> Bar<T> {
     fn foo(self: Bar<isize>, x: isize) -> isize {
-        //~^ ERROR invalid method receiver type
+        //~^ ERROR invalid `self` parameter type
         x
     }
     fn bar(self: &Bar<usize>, x: isize) -> isize {
-        //~^ ERROR invalid method receiver type
+        //~^ ERROR invalid `self` parameter type
         x
     }
 }
@@ -34,14 +34,14 @@ trait SomeTrait {
 
 impl<'a, T> SomeTrait for &'a Bar<T> {
     fn dummy1(self: &&'a Bar<T>) { }
-    fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched method receiver
-    //~^ ERROR mismatched method receiver
+    fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched `self` parameter type
+    //~^ ERROR mismatched `self` parameter type
     fn dummy3(self: &&Bar<T>) {}
-    //~^ ERROR mismatched method receiver
+    //~^ ERROR mismatched `self` parameter type
     //~| expected type `&'a Bar<T>`
     //~| found type `&Bar<T>`
     //~| lifetime mismatch
-    //~| ERROR mismatched method receiver
+    //~| ERROR mismatched `self` parameter type
     //~| expected type `&'a Bar<T>`
     //~| found type `&Bar<T>`
     //~| lifetime mismatch
diff --git a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr
index 6da20e37577b0..b2fe1b281fc99 100644
--- a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr
+++ b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr
@@ -1,31 +1,31 @@
-error[E0307]: invalid method receiver type: isize
+error[E0307]: invalid `self` parameter type: isize
   --> $DIR/ufcs-explicit-self-bad.rs:8:18
    |
 LL |     fn foo(self: isize, x: isize) -> isize {
    |                  ^^^^^
    |
-   = note: type must be `Self` or a type that dereferences to it
+   = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error[E0307]: invalid method receiver type: Bar<isize>
+error[E0307]: invalid `self` parameter type: Bar<isize>
   --> $DIR/ufcs-explicit-self-bad.rs:19:18
    |
 LL |     fn foo(self: Bar<isize>, x: isize) -> isize {
    |                  ^^^^^^^^^^
    |
-   = note: type must be `Self` or a type that dereferences to it
+   = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error[E0307]: invalid method receiver type: &Bar<usize>
+error[E0307]: invalid `self` parameter type: &Bar<usize>
   --> $DIR/ufcs-explicit-self-bad.rs:23:18
    |
 LL |     fn bar(self: &Bar<usize>, x: isize) -> isize {
    |                  ^^^^^^^^^^^
    |
-   = note: type must be `Self` or a type that dereferences to it
+   = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/ufcs-explicit-self-bad.rs:37:21
    |
 LL |     fn dummy2(self: &Bar<T>) {}
@@ -44,7 +44,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
 LL | impl<'a, T> SomeTrait for &'a Bar<T> {
    |      ^^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/ufcs-explicit-self-bad.rs:37:21
    |
 LL |     fn dummy2(self: &Bar<T>) {}
@@ -63,7 +63,7 @@ note: ...does not necessarily outlive the anonymous lifetime #1 defined on the m
 LL |     fn dummy2(self: &Bar<T>) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/ufcs-explicit-self-bad.rs:39:21
    |
 LL |     fn dummy3(self: &&Bar<T>) {}
@@ -82,7 +82,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
 LL | impl<'a, T> SomeTrait for &'a Bar<T> {
    |      ^^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/ufcs-explicit-self-bad.rs:39:21
    |
 LL |     fn dummy3(self: &&Bar<T>) {}
@@ -103,4 +103,5 @@ LL |     fn dummy3(self: &&Bar<T>) {}
 
 error: aborting due to 7 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0307, E0308.
+For more information about an error, try `rustc --explain E0307`.

From c1e5e5c56717c5fe224db425d891c274a3f3cb5e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 2 Sep 2019 20:22:22 -0700
Subject: [PATCH 428/943] On object safety violation, point at source when
 possible

---
 src/librustc/traits/error_reporting.rs        |  5 +-
 src/librustc/traits/object_safety.rs          | 54 +++++++++++--------
 .../associated-const-in-trait.stderr          |  5 +-
 ...mpl-trait-for-trait-object-safe.old.stderr |  4 +-
 ...impl-trait-for-trait-object-safe.re.stderr |  4 +-
 src/test/ui/did_you_mean/issue-40006.stderr   |  5 +-
 src/test/ui/error-codes/E0033-teach.rs        |  3 +-
 src/test/ui/error-codes/E0033-teach.stderr    |  7 +--
 src/test/ui/error-codes/E0033.rs              |  3 +-
 src/test/ui/error-codes/E0033.stderr          |  7 +--
 src/test/ui/error-codes/E0038.stderr          |  5 +-
 src/test/ui/issues/issue-18959.stderr         |  5 +-
 src/test/ui/issues/issue-19380.stderr         |  5 +-
 src/test/ui/issues/issue-19538.stderr         |  9 ++--
 src/test/ui/issues/issue-50781.stderr         |  4 +-
 .../object-safety-associated-consts.stderr    |  5 +-
 .../object-safety-generics.stderr             | 10 ++--
 .../object-safety-mentions-Self.stderr        | 10 ++--
 .../object-safety-no-static.stderr            |  5 +-
 src/test/ui/resolve/issue-3907-2.stderr       |  2 -
 ...rbitrary-self-types-not-object-safe.stderr |  9 ++--
 src/test/ui/traits/trait-item-privacy.stderr  | 13 +++--
 src/test/ui/traits/trait-object-safety.stderr |  9 ++--
 src/test/ui/traits/trait-test-2.stderr        | 15 ++++--
 ...ter-defaults-referencing-Self-ppaux.stderr |  5 +-
 src/test/ui/wf/wf-object-safe.stderr          |  5 +-
 26 files changed, 129 insertions(+), 84 deletions(-)

diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index b38e1f5f83937..03cc00d87e3cd 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1384,7 +1384,10 @@ impl<'tcx> TyCtxt<'tcx> {
         let mut reported_violations = FxHashSet::default();
         for violation in violations {
             if reported_violations.insert(violation.clone()) {
-                err.note(&violation.error_msg());
+                match violation.span() {
+                    Some(span) => err.span_label(span, violation.error_msg()),
+                    None => err.note(&violation.error_msg()),
+                };
             }
         }
         Some(err)
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index aac722b56a983..50f497e302e6d 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -32,10 +32,10 @@ pub enum ObjectSafetyViolation {
     SupertraitSelf,
 
     /// Method has something illegal.
-    Method(ast::Name, MethodViolationCode),
+    Method(ast::Name, MethodViolationCode, Span),
 
     /// Associated const.
-    AssocConst(ast::Name),
+    AssocConst(ast::Name, Span),
 }
 
 impl ObjectSafetyViolation {
@@ -46,24 +46,33 @@ impl ObjectSafetyViolation {
             ObjectSafetyViolation::SupertraitSelf =>
                 "the trait cannot use `Self` as a type parameter \
                  in the supertraits or where-clauses".into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) =>
+            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) =>
                 format!("associated function `{}` has no `self` parameter", name).into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) => format!(
+            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!(
                 "method `{}` references the `Self` type in its arguments or return type",
                 name,
             ).into(),
             ObjectSafetyViolation::Method(
                 name,
-                MethodViolationCode::WhereClauseReferencesSelf(_),
+                MethodViolationCode::WhereClauseReferencesSelf,
+                _,
             ) => format!("method `{}` references the `Self` type in where clauses", name).into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
+            ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) =>
                 format!("method `{}` has generic type parameters", name).into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver) =>
+            ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) =>
                 format!("method `{}`'s receiver cannot be dispatched on", name).into(),
-            ObjectSafetyViolation::AssocConst(name) =>
+            ObjectSafetyViolation::AssocConst(name, _) =>
                 format!("the trait cannot contain associated consts like `{}`", name).into(),
         }
     }
+
+    pub fn span(&self) -> Option<Span> {
+        match self {
+            ObjectSafetyViolation::AssocConst(_, span) |
+            ObjectSafetyViolation::Method(_, _, span) => Some(*span),
+            _ => None,
+        }
+    }
 }
 
 /// Reasons a method might not be object-safe.
@@ -76,7 +85,7 @@ pub enum MethodViolationCode {
     ReferencesSelf,
 
     /// e.g., `fn foo(&self) where Self: Clone`
-    WhereClauseReferencesSelf(Span),
+    WhereClauseReferencesSelf,
 
     /// e.g., `fn foo<A>()`
     Generic,
@@ -90,9 +99,10 @@ impl<'tcx> TyCtxt<'tcx> {
     /// astconv -- currently, `Self` in supertraits. This is needed
     /// because `object_safety_violations` can't be used during
     /// type collection.
-    pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
-                                            -> Vec<ObjectSafetyViolation>
-    {
+    pub fn astconv_object_safety_violations(
+        self,
+        trait_def_id: DefId,
+    ) -> Vec<ObjectSafetyViolation> {
         debug_assert!(self.generics_of(trait_def_id).has_self);
         let violations = traits::supertrait_def_ids(self, trait_def_id)
             .filter(|&def_id| self.predicates_reference_self(def_id, true))
@@ -130,7 +140,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
 
         match self.virtual_call_violation_for_method(trait_def_id, method) {
-            None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
+            None | Some(MethodViolationCode::WhereClauseReferencesSelf) => true,
             Some(_) => false,
         }
     }
@@ -140,12 +150,15 @@ impl<'tcx> TyCtxt<'tcx> {
         let mut violations: Vec<_> = self.associated_items(trait_def_id)
             .filter(|item| item.kind == ty::AssocKind::Method)
             .filter_map(|item|
-                self.object_safety_violation_for_method(trait_def_id, &item)
-                    .map(|code| ObjectSafetyViolation::Method(item.ident.name, code))
+                self.object_safety_violation_for_method(trait_def_id, &item).map(|code| {
+                    ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span)
+                })
             ).filter(|violation| {
-                if let ObjectSafetyViolation::Method(_,
-                    MethodViolationCode::WhereClauseReferencesSelf(span)) = violation
-                {
+                if let ObjectSafetyViolation::Method(
+                    _,
+                    MethodViolationCode::WhereClauseReferencesSelf,
+                    span,
+                ) = violation {
                     // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
                     // It's also hard to get a use site span, so we use the method definition span.
                     self.lint_node_note(
@@ -171,7 +184,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
         violations.extend(self.associated_items(trait_def_id)
             .filter(|item| item.kind == ty::AssocKind::Const)
-            .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name)));
+            .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span)));
 
         debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
                trait_def_id,
@@ -327,8 +340,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 .visit_tys_shallow(|t| {
                     self.contains_illegal_self_type_reference(trait_def_id, t)
                 }) {
-            let span = self.def_span(method.def_id);
-            return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
+            return Some(MethodViolationCode::WhereClauseReferencesSelf);
         }
 
         let receiver_ty = self.liberate_late_bound_regions(
diff --git a/src/test/ui/associated-const/associated-const-in-trait.stderr b/src/test/ui/associated-const/associated-const-in-trait.stderr
index dff268a55c909..a5d7fc5b70246 100644
--- a/src/test/ui/associated-const/associated-const-in-trait.stderr
+++ b/src/test/ui/associated-const/associated-const-in-trait.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/associated-const-in-trait.rs:9:6
    |
+LL |     const N: usize;
+   |           - the trait cannot contain associated consts like `N`
+...
 LL | impl dyn Trait {
    |      ^^^^^^^^^ the trait `Trait` cannot be made into an object
-   |
-   = note: the trait cannot contain associated consts like `N`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr
index c38d7456a9952..2626eab3cbf23 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr
@@ -1,10 +1,10 @@
 error[E0038]: the trait `NotObjectSafe` cannot be made into an object
   --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
    |
+LL | trait NotObjectSafe { fn eq(&self, other: Self); }
+   |                          -- method `eq` references the `Self` type in its arguments or return type
 LL | impl NotObjectSafe for dyn NotObjectSafe { }
    |      ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
-   |
-   = note: method `eq` references the `Self` type in its arguments or return type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr
index c38d7456a9952..2626eab3cbf23 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr
@@ -1,10 +1,10 @@
 error[E0038]: the trait `NotObjectSafe` cannot be made into an object
   --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
    |
+LL | trait NotObjectSafe { fn eq(&self, other: Self); }
+   |                          -- method `eq` references the `Self` type in its arguments or return type
 LL | impl NotObjectSafe for dyn NotObjectSafe { }
    |      ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
-   |
-   = note: method `eq` references the `Self` type in its arguments or return type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr
index 6f219a6e0b1fe..5b384045a486a 100644
--- a/src/test/ui/did_you_mean/issue-40006.stderr
+++ b/src/test/ui/did_you_mean/issue-40006.stderr
@@ -61,8 +61,9 @@ error[E0038]: the trait `X` cannot be made into an object
    |
 LL | impl dyn X {
    |      ^^^^^ the trait `X` cannot be made into an object
-   |
-   = note: associated function `xxx` has no `self` parameter
+...
+LL |     fn xxx() { ### }
+   |        --- associated function `xxx` has no `self` parameter
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/error-codes/E0033-teach.rs b/src/test/ui/error-codes/E0033-teach.rs
index 9b5e719781281..1943965139423 100644
--- a/src/test/ui/error-codes/E0033-teach.rs
+++ b/src/test/ui/error-codes/E0033-teach.rs
@@ -1,14 +1,13 @@
 // compile-flags: -Z teach
 
 trait SomeTrait {
-    fn foo();
+    fn foo(); //~ associated function `foo` has no `self` parameter
 }
 
 fn main() {
     let trait_obj: &dyn SomeTrait = SomeTrait;
     //~^ ERROR expected value, found trait `SomeTrait`
     //~| ERROR E0038
-    //~| associated function `foo` has no `self` parameter
 
     let &invalid = trait_obj;
     //~^ ERROR E0033
diff --git a/src/test/ui/error-codes/E0033-teach.stderr b/src/test/ui/error-codes/E0033-teach.stderr
index 1d4c2d788a43b..80f3d4441bd9f 100644
--- a/src/test/ui/error-codes/E0033-teach.stderr
+++ b/src/test/ui/error-codes/E0033-teach.stderr
@@ -7,13 +7,14 @@ LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
 error[E0038]: the trait `SomeTrait` cannot be made into an object
   --> $DIR/E0033-teach.rs:8:20
    |
+LL |     fn foo();
+   |        --- associated function `foo` has no `self` parameter
+...
 LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
    |                    ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
-   |
-   = note: associated function `foo` has no `self` parameter
 
 error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
-  --> $DIR/E0033-teach.rs:13:9
+  --> $DIR/E0033-teach.rs:12:9
    |
 LL |     let &invalid = trait_obj;
    |         ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
diff --git a/src/test/ui/error-codes/E0033.rs b/src/test/ui/error-codes/E0033.rs
index 86dacfd1a47ba..e5f0530f45ff8 100644
--- a/src/test/ui/error-codes/E0033.rs
+++ b/src/test/ui/error-codes/E0033.rs
@@ -1,12 +1,11 @@
 trait SomeTrait {
-    fn foo();
+    fn foo(); //~ associated function `foo` has no `self` parameter
 }
 
 fn main() {
     let trait_obj: &dyn SomeTrait = SomeTrait;
     //~^ ERROR expected value, found trait `SomeTrait`
     //~| ERROR E0038
-    //~| associated function `foo` has no `self` parameter
 
     let &invalid = trait_obj;
     //~^ ERROR E0033
diff --git a/src/test/ui/error-codes/E0033.stderr b/src/test/ui/error-codes/E0033.stderr
index 803d7917e5638..c2843796cc851 100644
--- a/src/test/ui/error-codes/E0033.stderr
+++ b/src/test/ui/error-codes/E0033.stderr
@@ -7,13 +7,14 @@ LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
 error[E0038]: the trait `SomeTrait` cannot be made into an object
   --> $DIR/E0033.rs:6:20
    |
+LL |     fn foo();
+   |        --- associated function `foo` has no `self` parameter
+...
 LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
    |                    ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
-   |
-   = note: associated function `foo` has no `self` parameter
 
 error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
-  --> $DIR/E0033.rs:11:9
+  --> $DIR/E0033.rs:10:9
    |
 LL |     let &invalid = trait_obj;
    |         ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr
index e3d7593e42a71..93a7681393b29 100644
--- a/src/test/ui/error-codes/E0038.stderr
+++ b/src/test/ui/error-codes/E0038.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/E0038.rs:5:1
    |
+LL |     fn foo(&self) -> Self;
+   |        --- method `foo` references the `Self` type in its arguments or return type
+...
 LL | fn call_foo(x: Box<dyn Trait>) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object
-   |
-   = note: method `foo` references the `Self` type in its arguments or return type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr
index 63c33b7f4472d..d5e7092801ecd 100644
--- a/src/test/ui/issues/issue-18959.stderr
+++ b/src/test/ui/issues/issue-18959.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-18959.rs:11:1
    |
+LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
+   |                    --- method `foo` has generic type parameters
+...
 LL | fn foo(b: &dyn Bar) {
    | ^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: method `foo` has generic type parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-19380.stderr b/src/test/ui/issues/issue-19380.stderr
index d70a7c2b5299c..92bfdf1f26e93 100644
--- a/src/test/ui/issues/issue-19380.stderr
+++ b/src/test/ui/issues/issue-19380.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Qiz` cannot be made into an object
   --> $DIR/issue-19380.rs:11:3
    |
+LL |   fn qiz();
+   |      --- associated function `qiz` has no `self` parameter
+...
 LL |   foos: &'static [&'static (dyn Qiz + 'static)]
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object
-   |
-   = note: associated function `qiz` has no `self` parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/issues/issue-19538.stderr
index e5da0a9b0dac3..5415a45f7d621 100644
--- a/src/test/ui/issues/issue-19538.stderr
+++ b/src/test/ui/issues/issue-19538.stderr
@@ -1,18 +1,21 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-19538.rs:17:15
    |
+LL |     fn foo<T>(&self, val: T);
+   |        --- method `foo` has generic type parameters
+...
 LL |     let test: &mut dyn Bar = &mut thing;
    |               ^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: method `foo` has generic type parameters
 
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-19538.rs:17:30
    |
+LL |     fn foo<T>(&self, val: T);
+   |        --- method `foo` has generic type parameters
+...
 LL |     let test: &mut dyn Bar = &mut thing;
    |                              ^^^^^^^^^^ the trait `Bar` cannot be made into an object
    |
-   = note: method `foo` has generic type parameters
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr
index c98f78c51ee5f..02475ea97e3d1 100644
--- a/src/test/ui/issues/issue-50781.stderr
+++ b/src/test/ui/issues/issue-50781.stderr
@@ -1,8 +1,8 @@
 error: the trait `X` cannot be made into an object
-  --> $DIR/issue-50781.rs:6:5
+  --> $DIR/issue-50781.rs:6:8
    |
 LL |     fn foo(&self) where Self: Trait;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^
    |
 note: lint level defined here
   --> $DIR/issue-50781.rs:1:9
diff --git a/src/test/ui/object-safety/object-safety-associated-consts.stderr b/src/test/ui/object-safety/object-safety-associated-consts.stderr
index 55f9e3f9f138b..7d5aa00356e0b 100644
--- a/src/test/ui/object-safety/object-safety-associated-consts.stderr
+++ b/src/test/ui/object-safety/object-safety-associated-consts.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-associated-consts.rs:9:1
    |
+LL |     const X: usize;
+   |           - the trait cannot contain associated consts like `X`
+...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: the trait cannot contain associated consts like `X`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/object-safety/object-safety-generics.stderr b/src/test/ui/object-safety/object-safety-generics.stderr
index d66cdb98448d4..b25e0052e4163 100644
--- a/src/test/ui/object-safety/object-safety-generics.stderr
+++ b/src/test/ui/object-safety/object-safety-generics.stderr
@@ -1,18 +1,20 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-generics.rs:14:1
    |
+LL |     fn bar<T>(&self, t: T);
+   |        --- method `bar` has generic type parameters
+...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: method `bar` has generic type parameters
 
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-generics.rs:19:1
    |
+LL |     fn bar<T>(&self, t: T);
+   |        --- method `bar` has generic type parameters
+...
 LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: method `bar` has generic type parameters
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.stderr
index c0c471c2b1e72..e2d1e773809bb 100644
--- a/src/test/ui/object-safety/object-safety-mentions-Self.stderr
+++ b/src/test/ui/object-safety/object-safety-mentions-Self.stderr
@@ -1,18 +1,20 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-mentions-Self.rs:17:1
    |
+LL |     fn bar(&self, x: &Self);
+   |        --- method `bar` references the `Self` type in its arguments or return type
+...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: method `bar` references the `Self` type in its arguments or return type
 
 error[E0038]: the trait `Baz` cannot be made into an object
   --> $DIR/object-safety-mentions-Self.rs:22:1
    |
+LL |     fn bar(&self) -> Self;
+   |        --- method `bar` references the `Self` type in its arguments or return type
+...
 LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Baz` cannot be made into an object
-   |
-   = note: method `bar` references the `Self` type in its arguments or return type
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/object-safety/object-safety-no-static.stderr b/src/test/ui/object-safety/object-safety-no-static.stderr
index c189c358b4223..0de783f60ea47 100644
--- a/src/test/ui/object-safety/object-safety-no-static.stderr
+++ b/src/test/ui/object-safety/object-safety-no-static.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/object-safety-no-static.rs:8:1
    |
+LL |     fn foo();
+   |        --- associated function `foo` has no `self` parameter
+...
 LL | fn foo_implicit<T:Foo+'static>(b: Box<T>) -> Box<dyn Foo + 'static> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
-   |
-   = note: associated function `foo` has no `self` parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr
index 63ac11dc8ae01..087d1a5b9d365 100644
--- a/src/test/ui/resolve/issue-3907-2.stderr
+++ b/src/test/ui/resolve/issue-3907-2.stderr
@@ -3,8 +3,6 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
    |
 LL | fn bar(_x: Foo) {}
    | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
-   |
-   = note: associated function `bar` has no `self` parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
index e45bc2657f1ea..9fb1500afce47 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
@@ -1,18 +1,21 @@
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/arbitrary-self-types-not-object-safe.rs:31:32
    |
+LL |     fn foo(self: &Rc<Self>) -> usize;
+   |        --- method `foo`'s receiver cannot be dispatched on
+...
 LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
    |                                ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
-   |
-   = note: method `foo`'s receiver cannot be dispatched on
 
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/arbitrary-self-types-not-object-safe.rs:31:13
    |
+LL |     fn foo(self: &Rc<Self>) -> usize;
+   |        --- method `foo`'s receiver cannot be dispatched on
+...
 LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
    |             ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
    |
-   = note: method `foo`'s receiver cannot be dispatched on
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr
index de699a69fa8bc..aec648d7b8473 100644
--- a/src/test/ui/traits/trait-item-privacy.stderr
+++ b/src/test/ui/traits/trait-item-privacy.stderr
@@ -103,12 +103,17 @@ LL |     C::A;
 error[E0038]: the trait `assoc_const::C` cannot be made into an object
   --> $DIR/trait-item-privacy.rs:101:5
    |
+LL |         const A: u8 = 0;
+   |               - the trait cannot contain associated consts like `A`
+...
+LL |         const B: u8 = 0;
+   |               - the trait cannot contain associated consts like `B`
+...
+LL |         const C: u8 = 0;
+   |               - the trait cannot contain associated consts like `C`
+...
 LL |     C::A;
    |     ^^^^ the trait `assoc_const::C` cannot be made into an object
-   |
-   = note: the trait cannot contain associated consts like `C`
-   = note: the trait cannot contain associated consts like `B`
-   = note: the trait cannot contain associated consts like `A`
 
 error[E0223]: ambiguous associated type
   --> $DIR/trait-item-privacy.rs:115:12
diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr
index 7f6bc0ebb70e5..3ac1e96b30c95 100644
--- a/src/test/ui/traits/trait-object-safety.stderr
+++ b/src/test/ui/traits/trait-object-safety.stderr
@@ -1,19 +1,22 @@
 error[E0038]: the trait `Tr` cannot be made into an object
   --> $DIR/trait-object-safety.rs:15:22
    |
+LL |     fn foo();
+   |        --- associated function `foo` has no `self` parameter
+...
 LL |     let _: &dyn Tr = &St;
    |                      ^^^ the trait `Tr` cannot be made into an object
    |
-   = note: associated function `foo` has no `self` parameter
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St`
 
 error[E0038]: the trait `Tr` cannot be made into an object
   --> $DIR/trait-object-safety.rs:15:12
    |
+LL |     fn foo();
+   |        --- associated function `foo` has no `self` parameter
+...
 LL |     let _: &dyn Tr = &St;
    |            ^^^^^^^ the trait `Tr` cannot be made into an object
-   |
-   = note: associated function `foo` has no `self` parameter
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr
index 5d5251925a1ae..4d2aca0d4094a 100644
--- a/src/test/ui/traits/trait-test-2.stderr
+++ b/src/test/ui/traits/trait-test-2.stderr
@@ -13,20 +13,25 @@ LL |     10.blah::<i32, i32>();
 error[E0038]: the trait `bar` cannot be made into an object
   --> $DIR/trait-test-2.rs:11:16
    |
+LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
+   |                ---                    ---- method `blah` has generic type parameters
+   |                |
+   |                method `dup` references the `Self` type in its arguments or return type
+...
 LL |     (box 10 as Box<dyn bar>).dup();
    |                ^^^^^^^^^^^^ the trait `bar` cannot be made into an object
-   |
-   = note: method `dup` references the `Self` type in its arguments or return type
-   = note: method `blah` has generic type parameters
 
 error[E0038]: the trait `bar` cannot be made into an object
   --> $DIR/trait-test-2.rs:11:6
    |
+LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
+   |                ---                    ---- method `blah` has generic type parameters
+   |                |
+   |                method `dup` references the `Self` type in its arguments or return type
+...
 LL |     (box 10 as Box<dyn bar>).dup();
    |      ^^^^^^ the trait `bar` cannot be made into an object
    |
-   = note: method `dup` references the `Self` type in its arguments or return type
-   = note: method `blah` has generic type parameters
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn bar>>` for `std::boxed::Box<{integer}>`
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
index 58727ea0fef99..03df5b8211889 100644
--- a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
+++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
@@ -13,10 +13,11 @@ LL |     let y = x as dyn MyAdd<i32>;
 error[E0038]: the trait `MyAdd` cannot be made into an object
   --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18
    |
+LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; }
+   |                            --- method `add` references the `Self` type in its arguments or return type
+...
 LL |     let y = x as dyn MyAdd<i32>;
    |                  ^^^^^^^^^^^^^^ the trait `MyAdd` cannot be made into an object
-   |
-   = note: method `add` references the `Self` type in its arguments or return type
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr
index 3b264ecd580ec..d11af11f05051 100644
--- a/src/test/ui/wf/wf-object-safe.stderr
+++ b/src/test/ui/wf/wf-object-safe.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `A` cannot be made into an object
   --> $DIR/wf-object-safe.rs:9:13
    |
+LL |     fn foo(&self, _x: &Self);
+   |        --- method `foo` references the `Self` type in its arguments or return type
+...
 LL |     let _x: &dyn A;
    |             ^^^^^^ the trait `A` cannot be made into an object
-   |
-   = note: method `foo` references the `Self` type in its arguments or return type
 
 error: aborting due to previous error
 

From 3cb1ed4279d8ca4528e3777d5470ca7dc85a976a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 2 Sep 2019 20:51:31 -0700
Subject: [PATCH 429/943] review comments

---
 src/librustc_typeck/constrained_generic_params.rs |  4 ++--
 src/test/ui/issues/issue-36836.rs                 | 10 ++++++++++
 src/test/ui/issues/issue-36836.stderr             |  2 +-
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/src/librustc_typeck/constrained_generic_params.rs b/src/librustc_typeck/constrained_generic_params.rs
index c95f81506cd59..dd44f86717fe5 100644
--- a/src/librustc_typeck/constrained_generic_params.rs
+++ b/src/librustc_typeck/constrained_generic_params.rs
@@ -36,8 +36,8 @@ pub fn parameters_for_impl<'tcx>(
 /// uniquely determined by `t` (see RFC 447). If it is true, return the list
 /// of parameters whose values are needed in order to constrain `ty` - these
 /// differ, with the latter being a superset, in the presence of projections.
-pub fn parameters_for<'tcx, T: TypeFoldable<'tcx>>(
-    t: &T,
+pub fn parameters_for<'tcx>(
+    t: &impl TypeFoldable<'tcx>,
     include_nonconstraining: bool,
 ) -> Vec<Parameter> {
     let mut collector = ParameterCollector {
diff --git a/src/test/ui/issues/issue-36836.rs b/src/test/ui/issues/issue-36836.rs
index 56d5a7cca4566..99c56213153e4 100644
--- a/src/test/ui/issues/issue-36836.rs
+++ b/src/test/ui/issues/issue-36836.rs
@@ -1,3 +1,13 @@
+// Previously, in addition to the real cause of the problem as seen below,
+// the compiler would tell the user:
+//
+// ```
+// error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or
+// predicates
+// ```
+//
+// With this test, we check that only the relevant error is emitted.
+
 trait Foo {}
 
 impl<T> Foo for Bar<T> {} //~ ERROR cannot find type `Bar` in this scope
diff --git a/src/test/ui/issues/issue-36836.stderr b/src/test/ui/issues/issue-36836.stderr
index bfda9b0bbdd7e..418194fac9923 100644
--- a/src/test/ui/issues/issue-36836.stderr
+++ b/src/test/ui/issues/issue-36836.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `Bar` in this scope
-  --> $DIR/issue-36836.rs:3:17
+  --> $DIR/issue-36836.rs:13:17
    |
 LL | impl<T> Foo for Bar<T> {}
    |                 ^^^ not found in this scope

From bb99fc31d0a8f962662e636938cf96f0f70d3803 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 2 Sep 2019 21:08:34 -0700
Subject: [PATCH 430/943] review comment: update error code descr

---
 src/librustc_typeck/error_codes.rs | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index ae0f17892959d..ebfa6acf23e00 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -212,7 +212,7 @@ match string {
 E0033: r##"
 This error indicates that a pointer to a trait type cannot be implicitly
 dereferenced by a pattern. Every trait defines a type, but because the
-size of trait implementors isn't fixed, this type has no compile-time size.
+size of trait implementers isn't fixed, this type has no compile-time size.
 Therefore, all accesses to trait types must be through pointers. If you
 encounter this error you should try to avoid dereferencing the pointer.
 
@@ -2430,23 +2430,23 @@ This error indicates that the `self` parameter in a method has an invalid
 "reciever type".
 
 Methods take a special first parameter, of which there are three variants:
-`self`, `&self`, and `&mut self`. The type `Self` acts as an alias to the
-type of the current trait implementor, or "receiver type". Besides the
-already mentioned `Self`, `&Self` and `&mut Self` valid receiver types, the
-following are also valid, if less common: `self: Box<Self>`,
-`self: Rc<Self>`, `self: Arc<Self>`, and `self: Pin<P>` (where P is one of
-the previous types except `Self`).
+`self`, `&self`, and `&mut self`. These are syntactic sugar for
+`self: Self`, `self: &Self`, and `self: &mut Self` respectively. The type
+`Self` acts as an alias to the type of the current trait implementer, or
+"receiver type". Besides the already mentioned `Self`, `&Self` and
+`&mut Self` valid receiver types, the following are also valid:
+`self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, and `self: Pin<P>`
+(where P is one of the previous types except `Self`).
 
 ```
 # struct Foo;
 trait Trait {
     fn foo(&self);
-//         ^^^^^ this let's you refer to the type that implements this trait
 }
+
 impl Trait for Foo {
-//             ^^^ this is the "receiver type"
     fn foo(&self) {}
-//         ^^^^^ this is of type `Foo`
+//         ^^^^^ this the receiver type `&Foo`
 }
 ```
 
@@ -2458,11 +2458,12 @@ The above is equivalent to:
 #     fn foo(&self);
 # }
 impl Trait for Foo {
-    fn foo(&self: &Foo) {}
+    fn foo(self: &Foo) {}
 }
 ```
 
-When using an invalid reciver type, like in the following example,
+E0307 will be emitted by the compiler when using an invalid reciver type,
+like in the following example:
 
 ```compile_fail,E0307
 # struct Foo;
@@ -2471,12 +2472,13 @@ When using an invalid reciver type, like in the following example,
 #     fn foo(&self);
 # }
 impl Trait for Struct {
-    fn foo(&self: &Bar) {}
+    fn foo(self: &Bar) {}
 }
 ```
 
 The nightly feature [Arbintrary self types][AST] extends the accepted
-receiver type to also include any type that can dereference to `Self`:
+set of receiver types to also include any type that can dereference to
+`Self`:
 
 ```
 #![feature(arbitrary_self_types)]

From efe85943b3a5e7b3920db5a5a53183c75fc80d0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 2 Sep 2019 22:11:29 -0700
Subject: [PATCH 431/943] account for DUMMY_SP and correct wording

---
 src/librustc/error_codes.rs                               | 2 +-
 src/librustc/traits/object_safety.rs                      | 8 ++++----
 .../coherence-impl-trait-for-trait-object-safe.old.stderr | 2 +-
 .../coherence-impl-trait-for-trait-object-safe.re.stderr  | 2 +-
 src/test/ui/error-codes/E0038.stderr                      | 2 +-
 .../ui/object-safety/object-safety-mentions-Self.stderr   | 4 ++--
 src/test/ui/resolve/issue-3907-2.stderr                   | 2 ++
 src/test/ui/traits/trait-test-2.stderr                    | 4 ++--
 .../type-parameter-defaults-referencing-Self-ppaux.stderr | 2 +-
 src/test/ui/wf/wf-object-safe.stderr                      | 2 +-
 10 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index 2d09013f675a7..937a9ea6c1bd4 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -39,7 +39,7 @@ Generally, `Self: Sized` is used to indicate that the trait should not be used
 as a trait object. If the trait comes from your own crate, consider removing
 this restriction.
 
-### Method references the `Self` type in its arguments or return type
+### Method references the `Self` type in its parameters or return type
 
 This happens when a trait has a method like the following:
 
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 50f497e302e6d..5392e9100c6d1 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -20,7 +20,7 @@ use std::borrow::Cow;
 use std::iter::{self};
 use syntax::ast::{self};
 use syntax::symbol::InternedString;
-use syntax_pos::Span;
+use syntax_pos::{Span, DUMMY_SP};
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub enum ObjectSafetyViolation {
@@ -49,7 +49,7 @@ impl ObjectSafetyViolation {
             ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) =>
                 format!("associated function `{}` has no `self` parameter", name).into(),
             ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!(
-                "method `{}` references the `Self` type in its arguments or return type",
+                "method `{}` references the `Self` type in its parameters or return type",
                 name,
             ).into(),
             ObjectSafetyViolation::Method(
@@ -67,9 +67,9 @@ impl ObjectSafetyViolation {
     }
 
     pub fn span(&self) -> Option<Span> {
-        match self {
+        match *self {
             ObjectSafetyViolation::AssocConst(_, span) |
-            ObjectSafetyViolation::Method(_, _, span) => Some(*span),
+            ObjectSafetyViolation::Method(_, _, span) if span != DUMMY_SP => Some(span),
             _ => None,
         }
     }
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr
index 2626eab3cbf23..18a7cea95bdb9 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr
@@ -2,7 +2,7 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object
   --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
    |
 LL | trait NotObjectSafe { fn eq(&self, other: Self); }
-   |                          -- method `eq` references the `Self` type in its arguments or return type
+   |                          -- method `eq` references the `Self` type in its parameters or return type
 LL | impl NotObjectSafe for dyn NotObjectSafe { }
    |      ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
 
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr
index 2626eab3cbf23..18a7cea95bdb9 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr
@@ -2,7 +2,7 @@ error[E0038]: the trait `NotObjectSafe` cannot be made into an object
   --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
    |
 LL | trait NotObjectSafe { fn eq(&self, other: Self); }
-   |                          -- method `eq` references the `Self` type in its arguments or return type
+   |                          -- method `eq` references the `Self` type in its parameters or return type
 LL | impl NotObjectSafe for dyn NotObjectSafe { }
    |      ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
 
diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr
index 93a7681393b29..5c4d6d53c4626 100644
--- a/src/test/ui/error-codes/E0038.stderr
+++ b/src/test/ui/error-codes/E0038.stderr
@@ -2,7 +2,7 @@ error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/E0038.rs:5:1
    |
 LL |     fn foo(&self) -> Self;
-   |        --- method `foo` references the `Self` type in its arguments or return type
+   |        --- method `foo` references the `Self` type in its parameters or return type
 ...
 LL | fn call_foo(x: Box<dyn Trait>) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object
diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.stderr
index e2d1e773809bb..971e79cb0210f 100644
--- a/src/test/ui/object-safety/object-safety-mentions-Self.stderr
+++ b/src/test/ui/object-safety/object-safety-mentions-Self.stderr
@@ -2,7 +2,7 @@ error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-mentions-Self.rs:17:1
    |
 LL |     fn bar(&self, x: &Self);
-   |        --- method `bar` references the `Self` type in its arguments or return type
+   |        --- method `bar` references the `Self` type in its parameters or return type
 ...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
@@ -11,7 +11,7 @@ error[E0038]: the trait `Baz` cannot be made into an object
   --> $DIR/object-safety-mentions-Self.rs:22:1
    |
 LL |     fn bar(&self) -> Self;
-   |        --- method `bar` references the `Self` type in its arguments or return type
+   |        --- method `bar` references the `Self` type in its parameters or return type
 ...
 LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Baz` cannot be made into an object
diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr
index 087d1a5b9d365..63ac11dc8ae01 100644
--- a/src/test/ui/resolve/issue-3907-2.stderr
+++ b/src/test/ui/resolve/issue-3907-2.stderr
@@ -3,6 +3,8 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
    |
 LL | fn bar(_x: Foo) {}
    | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
+   |
+   = note: associated function `bar` has no `self` parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr
index 4d2aca0d4094a..83c2c06527493 100644
--- a/src/test/ui/traits/trait-test-2.stderr
+++ b/src/test/ui/traits/trait-test-2.stderr
@@ -16,7 +16,7 @@ error[E0038]: the trait `bar` cannot be made into an object
 LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
    |                ---                    ---- method `blah` has generic type parameters
    |                |
-   |                method `dup` references the `Self` type in its arguments or return type
+   |                method `dup` references the `Self` type in its parameters or return type
 ...
 LL |     (box 10 as Box<dyn bar>).dup();
    |                ^^^^^^^^^^^^ the trait `bar` cannot be made into an object
@@ -27,7 +27,7 @@ error[E0038]: the trait `bar` cannot be made into an object
 LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
    |                ---                    ---- method `blah` has generic type parameters
    |                |
-   |                method `dup` references the `Self` type in its arguments or return type
+   |                method `dup` references the `Self` type in its parameters or return type
 ...
 LL |     (box 10 as Box<dyn bar>).dup();
    |      ^^^^^^ the trait `bar` cannot be made into an object
diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
index 03df5b8211889..b315fe9df8afd 100644
--- a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
+++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
@@ -14,7 +14,7 @@ error[E0038]: the trait `MyAdd` cannot be made into an object
   --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18
    |
 LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; }
-   |                            --- method `add` references the `Self` type in its arguments or return type
+   |                            --- method `add` references the `Self` type in its parameters or return type
 ...
 LL |     let y = x as dyn MyAdd<i32>;
    |                  ^^^^^^^^^^^^^^ the trait `MyAdd` cannot be made into an object
diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr
index d11af11f05051..0d8441f87e7e7 100644
--- a/src/test/ui/wf/wf-object-safe.stderr
+++ b/src/test/ui/wf/wf-object-safe.stderr
@@ -2,7 +2,7 @@ error[E0038]: the trait `A` cannot be made into an object
   --> $DIR/wf-object-safe.rs:9:13
    |
 LL |     fn foo(&self, _x: &Self);
-   |        --- method `foo` references the `Self` type in its arguments or return type
+   |        --- method `foo` references the `Self` type in its parameters or return type
 ...
 LL |     let _x: &dyn A;
    |             ^^^^^^ the trait `A` cannot be made into an object

From 05dcd0e7e3ad44a34266cbca3eb6aa755fb0b56d Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 3 Sep 2019 15:48:14 +1000
Subject: [PATCH 432/943] Remove `LocalInternedString` uses from
 `librustc_typeck`.

---
 src/librustc_typeck/check/expr.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index a53fb12367d0e..2a7b26db35bfc 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -19,7 +19,7 @@ use crate::astconv::AstConv as _;
 
 use errors::{Applicability, DiagnosticBuilder};
 use syntax::ast;
-use syntax::symbol::{Symbol, LocalInternedString, kw, sym};
+use syntax::symbol::{Symbol, kw, sym};
 use syntax::source_map::Span;
 use syntax::util::lev_distance::find_best_match_for_name;
 use rustc::hir;
@@ -1198,7 +1198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             _ => {
                 // prevent all specified fields from being suggested
-                let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str());
+                let skip_fields = skip_fields.iter().map(|ref x| x.ident.name);
                 if let Some(field_name) = Self::suggest_field_name(
                     variant,
                     &field.ident.as_str(),
@@ -1242,11 +1242,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     // Return an hint about the closest match in field names
     fn suggest_field_name(variant: &'tcx ty::VariantDef,
                           field: &str,
-                          skip: Vec<LocalInternedString>)
+                          skip: Vec<Symbol>)
                           -> Option<Symbol> {
         let names = variant.fields.iter().filter_map(|field| {
             // ignore already set fields and private fields from non-local crates
-            if skip.iter().any(|x| *x == field.ident.as_str()) ||
+            if skip.iter().any(|&x| x == field.ident.name) ||
                (!variant.def_id.is_local() && field.vis != Visibility::Public)
             {
                 None

From a8975a0752d52741615728394a0a8a867187ae01 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 3 Sep 2019 16:02:32 +1000
Subject: [PATCH 433/943] Remove `LocalInternedString` uses from
 `librustc/lint/`.

---
 src/librustc/lint/context.rs | 4 ++--
 src/librustc/lint/levels.rs  | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index affda256322a4..77df93080cd16 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -33,7 +33,7 @@ use crate::util::common::time;
 use std::default::Default as StdDefault;
 use syntax::ast;
 use syntax::edition;
-use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}};
+use syntax_pos::{MultiSpan, Span, symbol::Symbol};
 use errors::DiagnosticBuilder;
 use crate::hir;
 use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -405,7 +405,7 @@ impl LintStore {
     pub fn check_lint_name(
         &self,
         lint_name: &str,
-        tool_name: Option<LocalInternedString>,
+        tool_name: Option<Symbol>,
     ) -> CheckLintNameResult<'_> {
         let complete_name = if let Some(tool_name) = tool_name {
             format!("{}::{}", tool_name, lint_name)
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 139f4343117af..cbc6dbdba7e6c 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -291,7 +291,7 @@ impl<'a> LintLevelsBuilder<'a> {
                         continue;
                     }
 
-                    Some(tool_ident.as_str())
+                    Some(tool_ident.name)
                 } else {
                     None
                 };

From ff63bf8fc7a19ca27b3d43aa36036f8e77567b20 Mon Sep 17 00:00:00 2001
From: Hal Gentz <zegentzy@protonmail.com>
Date: Tue, 3 Sep 2019 01:28:33 -0600
Subject: [PATCH 434/943] Fix minor typo in docs.

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

diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 5aa487d901663..a745559d8514d 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -589,7 +589,7 @@ pub fn const_eval_provider<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
 ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> {
-    // see comment in const_eval_provider for what we're doing here
+    // see comment in const_eval_raw_provider for what we're doing here
     if key.param_env.reveal == Reveal::All {
         let mut key = key.clone();
         key.param_env.reveal = Reveal::UserFacing;

From 7589d3a400dfaa13027232ef0a5352fd20680193 Mon Sep 17 00:00:00 2001
From: Hal Gentz <zegentzy@protonmail.com>
Date: Tue, 3 Sep 2019 01:54:48 -0600
Subject: [PATCH 435/943] Update other doc.

Value was renamed to Operand in https://github.com/rust-lang/rust/commit/ad2de8b4ee099916113b7b3577ac86857b1568be
ScalarPair to Slice in https://github.com/rust-lang/rust/commit/fe50b4eb1d6f7a31c53798bca3d0fa2b0670fa3d

Not familiar enough with rustc's source to know if the comment is even still applicable.
---
 src/librustc/mir/interpret/value.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 3da5a65c37932..811c872968a56 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -17,8 +17,8 @@ pub struct RawConst<'tcx> {
     pub ty: Ty<'tcx>,
 }
 
-/// Represents a constant value in Rust. `Scalar` and `ScalarPair` are optimizations that
-/// match the `LocalState` optimizations for easy conversions between `Value` and `ConstValue`.
+/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations that
+/// match the `LocalState` optimizations for easy conversions between `Operand` and `ConstValue`.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord,
          RustcEncodable, RustcDecodable, Hash, HashStable)]
 pub enum ConstValue<'tcx> {

From 8c74eb77902dc5c4fdf853e9159dd5fadd00601d Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 3 Sep 2019 17:21:58 +1000
Subject: [PATCH 436/943] Move path parsing earlier.

It's a hot enough path that moving it slightly earlier gives a tiny but
easy speedup.
---
 src/libsyntax/parse/parser/expr.rs | 56 ++++++++++++++++--------------
 1 file changed, 30 insertions(+), 26 deletions(-)

diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 5b9f0f1df6718..e502a08f4b253 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -889,6 +889,36 @@ impl<'a> Parser<'a> {
                     hi = path.span;
                     return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs));
                 }
+                if self.token.is_path_start() {
+                    let path = self.parse_path(PathStyle::Expr)?;
+
+                    // `!`, as an operator, is prefix, so we know this isn't that
+                    if self.eat(&token::Not) {
+                        // MACRO INVOCATION expression
+                        let (delim, tts) = self.expect_delimited_token_tree()?;
+                        hi = self.prev_span;
+                        ex = ExprKind::Mac(Mac {
+                            path,
+                            tts,
+                            delim,
+                            span: lo.to(hi),
+                            prior_type_ascription: self.last_type_ascription,
+                        });
+                    } else if self.check(&token::OpenDelim(token::Brace)) {
+                        if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) {
+                            return expr;
+                        } else {
+                            hi = path.span;
+                            ex = ExprKind::Path(None, path);
+                        }
+                    } else {
+                        hi = path.span;
+                        ex = ExprKind::Path(None, path);
+                    }
+
+                    let expr = self.mk_expr(lo.to(hi), ex, attrs);
+                    return self.maybe_recover_from_bad_qpath(expr, true);
+                }
                 if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
                     return self.parse_lambda_expr(attrs);
                 }
@@ -1007,32 +1037,6 @@ impl<'a> Parser<'a> {
                     let (await_hi, e_kind) = self.parse_incorrect_await_syntax(lo, self.prev_span)?;
                     hi = await_hi;
                     ex = e_kind;
-                } else if self.token.is_path_start() {
-                    let path = self.parse_path(PathStyle::Expr)?;
-
-                    // `!`, as an operator, is prefix, so we know this isn't that
-                    if self.eat(&token::Not) {
-                        // MACRO INVOCATION expression
-                        let (delim, tts) = self.expect_delimited_token_tree()?;
-                        hi = self.prev_span;
-                        ex = ExprKind::Mac(Mac {
-                            path,
-                            tts,
-                            delim,
-                            span: lo.to(hi),
-                            prior_type_ascription: self.last_type_ascription,
-                        });
-                    } else if self.check(&token::OpenDelim(token::Brace)) {
-                        if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) {
-                            return expr;
-                        } else {
-                            hi = path.span;
-                            ex = ExprKind::Path(None, path);
-                        }
-                    } else {
-                        hi = path.span;
-                        ex = ExprKind::Path(None, path);
-                    }
                 } else {
                     if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
                         // Don't complain about bare semicolons after unclosed braces

From 23c76ff7b912f16f6fdbde167306b08e59353427 Mon Sep 17 00:00:00 2001
From: Daniel Henry-Mantilla <daniel.henrymantilla@gatewatcher.com>
Date: Tue, 3 Sep 2019 12:17:03 +0200
Subject: [PATCH 437/943] Added warning around code with reference to uninit
 bytes

---
 src/libstd/io/mod.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 5060f368229bb..495c0c8d17256 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -371,6 +371,14 @@ where
     loop {
         if g.len == g.buf.len() {
             unsafe {
+                // FIXME(danielhenrymantilla): #42788
+                //
+                //   - This creates a (mut) reference to a slice of
+                //     _uninitialized integers_.
+                //
+                //   - This having defined behavior is **unstable**:
+                //     it could become UB in the future,
+                //     at which point it would have be changed.
                 g.buf.reserve(reservation_size(r));
                 let capacity = g.buf.capacity();
                 g.buf.set_len(capacity);

From e85b181638f228b6dd6b0aa10d41552f4de5ea58 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 3 Sep 2019 15:33:30 +0200
Subject: [PATCH 438/943] unused_parens: fix for or-patterns + &(mut x)

---
 src/librustc_lint/unused.rs                   |  81 ++++++++--
 .../ui/lint/issue-54538-unused-parens-lint.rs |  90 ++++++++---
 .../issue-54538-unused-parens-lint.stderr     | 149 ++++++++++++++----
 3 files changed, 256 insertions(+), 64 deletions(-)

diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 90e467713968b..39c0698aeec9f 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -398,18 +398,37 @@ impl UnusedParens {
         }
     }
 
-    fn check_unused_parens_pat(&self,
-                                cx: &EarlyContext<'_>,
-                                value: &ast::Pat,
-                                msg: &str) {
-        if let ast::PatKind::Paren(_) = value.node {
+    fn check_unused_parens_pat(
+        &self,
+        cx: &EarlyContext<'_>,
+        value: &ast::Pat,
+        avoid_or: bool,
+        avoid_mut: bool,
+    ) {
+        use ast::{PatKind, BindingMode::ByValue, Mutability::Mutable};
+
+        if let PatKind::Paren(inner) = &value.node {
+            match inner.node {
+                // The lint visitor will visit each subpattern of `p`. We do not want to lint
+                // any range pattern no matter where it occurs in the pattern. For something like
+                // `&(a..=b)`, there is a recursive `check_pat` on `a` and `b`, but we will assume
+                // that if there are unnecessary parens they serve a purpose of readability.
+                PatKind::Range(..) => return,
+                // Avoid `p0 | .. | pn` if we should.
+                PatKind::Or(..) if avoid_or => return,
+                // Avoid `mut x` and `mut x @ p` if we should:
+                PatKind::Ident(ByValue(Mutable), ..) if avoid_mut => return,
+                // Otherwise proceed with linting.
+                _ => {}
+            }
+
             let pattern_text = if let Ok(snippet) = cx.sess().source_map()
                 .span_to_snippet(value.span) {
                     snippet
                 } else {
                     pprust::pat_to_string(value)
                 };
-            Self::remove_outer_parens(cx, value.span, &pattern_text, msg, (false, false));
+            Self::remove_outer_parens(cx, value.span, &pattern_text, "pattern", (false, false));
         }
     }
 
@@ -474,6 +493,13 @@ impl EarlyLintPass for UnusedParens {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
         use syntax::ast::ExprKind::*;
         let (value, msg, followed_by_block, left_pos, right_pos) = match e.node {
+            Let(ref pats, ..) => {
+                for p in pats {
+                    self.check_unused_parens_pat(cx, p, false, false);
+                }
+                return;
+            }
+
             If(ref cond, ref block, ..) => {
                 let left = e.span.lo() + syntax_pos::BytePos(2);
                 let right = block.span.lo();
@@ -486,7 +512,8 @@ impl EarlyLintPass for UnusedParens {
                 (cond, "`while` condition", true, Some(left), Some(right))
             },
 
-            ForLoop(_, ref cond, ref block, ..) => {
+            ForLoop(ref pat, ref cond, ref block, ..) => {
+                self.check_unused_parens_pat(cx, pat, false, false);
                 (cond, "`for` head expression", true, None, Some(block.span.lo()))
             }
 
@@ -531,26 +558,46 @@ impl EarlyLintPass for UnusedParens {
     }
 
     fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
-        use ast::PatKind::{Paren, Range};
-        // The lint visitor will visit each subpattern of `p`. We do not want to lint any range
-        // pattern no matter where it occurs in the pattern. For something like `&(a..=b)`, there
-        // is a recursive `check_pat` on `a` and `b`, but we will assume that if there are
-        // unnecessary parens they serve a purpose of readability.
-        if let Paren(ref pat) = p.node {
-            match pat.node {
-                Range(..) => {}
-                _ => self.check_unused_parens_pat(cx, &p, "pattern")
-            }
+        use ast::{PatKind::*, Mutability};
+        match &p.node {
+            // Do not lint on `(..)` as that will result in the other arms being useless.
+            Paren(_)
+            // The other cases do not contain sub-patterns.
+            | Wild | Rest | Lit(..) | Mac(..) | Range(..) | Ident(.., None) | Path(..) => return,
+            // These are list-like patterns; parens can always be removed.
+            TupleStruct(_, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
+                self.check_unused_parens_pat(cx, p, false, false);
+            },
+            Struct(_, fps, _) => for f in fps {
+                self.check_unused_parens_pat(cx, &f.pat, false, false);
+            },
+            // Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
+            Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false),
+            // Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
+            // Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
+            Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Immutable),
         }
     }
 
     fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
         if let ast::StmtKind::Local(ref local) = s.node {
+            self.check_unused_parens_pat(cx, &local.pat, false, false);
+
             if let Some(ref value) = local.init {
                 self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None);
             }
         }
     }
+
+    fn check_param(&mut self, cx: &EarlyContext<'_>, param: &ast::Param) {
+        self.check_unused_parens_pat(cx, &param.pat, true, false);
+    }
+
+    fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
+        for p in &arm.pats {
+            self.check_unused_parens_pat(cx, p, false, false);
+        }
+    }
 }
 
 declare_lint! {
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
index eda9e2cdfaa2f..c442c39fe010e 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
@@ -1,25 +1,75 @@
-// build-pass (FIXME(62277): could be check-pass?)
+#![feature(box_patterns)]
+
+#![feature(or_patterns)]
+//~^ WARN the feature `or_patterns` is incomplete
 
 #![allow(ellipsis_inclusive_range_patterns)]
 #![allow(unreachable_patterns)]
 #![allow(unused_variables)]
-#![warn(unused_parens)]
+#![deny(unused_parens)]
+
+fn lint_on_top_level() {
+    let (a) = 0; //~ ERROR unnecessary parentheses around pattern
+    for (a) in 0..1 {} //~ ERROR unnecessary parentheses around pattern
+    if let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern
+    while let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern
+    fn foo((a): u8) {} //~ ERROR unnecessary parentheses around pattern
+    let _ = |(a): u8| 0; //~ ERROR unnecessary parentheses around pattern
+}
+
+// Don't lint in these cases (#64106).
+fn or_patterns_no_lint() {
+    match Box::new(0) {
+        box (0 | 1) => {} // Should not lint as `box 0 | 1` binds as `(box 0) | 1`.
+        _ => {}
+    }
+
+    match 0 {
+        x @ (0 | 1) => {} // Should not lint as `x @ 0 | 1` binds as `(x @ 0) | 1`.
+        _ => {}
+    }
+
+    if let &(0 | 1) = &0 {} // Should also not lint.
+    if let &mut (0 | 1) = &mut 0 {} // Same.
+
+    fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now.
+    //~^ ERROR identifier `a` is bound more than once
+
+    let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or.
+    //~^ ERROR identifier `a` is bound more than once
+}
+
+fn or_patterns_will_lint() {
+    if let (0 | 1) = 0 {} //~ ERROR unnecessary parentheses around pattern
+    if let ((0 | 1),) = (0,) {} //~ ERROR unnecessary parentheses around pattern
+    if let [(0 | 1)] = [0] {} //~ ERROR unnecessary parentheses around pattern
+    if let 0 | (1 | 2) = 0 {} //~ ERROR unnecessary parentheses around pattern
+    struct TS(u8);
+    if let TS((0 | 1)) = TS(0) {} //~ ERROR unnecessary parentheses around pattern
+    struct NS { f: u8 }
+    if let NS { f: (0 | 1) } = (NS { f: 0 }) {} //~ ERROR unnecessary parentheses around pattern
+}
+
+// Don't lint on `&(mut x)` because `&mut x` means something else (#55342).
+fn deref_mut_binding_no_lint() {
+    let &(mut x) = &0;
+}
 
 fn main() {
     match 1 {
-        (_) => {}         //~ WARNING: unnecessary parentheses around pattern
-        (y) => {}         //~ WARNING: unnecessary parentheses around pattern
-        (ref r) => {}     //~ WARNING: unnecessary parentheses around pattern
-        (e @ 1...2) => {} //~ WARNING: unnecessary parentheses around outer pattern
-        (1...2) => {}     // Non ambiguous range pattern should not warn
+        (_) => {} //~ ERROR unnecessary parentheses around pattern
+        (y) => {} //~ ERROR unnecessary parentheses around pattern
+        (ref r) => {} //~ ERROR unnecessary parentheses around pattern
+        (e @ 1...2) => {} //~ ERROR unnecessary parentheses around pattern
+        (1...2) => {} // Non ambiguous range pattern should not warn
         e @ (3...4) => {} // Non ambiguous range pattern should not warn
     }
 
     match &1 {
-        (e @ &(1...2)) => {} //~ WARNING: unnecessary parentheses around outer pattern
-        &(_) => {}           //~ WARNING: unnecessary parentheses around pattern
-        e @ &(1...2) => {}   // Ambiguous range pattern should not warn
-        &(1...2) => {}       // Ambiguous range pattern should not warn
+        (e @ &(1...2)) => {} //~ ERROR unnecessary parentheses around pattern
+        &(_) => {} //~ ERROR unnecessary parentheses around pattern
+        e @ &(1...2) => {} // Ambiguous range pattern should not warn
+        &(1...2) => {} // Ambiguous range pattern should not warn
     }
 
     match &1 {
@@ -28,19 +78,19 @@ fn main() {
     }
 
     match 1 {
-        (_) => {}         //~ WARNING: unnecessary parentheses around pattern
-        (y) => {}         //~ WARNING: unnecessary parentheses around pattern
-        (ref r) => {}     //~ WARNING: unnecessary parentheses around pattern
-        (e @ 1..=2) => {} //~ WARNING: unnecessary parentheses around outer pattern
-        (1..=2) => {}     // Non ambiguous range pattern should not warn
+        (_) => {} //~ ERROR unnecessary parentheses around pattern
+        (y) => {} //~ ERROR unnecessary parentheses around pattern
+        (ref r) => {} //~ ERROR unnecessary parentheses around pattern
+        (e @ 1..=2) => {} //~ ERROR unnecessary parentheses around pattern
+        (1..=2) => {} // Non ambiguous range pattern should not warn
         e @ (3..=4) => {} // Non ambiguous range pattern should not warn
     }
 
     match &1 {
-        (e @ &(1..=2)) => {} //~ WARNING: unnecessary parentheses around outer pattern
-        &(_) => {}           //~ WARNING: unnecessary parentheses around pattern
-        e @ &(1..=2) => {}   // Ambiguous range pattern should not warn
-        &(1..=2) => {}       // Ambiguous range pattern should not warn
+        (e @ &(1..=2)) => {} //~ ERROR unnecessary parentheses around pattern
+        &(_) => {} //~ ERROR unnecessary parentheses around pattern
+        e @ &(1..=2) => {} // Ambiguous range pattern should not warn
+        &(1..=2) => {} // Ambiguous range pattern should not warn
     }
 
     match &1 {
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
index 3b312198952a5..a3e0fb938b3c6 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
@@ -1,78 +1,173 @@
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:10:9
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:35:25
    |
-LL |         (_) => {}
+LL |     fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now.
+   |                         ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:38:27
+   |
+LL |     let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or.
+   |                           ^ used in a pattern more than once
+
+warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
+  --> $DIR/issue-54538-unused-parens-lint.rs:3:12
+   |
+LL | #![feature(or_patterns)]
+   |            ^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:12:9
+   |
+LL |     let (a) = 0;
    |         ^^^ help: remove these parentheses
    |
 note: lint level defined here
-  --> $DIR/issue-54538-unused-parens-lint.rs:6:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:9:9
    |
-LL | #![warn(unused_parens)]
+LL | #![deny(unused_parens)]
    |         ^^^^^^^^^^^^^
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:11:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:13:9
+   |
+LL |     for (a) in 0..1 {}
+   |         ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:14:12
+   |
+LL |     if let (a) = 0 {}
+   |            ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:15:15
+   |
+LL |     while let (a) = 0 {}
+   |               ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:16:12
+   |
+LL |     fn foo((a): u8) {}
+   |            ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:17:14
+   |
+LL |     let _ = |(a): u8| 0;
+   |              ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:43:12
+   |
+LL |     if let (0 | 1) = 0 {}
+   |            ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:44:13
+   |
+LL |     if let ((0 | 1),) = (0,) {}
+   |             ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:45:13
+   |
+LL |     if let [(0 | 1)] = [0] {}
+   |             ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:46:16
+   |
+LL |     if let 0 | (1 | 2) = 0 {}
+   |                ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:48:15
+   |
+LL |     if let TS((0 | 1)) = TS(0) {}
+   |               ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:50:20
+   |
+LL |     if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
+   |                    ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:60:9
+   |
+LL |         (_) => {}
+   |         ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:61:9
    |
 LL |         (y) => {}
    |         ^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:12:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:62:9
    |
 LL |         (ref r) => {}
    |         ^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:13:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:63:9
    |
 LL |         (e @ 1...2) => {}
    |         ^^^^^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:19:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:69:9
    |
 LL |         (e @ &(1...2)) => {}
    |         ^^^^^^^^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:20:10
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:70:10
    |
 LL |         &(_) => {}
    |          ^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:31:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:81:9
    |
 LL |         (_) => {}
    |         ^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:32:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:82:9
    |
 LL |         (y) => {}
    |         ^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:33:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:83:9
    |
 LL |         (ref r) => {}
    |         ^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:34:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:84:9
    |
 LL |         (e @ 1..=2) => {}
    |         ^^^^^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:40:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:90:9
    |
 LL |         (e @ &(1..=2)) => {}
    |         ^^^^^^^^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:41:10
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:91:10
    |
 LL |         &(_) => {}
    |          ^^^ help: remove these parentheses
 
+error: aborting due to 26 previous errors
+
+For more information about this error, try `rustc --explain E0416`.

From b03d3dc478ba13f405cf9a877a4894de096a1cc1 Mon Sep 17 00:00:00 2001
From: Daniel Henry-Mantilla <daniel.henrymantilla@gatewatcher.com>
Date: Tue, 3 Sep 2019 15:36:21 +0200
Subject: [PATCH 439/943] Changed comment to better reflect std's exceptional
 situation

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

diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 495c0c8d17256..0386dbd490d03 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -374,11 +374,11 @@ where
                 // FIXME(danielhenrymantilla): #42788
                 //
                 //   - This creates a (mut) reference to a slice of
-                //     _uninitialized integers_.
+                //     _uninitialized_ integers, which is **undefined behavior**
                 //
-                //   - This having defined behavior is **unstable**:
-                //     it could become UB in the future,
-                //     at which point it would have be changed.
+                //   - Only the standard library gets to soundly "ignore" this,
+                //     based on its privileged knowledge of unstable rustc
+                //     internals;
                 g.buf.reserve(reservation_size(r));
                 let capacity = g.buf.capacity();
                 g.buf.set_len(capacity);

From 3284734f789ad1a4c71576c20664bfa80e78f539 Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Tue, 3 Sep 2019 20:22:03 +0900
Subject: [PATCH 440/943] Update Clippy

---
 src/tools/clippy | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/clippy b/src/tools/clippy
index 70e7d075df7b3..aeadf1562c024 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit 70e7d075df7b3e11e61fa99b30e1ede26cee6afd
+Subproject commit aeadf1562c024d3c5421e61dc6b8d48c2d7902f5

From 0662fcf4f950ec2800f0b1e02254ef2389b55079 Mon Sep 17 00:00:00 2001
From: Artyom Pavlov <newpavlov@gmail.com>
Date: Tue, 3 Sep 2019 14:37:53 +0000
Subject: [PATCH 441/943] make wasi a target-specific dependency

---
 src/libstd/Cargo.toml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 0d04b7a274037..173bcea0846a0 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -24,7 +24,6 @@ compiler_builtins = { version = "0.1.16" }
 profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] }
-wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] }
 
 [dependencies.backtrace]
 version = "0.3.35"
@@ -57,6 +56,9 @@ dlmalloc = { version = "0.1", features = ['rustc-dep-of-std'] }
 [target.x86_64-fortanix-unknown-sgx.dependencies]
 fortanix-sgx-abi = { version = "0.3.2", features = ['rustc-dep-of-std'] }
 
+[target.wasm32-wasi.dependencies]
+wasi = { version = "0.7.0", features = ['rustc-dep-of-std', 'alloc'] }
+
 [build-dependencies]
 cc = "1.0"
 

From 28b518474ed2a5dee812e4f356f71f4c60628421 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 3 Sep 2019 08:03:09 -0700
Subject: [PATCH 442/943] review comments: error code text

---
 src/librustc_typeck/error_codes.rs | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index ebfa6acf23e00..a2b1f16ef3de7 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -2431,26 +2431,28 @@ This error indicates that the `self` parameter in a method has an invalid
 
 Methods take a special first parameter, of which there are three variants:
 `self`, `&self`, and `&mut self`. These are syntactic sugar for
-`self: Self`, `self: &Self`, and `self: &mut Self` respectively. The type
-`Self` acts as an alias to the type of the current trait implementer, or
-"receiver type". Besides the already mentioned `Self`, `&Self` and
-`&mut Self` valid receiver types, the following are also valid:
-`self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, and `self: Pin<P>`
-(where P is one of the previous types except `Self`).
+`self: Self`, `self: &Self`, and `self: &mut Self` respectively.
 
 ```
 # struct Foo;
 trait Trait {
     fn foo(&self);
+//         ^^^^^ `self` here is a reference to the receiver object
 }
 
 impl Trait for Foo {
     fn foo(&self) {}
-//         ^^^^^ this the receiver type `&Foo`
+//         ^^^^^ the receiver type is `&Foo`
 }
 ```
 
-The above is equivalent to:
+The type `Self` acts as an alias to the type of the current trait
+implementer, or "receiver type". Besides the already mentioned `Self`,
+`&Self` and `&mut Self` valid receiver types, the following are also valid:
+`self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, and `self: Pin<P>`
+(where P is one of the previous types except `Self`). Note that `Self` can
+also be the underlying implementing type, like `Foo` in the following
+example:
 
 ```
 # struct Foo;

From 4a79633ad2ff5ce1641405daefc41a13d786dacf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 3 Sep 2019 08:05:54 -0700
Subject: [PATCH 443/943] review comments

---
 src/librustc/traits/object_safety.rs                         | 4 +++-
 src/test/ui/self/arbitrary-self-types-not-object-safe.stderr | 4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 5392e9100c6d1..f7f459cd27f68 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -60,13 +60,15 @@ impl ObjectSafetyViolation {
             ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) =>
                 format!("method `{}` has generic type parameters", name).into(),
             ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) =>
-                format!("method `{}`'s receiver cannot be dispatched on", name).into(),
+                format!("method `{}`'s `self` parameter cannot be dispatched on", name).into(),
             ObjectSafetyViolation::AssocConst(name, _) =>
                 format!("the trait cannot contain associated consts like `{}`", name).into(),
         }
     }
 
     pub fn span(&self) -> Option<Span> {
+        // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so
+        // diagnostics use a `note` instead of a `span_label`.
         match *self {
             ObjectSafetyViolation::AssocConst(_, span) |
             ObjectSafetyViolation::Method(_, _, span) if span != DUMMY_SP => Some(span),
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
index 9fb1500afce47..e6eba377a9578 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
@@ -2,7 +2,7 @@ error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/arbitrary-self-types-not-object-safe.rs:31:32
    |
 LL |     fn foo(self: &Rc<Self>) -> usize;
-   |        --- method `foo`'s receiver cannot be dispatched on
+   |        --- method `foo`'s `self` parameter cannot be dispatched on
 ...
 LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
    |                                ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
@@ -11,7 +11,7 @@ error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/arbitrary-self-types-not-object-safe.rs:31:13
    |
 LL |     fn foo(self: &Rc<Self>) -> usize;
-   |        --- method `foo`'s receiver cannot be dispatched on
+   |        --- method `foo`'s `self` parameter cannot be dispatched on
 ...
 LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
    |             ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object

From e16ce8007a129fc3829d5ed9c1fed5cd4fb6c2c9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 3 Sep 2019 08:07:35 -0700
Subject: [PATCH 444/943] fix error code test

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

diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index a2b1f16ef3de7..093446d28533e 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -2473,7 +2473,7 @@ like in the following example:
 # trait Trait {
 #     fn foo(&self);
 # }
-impl Trait for Struct {
+impl Trait for Foo {
     fn foo(self: &Bar) {}
 }
 ```

From 12adc395c375d4ab14d24624a0ccdd519d5a5978 Mon Sep 17 00:00:00 2001
From: nathanwhit <nathan.whitaker01@gmail.com>
Date: Tue, 3 Sep 2019 11:56:08 -0400
Subject: [PATCH 445/943] Strip remote-test-client output from run stdout

The remote-test-client outputs a message of the form "uploaded
"<build_dir>/<executable_path>", waiting for result" onto stdout when
executing a test, which is then captured in the process result. This needs to be removed when
comparing the results of the run-pass test execution.
---
 src/tools/compiletest/src/runtest.rs | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 7b5e0752b3673..8fb1302936c66 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2951,8 +2951,24 @@ impl<'test> TestCx<'test> {
         let expected_stderr = self.load_expected_output(stderr_kind);
         let expected_stdout = self.load_expected_output(stdout_kind);
 
-        let normalized_stdout =
-            self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout);
+        let normalized_stdout = match output_kind {
+            TestOutput::Run if self.config.remote_test_client.is_some() => {
+                // When tests are run using the remote-test-client, the string
+                // 'uploaded "$TEST_BUILD_DIR/<test_executable>, waiting for result"'
+                // is printed to stdout by the client and then captured in the ProcRes,
+                // so it needs to be removed when comparing the run-pass test execution output
+                lazy_static! {
+                    static ref REMOTE_TEST_RE: Regex = Regex::new(
+                        "^uploaded \"\\$TEST_BUILD_DIR(/[[:alnum:]_\\-]+)+\", waiting for result\n"
+                    ).unwrap();
+                }
+                REMOTE_TEST_RE.replace(
+                    &self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout),
+                    ""
+                ).to_string()
+            }
+            _ => self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout)
+        };
 
         let stderr = if explicit_format {
             proc_res.stderr.clone()

From 87866714ee1cf3fba6e659f46413e361b9088362 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 3 Sep 2019 08:12:28 -0700
Subject: [PATCH 446/943] fix comment and add delay_span_bug

---
 src/librustc_typeck/impl_wf_check.rs | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index 8e69fbd9a79ef..82acbf7c74803 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -12,7 +12,7 @@ use crate::constrained_generic_params as cgp;
 use rustc::hir;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::hir::def_id::DefId;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, TyCtxt, TypeFoldable};
 use rustc::ty::query::Providers;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use std::collections::hash_map::Entry::{Occupied, Vacant};
@@ -99,8 +99,13 @@ fn enforce_impl_params_are_constrained(
 ) {
     // Every lifetime used in an associated type must be constrained.
     let impl_self_ty = tcx.type_of(impl_def_id);
-    if impl_self_ty.sty == ty::Error {
-        // Don't complain about unconstrained type params when self ty doesn't exist. (#36836)
+    if impl_self_ty.references_error() {
+        // Don't complain about unconstrained type params when self ty isn't known due to errors.
+        // (#36836)
+        tcx.sess.delay_span_bug(tcx.def_span(impl_def_id), &format(
+            "potentially unconstrained type parameters weren't evaluated on `{:?}`",
+            impl_self_ty,
+        ));
         return;
     }
     let impl_generics = tcx.generics_of(impl_def_id);

From c44ffafab902e687ef01d2366a7de7237e25245c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 3 Sep 2019 08:33:06 -0700
Subject: [PATCH 447/943] review comment

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

diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index 82acbf7c74803..bc0f17c3bf0fb 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -102,10 +102,10 @@ fn enforce_impl_params_are_constrained(
     if impl_self_ty.references_error() {
         // Don't complain about unconstrained type params when self ty isn't known due to errors.
         // (#36836)
-        tcx.sess.delay_span_bug(tcx.def_span(impl_def_id), &format(
-            "potentially unconstrained type parameters weren't evaluated on `{:?}`",
-            impl_self_ty,
-        ));
+        tcx.sess.delay_span_bug(
+            tcx.def_span(impl_def_id),
+            "potentially unconstrained type parameters weren't evaluated",
+        );
         return;
     }
     let impl_generics = tcx.generics_of(impl_def_id);

From 925a766bc0d34f8808e9902c47bea54b09540774 Mon Sep 17 00:00:00 2001
From: Jane Lusby <jlusby@yaah.dev>
Date: Wed, 28 Aug 2019 20:28:42 -0700
Subject: [PATCH 448/943] Add Yaah to clippy toolstain notification list

---
 src/tools/publish_toolstate.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 1411f4c0b05a2..2e2505b7f0246 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -22,7 +22,7 @@
 # List of people to ping when the status of a tool or a book changed.
 MAINTAINERS = {
     'miri': '@oli-obk @RalfJung @eddyb',
-    'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk @phansch @flip1995',
+    'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk @phansch @flip1995 @yaahc',
     'rls': '@Xanewok',
     'rustfmt': '@topecongiro',
     'book': '@carols10cents @steveklabnik',

From fa893a322570ea60cc8815b3dddb5311f0cb3b63 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Sat, 31 Aug 2019 20:08:06 +0300
Subject: [PATCH 449/943] use TokenStream rather than &[TokenTree] for built-in
 macros

That way, we don't loose the jointness info
---
 .../src/language-features/plugin.md           |  6 +--
 src/librustc_metadata/encoder.rs              |  2 +-
 src/libsyntax/diagnostics/plugin.rs           | 46 +++++++++----------
 src/libsyntax/ext/base.rs                     | 27 +++++------
 src/libsyntax/ext/expand.rs                   |  2 +-
 src/libsyntax/print/pprust.rs                 |  6 +--
 src/libsyntax/tokenstream.rs                  |  2 +-
 src/libsyntax_ext/asm.rs                      | 24 ++++------
 src/libsyntax_ext/assert.rs                   |  6 +--
 src/libsyntax_ext/cfg.rs                      |  6 +--
 src/libsyntax_ext/compile_error.rs            |  4 +-
 src/libsyntax_ext/concat.rs                   |  4 +-
 src/libsyntax_ext/concat_idents.rs            | 10 ++--
 src/libsyntax_ext/env.rs                      |  6 +--
 src/libsyntax_ext/format.rs                   | 10 ++--
 src/libsyntax_ext/global_asm.rs               |  6 +--
 src/libsyntax_ext/log_syntax.rs               |  4 +-
 src/libsyntax_ext/source_util.rs              | 18 ++++----
 src/libsyntax_ext/trace_macros.rs             | 27 +++++++----
 .../ui-fulldeps/auxiliary/roman-numerals.rs   |  6 +--
 20 files changed, 109 insertions(+), 113 deletions(-)

diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md
index 53e8393ec52e4..68877b48433d5 100644
--- a/src/doc/unstable-book/src/language-features/plugin.md
+++ b/src/doc/unstable-book/src/language-features/plugin.md
@@ -57,12 +57,12 @@ extern crate rustc;
 extern crate rustc_driver;
 
 use syntax::parse::token::{self, Token};
-use syntax::tokenstream::TokenTree;
+use syntax::tokenstream::{TokenTree, TokenStream};
 use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
 use syntax_pos::Span;
 use rustc_driver::plugin::Registry;
 
-fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
+fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: TokenStream)
         -> Box<dyn MacResult + 'static> {
 
     static NUMERALS: &'static [(&'static str, usize)] = &[
@@ -78,7 +78,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         return DummyResult::any(sp);
     }
 
-    let text = match args[0] {
+    let text = match args.into_trees().next().unwrap() {
         TokenTree::Token(Token { kind: token::Ident(s, _), .. }) => s.to_string(),
         _ => {
             cx.span_err(sp, "argument should be a single identifier");
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index db212408d8ebd..f430f01542efe 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1354,7 +1354,7 @@ impl EncodeContext<'tcx> {
         let def_id = self.tcx.hir().local_def_id(macro_def.hir_id);
         Entry {
             kind: EntryKind::MacroDef(self.lazy(MacroDef {
-                body: pprust::tokens_to_string(macro_def.body.clone()),
+                body: pprust::tts_to_string(macro_def.body.clone()),
                 legacy: macro_def.legacy,
             })),
             visibility: self.lazy(ty::Visibility::Public),
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index e9a55af52e878..5de39c8d14d17 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -6,7 +6,7 @@ use crate::ext::base::{ExtCtxt, MacEager, MacResult};
 use crate::parse::token::{self, Token};
 use crate::ptr::P;
 use crate::symbol::kw;
-use crate::tokenstream::{TokenTree};
+use crate::tokenstream::{TokenTree, TokenStream};
 
 use smallvec::smallvec;
 use syntax_pos::Span;
@@ -27,12 +27,11 @@ pub type ErrorMap = BTreeMap<Name, ErrorInfo>;
 
 pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                    span: Span,
-                                   token_tree: &[TokenTree])
+                                   tts: TokenStream)
                                    -> Box<dyn MacResult+'cx> {
-    let code = match token_tree {
-        [
-            TokenTree::Token(Token { kind: token::Ident(code, _), .. })
-        ] => code,
+    assert_eq!(tts.len(), 1);
+    let code = match tts.into_trees().next() {
+        Some(TokenTree::Token(Token { kind: token::Ident(code, _), .. })) => code,
         _ => unreachable!()
     };
 
@@ -62,20 +61,21 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt<'_>,
 
 pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                        span: Span,
-                                       token_tree: &[TokenTree])
+                                       tts: TokenStream)
                                        -> Box<dyn MacResult+'cx> {
-    let (code, description) = match  token_tree {
-        [
-            TokenTree::Token(Token { kind: token::Ident(code, _), .. })
-        ] => {
-            (*code, None)
-        },
-        [
-            TokenTree::Token(Token { kind: token::Ident(code, _), .. }),
-            TokenTree::Token(Token { kind: token::Comma, .. }),
-            TokenTree::Token(Token { kind: token::Literal(token::Lit { symbol, .. }), ..})
-        ] => {
-            (*code, Some(*symbol))
+    assert!(tts.len() == 1 || tts.len() == 3);
+    let mut cursor = tts.into_trees();
+    let code = match cursor.next() {
+        Some(TokenTree::Token(Token { kind: token::Ident(code, _), .. })) => code,
+        _ => unreachable!()
+    };
+    let description = match  (cursor.next(), cursor.next()) {
+        (None, None) => None,
+        (
+            Some(TokenTree::Token(Token { kind: token::Comma, .. })),
+            Some(TokenTree::Token(Token { kind: token::Literal(token::Lit { symbol, .. }), ..}))
+        ) => {
+            Some(symbol)
         },
         _ => unreachable!()
     };
@@ -121,12 +121,12 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>,
 
 pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                           span: Span,
-                                          token_tree: &[TokenTree])
+                                          tts: TokenStream)
                                           -> Box<dyn MacResult+'cx> {
-    assert_eq!(token_tree.len(), 3);
-    let ident = match &token_tree[2] {
+    assert_eq!(tts.len(), 3);
+    let ident = match tts.into_trees().nth(2) {
         // DIAGNOSTICS ident.
-        &TokenTree::Token(Token { kind: token::Ident(name, _), span })
+        Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }))
         => Ident::new(name, span),
         _ => unreachable!()
     };
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 5d68983d7cb66..109ba041016c6 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -10,7 +10,7 @@ use crate::parse::token;
 use crate::ptr::P;
 use crate::symbol::{kw, sym, Ident, Symbol};
 use crate::{ThinVec, MACRO_ARGUMENTS};
-use crate::tokenstream::{self, TokenStream, TokenTree};
+use crate::tokenstream::{self, TokenStream};
 use crate::visit::Visitor;
 
 use errors::{DiagnosticBuilder, DiagnosticId};
@@ -235,18 +235,18 @@ pub trait TTMacroExpander {
 }
 
 pub type MacroExpanderFn =
-    for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, &[tokenstream::TokenTree])
+    for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream)
                 -> Box<dyn MacResult+'cx>;
 
 impl<F> TTMacroExpander for F
-    where F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, &[tokenstream::TokenTree])
+    where F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream)
     -> Box<dyn MacResult+'cx>
 {
     fn expand<'cx>(
         &self,
         ecx: &'cx mut ExtCtxt<'_>,
         span: Span,
-        input: TokenStream,
+        mut input: TokenStream,
     ) -> Box<dyn MacResult+'cx> {
         struct AvoidInterpolatedIdents;
 
@@ -268,10 +268,8 @@ impl<F> TTMacroExpander for F
                 mut_visit::noop_visit_mac(mac, self)
             }
         }
-
-        let input: Vec<_> =
-            input.trees().map(|mut tt| { AvoidInterpolatedIdents.visit_tt(&mut tt); tt }).collect();
-        (*self)(ecx, span, &input)
+        AvoidInterpolatedIdents.visit_tts(&mut input);
+        (*self)(ecx, span, input)
     }
 }
 
@@ -677,7 +675,7 @@ impl SyntaxExtension {
     }
 
     pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
-        fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: &[TokenTree])
+        fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: TokenStream)
                          -> Box<dyn MacResult + 'cx> {
             DummyResult::any(span)
         }
@@ -811,9 +809,8 @@ impl<'a> ExtCtxt<'a> {
     pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
         expand::MacroExpander::new(self, true)
     }
-
-    pub fn new_parser_from_tts(&self, tts: &[tokenstream::TokenTree]) -> parser::Parser<'a> {
-        parse::stream_to_parser(self.parse_sess, tts.iter().cloned().collect(), MACRO_ARGUMENTS)
+    pub fn new_parser_from_tts(&self, stream: TokenStream) -> parser::Parser<'a> {
+        parse::stream_to_parser(self.parse_sess, stream, MACRO_ARGUMENTS)
     }
     pub fn source_map(&self) -> &'a SourceMap { self.parse_sess.source_map() }
     pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
@@ -1019,7 +1016,7 @@ pub fn expr_to_string(cx: &mut ExtCtxt<'_>, expr: P<ast::Expr>, err_msg: &str)
 /// done as rarely as possible).
 pub fn check_zero_tts(cx: &ExtCtxt<'_>,
                       sp: Span,
-                      tts: &[tokenstream::TokenTree],
+                      tts: TokenStream,
                       name: &str) {
     if !tts.is_empty() {
         cx.span_err(sp, &format!("{} takes no arguments", name));
@@ -1030,7 +1027,7 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>,
 /// expect exactly one string literal, or emit an error and return `None`.
 pub fn get_single_str_from_tts(cx: &mut ExtCtxt<'_>,
                                sp: Span,
-                               tts: &[tokenstream::TokenTree],
+                               tts: TokenStream,
                                name: &str)
                                -> Option<String> {
     let mut p = cx.new_parser_from_tts(tts);
@@ -1053,7 +1050,7 @@ pub fn get_single_str_from_tts(cx: &mut ExtCtxt<'_>,
 /// parsing error, emit a non-fatal error and return `None`.
 pub fn get_exprs_from_tts(cx: &mut ExtCtxt<'_>,
                           sp: Span,
-                          tts: &[tokenstream::TokenTree]) -> Option<Vec<P<ast::Expr>>> {
+                          tts: TokenStream) -> Option<Vec<P<ast::Expr>>> {
     let mut p = cx.new_parser_from_tts(tts);
     let mut es = Vec::new();
     while p.token != token::Eof {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 7b4a516744642..4fd0c367288bf 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -701,7 +701,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         path: &Path,
         span: Span,
     ) -> AstFragment {
-        let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::<Vec<_>>());
+        let mut parser = self.cx.new_parser_from_tts(toks);
         match parser.parse_ast_fragment(kind, false) {
             Ok(fragment) => {
                 parser.ensure_complete_parse(path, kind.name(), span);
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index bead941b20d5a..37305055e62a3 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -356,11 +356,7 @@ pub fn tt_to_string(tt: tokenstream::TokenTree) -> String {
     to_string(|s| s.print_tt(tt, false))
 }
 
-pub fn tts_to_string(tts: &[tokenstream::TokenTree]) -> String {
-    tokens_to_string(tts.iter().cloned().collect())
-}
-
-pub fn tokens_to_string(tokens: TokenStream) -> String {
+pub fn tts_to_string(tokens: TokenStream) -> String {
     to_string(|s| s.print_tts(tokens, false))
 }
 
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 0d9f3769ce904..480553586197e 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -506,7 +506,7 @@ impl Cursor {
 
 impl fmt::Display for TokenStream {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&pprust::tokens_to_string(self.clone()))
+        f.write_str(&pprust::tts_to_string(self.clone()))
     }
 }
 
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 28f907441d872..328b307361d9e 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -8,13 +8,12 @@ use errors::DiagnosticBuilder;
 
 use syntax::ast;
 use syntax::ext::base::{self, *};
-use syntax::parse;
 use syntax::parse::token::{self, Token};
 use syntax::ptr::P;
 use syntax::symbol::{kw, sym, Symbol};
 use syntax::ast::AsmDialect;
 use syntax_pos::Span;
-use syntax::tokenstream;
+use syntax::tokenstream::{self, TokenStream};
 use syntax::{span_err, struct_span_err};
 
 enum State {
@@ -43,7 +42,7 @@ const OPTIONS: &[Symbol] = &[sym::volatile, sym::alignstack, sym::intel];
 
 pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                        sp: Span,
-                       tts: &[tokenstream::TokenTree])
+                       tts: TokenStream)
                        -> Box<dyn base::MacResult + 'cx> {
     let mut inline_asm = match parse_inline_asm(cx, sp, tts) {
         Ok(Some(inline_asm)) => inline_asm,
@@ -71,20 +70,20 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
 fn parse_inline_asm<'a>(
     cx: &mut ExtCtxt<'a>,
     sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Result<Option<ast::InlineAsm>, DiagnosticBuilder<'a>> {
     // Split the tts before the first colon, to avoid `asm!("x": y)`  being
     // parsed as `asm!(z)` with `z = "x": y` which is type ascription.
-    let first_colon = tts.iter()
+    let first_colon = tts.trees()
         .position(|tt| {
-            match *tt {
+            match tt {
                 tokenstream::TokenTree::Token(Token { kind: token::Colon, .. }) |
                 tokenstream::TokenTree::Token(Token { kind: token::ModSep, .. }) => true,
                 _ => false,
             }
         })
         .unwrap_or(tts.len());
-    let mut p = cx.new_parser_from_tts(&tts[first_colon..]);
+    let mut p = cx.new_parser_from_tts(tts.trees().skip(first_colon).collect());
     let mut asm = kw::Invalid;
     let mut asm_str_style = None;
     let mut outputs = Vec::new();
@@ -110,7 +109,8 @@ fn parse_inline_asm<'a>(
                     ));
                 }
                 // Nested parser, stop before the first colon (see above).
-                let mut p2 = cx.new_parser_from_tts(&tts[..first_colon]);
+                let mut p2 =
+                    cx.new_parser_from_tts(tts.trees().take(first_colon).collect());
 
                 if p2.token == token::Eof {
                     let mut err =
@@ -129,12 +129,8 @@ fn parse_inline_asm<'a>(
                 // This is most likely malformed.
                 if p2.token != token::Eof {
                     let mut extra_tts = p2.parse_all_token_trees()?;
-                    extra_tts.extend(tts[first_colon..].iter().cloned());
-                    p = parse::stream_to_parser(
-                        cx.parse_sess,
-                        extra_tts.into_iter().collect(),
-                        Some("inline assembly"),
-                    );
+                    extra_tts.extend(tts.trees().skip(first_colon));
+                    p = cx.new_parser_from_tts(extra_tts.into_iter().collect());
                 }
 
                 asm = s;
diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs
index 84583d0e5eca7..001996e1db718 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -13,7 +13,7 @@ use syntax_pos::{Span, DUMMY_SP};
 pub fn expand_assert<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
-    tts: &[TokenTree],
+    tts: TokenStream,
 ) -> Box<dyn MacResult + 'cx> {
     let Assert { cond_expr, custom_message } = match parse_assert(cx, sp, tts) {
         Ok(assert) => assert,
@@ -59,9 +59,9 @@ struct Assert {
 fn parse_assert<'a>(
     cx: &mut ExtCtxt<'a>,
     sp: Span,
-    tts: &[TokenTree]
+    stream: TokenStream
 ) -> Result<Assert, DiagnosticBuilder<'a>> {
-    let mut parser = cx.new_parser_from_tts(tts);
+    let mut parser = cx.new_parser_from_tts(stream);
 
     if parser.token == token::Eof {
         let mut err = cx.struct_span_err(sp, "macro requires a boolean expression as an argument");
diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs
index 21cee8ae1cb9c..0342e442df2e9 100644
--- a/src/libsyntax_ext/cfg.rs
+++ b/src/libsyntax_ext/cfg.rs
@@ -7,14 +7,14 @@ use errors::DiagnosticBuilder;
 use syntax::ast;
 use syntax::ext::base::{self, *};
 use syntax::attr;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 use syntax::parse::token;
 use syntax_pos::Span;
 
 pub fn expand_cfg(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
     let sp = cx.with_legacy_ctxt(sp);
 
@@ -33,7 +33,7 @@ pub fn expand_cfg(
 fn parse_cfg<'a>(
     cx: &mut ExtCtxt<'a>,
     sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Result<ast::MetaItem, DiagnosticBuilder<'a>> {
     let mut p = cx.new_parser_from_tts(tts);
 
diff --git a/src/libsyntax_ext/compile_error.rs b/src/libsyntax_ext/compile_error.rs
index 59d3f2c9c7813..24f3a66d4ae19 100644
--- a/src/libsyntax_ext/compile_error.rs
+++ b/src/libsyntax_ext/compile_error.rs
@@ -2,11 +2,11 @@
 
 use syntax::ext::base::{self, *};
 use syntax_pos::Span;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 
 pub fn expand_compile_error<'cx>(cx: &'cx mut ExtCtxt<'_>,
                               sp: Span,
-                              tts: &[tokenstream::TokenTree])
+                              tts: TokenStream)
                               -> Box<dyn base::MacResult + 'cx> {
     let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") {
         None => return DummyResult::any(sp),
diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs
index ffa5154ca0c36..514e95390bca8 100644
--- a/src/libsyntax_ext/concat.rs
+++ b/src/libsyntax_ext/concat.rs
@@ -1,14 +1,14 @@
 use syntax::ast;
 use syntax::ext::base::{self, DummyResult};
 use syntax::symbol::Symbol;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 
 use std::string::String;
 
 pub fn expand_syntax_ext(
     cx: &mut base::ExtCtxt<'_>,
     sp: syntax_pos::Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
     let es = match base::get_exprs_from_tts(cx, sp, tts) {
         Some(e) => e,
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index 96677072d1b80..73de25b222586 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -6,11 +6,11 @@ use syntax::parse::token::{self, Token};
 use syntax::ptr::P;
 use syntax_pos::Span;
 use syntax_pos::symbol::Symbol;
-use syntax::tokenstream::TokenTree;
+use syntax::tokenstream::{TokenTree, TokenStream};
 
 pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
                               sp: Span,
-                              tts: &[TokenTree])
+                              tts: TokenStream)
                               -> Box<dyn base::MacResult + 'cx> {
     if tts.is_empty() {
         cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
@@ -18,9 +18,9 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
     }
 
     let mut res_str = String::new();
-    for (i, e) in tts.iter().enumerate() {
+    for (i, e) in tts.into_trees().enumerate() {
         if i & 1 == 1 {
-            match *e {
+            match e {
                 TokenTree::Token(Token { kind: token::Comma, .. }) => {}
                 _ => {
                     cx.span_err(sp, "concat_idents! expecting comma.");
@@ -28,7 +28,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
                 }
             }
         } else {
-            match *e {
+            match e {
                 TokenTree::Token(Token { kind: token::Ident(name, _), .. }) =>
                     res_str.push_str(&name.as_str()),
                 _ => {
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 6343d218de829..179b7fe00a97a 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -7,13 +7,13 @@ use syntax::ast::{self, Ident, GenericArg};
 use syntax::ext::base::{self, *};
 use syntax::symbol::{kw, sym, Symbol};
 use syntax_pos::Span;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 
 use std::env;
 
 pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
                               sp: Span,
-                              tts: &[tokenstream::TokenTree])
+                              tts: TokenStream)
                               -> Box<dyn base::MacResult + 'cx> {
     let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
         None => return DummyResult::any(sp),
@@ -45,7 +45,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
 
 pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
                        sp: Span,
-                       tts: &[tokenstream::TokenTree])
+                       tts: TokenStream)
                        -> Box<dyn base::MacResult + 'cx> {
     let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
         Some(ref exprs) if exprs.is_empty() => {
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 47394c02b4186..ad275f421af49 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -11,7 +11,7 @@ use syntax::ext::base::{self, *};
 use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::symbol::{Symbol, sym};
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 use syntax_pos::{MultiSpan, Span};
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -126,7 +126,7 @@ struct Context<'a, 'b> {
 fn parse_args<'a>(
     ecx: &mut ExtCtxt<'a>,
     sp: Span,
-    tts: &[tokenstream::TokenTree]
+    tts: TokenStream,
 ) -> Result<(P<ast::Expr>, Vec<P<ast::Expr>>, FxHashMap<Symbol, usize>), DiagnosticBuilder<'a>> {
     let mut args = Vec::<P<ast::Expr>>::new();
     let mut names = FxHashMap::<Symbol, usize>::default();
@@ -794,7 +794,7 @@ impl<'a, 'b> Context<'a, 'b> {
 fn expand_format_args_impl<'cx>(
     ecx: &'cx mut ExtCtxt<'_>,
     mut sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
     nl: bool,
 ) -> Box<dyn base::MacResult + 'cx> {
     sp = ecx.with_def_site_ctxt(sp);
@@ -812,7 +812,7 @@ fn expand_format_args_impl<'cx>(
 pub fn expand_format_args<'cx>(
     ecx: &'cx mut ExtCtxt<'_>,
     sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
     expand_format_args_impl(ecx, sp, tts, false)
 }
@@ -820,7 +820,7 @@ pub fn expand_format_args<'cx>(
 pub fn expand_format_args_nl<'cx>(
     ecx: &'cx mut ExtCtxt<'_>,
     sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
     expand_format_args_impl(ecx, sp, tts, true)
 }
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index a8b61593db749..6140f0df58af9 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -16,12 +16,12 @@ use syntax::ext::base::{self, *};
 use syntax::parse::token;
 use syntax::ptr::P;
 use syntax_pos::Span;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 use smallvec::smallvec;
 
 pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                               sp: Span,
-                              tts: &[tokenstream::TokenTree]) -> Box<dyn base::MacResult + 'cx> {
+                              tts: TokenStream) -> Box<dyn base::MacResult + 'cx> {
     match parse_global_asm(cx, sp, tts) {
         Ok(Some(global_asm)) => {
             MacEager::items(smallvec![P(ast::Item {
@@ -45,7 +45,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
 fn parse_global_asm<'a>(
     cx: &mut ExtCtxt<'a>,
     sp: Span,
-    tts: &[tokenstream::TokenTree]
+    tts: TokenStream
 ) -> Result<Option<ast::GlobalAsm>, DiagnosticBuilder<'a>> {
     let mut p = cx.new_parser_from_tts(tts);
 
diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs
index cbdfd08b4977f..d09d72a97be15 100644
--- a/src/libsyntax_ext/log_syntax.rs
+++ b/src/libsyntax_ext/log_syntax.rs
@@ -1,11 +1,11 @@
 use syntax::ext::base;
 use syntax::print;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 use syntax_pos;
 
 pub fn expand_syntax_ext<'cx>(_cx: &'cx mut base::ExtCtxt<'_>,
                               sp: syntax_pos::Span,
-                              tts: &[tokenstream::TokenTree])
+                              tts: TokenStream)
                               -> Box<dyn base::MacResult + 'cx> {
     println!("{}", print::pprust::tts_to_string(tts));
 
diff --git a/src/libsyntax_ext/source_util.rs b/src/libsyntax_ext/source_util.rs
index e008ed710e4d0..9dc9d66b86f1d 100644
--- a/src/libsyntax_ext/source_util.rs
+++ b/src/libsyntax_ext/source_util.rs
@@ -4,7 +4,7 @@ use syntax::parse::{self, token, DirectoryOwnership};
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::symbol::Symbol;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 
 use smallvec::SmallVec;
 use syntax_pos::{self, Pos, Span};
@@ -16,7 +16,7 @@ use rustc_data_structures::sync::Lrc;
 // a given file into the current one.
 
 /// line!(): expands to the current line number
-pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                    -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "line!");
 
@@ -27,7 +27,7 @@ pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree
 }
 
 /* column!(): expands to the current column number */
-pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                   -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "column!");
 
@@ -40,7 +40,7 @@ pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTr
 /// file!(): expands to the current filename */
 /// The source_file (`loc.file`) contains a bunch more information we could spit
 /// out if we wanted.
-pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                    -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "file!");
 
@@ -49,13 +49,13 @@ pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree
     base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name.to_string())))
 }
 
-pub fn expand_stringify(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_stringify(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                         -> Box<dyn base::MacResult+'static> {
     let s = pprust::tts_to_string(tts);
     base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
 }
 
-pub fn expand_mod(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_mod(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                   -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "module_path!");
     let mod_path = &cx.current_expansion.module.mod_path;
@@ -67,7 +67,7 @@ pub fn expand_mod(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]
 /// include! : parse the given file as an expr
 /// This is generally a bad idea because it's going to behave
 /// unhygienically.
-pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                            -> Box<dyn base::MacResult+'cx> {
     let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
         Some(f) => f,
@@ -105,7 +105,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstrea
 }
 
 // include_str! : read the given file, insert it as a literal string expr
-pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                           -> Box<dyn base::MacResult+'static> {
     let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
         Some(f) => f,
@@ -130,7 +130,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::To
     }
 }
 
-pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                             -> Box<dyn base::MacResult+'static> {
     let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
         Some(f) => f,
diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs
index 0dce8a36f4c7b..d83c24046d9e5 100644
--- a/src/libsyntax_ext/trace_macros.rs
+++ b/src/libsyntax_ext/trace_macros.rs
@@ -1,20 +1,27 @@
 use syntax::ext::base::{self, ExtCtxt};
 use syntax::symbol::kw;
 use syntax_pos::Span;
-use syntax::tokenstream::TokenTree;
+use syntax::tokenstream::{TokenTree, TokenStream};
 
 pub fn expand_trace_macros(cx: &mut ExtCtxt<'_>,
                            sp: Span,
-                           tt: &[TokenTree])
+                           tt: TokenStream)
                            -> Box<dyn base::MacResult + 'static> {
-    match tt {
-        [TokenTree::Token(token)] if token.is_keyword(kw::True) => {
-            cx.set_trace_macros(true);
-        }
-        [TokenTree::Token(token)] if token.is_keyword(kw::False) => {
-            cx.set_trace_macros(false);
-        }
-        _ => cx.span_err(sp, "trace_macros! accepts only `true` or `false`"),
+    let mut cursor = tt.into_trees();
+    let mut err = false;
+    let value = match &cursor.next() {
+        Some(TokenTree::Token(token)) if token.is_keyword(kw::True) => true,
+        Some(TokenTree::Token(token)) if token.is_keyword(kw::False) => false,
+        _ => {
+            err = true;
+            false
+        },
+    };
+    err |= cursor.next().is_some();
+    if err {
+        cx.span_err(sp, "trace_macros! accepts only `true` or `false`")
+    } else {
+        cx.set_trace_macros(value);
     }
 
     base::DummyResult::any_valid(sp)
diff --git a/src/test/ui-fulldeps/auxiliary/roman-numerals.rs b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
index 027025b72b31b..2b57e9289b525 100644
--- a/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
+++ b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
@@ -15,12 +15,12 @@ extern crate rustc;
 extern crate rustc_driver;
 
 use syntax::parse::token::{self, Token};
-use syntax::tokenstream::TokenTree;
+use syntax::tokenstream::{TokenTree, TokenStream};
 use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
 use syntax_pos::Span;
 use rustc_driver::plugin::Registry;
 
-fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
+fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: TokenStream)
         -> Box<dyn MacResult + 'static> {
 
     static NUMERALS: &'static [(&'static str, usize)] = &[
@@ -36,7 +36,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         return DummyResult::any(sp);
     }
 
-    let text = match args[0] {
+    let text = match args.into_trees().next().unwrap() {
         TokenTree::Token(Token { kind: token::Ident(s, _), .. }) => s.to_string(),
         _ => {
             cx.span_err(sp, "argument should be a single identifier");

From 613649584a9571168c292f82156aee1c173337a8 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Tue, 3 Sep 2019 17:43:25 +0300
Subject: [PATCH 450/943] use consistent naming for buildin expansion functions

---
 src/libsyntax_ext/concat.rs        | 2 +-
 src/libsyntax_ext/concat_idents.rs | 8 ++++----
 src/libsyntax_ext/lib.rs           | 6 +++---
 src/libsyntax_ext/log_syntax.rs    | 2 +-
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs
index 514e95390bca8..fc56dff65e4e2 100644
--- a/src/libsyntax_ext/concat.rs
+++ b/src/libsyntax_ext/concat.rs
@@ -5,7 +5,7 @@ use syntax::tokenstream::TokenStream;
 
 use std::string::String;
 
-pub fn expand_syntax_ext(
+pub fn expand_concat(
     cx: &mut base::ExtCtxt<'_>,
     sp: syntax_pos::Span,
     tts: TokenStream,
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index 73de25b222586..6391b62b58dc9 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -8,10 +8,10 @@ use syntax_pos::Span;
 use syntax_pos::symbol::Symbol;
 use syntax::tokenstream::{TokenTree, TokenStream};
 
-pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
-                              sp: Span,
-                              tts: TokenStream)
-                              -> Box<dyn base::MacResult + 'cx> {
+pub fn expand_concat_idents<'cx>(cx: &'cx mut ExtCtxt<'_>,
+                                 sp: Span,
+                                 tts: TokenStream)
+                                 -> Box<dyn base::MacResult + 'cx> {
     if tts.is_empty() {
         cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
         return DummyResult::any(sp);
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 1a6176916623b..26ef80b2b06df 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -67,8 +67,8 @@ pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, e
         cfg: cfg::expand_cfg,
         column: source_util::expand_column,
         compile_error: compile_error::expand_compile_error,
-        concat_idents: concat_idents::expand_syntax_ext,
-        concat: concat::expand_syntax_ext,
+        concat_idents: concat_idents::expand_concat_idents,
+        concat: concat::expand_concat,
         env: env::expand_env,
         file: source_util::expand_file,
         format_args_nl: format::expand_format_args_nl,
@@ -78,7 +78,7 @@ pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, e
         include_str: source_util::expand_include_str,
         include: source_util::expand_include,
         line: source_util::expand_line,
-        log_syntax: log_syntax::expand_syntax_ext,
+        log_syntax: log_syntax::expand_log_syntax,
         module_path: source_util::expand_mod,
         option_env: env::expand_option_env,
         stringify: source_util::expand_stringify,
diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs
index d09d72a97be15..92130bfaf68e3 100644
--- a/src/libsyntax_ext/log_syntax.rs
+++ b/src/libsyntax_ext/log_syntax.rs
@@ -3,7 +3,7 @@ use syntax::print;
 use syntax::tokenstream::TokenStream;
 use syntax_pos;
 
-pub fn expand_syntax_ext<'cx>(_cx: &'cx mut base::ExtCtxt<'_>,
+pub fn expand_log_syntax<'cx>(_cx: &'cx mut base::ExtCtxt<'_>,
                               sp: syntax_pos::Span,
                               tts: TokenStream)
                               -> Box<dyn base::MacResult + 'cx> {

From 98bd8fd88c3750cfc33b6ae56a0ff1078940bdc6 Mon Sep 17 00:00:00 2001
From: Dario Gonzalez <dario.gonzalez@fortanix.com>
Date: Fri, 26 Apr 2019 13:52:56 -0700
Subject: [PATCH 451/943] Added ability to crosscompile doctests

---
 src/librustdoc/config.rs              | 10 ++++++
 src/librustdoc/html/markdown.rs       | 34 +++++++++++++++++----
 src/librustdoc/html/markdown/tests.rs | 44 ++++++++++++++-------------
 src/librustdoc/lib.rs                 | 12 ++++++++
 src/librustdoc/test.rs                | 42 +++++++++++++++++++++----
 5 files changed, 109 insertions(+), 33 deletions(-)

diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index d261408fc148a..6d1258fe3a390 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -77,6 +77,10 @@ pub struct Options {
     /// Optional path to persist the doctest executables to, defaults to a
     /// temporary directory if not set.
     pub persist_doctests: Option<PathBuf>,
+    /// Runtool to run doctests with
+    pub runtool: Option<String>,
+    /// Arguments to pass to the runtool
+    pub runtool_args: Vec<String>,
 
     // Options that affect the documentation process
 
@@ -140,6 +144,8 @@ impl fmt::Debug for Options {
             .field("show_coverage", &self.show_coverage)
             .field("crate_version", &self.crate_version)
             .field("render_options", &self.render_options)
+            .field("runtool", &self.runtool)
+            .field("runtool_args", &self.runtool_args)
             .finish()
     }
 }
@@ -466,6 +472,8 @@ impl Options {
         let codegen_options_strs = matches.opt_strs("C");
         let lib_strs = matches.opt_strs("L");
         let extern_strs = matches.opt_strs("extern");
+        let runtool = matches.opt_str("runtool");
+        let runtool_args = matches.opt_strs("runtool-arg");
 
         let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
 
@@ -496,6 +504,8 @@ impl Options {
             show_coverage,
             crate_version,
             persist_doctests,
+            runtool,
+            runtool_args,
             render_options: RenderOptions {
                 output,
                 external_html,
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 74413a7f905d4..45f2efd411fae 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -272,7 +272,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
             ))
         });
 
-        let tooltip = if ignore {
+        let tooltip = if ignore != Ignore::None {
             Some(("This example is not tested".to_owned(), "ignore"))
         } else if compile_fail {
             Some(("This example deliberately fails to compile".to_owned(), "compile_fail"))
@@ -286,7 +286,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
             s.push_str(&highlight::render_with_highlighting(
                 &text,
                 Some(&format!("rust-example-rendered{}",
-                                if ignore { " ignore" }
+                                if ignore != Ignore::None { " ignore" }
                                 else if compile_fail { " compile_fail" }
                                 else if explicit_edition { " edition " }
                                 else { "" })),
@@ -297,7 +297,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
             s.push_str(&highlight::render_with_highlighting(
                 &text,
                 Some(&format!("rust-example-rendered{}",
-                                if ignore { " ignore" }
+                                if ignore != Ignore::None { " ignore" }
                                 else if compile_fail { " compile_fail" }
                                 else if explicit_edition { " edition " }
                                 else { "" })),
@@ -607,7 +607,7 @@ pub struct LangString {
     original: String,
     pub should_panic: bool,
     pub no_run: bool,
-    pub ignore: bool,
+    pub ignore: Ignore,
     pub rust: bool,
     pub test_harness: bool,
     pub compile_fail: bool,
@@ -616,13 +616,20 @@ pub struct LangString {
     pub edition: Option<Edition>
 }
 
+#[derive(Eq, PartialEq, Clone, Debug)]
+pub enum Ignore {
+    All,
+    None,
+    Some(Vec<String>),
+}
+
 impl LangString {
     fn all_false() -> LangString {
         LangString {
             original: String::new(),
             should_panic: false,
             no_run: false,
-            ignore: false,
+            ignore: Ignore::None,
             rust: true,  // NB This used to be `notrust = false`
             test_harness: false,
             compile_fail: false,
@@ -637,6 +644,7 @@ impl LangString {
         let mut seen_rust_tags = false;
         let mut seen_other_tags = false;
         let mut data = LangString::all_false();
+        let mut ignores = vec![];
 
         data.original = string.to_owned();
         let tokens = string.split(|c: char|
@@ -651,7 +659,11 @@ impl LangString {
                     seen_rust_tags = seen_other_tags == false;
                 }
                 "no_run" => { data.no_run = true; seen_rust_tags = !seen_other_tags; }
-                "ignore" => { data.ignore = true; seen_rust_tags = !seen_other_tags; }
+                "ignore" => { data.ignore = Ignore::All; seen_rust_tags = !seen_other_tags; }
+                x if x.starts_with("ignore-") => {
+                    ignores.push(x.trim_start_matches("ignore-").to_owned());
+                    seen_rust_tags = !seen_other_tags;
+                }
                 "allow_fail" => { data.allow_fail = true; seen_rust_tags = !seen_other_tags; }
                 "rust" => { data.rust = true; seen_rust_tags = true; }
                 "test_harness" => {
@@ -680,6 +692,16 @@ impl LangString {
             }
         }
 
+        match data.ignore {
+            Ignore::All => {},
+            Ignore::None => {
+                if !ignores.is_empty() {
+                    data.ignore = Ignore::Some(ignores);
+                }
+            },
+            _ => unreachable!(),
+        }
+
         data.rust &= !seen_other_tags || seen_rust_tags;
 
         data
diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs
index a95c29038d46f..5d6811a29a3eb 100644
--- a/src/librustdoc/html/markdown/tests.rs
+++ b/src/librustdoc/html/markdown/tests.rs
@@ -1,4 +1,4 @@
-use super::{ErrorCodes, LangString, Markdown, MarkdownHtml, IdMap};
+use super::{ErrorCodes, LangString, Markdown, MarkdownHtml, IdMap, Ignore};
 use super::plain_summary_line;
 use std::cell::RefCell;
 use syntax::edition::{Edition, DEFAULT_EDITION};
@@ -26,10 +26,10 @@ fn test_unique_id() {
 #[test]
 fn test_lang_string_parse() {
     fn t(s: &str,
-        should_panic: bool, no_run: bool, ignore: bool, rust: bool, test_harness: bool,
+        should_panic: bool, no_run: bool, ignore: Ignore, rust: bool, test_harness: bool,
         compile_fail: bool, allow_fail: bool, error_codes: Vec<String>,
-         edition: Option<Edition>) {
-        assert_eq!(LangString::parse(s, ErrorCodes::Yes), LangString {
+        edition: Option<Edition>) {
+        assert_eq!(LangString::parse(s, ErrorCodes::Yes, true), LangString {
             should_panic,
             no_run,
             ignore,
@@ -42,6 +42,7 @@ fn test_lang_string_parse() {
             edition,
         })
     }
+    let ignore_foo = Ignore::Some(vec!("foo".to_string()));
 
     fn v() -> Vec<String> {
         Vec::new()
@@ -50,23 +51,24 @@ fn test_lang_string_parse() {
     // ignore-tidy-linelength
     // marker                | should_panic | no_run | ignore | rust | test_harness
     //                       | compile_fail | allow_fail | error_codes | edition
-    t("",                      false,         false,   false,   true,  false, false, false, v(), None);
-    t("rust",                  false,         false,   false,   true,  false, false, false, v(), None);
-    t("sh",                    false,         false,   false,   false, false, false, false, v(), None);
-    t("ignore",                false,         false,   true,    true,  false, false, false, v(), None);
-    t("should_panic",          true,          false,   false,   true,  false, false, false, v(), None);
-    t("no_run",                false,         true,    false,   true,  false, false, false, v(), None);
-    t("test_harness",          false,         false,   false,   true,  true,  false, false, v(), None);
-    t("compile_fail",          false,         true,    false,   true,  false, true,  false, v(), None);
-    t("allow_fail",            false,         false,   false,   true,  false, false, true,  v(), None);
-    t("{.no_run .example}",    false,         true,    false,   true,  false, false, false, v(), None);
-    t("{.sh .should_panic}",   true,          false,   false,   false, false, false, false, v(), None);
-    t("{.example .rust}",      false,         false,   false,   true,  false, false, false, v(), None);
-    t("{.test_harness .rust}", false,         false,   false,   true,  true,  false, false, v(), None);
-    t("text, no_run",          false,         true,    false,   false, false, false, false, v(), None);
-    t("text,no_run",           false,         true,    false,   false, false, false, false, v(), None);
-    t("edition2015",           false,         false,   false,   true,  false, false, false, v(), Some(Edition::Edition2015));
-    t("edition2018",           false,         false,   false,   true,  false, false, false, v(), Some(Edition::Edition2018));
+    t("",                      false,         false,   Ignore::None,   true,  false, false, false, v(), None);
+    t("rust",                  false,         false,   Ignore::None,   true,  false, false, false, v(), None);
+    t("sh",                    false,         false,   Ignore::None,   false, false, false, false, v(), None);
+    t("ignore",                false,         false,   Ignore::All,    true,  false, false, false, v(), None);
+    t("ignore-foo",            false,         false,   ignore_foo,     true,  false, false, false, v(), None);
+    t("should_panic",          true,          false,   Ignore::None,   true,  false, false, false, v(), None);
+    t("no_run",                false,         true,    Ignore::None,   true,  false, false, false, v(), None);
+    t("test_harness",          false,         false,   Ignore::None,   true,  true,  false, false, v(), None);
+    t("compile_fail",          false,         true,    Ignore::None,   true,  false, true,  false, v(), None);
+    t("allow_fail",            false,         false,   Ignore::None,   true,  false, false, true,  v(), None);
+    t("{.no_run .example}",    false,         true,    Ignore::None,   true,  false, false, false, v(), None);
+    t("{.sh .should_panic}",   true,          false,   Ignore::None,   false, false, false, false, v(), None);
+    t("{.example .rust}",      false,         false,   Ignore::None,   true,  false, false, false, v(), None);
+    t("{.test_harness .rust}", false,         false,   Ignore::None,   true,  true,  false, false, v(), None);
+    t("text, no_run",          false,         true,    Ignore::None,   false, false, false, false, v(), None);
+    t("text,no_run",           false,         true,    Ignore::None,   false, false, false, false, v(), None);
+    t("edition2015",           false,         false,   Ignore::None,   true,  false, false, false, v(), Some(Edition::Edition2015));
+    t("edition2018",           false,         false,   Ignore::None,   true,  false, false, false, v(), Some(Edition::Edition2018));
 }
 
 #[test]
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index dfa0db0d23b74..c5ac2440f6791 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -355,6 +355,18 @@ fn opts() -> Vec<RustcOptGroup> {
                       "show-coverage",
                       "calculate percentage of public items with documentation")
         }),
+        unstable("runtool", |o| {
+            o.optopt("",
+                     "runtool",
+                     "",
+                     "The tool to run tests with when building for a different target than host")
+        }),
+        unstable("runtool-arg", |o| {
+            o.optmulti("",
+                       "runtool-arg",
+                       "",
+                       "One (of possibly many) arguments to pass to the runtool")
+        }),
     ]
 }
 
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index adcc9930b6c33..2c9e530b9e6b1 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -1,5 +1,6 @@
 use rustc_data_structures::sync::Lrc;
 use rustc_interface::interface;
+use rustc_target::spec::TargetTriple;
 use rustc::hir;
 use rustc::hir::intravisit;
 use rustc::session::{self, config, DiagnosticOutput};
@@ -22,7 +23,7 @@ use testing;
 
 use crate::clean::Attributes;
 use crate::config::Options;
-use crate::html::markdown::{self, ErrorCodes, LangString};
+use crate::html::markdown::{self, ErrorCodes, LangString, Ignore};
 
 #[derive(Clone, Default)]
 pub struct TestOptions {
@@ -44,7 +45,7 @@ pub fn run(options: Options) -> i32 {
         vec![config::CrateType::Dylib]
     };
 
-    let sessopts = config::Options {
+    let mut sessopts = config::Options {
         maybe_sysroot: options.maybe_sysroot.clone(),
         search_paths: options.libs.clone(),
         crate_types,
@@ -59,7 +60,7 @@ pub fn run(options: Options) -> i32 {
         edition: options.edition,
         ..config::Options::default()
     };
-
+    options.target.as_ref().map(|t| { sessopts.target_triple = t.clone() });
     let config = interface::Config {
         opts: sessopts,
         crate_cfg: config::parse_cfgspecs(options.cfgs.clone()),
@@ -181,6 +182,9 @@ fn run_test(
     should_panic: bool,
     no_run: bool,
     as_test_harness: bool,
+    runtool: Option<String>,
+    runtool_args: Vec<String>,
+    target: Option<TargetTriple>,
     compile_fail: bool,
     mut error_codes: Vec<String>,
     opts: &TestOptions,
@@ -315,7 +319,15 @@ fn run_test(
     }
 
     // Run the code!
-    let mut cmd = Command::new(output_file);
+    let mut cmd;
+
+    if let Some(tool) = runtool {
+        cmd = Command::new(tool);
+        cmd.arg(output_file);
+        cmd.args(runtool_args);
+    }else{
+        cmd = Command::new(output_file);
+    }
 
     match cmd.output() {
         Err(e) => return Err(TestFailure::ExecutionError(e)),
@@ -661,12 +673,27 @@ impl Tester for Collector {
         let opts = self.opts.clone();
         let edition = config.edition.unwrap_or(self.options.edition.clone());
         let options = self.options.clone();
+        let maybe_sysroot = self.maybe_sysroot.clone();
+        let linker = self.linker.clone();
+        let edition = config.edition.unwrap_or(self.edition);
+        let persist_doctests = self.persist_doctests.clone();
+        let runtool = self.runtool.clone();
+        let runtool_args = self.runtool_args.clone();
+        let target = self.target.clone();
+        let target_str = target.as_ref().map(|t| t.to_string());
 
         debug!("creating test {}: {}", name, test);
         self.tests.push(testing::TestDescAndFn {
             desc: testing::TestDesc {
-                name: testing::DynTestName(name),
-                ignore: config.ignore,
+                name: testing::DynTestName(name.clone()),
+                ignore: match config.ignore {
+                    Ignore::All => true,
+                    Ignore::None => false,
+                    Ignore::Some(ref ignores) => {
+                        target_str.map_or(false,
+                                          |s| ignores.iter().any(|t| s.contains(t)))
+                    },
+                },
                 // compiler failures are test failures
                 should_panic: testing::ShouldPanic::No,
                 allow_fail: config.allow_fail,
@@ -681,6 +708,9 @@ impl Tester for Collector {
                     config.should_panic,
                     config.no_run,
                     config.test_harness,
+                    runtool,
+                    runtool_args,
+                    target,
                     config.compile_fail,
                     config.error_codes,
                     &opts,

From 3f7640884128c6d2acaa9aee3b582cc372044b6d Mon Sep 17 00:00:00 2001
From: Dario Gonzalez <dario.gonzalez@fortanix.com>
Date: Thu, 6 Jun 2019 16:01:53 -0700
Subject: [PATCH 452/943] added feature gate enable-per-target-ignores updated
 and augmented tests in html/markdown.rs

---
 src/librustdoc/config.rs        |  7 +++++++
 src/librustdoc/html/markdown.rs | 17 +++++++++++------
 src/librustdoc/lib.rs           |  5 +++++
 src/librustdoc/markdown.rs      |  2 +-
 src/librustdoc/passes/mod.rs    |  2 +-
 src/librustdoc/test.rs          |  7 +++++--
 6 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 6d1258fe3a390..d8fe8d6c8a362 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -81,6 +81,10 @@ pub struct Options {
     pub runtool: Option<String>,
     /// Arguments to pass to the runtool
     pub runtool_args: Vec<String>,
+    /// Whether to allow ignoring doctests on a per-target basis
+    /// For example, using ignore-foo to ignore running the doctest on any target that
+    /// contains "foo" as a substring
+    pub enable_per_target_ignores: bool,
 
     // Options that affect the documentation process
 
@@ -146,6 +150,7 @@ impl fmt::Debug for Options {
             .field("render_options", &self.render_options)
             .field("runtool", &self.runtool)
             .field("runtool_args", &self.runtool_args)
+            .field("enable-per-target-ignores", &self.enable_per_target_ignores)
             .finish()
     }
 }
@@ -474,6 +479,7 @@ impl Options {
         let extern_strs = matches.opt_strs("extern");
         let runtool = matches.opt_str("runtool");
         let runtool_args = matches.opt_strs("runtool-arg");
+        let enable_per_target_ignores = matches.opt_present("enable-per-target-ignores");
 
         let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
 
@@ -506,6 +512,7 @@ impl Options {
             persist_doctests,
             runtool,
             runtool_args,
+            enable_per_target_ignores,
             render_options: RenderOptions {
                 output,
                 external_html,
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 45f2efd411fae..cdc6d4eda4006 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -199,7 +199,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
         let ignore;
         let edition;
         if let Some(Event::Start(Tag::CodeBlock(lang))) = event {
-            let parse_result = LangString::parse(&lang, self.check_error_codes);
+            let parse_result = LangString::parse(&lang, self.check_error_codes, false);
             if !parse_result.rust {
                 return Some(Event::Start(Tag::CodeBlock(lang)));
             }
@@ -551,7 +551,8 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
     }
 }
 
-pub fn find_testable_code<T: test::Tester>(doc: &str, tests: &mut T, error_codes: ErrorCodes) {
+pub fn find_testable_code<T: test::Tester>(doc: &str, tests: &mut T, error_codes: ErrorCodes,
+                                           enable_per_target_ignores: bool) {
     let mut parser = Parser::new(doc);
     let mut prev_offset = 0;
     let mut nb_lines = 0;
@@ -564,7 +565,7 @@ pub fn find_testable_code<T: test::Tester>(doc: &str, tests: &mut T, error_codes
                 let block_info = if s.is_empty() {
                     LangString::all_false()
                 } else {
-                    LangString::parse(&*s, error_codes)
+                    LangString::parse(&*s, error_codes, enable_per_target_ignores)
                 };
                 if !block_info.rust {
                     continue;
@@ -639,7 +640,11 @@ impl LangString {
         }
     }
 
-    fn parse(string: &str, allow_error_code_check: ErrorCodes) -> LangString {
+    fn parse(
+        string: &str,
+        allow_error_code_check: ErrorCodes,
+        enable_per_target_ignores: bool
+    ) -> LangString {
         let allow_error_code_check = allow_error_code_check.as_bool();
         let mut seen_rust_tags = false;
         let mut seen_other_tags = false;
@@ -660,7 +665,7 @@ impl LangString {
                 }
                 "no_run" => { data.no_run = true; seen_rust_tags = !seen_other_tags; }
                 "ignore" => { data.ignore = Ignore::All; seen_rust_tags = !seen_other_tags; }
-                x if x.starts_with("ignore-") => {
+                x if enable_per_target_ignores && x.starts_with("ignore-") => {
                     ignores.push(x.trim_start_matches("ignore-").to_owned());
                     seen_rust_tags = !seen_other_tags;
                 }
@@ -941,7 +946,7 @@ crate fn rust_code_blocks(md: &str) -> Vec<RustCodeBlock> {
                 let lang_string = if syntax.is_empty() {
                     LangString::all_false()
                 } else {
-                    LangString::parse(&*syntax, ErrorCodes::Yes)
+                    LangString::parse(&*syntax, ErrorCodes::Yes, false)
                 };
 
                 if lang_string.rust {
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index c5ac2440f6791..8f6067da08335 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -355,6 +355,11 @@ fn opts() -> Vec<RustcOptGroup> {
                       "show-coverage",
                       "calculate percentage of public items with documentation")
         }),
+        unstable("enable-per-target-ignores", |o| {
+            o.optflag("",
+                      "enable-per-target-ignores",
+                      "parse ignore-foo for ignoring doctests on a per-target basis")
+        }),
         unstable("runtool", |o| {
             o.optopt("",
                      "runtool",
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index a30fc05f36acd..67faec6bd3d0c 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -147,7 +147,7 @@ pub fn test(mut options: Options, diag: &errors::Handler) -> i32 {
     collector.set_position(DUMMY_SP);
     let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
 
-    find_testable_code(&input_str, &mut collector, codes);
+    find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores);
 
     options.test_args.insert(0, "rustdoctest".to_string());
     testing::test_main(&options.test_args, collector.tests,
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 641a6df221446..3bb1d0deca78d 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -336,7 +336,7 @@ pub fn look_for_tests<'tcx>(
         found_tests: 0,
     };
 
-    find_testable_code(&dox, &mut tests, ErrorCodes::No);
+    find_testable_code(&dox, &mut tests, ErrorCodes::No, false);
 
     if check_missing_code == true && tests.found_tests == 0 {
         let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span());
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 2c9e530b9e6b1..a30ac1a512893 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -325,7 +325,7 @@ fn run_test(
         cmd = Command::new(tool);
         cmd.arg(output_file);
         cmd.args(runtool_args);
-    }else{
+    } else {
         cmd = Command::new(output_file);
     }
 
@@ -857,7 +857,10 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
         // anything else, this will combine them for us.
         if let Some(doc) = attrs.collapsed_doc_value() {
             self.collector.set_position(attrs.span.unwrap_or(DUMMY_SP));
-            markdown::find_testable_code(&doc, self.collector, self.codes);
+            markdown::find_testable_code(&doc,
+                                         self.collector,
+                                         self.codes,
+                                         self.collector.enable_per_target_ignores);
         }
 
         nested(self);

From 657e24c56b11a45ee1cc019eb0763838f4437475 Mon Sep 17 00:00:00 2001
From: Dario Gonzalez <dario.gonzalez@fortanix.com>
Date: Tue, 11 Jun 2019 11:06:34 -0700
Subject: [PATCH 453/943] changed target from option to plain target, populated
 with host triple at argument parsing time if no --target arguments

---
 src/librustdoc/config.rs | 8 +++++---
 src/librustdoc/core.rs   | 3 +--
 src/librustdoc/test.rs   | 8 +++-----
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index d8fe8d6c8a362..995a340143f78 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -9,7 +9,7 @@ use rustc::session;
 use rustc::session::config::{CrateType, parse_crate_types_from_list};
 use rustc::session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs};
 use rustc::session::config::{nightly_options, build_codegen_options, build_debugging_options,
-                             get_cmd_lint_options, ExternEntry};
+                             get_cmd_lint_options, host_triple, ExternEntry};
 use rustc::session::search_paths::SearchPath;
 use rustc_driver;
 use rustc_target::spec::TargetTriple;
@@ -54,7 +54,7 @@ pub struct Options {
     /// Debugging (`-Z`) options to pass to the compiler.
     pub debugging_options: DebuggingOptions,
     /// The target used to compile the crate against.
-    pub target: Option<TargetTriple>,
+    pub target: TargetTriple,
     /// Edition used when reading the crate. Defaults to "2015". Also used by default when
     /// compiling doctests from the crate.
     pub edition: Edition,
@@ -425,7 +425,9 @@ impl Options {
             }
         }
 
-        let target = matches.opt_str("target").map(|target| {
+        let target = matches.opt_str("target").map_or(
+            TargetTriple::from_triple(host_triple()),
+            |target| {
             if target.ends_with(".json") {
                 TargetTriple::TargetPath(PathBuf::from(target))
             } else {
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 9cfcad4271966..66a32c73e0f16 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -13,7 +13,6 @@ use rustc_interface::interface;
 use rustc_driver::abort_on_err;
 use rustc_resolve as resolve;
 use rustc_metadata::cstore::CStore;
-use rustc_target::spec::TargetTriple;
 
 use syntax::source_map;
 use syntax::attr;
@@ -313,7 +312,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
         lint_cap: Some(lint_cap.unwrap_or_else(|| lint::Forbid)),
         cg: codegen_options,
         externs,
-        target_triple: target.unwrap_or(host_triple),
+        target_triple: target,
         // Ensure that rustdoc works even if rustc is feature-staged
         unstable_features: UnstableFeatures::Allow,
         actually_rustdoc: true,
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index a30ac1a512893..daec977810682 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -60,7 +60,6 @@ pub fn run(options: Options) -> i32 {
         edition: options.edition,
         ..config::Options::default()
     };
-    options.target.as_ref().map(|t| { sessopts.target_triple = t.clone() });
     let config = interface::Config {
         opts: sessopts,
         crate_cfg: config::parse_cfgspecs(options.cfgs.clone()),
@@ -184,7 +183,7 @@ fn run_test(
     as_test_harness: bool,
     runtool: Option<String>,
     runtool_args: Vec<String>,
-    target: Option<TargetTriple>,
+    target: TargetTriple,
     compile_fail: bool,
     mut error_codes: Vec<String>,
     opts: &TestOptions,
@@ -680,7 +679,7 @@ impl Tester for Collector {
         let runtool = self.runtool.clone();
         let runtool_args = self.runtool_args.clone();
         let target = self.target.clone();
-        let target_str = target.as_ref().map(|t| t.to_string());
+        let target_str = target.to_string();
 
         debug!("creating test {}: {}", name, test);
         self.tests.push(testing::TestDescAndFn {
@@ -690,8 +689,7 @@ impl Tester for Collector {
                     Ignore::All => true,
                     Ignore::None => false,
                     Ignore::Some(ref ignores) => {
-                        target_str.map_or(false,
-                                          |s| ignores.iter().any(|t| s.contains(t)))
+                        ignores.iter().any(|s| target_str.contains(s))
                     },
                 },
                 // compiler failures are test failures

From 14110ebd936747eff905ec4e444a02a4a74f6e11 Mon Sep 17 00:00:00 2001
From: Dario Gonzalez <dario.gonzalez@fortanix.com>
Date: Wed, 12 Jun 2019 10:49:41 -0700
Subject: [PATCH 454/943] added rustdoc book documentation, improved behavior
 when unstable flag not present

---
 src/doc/rustdoc/src/unstable-features.md | 50 ++++++++++++++++++++++++
 src/librustdoc/html/markdown.rs          | 14 ++-----
 src/librustdoc/test.rs                   |  2 +
 3 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index 993fc8412836e..49d05b5038df7 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -471,3 +471,53 @@ Some methodology notes about what rustdoc counts in this metric:
 
 Public items that are not documented can be seen with the built-in `missing_docs` lint. Private
 items that are not documented can be seen with Clippy's `missing_docs_in_private_items` lint.
+
+### `--enable-per-target-ignores`: allow `ignore-foo` style filters for doctests
+
+Using this flag looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --enable-per-target-ignores
+```
+
+This flag allows you to tag doctests with compiltest style `ignore-foo` filters that prevent
+rustdoc from running that test if the target triple string contains foo. For example:
+
+```rust
+///```ignore-foo,ignore-bar
+///assert!(2 == 2);
+///```
+struct Foo;
+```
+
+This will not be run when the build target is `super-awesome-foo` or `less-bar-awesome`.
+If the flag is not enabled, then rustdoc will consume the filter, but do nothing with it, and
+the above example will be run for all targets.
+If you want to preserve backwards compatibility for older versions of rustdoc, you can use
+
+```rust
+///```ignore,ignore-foo
+///assert!(2 == 2);
+///```
+struct Foo;
+```
+
+In older versions, this will be ignored on all targets, but on newer versions `ignore-gnu` will
+override `ignore`.
+
+### `--runtool`, `--runtool-arg`: program to run tests with; args to pass to it
+
+Using thses options looks like this:
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --runtool runner --runtool-arg --do-thing --runtool-arg --do-other-thing
+```
+
+These options can be used to run the doctest under a program, and also pass arguments to
+that program. For example, if you want to run your doctests under valgrind you might run
+
+```bash
+$ rustdoc src/lib.rs -Z unstable-options --runtool valgrind
+```
+
+Another use case would be to run a test inside an emulator, or through a Virtual Machine.
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index cdc6d4eda4006..05e6c77256e7b 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -665,7 +665,7 @@ impl LangString {
                 }
                 "no_run" => { data.no_run = true; seen_rust_tags = !seen_other_tags; }
                 "ignore" => { data.ignore = Ignore::All; seen_rust_tags = !seen_other_tags; }
-                x if enable_per_target_ignores && x.starts_with("ignore-") => {
+                x if x.starts_with("ignore-") => if enable_per_target_ignores {
                     ignores.push(x.trim_start_matches("ignore-").to_owned());
                     seen_rust_tags = !seen_other_tags;
                 }
@@ -696,15 +696,9 @@ impl LangString {
                 _ => { seen_other_tags = true }
             }
         }
-
-        match data.ignore {
-            Ignore::All => {},
-            Ignore::None => {
-                if !ignores.is_empty() {
-                    data.ignore = Ignore::Some(ignores);
-                }
-            },
-            _ => unreachable!(),
+        // ignore-foo overrides ignore
+        if !ignores.is_empty() {
+            data.ignore = Ignore::Some(ignores);
         }
 
         data.rust &= !seen_other_tags || seen_rust_tags;
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index daec977810682..840eeda9ad7ca 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -58,8 +58,10 @@ pub fn run(options: Options) -> i32 {
             ..config::basic_debugging_options()
         },
         edition: options.edition,
+        target_triple: options.target.clone(),
         ..config::Options::default()
     };
+
     let config = interface::Config {
         opts: sessopts,
         crate_cfg: config::parse_cfgspecs(options.cfgs.clone()),

From 20b9ea88c7360bfbcf76021db568463deb158bc1 Mon Sep 17 00:00:00 2001
From: Baoshan Pang <baoshan.pang@windriver.com>
Date: Tue, 3 Sep 2019 19:01:14 -0700
Subject: [PATCH 455/943] change RUST_TEST_DYLINK to RUST_VXWORKS_TEST_DYLINK

---
 src/tools/compiletest/src/runtest.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 0bc77c6c502dc..7b68896df7e66 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1727,7 +1727,7 @@ impl<'test> TestCx<'test> {
 
     fn is_vxworks_pure_static(&self) -> bool {
         if self.config.target.contains("vxworks") {
-            match env::var("RUST_TEST_DYLINK") {
+            match env::var("RUST_VXWORKS_TEST_DYLINK") {
                 Ok(s) => s != "1",
                 _ => true
             }
@@ -1738,7 +1738,7 @@ impl<'test> TestCx<'test> {
 
     fn is_vxworks_pure_dynamic(&self) -> bool {
         if self.config.target.contains("vxworks") {
-            match env::var("RUST_TEST_DYLINK") {
+            match env::var("RUST_VXWORKS_TEST_DYLINK") {
                 Ok(s) => s == "1",
                 _ => false
             }

From 0ad111f8bb9bf534c9d2a9ba46d6850907c757e3 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 3 Sep 2019 16:06:42 +1000
Subject: [PATCH 456/943] Remove `LocalInternedString` uses from
 `librustc/ty/`.

This is not a compelling change in isolation, but it is a necessary
step.
---
 src/librustc/ty/mod.rs                          | 6 +-----
 src/librustc_codegen_llvm/callee.rs             | 2 +-
 src/librustc_codegen_llvm/consts.rs             | 2 +-
 src/librustc_codegen_llvm/debuginfo/metadata.rs | 2 +-
 src/librustc_codegen_llvm/debuginfo/mod.rs      | 2 +-
 src/librustc_codegen_ssa/back/symbol_export.rs  | 2 +-
 src/librustc_codegen_ssa/mono_item.rs           | 2 +-
 src/librustc_codegen_utils/symbol_names_test.rs | 2 +-
 src/librustc_mir/monomorphize/partitioning.rs   | 2 +-
 9 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 56505c04f0f0c..2da50f37409ae 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -46,7 +46,7 @@ use std::ops::Range;
 use syntax::ast::{self, Name, Ident, NodeId};
 use syntax::attr;
 use syntax::ext::hygiene::ExpnId;
-use syntax::symbol::{kw, sym, Symbol, LocalInternedString, InternedString};
+use syntax::symbol::{kw, sym, Symbol, InternedString};
 use syntax_pos::Span;
 
 use smallvec;
@@ -3386,10 +3386,6 @@ impl SymbolName {
             name: InternedString::intern(name)
         }
     }
-
-    pub fn as_str(&self) -> LocalInternedString {
-        self.name.as_str()
-    }
 }
 
 impl fmt::Display for SymbolName {
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index 2c0a6f631b739..35d5107842d5b 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -37,7 +37,7 @@ pub fn get_fn(
         return llfn;
     }
 
-    let sym = tcx.symbol_name(instance).as_str();
+    let sym = tcx.symbol_name(instance).name.as_str();
     debug!("get_fn({:?}: {:?}) => {}", instance, sig, sym);
 
     // Create a fn pointer with the substituted signature.
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 0077df3cf5eea..d2362a3da6fa8 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -203,7 +203,7 @@ impl CodegenCx<'ll, 'tcx> {
                  def_id);
 
         let ty = instance.ty(self.tcx);
-        let sym = self.tcx.symbol_name(instance).as_str();
+        let sym = self.tcx.symbol_name(instance).name.as_str();
 
         debug!("get_static: sym={} instance={:?}", sym, instance);
 
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 928532a1f4760..d0b607bd88ee4 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -2251,7 +2251,7 @@ pub fn create_global_var_metadata(
         None
     } else {
         let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
-        Some(SmallCStr::new(&linkage_name.as_str()))
+        Some(SmallCStr::new(&linkage_name.name.as_str()))
     };
 
     let global_align = cx.align_of(variable_type);
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index 548ea0b1036e0..cad2bcdc05fc9 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -290,7 +290,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         let scope_line = span_start(self, span).line;
 
         let function_name = CString::new(name).unwrap();
-        let linkage_name = SmallCStr::new(&linkage_name.as_str());
+        let linkage_name = SmallCStr::new(&linkage_name.name.as_str());
 
         let mut flags = DIFlags::FlagPrototyped;
 
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index 2d9220f897cff..7e700e6819426 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -121,7 +121,7 @@ fn reachable_non_generics_provider(
         })
         .map(|def_id| {
             let export_level = if special_runtime_crate {
-                let name = tcx.symbol_name(Instance::mono(tcx, def_id)).as_str();
+                let name = tcx.symbol_name(Instance::mono(tcx, def_id)).name.as_str();
                 // We can probably do better here by just ensuring that
                 // it has hidden visibility rather than public
                 // visibility, as this is primarily here to ensure it's
diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs
index 4446f1a3a5ce2..5801963c101ef 100644
--- a/src/librustc_codegen_ssa/mono_item.rs
+++ b/src/librustc_codegen_ssa/mono_item.rs
@@ -58,7 +58,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
                self.to_raw_string(),
                cx.codegen_unit().name());
 
-        let symbol_name = self.symbol_name(cx.tcx()).as_str();
+        let symbol_name = self.symbol_name(cx.tcx()).name.as_str();
 
         debug!("symbol {}", &symbol_name);
 
diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs
index f562744dbe753..51269be4e9f40 100644
--- a/src/librustc_codegen_utils/symbol_names_test.rs
+++ b/src/librustc_codegen_utils/symbol_names_test.rs
@@ -40,7 +40,7 @@ impl SymbolNamesTest<'tcx> {
                 let instance = Instance::mono(tcx, def_id);
                 let mangled = self.tcx.symbol_name(instance);
                 tcx.sess.span_err(attr.span, &format!("symbol-name({})", mangled));
-                if let Ok(demangling) = rustc_demangle::try_demangle(&mangled.as_str()) {
+                if let Ok(demangling) = rustc_demangle::try_demangle(&mangled.name.as_str()) {
                     tcx.sess.span_err(attr.span, &format!("demangling({})", demangling));
                     tcx.sess.span_err(attr.span, &format!("demangling-alt({:#})", demangling));
                 }
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index ad9db4e0aa8d8..c193911247e2b 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -777,7 +777,7 @@ where
             debug!("CodegenUnit {}:", cgu.name());
 
             for (mono_item, linkage) in cgu.items() {
-                let symbol_name = mono_item.symbol_name(tcx).as_str();
+                let symbol_name = mono_item.symbol_name(tcx).name.as_str();
                 let symbol_hash_start = symbol_name.rfind('h');
                 let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..])
                                                    .unwrap_or("<no hash>");

From b50db34e4dd1321b4f075eaa6bc88fc8f95e17fc Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 3 Sep 2019 16:11:18 +1000
Subject: [PATCH 457/943] Remove `LocalInternedString` uses from
 `librustc_codegen_llvm/consts.rs`.

---
 src/librustc_codegen_llvm/consts.rs | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index d2362a3da6fa8..24741542d432c 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -11,12 +11,11 @@ use rustc::mir::interpret::{ConstValue, Allocation, read_target_uint,
     Pointer, ErrorHandled, GlobalId};
 use rustc::mir::mono::MonoItem;
 use rustc::hir::Node;
-use syntax_pos::Span;
 use rustc_target::abi::HasDataLayout;
-use syntax::symbol::sym;
-use syntax_pos::symbol::LocalInternedString;
 use rustc::ty::{self, Ty, Instance};
 use rustc_codegen_ssa::traits::*;
+use syntax::symbol::{Symbol, sym};
+use syntax_pos::Span;
 
 use rustc::ty::layout::{self, Size, Align, LayoutOf};
 
@@ -104,10 +103,11 @@ fn check_and_apply_linkage(
     cx: &CodegenCx<'ll, 'tcx>,
     attrs: &CodegenFnAttrs,
     ty: Ty<'tcx>,
-    sym: LocalInternedString,
+    sym: Symbol,
     span: Span
 ) -> &'ll Value {
     let llty = cx.layout_of(ty).llvm_type(cx);
+    let sym = sym.as_str();
     if let Some(linkage) = attrs.linkage {
         debug!("get_static: sym={} linkage={:?}", sym, linkage);
 
@@ -203,7 +203,7 @@ impl CodegenCx<'ll, 'tcx> {
                  def_id);
 
         let ty = instance.ty(self.tcx);
-        let sym = self.tcx.symbol_name(instance).name.as_str();
+        let sym = self.tcx.symbol_name(instance).name.as_symbol();
 
         debug!("get_static: sym={} instance={:?}", sym, instance);
 
@@ -214,11 +214,12 @@ impl CodegenCx<'ll, 'tcx> {
                 Node::Item(&hir::Item {
                     ref attrs, span, node: hir::ItemKind::Static(..), ..
                 }) => {
-                    if self.get_declared_value(&sym[..]).is_some() {
+                    let sym_str = sym.as_str();
+                    if self.get_declared_value(&sym_str).is_some() {
                         span_bug!(span, "Conflicting symbol names for static?");
                     }
 
-                    let g = self.define_global(&sym[..], llty).unwrap();
+                    let g = self.define_global(&sym_str, llty).unwrap();
 
                     if !self.tcx.is_reachable_non_generic(def_id) {
                         unsafe {

From d78b33a807445165307a645309c0283cb8ff182e Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 3 Sep 2019 16:23:21 +1000
Subject: [PATCH 458/943] Remove `LocalInternedString` uses from
 `librustc_codegen_llvm`.

---
 src/librustc_codegen_llvm/builder.rs       |  6 +++---
 src/librustc_codegen_llvm/common.rs        | 13 +++++++------
 src/librustc_codegen_llvm/context.rs       |  4 ++--
 src/librustc_codegen_ssa/mir/block.rs      | 11 +++++------
 src/librustc_codegen_ssa/traits/statics.rs |  6 +++---
 5 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index 894e5c2fd3d93..fc23ef1d47e5b 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -5,7 +5,6 @@ use crate::context::CodegenCx;
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
-use syntax::symbol::LocalInternedString;
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate};
 use rustc_codegen_ssa::MemFlags;
 use libc::{c_uint, c_char};
@@ -24,6 +23,7 @@ use std::ffi::CStr;
 use std::ops::{Deref, Range};
 use std::ptr;
 use std::iter::TrustedLen;
+use syntax::symbol::Symbol;
 
 // All Builders must have an llfn associated with them
 #[must_use]
@@ -1082,8 +1082,8 @@ impl StaticBuilderMethods for Builder<'a, 'll, 'tcx> {
 
     fn static_panic_msg(
         &mut self,
-        msg: Option<LocalInternedString>,
-        filename: LocalInternedString,
+        msg: Option<Symbol>,
+        filename: Symbol,
         line: Self::Value,
         col: Self::Value,
         kind: &str,
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index 19f18088579b3..c337e35460e18 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -17,7 +17,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
 
 use libc::{c_uint, c_char};
 
-use syntax::symbol::LocalInternedString;
+use syntax::symbol::Symbol;
 use syntax::ast::Mutability;
 
 pub use crate::context::CodegenCx;
@@ -122,7 +122,7 @@ impl CodegenCx<'ll, 'tcx> {
 
     fn const_cstr(
         &self,
-        s: LocalInternedString,
+        s: Symbol,
         null_terminated: bool,
     ) -> &'ll Value {
         unsafe {
@@ -130,9 +130,10 @@ impl CodegenCx<'ll, 'tcx> {
                 return llval;
             }
 
+            let s_str = s.as_str();
             let sc = llvm::LLVMConstStringInContext(self.llcx,
-                                                    s.as_ptr() as *const c_char,
-                                                    s.len() as c_uint,
+                                                    s_str.as_ptr() as *const c_char,
+                                                    s_str.len() as c_uint,
                                                     !null_terminated as Bool);
             let sym = self.generate_local_symbol_name("str");
             let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{
@@ -147,8 +148,8 @@ impl CodegenCx<'ll, 'tcx> {
         }
     }
 
-    pub fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value {
-        let len = s.len();
+    pub fn const_str_slice(&self, s: Symbol) -> &'ll Value {
+        let len = s.as_str().len();
         let cs = consts::ptrcast(self.const_cstr(s, false),
             self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)));
         self.const_fat_ptr(cs, self.const_usize(len as u64))
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index a2aaaddf0931c..58ce97039099e 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -29,7 +29,7 @@ use std::cell::{Cell, RefCell};
 use std::iter;
 use std::str;
 use std::sync::Arc;
-use syntax::symbol::LocalInternedString;
+use syntax::symbol::Symbol;
 use syntax::source_map::{DUMMY_SP, Span};
 use crate::abi::Abi;
 
@@ -52,7 +52,7 @@ pub struct CodegenCx<'ll, 'tcx> {
     pub vtables:
         RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>,
     /// Cache of constant strings,
-    pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'ll Value>>,
+    pub const_cstr_cache: RefCell<FxHashMap<Symbol, &'ll Value>>,
 
     /// Reverse-direction for const ptrs cast from globals.
     /// Key is a Value holding a *T,
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index d2a7571fde1e2..134c321456b6c 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -14,7 +14,7 @@ use crate::traits::*;
 
 use std::borrow::Cow;
 
-use syntax::symbol::LocalInternedString;
+use syntax::symbol::Symbol;
 use syntax_pos::Pos;
 
 use super::{FunctionCx, LocalRef};
@@ -397,7 +397,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         // Get the location information.
         let loc = bx.sess().source_map().lookup_char_pos(span.lo());
-        let filename = LocalInternedString::intern(&loc.file.name.to_string());
+        let filename = Symbol::intern(&loc.file.name.to_string());
         let line = bx.const_u32(loc.line as u32);
         let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
 
@@ -418,8 +418,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     vec![file_line_col, index, len])
             }
             _ => {
-                let str = msg.description();
-                let msg_str = LocalInternedString::intern(str);
+                let msg_str = Symbol::intern(msg.description());
                 let msg_file_line_col = bx.static_panic_msg(
                     Some(msg_str),
                     filename,
@@ -531,7 +530,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             let layout = bx.layout_of(ty);
             if layout.abi.is_uninhabited() {
                 let loc = bx.sess().source_map().lookup_char_pos(span.lo());
-                let filename = LocalInternedString::intern(&loc.file.name.to_string());
+                let filename = Symbol::intern(&loc.file.name.to_string());
                 let line = bx.const_u32(loc.line as u32);
                 let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
 
@@ -539,7 +538,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     "Attempted to instantiate uninhabited type {}",
                     ty
                 );
-                let msg_str = LocalInternedString::intern(&str);
+                let msg_str = Symbol::intern(&str);
                 let msg_file_line_col = bx.static_panic_msg(
                     Some(msg_str),
                     filename,
diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs
index 6983311d797dc..73c4c05397917 100644
--- a/src/librustc_codegen_ssa/traits/statics.rs
+++ b/src/librustc_codegen_ssa/traits/statics.rs
@@ -1,5 +1,5 @@
 use super::BackendTypes;
-use syntax_pos::symbol::LocalInternedString;
+use syntax_pos::symbol::Symbol;
 use rustc::hir::def_id::DefId;
 use rustc::ty::layout::Align;
 
@@ -12,8 +12,8 @@ pub trait StaticBuilderMethods: BackendTypes {
     fn get_static(&mut self, def_id: DefId) -> Self::Value;
     fn static_panic_msg(
         &mut self,
-        msg: Option<LocalInternedString>,
-        filename: LocalInternedString,
+        msg: Option<Symbol>,
+        filename: Symbol,
         line: Self::Value,
         col: Self::Value,
         kind: &str,

From bf536dde3b603a0eb4ab9d351010c29799e28676 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 3 Sep 2019 17:10:12 +1000
Subject: [PATCH 459/943] Remove `LocalInternedString` uses from
 `librustc/traits/`.

---
 src/librustc/traits/on_unimplemented.rs | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index 0a42b6b46f2c9..5a988d9509e80 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -9,10 +9,9 @@ use syntax::ast::{MetaItem, NestedMetaItem};
 use syntax::attr;
 use syntax::symbol::{Symbol, kw, sym};
 use syntax_pos::Span;
-use syntax_pos::symbol::LocalInternedString;
 
 #[derive(Clone, Debug)]
-pub struct OnUnimplementedFormatString(LocalInternedString);
+pub struct OnUnimplementedFormatString(Symbol);
 
 #[derive(Debug)]
 pub struct OnUnimplementedDirective {
@@ -89,19 +88,19 @@ impl<'tcx> OnUnimplementedDirective {
             if item.check_name(sym::message) && message.is_none() {
                 if let Some(message_) = item.value_str() {
                     message = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, message_.as_str(), span)?);
+                        tcx, trait_def_id, message_, span)?);
                     continue;
                 }
             } else if item.check_name(sym::label) && label.is_none() {
                 if let Some(label_) = item.value_str() {
                     label = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, label_.as_str(), span)?);
+                        tcx, trait_def_id, label_, span)?);
                     continue;
                 }
             } else if item.check_name(sym::note) && note.is_none() {
                 if let Some(note_) = item.value_str() {
                     note = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, note_.as_str(), span)?);
+                        tcx, trait_def_id, note_, span)?);
                     continue;
                 }
             } else if item.check_name(sym::on) && is_root &&
@@ -154,7 +153,7 @@ impl<'tcx> OnUnimplementedDirective {
                 message: None,
                 subcommands: vec![],
                 label: Some(OnUnimplementedFormatString::try_parse(
-                    tcx, trait_def_id, value.as_str(), attr.span)?),
+                    tcx, trait_def_id, value, attr.span)?),
                 note: None,
             }))
         } else {
@@ -218,7 +217,7 @@ impl<'tcx> OnUnimplementedFormatString {
     fn try_parse(
         tcx: TyCtxt<'tcx>,
         trait_def_id: DefId,
-        from: LocalInternedString,
+        from: Symbol,
         err_sp: Span,
     ) -> Result<Self, ErrorReported> {
         let result = OnUnimplementedFormatString(from);
@@ -234,7 +233,8 @@ impl<'tcx> OnUnimplementedFormatString {
     ) -> Result<(), ErrorReported> {
         let name = tcx.item_name(trait_def_id);
         let generics = tcx.generics_of(trait_def_id);
-        let parser = Parser::new(&self.0, None, vec![], false);
+        let s = self.0.as_str();
+        let parser = Parser::new(&s, None, vec![], false);
         let mut result = Ok(());
         for token in parser {
             match token {
@@ -294,7 +294,8 @@ impl<'tcx> OnUnimplementedFormatString {
         }).collect::<FxHashMap<Symbol, String>>();
         let empty_string = String::new();
 
-        let parser = Parser::new(&self.0, None, vec![], false);
+        let s = self.0.as_str();
+        let parser = Parser::new(&s, None, vec![], false);
         parser.map(|p|
             match p {
                 Piece::String(s) => s,

From 69ae8d9dfd9927d3db9d1d2676ca429c76007405 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Wed, 4 Sep 2019 09:13:56 +1000
Subject: [PATCH 460/943] Remove `LocalInternedString::as_interned_str()`.

It's unused.
---
 src/libsyntax_pos/symbol.rs | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index f44716e013ec8..42db2d21991e4 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -1169,12 +1169,6 @@ impl LocalInternedString {
         }
     }
 
-    pub fn as_interned_str(self) -> InternedString {
-        InternedString {
-            symbol: Symbol::intern(self.string)
-        }
-    }
-
     #[inline]
     pub fn get(&self) -> &str {
         // This returns a valid string since we ensure that `self` outlives the interner

From 224daa64bd3d8f34afaacd73ffc972153fe75eda Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Wed, 4 Sep 2019 09:30:54 +1000
Subject: [PATCH 461/943] Remove `LocalInternedString::get`.

It has a single use, which is easily changed to something better.
---
 src/librustc_mir/borrow_check/error_reporting.rs | 2 +-
 src/libsyntax_pos/symbol.rs                      | 9 ---------
 2 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 251d4b727c754..9f25e98052ec4 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -336,7 +336,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let local = &self.body.local_decls[local_index];
         match local.name {
             Some(name) if !local.from_compiler_desugaring() => {
-                buf.push_str(name.as_str().get());
+                buf.push_str(&name.as_str());
                 Ok(())
             }
             _ => Err(()),
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 42db2d21991e4..6c47ff823b96b 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -1168,15 +1168,6 @@ impl LocalInternedString {
             string: unsafe { std::mem::transmute::<&str, &str>(string) }
         }
     }
-
-    #[inline]
-    pub fn get(&self) -> &str {
-        // This returns a valid string since we ensure that `self` outlives the interner
-        // by creating the interner on a thread which outlives threads which can access it.
-        // This type cannot move to a thread which outlives the interner since it does
-        // not implement Send.
-        self.string
-    }
 }
 
 impl<U: ?Sized> std::convert::AsRef<U> for LocalInternedString

From 6025fc843a216a0bff9f25014dc61018266e0aa1 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Wed, 4 Sep 2019 09:45:57 +1000
Subject: [PATCH 462/943] Remove hashing impls for `LocalInternedString`.

---
 src/librustc/hir/map/collector.rs |  2 +-
 src/librustc/ich/impls_syntax.rs  | 23 +----------------------
 src/libsyntax_pos/symbol.rs       |  2 +-
 3 files changed, 3 insertions(+), 24 deletions(-)

diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index 773bb8dde0690..b8bd1d73fc28b 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -186,7 +186,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
             });
 
         let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| {
-            let name = cstore.crate_name_untracked(cnum).as_str();
+            let name = cstore.crate_name_untracked(cnum).as_interned_str();
             let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
             let hash = cstore.crate_hash_untracked(cnum);
             (name, disambiguator, hash)
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 05e2c7854b49c..ddfca3a4cfb72 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -9,7 +9,7 @@ use std::mem;
 use syntax::ast;
 use syntax::feature_gate;
 use syntax::parse::token;
-use syntax::symbol::{InternedString, LocalInternedString};
+use syntax::symbol::InternedString;
 use syntax::tokenstream;
 use syntax_pos::SourceFile;
 
@@ -39,27 +39,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for InternedString {
     }
 }
 
-impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let s: &str = &**self;
-        s.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
-    type KeyType = LocalInternedString;
-
-    #[inline]
-    fn to_stable_hash_key(&self,
-                          _: &StableHashingContext<'a>)
-                          -> LocalInternedString {
-        self.clone()
-    }
-}
-
 impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
     #[inline]
     fn hash_stable<W: StableHasherResult>(&self,
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 6c47ff823b96b..aeea3c920af57 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -1152,7 +1152,7 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
 // FIXME: ensure that the interner outlives any thread which uses
 // `LocalInternedString`, by creating a new thread right after constructing the
 // interner.
-#[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)]
+#[derive(Clone, Copy, Eq, PartialOrd, Ord)]
 pub struct LocalInternedString {
     string: &'static str,
 }

From a1cd79ff4e407ccaa1e3f7ac794812251600970c Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Wed, 4 Sep 2019 09:48:03 +1000
Subject: [PATCH 463/943] Remove `Encodable`/`Decodable` impls for
 `LocalInternedString`.

---
 src/libsyntax_pos/symbol.rs | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index aeea3c920af57..32ca1fdff9393 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -1231,18 +1231,6 @@ impl fmt::Display for LocalInternedString {
     }
 }
 
-impl Decodable for LocalInternedString {
-    fn decode<D: Decoder>(d: &mut D) -> Result<LocalInternedString, D::Error> {
-        Ok(LocalInternedString::intern(&d.read_str()?))
-    }
-}
-
-impl Encodable for LocalInternedString {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_str(self.string)
-    }
-}
-
 /// An alternative to `Symbol` that is focused on string contents. It has two
 /// main differences to `Symbol`.
 ///

From 7a1bc79cbd6fbf5577e5216b8e2f3c29cbbacb29 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Wed, 4 Sep 2019 09:49:23 +1000
Subject: [PATCH 464/943] Remove `LocalInternedString::intern`.

---
 src/libsyntax_pos/symbol.rs | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 32ca1fdff9393..5c6031327013c 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -1157,19 +1157,6 @@ pub struct LocalInternedString {
     string: &'static str,
 }
 
-impl LocalInternedString {
-    /// Maps a string to its interned representation.
-    pub fn intern(string: &str) -> Self {
-        let string = with_interner(|interner| {
-            let symbol = interner.intern(string);
-            interner.strings[symbol.0.as_usize()]
-        });
-        LocalInternedString {
-            string: unsafe { std::mem::transmute::<&str, &str>(string) }
-        }
-    }
-}
-
 impl<U: ?Sized> std::convert::AsRef<U> for LocalInternedString
 where
     str: std::convert::AsRef<U>

From cc17b1bc3c877c5cf9a2f5de58535477607972f2 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Wed, 4 Sep 2019 09:19:27 +1000
Subject: [PATCH 465/943] Add `Symbol::{with,with2}`.

And remove the `unsafe` blocks, they're not necessary.

Also rewrite `InternedString::{with,with2}` to use the new functions.

Finally, add some comments about the speed of the
`as_str()`/`as_interned_str()` functions.
---
 src/libsyntax_pos/symbol.rs | 42 +++++++++++++++++++++++++------------
 1 file changed, 29 insertions(+), 13 deletions(-)

diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 5c6031327013c..3a4dc1f5a096b 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -818,10 +818,14 @@ impl Ident {
         with_interner(|interner| interner.is_gensymed(self.name))
     }
 
+    /// Convert the name to a `LocalInternedString`. This is a slowish
+    /// operation because it requires locking the symbol interner.
     pub fn as_str(self) -> LocalInternedString {
         self.name.as_str()
     }
 
+    /// Convert the name to an `InternedString`. This is a slowish operation
+    /// because it requires locking the symbol interner.
     pub fn as_interned_str(self) -> InternedString {
         self.name.as_interned_str()
     }
@@ -916,6 +920,25 @@ impl Symbol {
         with_interner(|interner| interner.intern(string))
     }
 
+    /// Access the symbol's chars. This is a slowish operation because it
+    /// requires locking the symbol interner.
+    pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
+        with_interner(|interner| {
+            f(interner.get(self))
+        })
+    }
+
+    /// Access two symbols' chars. This is a slowish operation because it
+    /// requires locking the symbol interner, but it is faster than calling
+    /// `with()` twice.
+    fn with2<F: FnOnce(&str, &str) -> R, R>(self, other: Symbol, f: F) -> R {
+        with_interner(|interner| {
+            f(interner.get(self), interner.get(other))
+        })
+    }
+
+    /// Convert to a `LocalInternedString`. This is a slowish operation because
+    /// it requires locking the symbol interner.
     pub fn as_str(self) -> LocalInternedString {
         with_interner(|interner| unsafe {
             LocalInternedString {
@@ -924,6 +947,8 @@ impl Symbol {
         })
     }
 
+    /// Convert to an `InternedString`. This is a slowish operation because it
+    /// requires locking the symbol interner.
     pub fn as_interned_str(self) -> InternedString {
         with_interner(|interner| InternedString {
             symbol: interner.interned(self)
@@ -1245,28 +1270,19 @@ impl InternedString {
     }
 
     pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
-        let str = with_interner(|interner| {
-            interner.get(self.symbol) as *const str
-        });
-        // This is safe because the interner keeps string alive until it is dropped.
-        // We can access it because we know the interner is still alive since we use a
-        // scoped thread local to access it, and it was alive at the beginning of this scope
-        unsafe { f(&*str) }
+        self.symbol.with(f)
     }
 
     fn with2<F: FnOnce(&str, &str) -> R, R>(self, other: &InternedString, f: F) -> R {
-        let (self_str, other_str) = with_interner(|interner| {
-            (interner.get(self.symbol) as *const str,
-             interner.get(other.symbol) as *const str)
-        });
-        // This is safe for the same reason that `with` is safe.
-        unsafe { f(&*self_str, &*other_str) }
+        self.symbol.with2(other.symbol, f)
     }
 
     pub fn as_symbol(self) -> Symbol {
         self.symbol
     }
 
+    /// Convert to a `LocalInternedString`. This is a slowish operation because it
+    /// requires locking the symbol interner.
     pub fn as_str(self) -> LocalInternedString {
         self.symbol.as_str()
     }

From 2adb246b5c6bfcaae09971c9d54810cb7d58d43e Mon Sep 17 00:00:00 2001
From: Albin Stjerna <albin.stjerna@gmail.com>
Date: Thu, 18 Jul 2019 12:32:06 +0200
Subject: [PATCH 466/943] NLL: New Polonius version

---
 Cargo.lock                  | 4 ++--
 src/librustc/Cargo.toml     | 2 +-
 src/librustc_mir/Cargo.toml | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index e0d30647809a9..6a5d4ebc1ecdb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2324,9 +2324,9 @@ checksum = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
 
 [[package]]
 name = "polonius-engine"
-version = "0.9.0"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6b8a5defa2aef9ba4999aaa745fbc01c622ecea35964a306adc3e44be4f3b5b"
+checksum = "50fa9dbfd0d3d60594da338cfe6f94028433eecae4b11b7e83fd99759227bbfe"
 dependencies = [
  "datafrog",
  "log",
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index 0222a3dde7ab9..a479fabafc014 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -21,7 +21,7 @@ scoped-tls = "1.0"
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
 rustc-rayon = "0.2.0"
 rustc-rayon-core = "0.2.0"
-polonius-engine  = "0.9.0"
+polonius-engine  = "0.10.0"
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_target = { path = "../librustc_target" }
 rustc_macros = { path = "../librustc_macros" }
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index 21008c737289f..1c0b0b63c0bbd 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -15,7 +15,7 @@ either = "1.5.0"
 dot = { path = "../libgraphviz", package = "graphviz" }
 log = "0.4"
 log_settings = "0.1.1"
-polonius-engine  = "0.9.0"
+polonius-engine  = "0.10.0"
 rustc = { path = "../librustc" }
 rustc_target = { path = "../librustc_target" }
 rustc_data_structures = { path = "../librustc_data_structures" }

From 996ba932ccd03f2372c5c25eaf5f5025d397a73c Mon Sep 17 00:00:00 2001
From: Albin Stjerna <albin.stjerna@gmail.com>
Date: Thu, 18 Jul 2019 12:38:32 +0200
Subject: [PATCH 467/943] NLL: Adapt to the new Polonius types

---
 src/librustc_mir/borrow_check/flows.rs           |  4 ++--
 src/librustc_mir/borrow_check/nll/facts.rs       | 16 +++++++++++++---
 src/librustc_mir/borrow_check/nll/mod.rs         |  4 ++--
 .../nll/type_check/liveness/trace.rs             | 14 +++++++-------
 4 files changed, 24 insertions(+), 14 deletions(-)

diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs
index bb217a1f965e2..4400e0c8395a2 100644
--- a/src/librustc_mir/borrow_check/flows.rs
+++ b/src/librustc_mir/borrow_check/flows.rs
@@ -12,7 +12,7 @@ use crate::borrow_check::location::LocationIndex;
 use polonius_engine::Output;
 
 use crate::dataflow::indexes::BorrowIndex;
-use crate::dataflow::move_paths::HasMoveData;
+use crate::dataflow::move_paths::{HasMoveData, MovePathIndex};
 use crate::dataflow::Borrows;
 use crate::dataflow::EverInitializedPlaces;
 use crate::dataflow::MaybeUninitializedPlaces;
@@ -21,7 +21,7 @@ use either::Either;
 use std::fmt;
 use std::rc::Rc;
 
-crate type PoloniusOutput = Output<RegionVid, BorrowIndex, LocationIndex, Local>;
+crate type PoloniusOutput = Output<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>;
 
 // (forced to be `pub` due to its use as an associated type below.)
 crate struct Flows<'b, 'tcx> {
diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs
index 05451cdfb83d8..10ce3a099cf2b 100644
--- a/src/librustc_mir/borrow_check/nll/facts.rs
+++ b/src/librustc_mir/borrow_check/nll/facts.rs
@@ -1,5 +1,5 @@
 use crate::borrow_check::location::{LocationIndex, LocationTable};
-use crate::dataflow::indexes::BorrowIndex;
+use crate::dataflow::indexes::{BorrowIndex, MovePathIndex};
 use polonius_engine::AllFacts as PoloniusAllFacts;
 use polonius_engine::Atom;
 use rustc::mir::Local;
@@ -11,7 +11,7 @@ use std::fs::{self, File};
 use std::io::Write;
 use std::path::Path;
 
-crate type AllFacts = PoloniusAllFacts<RegionVid, BorrowIndex, LocationIndex, Local>;
+crate type AllFacts = PoloniusAllFacts<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>;
 
 crate trait AllFactsExt {
     /// Returns `true` if there is a need to gather `AllFacts` given the
@@ -65,7 +65,11 @@ impl AllFactsExt for AllFacts {
                 var_drop_used,
                 var_uses_region,
                 var_drops_region,
-                var_initialized_on_exit,
+                var_maybe_initialized_on_exit,
+                parent,
+                var_starts_path,
+                initialized_at,
+                moved_out_at,
             ])
         }
         Ok(())
@@ -84,6 +88,12 @@ impl Atom for LocationIndex {
     }
 }
 
+impl Atom for MovePathIndex {
+    fn index(self) -> usize {
+        Idx::index(self)
+    }
+}
+
 struct FactWriter<'w> {
     location_table: &'w LocationTable,
     dir: &'w Path,
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 11ec154e5b5c1..19a3d0eb03d56 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -4,7 +4,7 @@ use crate::borrow_check::nll::facts::AllFactsExt;
 use crate::borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
 use crate::borrow_check::nll::region_infer::values::RegionValueElements;
 use crate::dataflow::indexes::BorrowIndex;
-use crate::dataflow::move_paths::MoveData;
+use crate::dataflow::move_paths::{MoveData, MovePathIndex};
 use crate::dataflow::FlowAtLocation;
 use crate::dataflow::MaybeInitializedPlaces;
 use crate::transform::MirSource;
@@ -87,7 +87,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
     errors_buffer: &mut Vec<Diagnostic>,
 ) -> (
     RegionInferenceContext<'tcx>,
-    Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex, Local>>>,
+    Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>>>,
     Option<ClosureRegionRequirements<'tcx>>,
 ) {
     let mut all_facts = if AllFacts::enabled(infcx.tcx) {
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
index 039ed939ada7c..de085fc480a0e 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
@@ -134,7 +134,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
 
             // FIXME: this is temporary until we can generate our own initialization
             if self.cx.typeck.borrowck_context.all_facts.is_some() {
-                self.add_polonius_var_initialized_on_exit_for(local)
+                self.add_polonius_var_maybe_initialized_on_exit_for(local)
             }
 
             self.compute_use_live_points_for(local);
@@ -161,14 +161,14 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
     //
     // FIXME: this analysis (the initialization tracking) should be
     // done in Polonius, but isn't yet.
-    fn add_polonius_var_initialized_on_exit_for(&mut self, local: Local) {
+    fn add_polonius_var_maybe_initialized_on_exit_for(&mut self, local: Local) {
         let move_path = self.cx.move_data.rev_lookup.find_local(local);
         let facts = self.cx.typeck.borrowck_context.all_facts.as_mut().unwrap();
         for block in self.cx.body.basic_blocks().indices() {
             debug!("polonius: generating initialization facts for {:?} in {:?}", local, block);
 
             // iterate through the block, applying the effects of each statement
-            // up to and including location, and populate `var_initialized_on_exit`
+            // up to and including location, and populate `var_maybe_initialized_on_exit`
             self.cx.flow_inits.reset_to_entry_of(block);
             let start_location = Location { block, statement_index: 0 };
             self.cx.flow_inits.apply_local_effect(start_location);
@@ -181,7 +181,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
                 // statement has not yet taken effect:
                 if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
                     facts
-                        .var_initialized_on_exit
+                        .var_maybe_initialized_on_exit
                         .push((local, self.cx.location_table.start_index(current_location)));
                 }
 
@@ -190,7 +190,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
 
                 if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
                     facts
-                        .var_initialized_on_exit
+                        .var_maybe_initialized_on_exit
                         .push((local, self.cx.location_table.mid_index(current_location)));
                 }
             }
@@ -199,7 +199,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
 
             if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
                 facts
-                    .var_initialized_on_exit
+                    .var_maybe_initialized_on_exit
                     .push((local, self.cx.location_table.start_index(terminator_location)));
             }
 
@@ -208,7 +208,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
 
             if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
                 facts
-                    .var_initialized_on_exit
+                    .var_maybe_initialized_on_exit
                     .push((local, self.cx.location_table.mid_index(terminator_location)));
             }
         }

From 6b09477e91ba7cb6b657b87a51ebd0b127e5ca67 Mon Sep 17 00:00:00 2001
From: Albin Stjerna <albin.stjerna@gmail.com>
Date: Fri, 19 Jul 2019 15:38:54 +0200
Subject: [PATCH 468/943] Polonius: emit initialization/move tracking facts

- var_starts_path
- parent
- initialized_at
- moved_out_at

This also switches to the intended emission of `var_drop_used` fact emission,
where that fact is always emitted on a drop-use of a variable, regardless of its
initialization status, as Polonius now handles that.
---
 src/librustc_mir/borrow_check/nll/mod.rs      | 60 ++++++++++++++++++-
 .../nll/type_check/liveness/polonius.rs       |  9 ++-
 .../nll/type_check/liveness/trace.rs          |  5 --
 src/librustc_mir/dataflow/move_paths/mod.rs   |  9 ++-
 4 files changed, 74 insertions(+), 9 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 19a3d0eb03d56..9b920eb15599d 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -4,14 +4,14 @@ use crate::borrow_check::nll::facts::AllFactsExt;
 use crate::borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
 use crate::borrow_check::nll::region_infer::values::RegionValueElements;
 use crate::dataflow::indexes::BorrowIndex;
-use crate::dataflow::move_paths::{MoveData, MovePathIndex};
+use crate::dataflow::move_paths::{InitLocation, MoveData, MovePathIndex, InitKind};
 use crate::dataflow::FlowAtLocation;
 use crate::dataflow::MaybeInitializedPlaces;
 use crate::transform::MirSource;
 use crate::borrow_check::Upvar;
 use rustc::hir::def_id::DefId;
 use rustc::infer::InferCtxt;
-use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Local, Body, Promoted};
+use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Local, Location, Body, LocalKind, BasicBlock, Promoted};
 use rustc::ty::{self, RegionKind, RegionVid};
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_errors::Diagnostic;
@@ -69,6 +69,61 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
     universal_regions
 }
 
+
+// This function populates an AllFacts instance with base facts related to
+// MovePaths and needed for the move analysis.
+fn populate_polonius_move_facts(all_facts: &mut AllFacts, move_data: &MoveData<'_>, location_table: &LocationTable, body: &Body<'_>) {
+    all_facts.var_starts_path.extend(move_data.rev_lookup.iter_locals_enumerated().map(|(v, &m)| (v, m)));
+
+    for (idx, move_path) in move_data.move_paths.iter_enumerated() {
+        all_facts.parent.extend(move_path.parents(&move_data.move_paths).iter().map(|&parent| (parent, idx)));
+    }
+
+    // initialized_at
+    for init in move_data.inits.iter() {
+
+        match init.location {
+            InitLocation::Statement(location) => {
+                let block_data = &body[location.block];
+                let is_terminator = location.statement_index == block_data.statements.len();
+
+                if is_terminator && init.kind == InitKind::NonPanicPathOnly {
+                    // We are at the terminator of an init that has a panic path,
+                    // and where the init should not happen on panic
+
+                    for &successor in block_data.terminator().successors() {
+                        if body[successor].is_cleanup {
+                            continue;
+                        }
+
+                        // The initialization happened in (or rather, when arriving at)
+                        // the successors, but not in the unwind block.
+                        let first_statement = Location { block: successor, statement_index: 0};
+                        all_facts.initialized_at.push((init.path, location_table.start_index(first_statement)));
+                    }
+
+                } else {
+                    // In all other cases, the initialization just happens at the
+                    // midpoint, like any other effect.
+                    all_facts.initialized_at.push((init.path, location_table.mid_index(location)));
+                }
+            },
+            // Arguments are initialized on function entry
+            InitLocation::Argument(local) => {
+                assert!(body.local_kind(local) == LocalKind::Arg);
+                let fn_entry = Location {block: BasicBlock::from_u32(0u32), statement_index: 0 };
+                all_facts.initialized_at.push((init.path, location_table.start_index(fn_entry)));
+
+            }
+        }
+    }
+
+
+    // moved_out_at
+    // deinitialisation is assumed to always happen!
+    all_facts.moved_out_at.extend(move_data.moves.iter().map(|mo| (mo.path, location_table.mid_index(mo.source))));
+}
+
 /// Computes the (non-lexical) regions from the input MIR.
 ///
 /// This may result in errors being reported.
@@ -123,6 +178,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
         all_facts
             .universal_region
             .extend(universal_regions.universal_regions());
+        populate_polonius_move_facts(all_facts, move_data, location_table, body);
     }
 
     // Create the region inference context, taking ownership of the
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs
index 20d7ec55e3e84..dcdacbbe5be06 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs
@@ -13,6 +13,7 @@ struct LivenessPointFactsExtractor<'me> {
     var_defined: &'me mut VarPointRelations,
     var_used: &'me mut VarPointRelations,
     location_table: &'me LocationTable,
+    var_drop_used: &'me mut VarPointRelations,
 }
 
 // A Visitor to walk through the MIR and extract point-wise facts
@@ -30,6 +31,11 @@ impl LivenessPointFactsExtractor<'_> {
         debug!("LivenessFactsExtractor::insert_use()");
         self.var_used.push((local, self.location_to_index(location)));
     }
+
+    fn insert_drop_use(&mut self, local: Local, location: Location) {
+        debug!("LivenessFactsExtractor::insert_drop_use()");
+        self.var_drop_used.push((local, self.location_to_index(location)));
+    }
 }
 
 impl Visitor<'tcx> for LivenessPointFactsExtractor<'_> {
@@ -37,8 +43,8 @@ impl Visitor<'tcx> for LivenessPointFactsExtractor<'_> {
         match categorize(context) {
             Some(DefUse::Def) => self.insert_def(local, location),
             Some(DefUse::Use) => self.insert_use(local, location),
+            Some(DefUse::Drop) => self.insert_drop_use(local, location),
             _ => (),
-            // NOTE: Drop handling is now done in trace()
         }
     }
 }
@@ -65,6 +71,7 @@ pub(super) fn populate_var_liveness_facts(
         LivenessPointFactsExtractor {
             var_defined: &mut facts.var_defined,
             var_used: &mut facts.var_used,
+            var_drop_used: &mut facts.var_drop_used,
             location_table,
         }
         .visit_body(mir);
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
index de085fc480a0e..1e1768a8e4601 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
@@ -273,11 +273,6 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
             debug_assert_eq!(self.cx.body.terminator_loc(location.block), location,);
 
             if self.cx.initialized_at_terminator(location.block, mpi) {
-                // FIXME: this analysis (the initialization tracking) should be
-                // done in Polonius, but isn't yet.
-                if let Some(facts) = self.cx.typeck.borrowck_context.all_facts {
-                    facts.var_drop_used.push((local, self.cx.location_table.mid_index(location)));
-                }
                 if self.drop_live_at.insert(drop_point) {
                     self.drop_locations.push(location);
                     self.stack.push(drop_point);
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index e5a19572170a7..07b9b662a07aa 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -1,9 +1,10 @@
 use rustc::ty::{Ty, TyCtxt};
 use rustc::mir::*;
 use rustc::util::nodemap::FxHashMap;
-use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use rustc_data_structures::indexed_vec::{Idx, IndexVec, Enumerated};
 use smallvec::SmallVec;
 use syntax_pos::{Span};
+use core::slice::Iter;
 
 use std::fmt;
 use std::ops::{Index, IndexMut};
@@ -262,6 +263,12 @@ impl MovePathLookup {
     pub fn find_local(&self, local: Local) -> MovePathIndex {
         self.locals[local]
     }
+
+    /// An enumerated iterator of `local`s and their associated
+    /// `MovePathIndex`es.
+    pub fn iter_locals_enumerated(&self) -> Enumerated<Local, Iter<'_, MovePathIndex>> {
+        self.locals.iter_enumerated()
+    }
 }
 
 #[derive(Debug)]

From 9f39e001df1f665ce4f2bdbc38576f5fcc02f898 Mon Sep 17 00:00:00 2001
From: Albin Stjerna <albin.stjerna@gmail.com>
Date: Tue, 6 Aug 2019 12:12:36 +0200
Subject: [PATCH 469/943] Polonius: Rename `parent` and `var_starts_path`

---
 src/librustc_mir/borrow_check/nll/facts.rs | 5 ++---
 src/librustc_mir/borrow_check/nll/mod.rs   | 6 +++---
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs
index 10ce3a099cf2b..9458b24f07d90 100644
--- a/src/librustc_mir/borrow_check/nll/facts.rs
+++ b/src/librustc_mir/borrow_check/nll/facts.rs
@@ -65,9 +65,8 @@ impl AllFactsExt for AllFacts {
                 var_drop_used,
                 var_uses_region,
                 var_drops_region,
-                var_maybe_initialized_on_exit,
-                parent,
-                var_starts_path,
+                child,
+                path_belongs_to_var,
                 initialized_at,
                 moved_out_at,
             ])
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 9b920eb15599d..4c76d14bdbbbb 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -73,10 +73,10 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
 // This function populates an AllFacts instance with base facts related to
 // MovePaths and needed for the move analysis.
 fn populate_polonius_move_facts(all_facts: &mut AllFacts, move_data: &MoveData<'_>, location_table: &LocationTable, body: &Body<'_>) {
-    all_facts.var_starts_path.extend(move_data.rev_lookup.iter_locals_enumerated().map(|(v, &m)| (v, m)));
+    all_facts.path_belongs_to_var.extend(move_data.rev_lookup.iter_locals_enumerated().map(|(v, &m)| (m, v)));
 
-    for (idx, move_path) in move_data.move_paths.iter_enumerated() {
-        all_facts.parent.extend(move_path.parents(&move_data.move_paths).iter().map(|&parent| (parent, idx)));
+    for (child, move_path) in move_data.move_paths.iter_enumerated() {
+        all_facts.child.extend(move_path.parents(&move_data.move_paths).iter().map(|&parent| (child, parent)));
     }
 
     // initialized_at

From 6568b086a27c750c9ac69a00f5146a3b51881fb7 Mon Sep 17 00:00:00 2001
From: Albin Stjerna <albin.stjerna@gmail.com>
Date: Fri, 16 Aug 2019 15:39:17 +0200
Subject: [PATCH 470/943] Polonius: don't emit `var_maybe_initialized_on_exit`

---
 .../nll/type_check/liveness/trace.rs          | 63 -------------------
 1 file changed, 63 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
index 1e1768a8e4601..0990074c990d0 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
@@ -131,12 +131,6 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
         for local in live_locals {
             self.reset_local_state();
             self.add_defs_for(local);
-
-            // FIXME: this is temporary until we can generate our own initialization
-            if self.cx.typeck.borrowck_context.all_facts.is_some() {
-                self.add_polonius_var_maybe_initialized_on_exit_for(local)
-            }
-
             self.compute_use_live_points_for(local);
             self.compute_drop_live_points_for(local);
 
@@ -157,63 +151,6 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
         }
     }
 
-    // WARNING: panics if self.cx.typeck.borrowck_context.all_facts != None
-    //
-    // FIXME: this analysis (the initialization tracking) should be
-    // done in Polonius, but isn't yet.
-    fn add_polonius_var_maybe_initialized_on_exit_for(&mut self, local: Local) {
-        let move_path = self.cx.move_data.rev_lookup.find_local(local);
-        let facts = self.cx.typeck.borrowck_context.all_facts.as_mut().unwrap();
-        for block in self.cx.body.basic_blocks().indices() {
-            debug!("polonius: generating initialization facts for {:?} in {:?}", local, block);
-
-            // iterate through the block, applying the effects of each statement
-            // up to and including location, and populate `var_maybe_initialized_on_exit`
-            self.cx.flow_inits.reset_to_entry_of(block);
-            let start_location = Location { block, statement_index: 0 };
-            self.cx.flow_inits.apply_local_effect(start_location);
-
-            for statement_index in 0..self.cx.body[block].statements.len() {
-                let current_location = Location { block, statement_index };
-
-                self.cx.flow_inits.reconstruct_statement_effect(current_location);
-
-                // statement has not yet taken effect:
-                if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
-                    facts
-                        .var_maybe_initialized_on_exit
-                        .push((local, self.cx.location_table.start_index(current_location)));
-                }
-
-                // statement has now taken effect
-                self.cx.flow_inits.apply_local_effect(current_location);
-
-                if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
-                    facts
-                        .var_maybe_initialized_on_exit
-                        .push((local, self.cx.location_table.mid_index(current_location)));
-                }
-            }
-
-            let terminator_location = self.cx.body.terminator_loc(block);
-
-            if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
-                facts
-                    .var_maybe_initialized_on_exit
-                    .push((local, self.cx.location_table.start_index(terminator_location)));
-            }
-
-            // apply the effects of the terminator and push it if needed
-            self.cx.flow_inits.reset_to_exit_of(block);
-
-            if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
-                facts
-                    .var_maybe_initialized_on_exit
-                    .push((local, self.cx.location_table.mid_index(terminator_location)));
-            }
-        }
-    }
-
     /// Clear the value of fields that are "per local variable".
     fn reset_local_state(&mut self) {
         self.defs.clear();

From 9cd1a1157199b8303bc4fb5af3ae0fab6b91e786 Mon Sep 17 00:00:00 2001
From: Albin Stjerna <albin.stjerna@gmail.com>
Date: Fri, 16 Aug 2019 15:42:22 +0200
Subject: [PATCH 471/943] Polonius: don't emit `region_live_at`

---
 src/librustc_mir/borrow_check/nll/facts.rs     |  1 -
 .../nll/type_check/liveness/mod.rs             |  2 +-
 .../nll/type_check/liveness/trace.rs           | 18 ------------------
 3 files changed, 1 insertion(+), 20 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs
index 9458b24f07d90..b11e5e7a85d0e 100644
--- a/src/librustc_mir/borrow_check/nll/facts.rs
+++ b/src/librustc_mir/borrow_check/nll/facts.rs
@@ -58,7 +58,6 @@ impl AllFactsExt for AllFacts {
                 cfg_edge,
                 killed,
                 outlives,
-                region_live_at,
                 invalidates,
                 var_used,
                 var_defined,
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
index 8970009b6ee9f..25d7985653c0e 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
@@ -58,7 +58,7 @@ pub(super) fn generate<'tcx>(
     };
 
     if !live_locals.is_empty() {
-        trace::trace(typeck, body, elements, flow_inits, move_data, live_locals, location_table);
+        trace::trace(typeck, body, elements, flow_inits, move_data, live_locals);
 
         polonius::populate_var_liveness_facts(typeck, body, location_table);
     }
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
index 0990074c990d0..eba52ae3384b0 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
@@ -1,4 +1,3 @@
-use crate::borrow_check::location::LocationTable;
 use crate::borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements};
 use crate::borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap;
 use crate::borrow_check::nll::type_check::liveness::polonius;
@@ -38,7 +37,6 @@ pub(super) fn trace(
     flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
     move_data: &MoveData<'tcx>,
     live_locals: Vec<Local>,
-    location_table: &LocationTable,
 ) {
     debug!("trace()");
 
@@ -52,7 +50,6 @@ pub(super) fn trace(
         local_use_map,
         move_data,
         drop_data: FxHashMap::default(),
-        location_table,
     };
 
     LivenessResults::new(cx).compute_for_all_locals(live_locals);
@@ -82,9 +79,6 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
     /// Index indicating where each variable is assigned, used, or
     /// dropped.
     local_use_map: &'me LocalUseMap,
-
-    /// Maps between a MIR Location and a LocationIndex
-    location_table: &'me LocationTable,
 }
 
 struct DropData<'tcx> {
@@ -405,7 +399,6 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
             &mut self.typeck,
             value,
             live_at,
-            self.location_table,
         )
     }
 
@@ -462,7 +455,6 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
                 &mut self.typeck,
                 kind,
                 live_at,
-                self.location_table,
             );
 
             polonius::add_var_drops_regions(&mut self.typeck, dropped_local, &kind);
@@ -474,7 +466,6 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
         typeck: &mut TypeChecker<'_, 'tcx>,
         value: impl TypeFoldable<'tcx>,
         live_at: &HybridBitSet<PointIndex>,
-        location_table: &LocationTable,
     ) {
         debug!("make_all_regions_live(value={:?})", value);
         debug!(
@@ -491,15 +482,6 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
                 .constraints
                 .liveness_constraints
                 .add_elements(live_region_vid, live_at);
-
-            // FIXME: remove this when we can generate our own region-live-at reliably
-            if let Some(facts) = typeck.borrowck_context.all_facts {
-                for point in live_at.iter() {
-                    let loc = elements.to_location(point);
-                    facts.region_live_at.push((live_region_vid, location_table.start_index(loc)));
-                    facts.region_live_at.push((live_region_vid, location_table.mid_index(loc)));
-                }
-            }
         });
     }
 

From 560ef6d7103f18581b1dcc57de480247ba638677 Mon Sep 17 00:00:00 2001
From: Albin Stjerna <albin.stjerna@gmail.com>
Date: Wed, 7 Aug 2019 17:44:35 +0200
Subject: [PATCH 472/943] Polonius: emit variable access facts

---
 src/librustc_mir/borrow_check/nll/facts.rs    |  1 +
 .../nll/type_check/liveness/mod.rs            |  2 +-
 .../nll/type_check/liveness/polonius.rs       | 58 +++++++++++++++----
 3 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs
index b11e5e7a85d0e..f0beb4d3ae32d 100644
--- a/src/librustc_mir/borrow_check/nll/facts.rs
+++ b/src/librustc_mir/borrow_check/nll/facts.rs
@@ -68,6 +68,7 @@ impl AllFactsExt for AllFacts {
                 path_belongs_to_var,
                 initialized_at,
                 moved_out_at,
+                path_accessed_at,
             ])
         }
         Ok(())
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
index 25d7985653c0e..3f2ec1ba97017 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
@@ -60,7 +60,7 @@ pub(super) fn generate<'tcx>(
     if !live_locals.is_empty() {
         trace::trace(typeck, body, elements, flow_inits, move_data, live_locals);
 
-        polonius::populate_var_liveness_facts(typeck, body, location_table);
+        polonius::populate_access_facts(typeck, body, location_table, move_data);
     }
 }
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs
index dcdacbbe5be06..d61464b3f387d 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs
@@ -1,23 +1,28 @@
 use crate::borrow_check::location::{LocationIndex, LocationTable};
+use crate::dataflow::indexes::MovePathIndex;
+use crate::dataflow::move_paths::{LookupResult, MoveData};
 use crate::util::liveness::{categorize, DefUse};
-use rustc::mir::visit::{PlaceContext, Visitor};
-use rustc::mir::{Body, Local, Location};
+use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
+use rustc::mir::{Body, Local, Location, Place};
 use rustc::ty::subst::Kind;
 use rustc::ty::Ty;
 
 use super::TypeChecker;
 
 type VarPointRelations = Vec<(Local, LocationIndex)>;
+type MovePathPointRelations = Vec<(MovePathIndex, LocationIndex)>;
 
-struct LivenessPointFactsExtractor<'me> {
+struct UseFactsExtractor<'me> {
     var_defined: &'me mut VarPointRelations,
     var_used: &'me mut VarPointRelations,
     location_table: &'me LocationTable,
     var_drop_used: &'me mut VarPointRelations,
+    move_data: &'me MoveData<'me>,
+    path_accessed_at: &'me mut MovePathPointRelations,
 }
 
 // A Visitor to walk through the MIR and extract point-wise facts
-impl LivenessPointFactsExtractor<'_> {
+impl UseFactsExtractor<'_> {
     fn location_to_index(&self, location: Location) -> LocationIndex {
         self.location_table.mid_index(location)
     }
@@ -36,9 +41,21 @@ impl LivenessPointFactsExtractor<'_> {
         debug!("LivenessFactsExtractor::insert_drop_use()");
         self.var_drop_used.push((local, self.location_to_index(location)));
     }
+
+    fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
+        debug!("LivenessFactsExtractor::insert_path_access({:?}, {:?})", path, location);
+        self.path_accessed_at.push((path, self.location_to_index(location)));
+    }
+
+    fn place_to_mpi(&self, place: &Place<'_>) -> Option<MovePathIndex> {
+        match self.move_data.rev_lookup.find(place.as_ref()) {
+            LookupResult::Exact(mpi) => Some(mpi),
+            LookupResult::Parent(mmpi) => mmpi,
+        }
+    }
 }
 
-impl Visitor<'tcx> for LivenessPointFactsExtractor<'_> {
+impl Visitor<'tcx> for UseFactsExtractor<'_> {
     fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
         match categorize(context) {
             Some(DefUse::Def) => self.insert_def(local, location),
@@ -47,6 +64,24 @@ impl Visitor<'tcx> for LivenessPointFactsExtractor<'_> {
             _ => (),
         }
     }
+
+    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
+        self.super_place(place, context, location);
+        match context {
+            PlaceContext::NonMutatingUse(_) => {
+                if let Some(mpi) = self.place_to_mpi(place) {
+                    self.insert_path_access(mpi, location);
+                }
+            }
+
+            PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
+                if let Some(mpi) = self.place_to_mpi(place) {
+                    self.insert_path_access(mpi, location);
+                }
+            }
+            _ => (),
+        }
+    }
 }
 
 fn add_var_uses_regions(typeck: &mut TypeChecker<'_, 'tcx>, local: Local, ty: Ty<'tcx>) {
@@ -60,24 +95,27 @@ fn add_var_uses_regions(typeck: &mut TypeChecker<'_, 'tcx>, local: Local, ty: Ty
     });
 }
 
-pub(super) fn populate_var_liveness_facts(
+pub(super) fn populate_access_facts(
     typeck: &mut TypeChecker<'_, 'tcx>,
-    mir: &Body<'tcx>,
+    body: &Body<'tcx>,
     location_table: &LocationTable,
+    move_data: &MoveData<'_>,
 ) {
     debug!("populate_var_liveness_facts()");
 
     if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
-        LivenessPointFactsExtractor {
+        UseFactsExtractor {
             var_defined: &mut facts.var_defined,
             var_used: &mut facts.var_used,
             var_drop_used: &mut facts.var_drop_used,
+            path_accessed_at: &mut facts.path_accessed_at,
             location_table,
+            move_data,
         }
-        .visit_body(mir);
+        .visit_body(body);
     }
 
-    for (local, local_decl) in mir.local_decls.iter_enumerated() {
+    for (local, local_decl) in body.local_decls.iter_enumerated() {
         add_var_uses_regions(typeck, local, local_decl.ty);
     }
 }

From 28312b5b0604444b5806cfb42ea11a1be14098ac Mon Sep 17 00:00:00 2001
From: Albin Stjerna <albin.stjerna@gmail.com>
Date: Mon, 19 Aug 2019 15:56:16 +0200
Subject: [PATCH 473/943] Rustfmt the files I touched

---
 src/librustc_mir/borrow_check/nll/mod.rs      |  37 +++-
 .../nll/type_check/liveness/local_use_map.rs  |  22 +-
 .../nll/type_check/liveness/trace.rs          |  14 +-
 .../dataflow/move_paths/abs_domain.rs         |  40 ++--
 .../dataflow/move_paths/builder.rs            | 200 +++++++++---------
 src/librustc_mir/dataflow/move_paths/mod.rs   |  42 ++--
 6 files changed, 187 insertions(+), 168 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 4c76d14bdbbbb..1ff3228afa376 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -11,7 +11,8 @@ use crate::transform::MirSource;
 use crate::borrow_check::Upvar;
 use rustc::hir::def_id::DefId;
 use rustc::infer::InferCtxt;
-use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Local, Location, Body, LocalKind, BasicBlock, Promoted};
+use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements,
+                 Local, Location, Body, LocalKind, BasicBlock, Promoted};
 use rustc::ty::{self, RegionKind, RegionVid};
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_errors::Diagnostic;
@@ -72,11 +73,27 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
 
 // This function populates an AllFacts instance with base facts related to
 // MovePaths and needed for the move analysis.
-fn populate_polonius_move_facts(all_facts: &mut AllFacts, move_data: &MoveData<'_>, location_table: &LocationTable, body: &Body<'_>) {
-    all_facts.path_belongs_to_var.extend(move_data.rev_lookup.iter_locals_enumerated().map(|(v, &m)| (m, v)));
+fn populate_polonius_move_facts(
+    all_facts: &mut AllFacts,
+    move_data: &MoveData<'_>,
+    location_table: &LocationTable,
+    body: &Body<'_>) {
+    all_facts
+        .path_belongs_to_var
+        .extend(
+            move_data
+                .rev_lookup
+                .iter_locals_enumerated()
+                .map(|(v, &m)| (m, v)));
 
     for (child, move_path) in move_data.move_paths.iter_enumerated() {
-        all_facts.child.extend(move_path.parents(&move_data.move_paths).iter().map(|&parent| (child, parent)));
+        all_facts
+            .child
+            .extend(
+                move_path
+                    .parents(&move_data.move_paths)
+                    .iter()
+                    .map(|&parent| (child, parent)));
     }
 
     // initialized_at
@@ -99,7 +116,9 @@ fn populate_polonius_move_facts(all_facts: &mut AllFacts, move_data: &MoveData<'
                         // The initialization happened in (or rather, when arriving at)
                         // the successors, but not in the unwind block.
                         let first_statement = Location { block: successor, statement_index: 0};
-                        all_facts.initialized_at.push((init.path, location_table.start_index(first_statement)));
+                        all_facts
+                            .initialized_at
+                            .push((init.path, location_table.start_index(first_statement)));
                     }
 
                 } else {
@@ -121,7 +140,13 @@ fn populate_polonius_move_facts(all_facts: &mut AllFacts, move_data: &MoveData<'
 
     // moved_out_at
     // deinitialisation is assumed to always happen!
-    all_facts.moved_out_at.extend(move_data.moves.iter().map(|mo| (mo.path, location_table.mid_index(mo.source))));
+    all_facts
+        .moved_out_at
+        .extend(
+            move_data
+                .moves
+                .iter()
+                .map(|mo| (mo.path, location_table.mid_index(mo.source))));
 }
 
 /// Computes the (non-lexical) regions from the input MIR.
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
index 2a066538cc234..049d83bb22f1b 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
@@ -1,7 +1,7 @@
 use crate::borrow_check::nll::region_infer::values::{PointIndex, RegionValueElements};
 use crate::util::liveness::{categorize, DefUse};
 use rustc::mir::visit::{PlaceContext, Visitor};
-use rustc::mir::{Local, Location, Body};
+use rustc::mir::{Body, Local, Location};
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use rustc_data_structures::vec_linked_list as vll;
 
@@ -72,16 +72,10 @@ impl LocalUseMap {
 
         let mut locals_with_use_data: IndexVec<Local, bool> =
             IndexVec::from_elem_n(false, body.local_decls.len());
-        live_locals
-            .iter()
-            .for_each(|&local| locals_with_use_data[local] = true);
-
-        LocalUseMapBuild {
-            local_use_map: &mut local_use_map,
-            elements,
-            locals_with_use_data,
-        }
-        .visit_body(body);
+        live_locals.iter().for_each(|&local| locals_with_use_data[local] = true);
+
+        LocalUseMapBuild { local_use_map: &mut local_use_map, elements, locals_with_use_data }
+            .visit_body(body);
 
         local_use_map
     }
@@ -151,10 +145,8 @@ impl LocalUseMapBuild<'_> {
         location: Location,
     ) {
         let point_index = elements.point_from_location(location);
-        let appearance_index = appearances.push(Appearance {
-            point_index,
-            next: *first_appearance,
-        });
+        let appearance_index =
+            appearances.push(Appearance { point_index, next: *first_appearance });
         *first_appearance = Some(appearance_index);
     }
 }
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
index eba52ae3384b0..9b55881cb1b10 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
@@ -394,12 +394,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
     ) {
         debug!("add_use_live_facts_for(value={:?})", value);
 
-        Self::make_all_regions_live(
-            self.elements,
-            &mut self.typeck,
-            value,
-            live_at,
-        )
+        Self::make_all_regions_live(self.elements, &mut self.typeck, value, live_at)
     }
 
     /// Some variable with type `live_ty` is "drop live" at `location`
@@ -450,12 +445,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
         // All things in the `outlives` array may be touched by
         // the destructor and must be live at this point.
         for &kind in &drop_data.dropck_result.kinds {
-            Self::make_all_regions_live(
-                self.elements,
-                &mut self.typeck,
-                kind,
-                live_at,
-            );
+            Self::make_all_regions_live(self.elements, &mut self.typeck, kind, live_at);
 
             polonius::add_var_drops_regions(&mut self.typeck, dropped_local, &kind);
         }
diff --git a/src/librustc_mir/dataflow/move_paths/abs_domain.rs b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
index b26547c4ff77e..d97f3b7417286 100644
--- a/src/librustc_mir/dataflow/move_paths/abs_domain.rs
+++ b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
@@ -11,7 +11,7 @@
 //! `a[x]` would still overlap them both. But that is not this
 //! representation does today.)
 
-use rustc::mir::{Local, PlaceElem, Operand, ProjectionElem};
+use rustc::mir::{Local, Operand, PlaceElem, ProjectionElem};
 use rustc::ty::Ty;
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -26,36 +26,36 @@ pub trait Lift {
 }
 impl<'tcx> Lift for Operand<'tcx> {
     type Abstract = AbstractOperand;
-    fn lift(&self) -> Self::Abstract { AbstractOperand }
+    fn lift(&self) -> Self::Abstract {
+        AbstractOperand
+    }
 }
 impl Lift for Local {
     type Abstract = AbstractOperand;
-    fn lift(&self) -> Self::Abstract { AbstractOperand }
+    fn lift(&self) -> Self::Abstract {
+        AbstractOperand
+    }
 }
 impl<'tcx> Lift for Ty<'tcx> {
     type Abstract = AbstractType;
-    fn lift(&self) -> Self::Abstract { AbstractType }
+    fn lift(&self) -> Self::Abstract {
+        AbstractType
+    }
 }
 impl<'tcx> Lift for PlaceElem<'tcx> {
     type Abstract = AbstractElem;
     fn lift(&self) -> Self::Abstract {
         match *self {
-            ProjectionElem::Deref =>
-                ProjectionElem::Deref,
-            ProjectionElem::Field(ref f, ty) =>
-                ProjectionElem::Field(f.clone(), ty.lift()),
-            ProjectionElem::Index(ref i) =>
-                ProjectionElem::Index(i.lift()),
-            ProjectionElem::Subslice {from, to} =>
-                ProjectionElem::Subslice { from: from, to: to },
-            ProjectionElem::ConstantIndex {offset,min_length,from_end} =>
-                ProjectionElem::ConstantIndex {
-                    offset,
-                    min_length,
-                    from_end,
-                },
-            ProjectionElem::Downcast(a, u) =>
-                ProjectionElem::Downcast(a, u.clone()),
+            ProjectionElem::Deref => ProjectionElem::Deref,
+            ProjectionElem::Field(ref f, ty) => ProjectionElem::Field(f.clone(), ty.lift()),
+            ProjectionElem::Index(ref i) => ProjectionElem::Index(i.lift()),
+            ProjectionElem::Subslice { from, to } => {
+                ProjectionElem::Subslice { from: from, to: to }
+            }
+            ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
+                ProjectionElem::ConstantIndex { offset, min_length, from_end }
+            }
+            ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u.clone()),
         }
     }
 }
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 366b96b53b423..81451c2500c47 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -1,16 +1,18 @@
-use rustc::ty::{self, TyCtxt};
-use rustc::mir::*;
 use rustc::mir::tcx::RvalueInitializationState;
-use rustc_data_structures::indexed_vec::{IndexVec};
-use smallvec::{SmallVec, smallvec};
+use rustc::mir::*;
+use rustc::ty::{self, TyCtxt};
+use rustc_data_structures::indexed_vec::IndexVec;
+use smallvec::{smallvec, SmallVec};
 
 use std::collections::hash_map::Entry;
 use std::mem;
 
 use super::abs_domain::Lift;
-use super::{LocationMap, MoveData, MovePath, MovePathLookup, MovePathIndex, MoveOut, MoveOutIndex};
-use super::{MoveError, InitIndex, Init, InitLocation, LookupResult, InitKind};
 use super::IllegalMoveOriginKind::*;
+use super::{Init, InitIndex, InitKind, InitLocation, LookupResult, MoveError};
+use super::{
+    LocationMap, MoveData, MoveOut, MoveOutIndex, MovePath, MovePathIndex, MovePathLookup,
+};
 
 struct MoveDataBuilder<'a, 'tcx> {
     body: &'a Body<'tcx>,
@@ -33,15 +35,19 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
                 moves: IndexVec::new(),
                 loc_map: LocationMap::new(body),
                 rev_lookup: MovePathLookup {
-                    locals: body.local_decls.indices().map(|i| {
-                        Self::new_move_path(
-                            &mut move_paths,
-                            &mut path_map,
-                            &mut init_path_map,
-                            None,
-                            Place::from(i),
-                        )
-                    }).collect(),
+                    locals: body
+                        .local_decls
+                        .indices()
+                        .map(|i| {
+                            Self::new_move_path(
+                                &mut move_paths,
+                                &mut path_map,
+                                &mut init_path_map,
+                                None,
+                                Place::from(i),
+                            )
+                        })
+                        .collect(),
                     projections: Default::default(),
                 },
                 move_paths,
@@ -49,27 +55,22 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
                 inits: IndexVec::new(),
                 init_loc_map: LocationMap::new(body),
                 init_path_map,
-            }
+            },
         }
     }
 
-    fn new_move_path(move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
-                     path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
-                     init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
-                     parent: Option<MovePathIndex>,
-                     place: Place<'tcx>)
-                     -> MovePathIndex
-    {
-        let move_path = move_paths.push(MovePath {
-            next_sibling: None,
-            first_child: None,
-            parent,
-            place,
-        });
+    fn new_move_path(
+        move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
+        path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
+        init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
+        parent: Option<MovePathIndex>,
+        place: Place<'tcx>,
+    ) -> MovePathIndex {
+        let move_path =
+            move_paths.push(MovePath { next_sibling: None, first_child: None, parent, place });
 
         if let Some(parent) = parent {
-            let next_sibling =
-                mem::replace(&mut move_paths[parent].first_child, Some(move_path));
+            let next_sibling = mem::replace(&mut move_paths[parent].first_child, Some(move_path));
             move_paths[move_path].next_sibling = next_sibling;
         }
 
@@ -91,9 +92,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     /// problematic for borrowck.
     ///
     /// Maybe we should have separate "borrowck" and "moveck" modes.
-    fn move_path_for(&mut self, place: &Place<'tcx>)
-                     -> Result<MovePathIndex, MoveError<'tcx>>
-    {
+    fn move_path_for(&mut self, place: &Place<'tcx>) -> Result<MovePathIndex, MoveError<'tcx>> {
         debug!("lookup({:?})", place);
         place.iterate(|place_base, place_projection| {
             let mut base = match place_base {
@@ -108,39 +107,46 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                 let tcx = self.builder.tcx;
                 let place_ty = Place::ty_from(place_base, &proj.base, body, tcx).ty;
                 match place_ty.sty {
-                    ty::Ref(..) | ty::RawPtr(..) =>
+                    ty::Ref(..) | ty::RawPtr(..) => {
                         return Err(MoveError::cannot_move_out_of(
                             self.loc,
                             BorrowedContent {
                                 target_place: Place {
                                     base: place_base.clone(),
                                     projection: Some(Box::new(proj.clone())),
-                                }
-                            })),
-                    ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() =>
-                        return Err(MoveError::cannot_move_out_of(self.loc,
-                                                                 InteriorOfTypeWithDestructor {
-                            container_ty: place_ty
-                        })),
+                                },
+                            },
+                        ));
+                    }
+                    ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
+                        return Err(MoveError::cannot_move_out_of(
+                            self.loc,
+                            InteriorOfTypeWithDestructor { container_ty: place_ty },
+                        ));
+                    }
                     // move out of union - always move the entire union
-                    ty::Adt(adt, _) if adt.is_union() =>
-                        return Err(MoveError::UnionMove { path: base }),
-                    ty::Slice(_) =>
+                    ty::Adt(adt, _) if adt.is_union() => {
+                        return Err(MoveError::UnionMove { path: base });
+                    }
+                    ty::Slice(_) => {
                         return Err(MoveError::cannot_move_out_of(
                             self.loc,
                             InteriorOfSliceOrArray {
-                                ty: place_ty, is_index: match proj.elem {
+                                ty: place_ty,
+                                is_index: match proj.elem {
                                     ProjectionElem::Index(..) => true,
-                                    _ => false
+                                    _ => false,
                                 },
-                            })),
+                            },
+                        ));
+                    }
                     ty::Array(..) => match proj.elem {
-                        ProjectionElem::Index(..) =>
+                        ProjectionElem::Index(..) => {
                             return Err(MoveError::cannot_move_out_of(
                                 self.loc,
-                                InteriorOfSliceOrArray {
-                                    ty: place_ty, is_index: true
-                                })),
+                                InteriorOfSliceOrArray { ty: place_ty, is_index: true },
+                            ));
+                        }
                         _ => {
                             // FIXME: still badly broken
                         }
@@ -186,7 +192,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
 
 impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
     fn finalize(
-        self
+        self,
     ) -> Result<MoveData<'tcx>, (MoveData<'tcx>, Vec<(Place<'tcx>, MoveError<'tcx>)>)> {
         debug!("{}", {
             debug!("moves for {:?}:", self.body.span);
@@ -200,11 +206,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
             "done dumping moves"
         });
 
-        if !self.errors.is_empty() {
-            Err((self.data, self.errors))
-        } else {
-            Ok(self.data)
-        }
+        if !self.errors.is_empty() { Err((self.data, self.errors)) } else { Ok(self.data) }
     }
 }
 
@@ -222,10 +224,7 @@ pub(super) fn gather_moves<'tcx>(
             builder.gather_statement(source, stmt);
         }
 
-        let terminator_loc = Location {
-            block: bb,
-            statement_index: block.statements.len()
-        };
+        let terminator_loc = Location { block: bb, statement_index: block.statements.len() };
         builder.gather_terminator(terminator_loc, block.terminator());
     }
 
@@ -238,11 +237,12 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
             let path = self.data.rev_lookup.locals[arg];
 
             let init = self.data.inits.push(Init {
-                path, kind: InitKind::Deep, location: InitLocation::Argument(arg),
+                path,
+                kind: InitKind::Deep,
+                location: InitLocation::Argument(arg),
             });
 
-            debug!("gather_args: adding init {:?} of {:?} for argument {:?}",
-                init, path, arg);
+            debug!("gather_args: adding init {:?} of {:?} for argument {:?}", init, path, arg);
 
             self.data.init_path_map[path].push(init);
         }
@@ -297,26 +297,26 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             StatementKind::StorageDead(local) => {
                 self.gather_move(&Place::from(local));
             }
-            StatementKind::SetDiscriminant{ .. } => {
-                span_bug!(stmt.source_info.span,
-                          "SetDiscriminant should not exist during borrowck");
+            StatementKind::SetDiscriminant { .. } => {
+                span_bug!(
+                    stmt.source_info.span,
+                    "SetDiscriminant should not exist during borrowck"
+                );
             }
-            StatementKind::Retag { .. } |
-            StatementKind::AscribeUserType(..) |
-            StatementKind::Nop => {}
+            StatementKind::Retag { .. }
+            | StatementKind::AscribeUserType(..)
+            | StatementKind::Nop => {}
         }
     }
 
     fn gather_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
         match *rvalue {
-            Rvalue::Use(ref operand) |
-            Rvalue::Repeat(ref operand, _) |
-            Rvalue::Cast(_, ref operand, _) |
-            Rvalue::UnaryOp(_, ref operand) => {
-                self.gather_operand(operand)
-            }
-            Rvalue::BinaryOp(ref _binop, ref lhs, ref rhs) |
-            Rvalue::CheckedBinaryOp(ref _binop, ref lhs, ref rhs) => {
+            Rvalue::Use(ref operand)
+            | Rvalue::Repeat(ref operand, _)
+            | Rvalue::Cast(_, ref operand, _)
+            | Rvalue::UnaryOp(_, ref operand) => self.gather_operand(operand),
+            Rvalue::BinaryOp(ref _binop, ref lhs, ref rhs)
+            | Rvalue::CheckedBinaryOp(ref _binop, ref lhs, ref rhs) => {
                 self.gather_operand(lhs);
                 self.gather_operand(rhs);
             }
@@ -325,11 +325,11 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                     self.gather_operand(operand);
                 }
             }
-            Rvalue::Ref(..) |
-            Rvalue::Discriminant(..) |
-            Rvalue::Len(..) |
-            Rvalue::NullaryOp(NullOp::SizeOf, _) |
-            Rvalue::NullaryOp(NullOp::Box, _) => {
+            Rvalue::Ref(..)
+            | Rvalue::Discriminant(..)
+            | Rvalue::Len(..)
+            | Rvalue::NullaryOp(NullOp::SizeOf, _)
+            | Rvalue::NullaryOp(NullOp::Box, _) => {
                 // This returns an rvalue with uninitialized contents. We can't
                 // move out of it here because it is an rvalue - assignments always
                 // completely initialize their place.
@@ -346,13 +346,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
 
     fn gather_terminator(&mut self, term: &Terminator<'tcx>) {
         match term.kind {
-            TerminatorKind::Goto { target: _ } |
-            TerminatorKind::Resume |
-            TerminatorKind::Abort |
-            TerminatorKind::GeneratorDrop |
-            TerminatorKind::FalseEdges { .. } |
-            TerminatorKind::FalseUnwind { .. } |
-            TerminatorKind::Unreachable => { }
+            TerminatorKind::Goto { target: _ }
+            | TerminatorKind::Resume
+            | TerminatorKind::Abort
+            | TerminatorKind::GeneratorDrop
+            | TerminatorKind::FalseEdges { .. }
+            | TerminatorKind::FalseUnwind { .. }
+            | TerminatorKind::Unreachable => {}
 
             TerminatorKind::Return => {
                 self.gather_move(&Place::RETURN_PLACE);
@@ -399,9 +399,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
 
     fn gather_operand(&mut self, operand: &Operand<'tcx>) {
         match *operand {
-            Operand::Constant(..) |
-            Operand::Copy(..) => {} // not-a-move
-            Operand::Move(ref place) => { // a move
+            Operand::Constant(..) | Operand::Copy(..) => {} // not-a-move
+            Operand::Move(ref place) => {
+                // a move
                 self.gather_move(place);
             }
         }
@@ -419,8 +419,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
         };
         let move_out = self.builder.data.moves.push(MoveOut { path: path, source: self.loc });
 
-        debug!("gather_move({:?}, {:?}): adding move {:?} of {:?}",
-               self.loc, place, move_out, path);
+        debug!(
+            "gather_move({:?}, {:?}): adding move {:?} of {:?}",
+            self.loc, place, move_out, path
+        );
 
         self.builder.data.path_map[path].push(move_out);
         self.builder.data.loc_map[self.loc].push(move_out);
@@ -452,8 +454,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                 kind,
             });
 
-            debug!("gather_init({:?}, {:?}): adding init {:?} of {:?}",
-               self.loc, place, init, path);
+            debug!(
+                "gather_init({:?}, {:?}): adding init {:?} of {:?}",
+                self.loc, place, init, path
+            );
 
             self.builder.data.init_path_map[path].push(init);
             self.builder.data.init_loc_map[self.loc].push(init);
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index 07b9b662a07aa..5028e9650918c 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -1,10 +1,10 @@
-use rustc::ty::{Ty, TyCtxt};
+use core::slice::Iter;
 use rustc::mir::*;
+use rustc::ty::{Ty, TyCtxt};
 use rustc::util::nodemap::FxHashMap;
-use rustc_data_structures::indexed_vec::{Idx, IndexVec, Enumerated};
+use rustc_data_structures::indexed_vec::{Enumerated, Idx, IndexVec};
 use smallvec::SmallVec;
-use syntax_pos::{Span};
-use core::slice::Iter;
+use syntax_pos::Span;
 
 use std::fmt;
 use std::ops::{Index, IndexMut};
@@ -138,12 +138,17 @@ impl<T> IndexMut<Location> for LocationMap<T> {
     }
 }
 
-impl<T> LocationMap<T> where T: Default + Clone {
+impl<T> LocationMap<T>
+where
+    T: Default + Clone,
+{
     fn new(body: &Body<'_>) -> Self {
         LocationMap {
-            map: body.basic_blocks().iter().map(|block| {
-                vec![T::default(); block.statements.len()+1]
-            }).collect()
+            map: body
+                .basic_blocks()
+                .iter()
+                .map(|block| vec![T::default(); block.statements.len() + 1])
+                .collect(),
         }
     }
 }
@@ -179,7 +184,6 @@ pub struct Init {
     pub kind: InitKind,
 }
 
-
 /// Initializations can be from an argument or from a statement. Arguments
 /// do not have locations, in those cases the `Local` is kept..
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -225,7 +229,7 @@ pub struct MovePathLookup {
     /// subsequent search so that it is solely relative to that
     /// base-place). For the remaining lookup, we map the projection
     /// elem to the associated MovePathIndex.
-    projections: FxHashMap<(MovePathIndex, AbstractElem), MovePathIndex>
+    projections: FxHashMap<(MovePathIndex, AbstractElem), MovePathIndex>,
 }
 
 mod builder;
@@ -233,7 +237,7 @@ mod builder;
 #[derive(Copy, Clone, Debug)]
 pub enum LookupResult {
     Exact(MovePathIndex),
-    Parent(Option<MovePathIndex>)
+    Parent(Option<MovePathIndex>),
 }
 
 impl MovePathLookup {
@@ -296,7 +300,7 @@ pub(crate) enum IllegalMoveOriginKind<'tcx> {
     InteriorOfTypeWithDestructor { container_ty: Ty<'tcx> },
 
     /// Illegal move due to attempt to move out of a slice or array.
-    InteriorOfSliceOrArray { ty: Ty<'tcx>, is_index: bool, },
+    InteriorOfSliceOrArray { ty: Ty<'tcx>, is_index: bool },
 }
 
 #[derive(Debug)]
@@ -325,11 +329,15 @@ impl<'tcx> MoveData<'tcx> {
     pub fn base_local(&self, mut mpi: MovePathIndex) -> Option<Local> {
         loop {
             let path = &self.move_paths[mpi];
-            if let Place {
-                base: PlaceBase::Local(l),
-                projection: None,
-            } = path.place { return Some(l); }
-            if let Some(parent) = path.parent { mpi = parent; continue } else { return None }
+            if let Place { base: PlaceBase::Local(l), projection: None } = path.place {
+                return Some(l);
+            }
+            if let Some(parent) = path.parent {
+                mpi = parent;
+                continue;
+            } else {
+                return None;
+            }
         }
     }
 }

From 41deb835498391623388555b8d44fa358c804be7 Mon Sep 17 00:00:00 2001
From: Yuki Okushi <huyuumi.dev@gmail.com>
Date: Wed, 4 Sep 2019 18:32:00 +0900
Subject: [PATCH 474/943] Add compile flag

---
 src/test/ui/issues/issue-8460-const.rs     |  2 +
 src/test/ui/issues/issue-8460-const.stderr | 82 +++++++++++-----------
 2 files changed, 43 insertions(+), 41 deletions(-)

diff --git a/src/test/ui/issues/issue-8460-const.rs b/src/test/ui/issues/issue-8460-const.rs
index 611d280f774c0..4637814b277a4 100644
--- a/src/test/ui/issues/issue-8460-const.rs
+++ b/src/test/ui/issues/issue-8460-const.rs
@@ -1,3 +1,5 @@
+// compile-flags: -O
+
 #![deny(const_err)]
 
 use std::{isize, i8, i16, i32, i64};
diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr
index 31b1da4f804ab..7e5a22e651ee5 100644
--- a/src/test/ui/issues/issue-8460-const.stderr
+++ b/src/test/ui/issues/issue-8460-const.stderr
@@ -1,245 +1,245 @@
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:7:36
+  --> $DIR/issue-8460-const.rs:9:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/issue-8460-const.rs:1:9
+  --> $DIR/issue-8460-const.rs:3:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:7:36
+  --> $DIR/issue-8460-const.rs:9:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^ attempt to divide with overflow
 
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:10:36
+  --> $DIR/issue-8460-const.rs:12:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:10:36
+  --> $DIR/issue-8460-const.rs:12:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^ attempt to divide with overflow
 
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:13:36
+  --> $DIR/issue-8460-const.rs:15:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:13:36
+  --> $DIR/issue-8460-const.rs:15:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
 
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:16:36
+  --> $DIR/issue-8460-const.rs:18:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:16:36
+  --> $DIR/issue-8460-const.rs:18:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
 
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:19:36
+  --> $DIR/issue-8460-const.rs:21:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:19:36
+  --> $DIR/issue-8460-const.rs:21:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:22:36
+  --> $DIR/issue-8460-const.rs:24:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:22:36
+  --> $DIR/issue-8460-const.rs:24:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:25:36
+  --> $DIR/issue-8460-const.rs:27:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:25:36
+  --> $DIR/issue-8460-const.rs:27:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:28:36
+  --> $DIR/issue-8460-const.rs:30:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:28:36
+  --> $DIR/issue-8460-const.rs:30:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:31:36
+  --> $DIR/issue-8460-const.rs:33:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:31:36
+  --> $DIR/issue-8460-const.rs:33:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:34:36
+  --> $DIR/issue-8460-const.rs:36:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:34:36
+  --> $DIR/issue-8460-const.rs:36:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:37:36
+  --> $DIR/issue-8460-const.rs:39:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:37:36
+  --> $DIR/issue-8460-const.rs:39:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:40:36
+  --> $DIR/issue-8460-const.rs:42:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:40:36
+  --> $DIR/issue-8460-const.rs:42:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^ attempt to calculate the remainder with overflow
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:43:36
+  --> $DIR/issue-8460-const.rs:45:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:43:36
+  --> $DIR/issue-8460-const.rs:45:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:46:36
+  --> $DIR/issue-8460-const.rs:48:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:46:36
+  --> $DIR/issue-8460-const.rs:48:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:49:36
+  --> $DIR/issue-8460-const.rs:51:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:49:36
+  --> $DIR/issue-8460-const.rs:51:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:52:36
+  --> $DIR/issue-8460-const.rs:54:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:52:36
+  --> $DIR/issue-8460-const.rs:54:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:55:36
+  --> $DIR/issue-8460-const.rs:57:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:55:36
+  --> $DIR/issue-8460-const.rs:57:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:58:36
+  --> $DIR/issue-8460-const.rs:60:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:58:36
+  --> $DIR/issue-8460-const.rs:60:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:61:36
+  --> $DIR/issue-8460-const.rs:63:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:61:36
+  --> $DIR/issue-8460-const.rs:63:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:64:36
+  --> $DIR/issue-8460-const.rs:66:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:64:36
+  --> $DIR/issue-8460-const.rs:66:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero

From a0c186c34f67c7eb3b392755091dd3a17f5acbdf Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Sun, 21 Jul 2019 14:50:39 +0300
Subject: [PATCH 475/943] remove XID and Pattern_White_Space unicode tables
 from libcore

They are only used by rustc_lexer, and are not needed elsewhere.

So we move the relevant definitions into rustc_lexer (while the actual
unicode data comes from the unicode-xid crate) and make the rest of
the compiler use it.
---
 Cargo.lock                                    |  17 +-
 src/libcore/char/methods.rs                   |  23 --
 src/libcore/unicode/mod.rs                    |   5 -
 src/libcore/unicode/tables.rs                 | 375 ------------------
 src/libcore/unicode/unicode.py                |   9 +-
 src/libfmt_macros/Cargo.toml                  |   2 +-
 src/libfmt_macros/lib.rs                      |  10 +-
 src/librustc_lexer/Cargo.toml                 |   8 +-
 src/librustc_lexer/src/lib.rs                 |  63 ++-
 src/librustc_mir/Cargo.toml                   |   1 +
 src/librustc_mir/borrow_check/move_errors.rs  |   5 +-
 .../borrow_check/mutability_errors.rs         |   4 +-
 src/librustdoc/lib.rs                         |   1 +
 src/librustdoc/test.rs                        |   5 +-
 src/libsyntax/ext/proc_macro_server.rs        |   4 +-
 src/libsyntax_ext/Cargo.toml                  |   1 +
 16 files changed, 69 insertions(+), 464 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index e0d30647809a9..1b916576bc99c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1011,6 +1011,7 @@ dependencies = [
 name = "fmt_macros"
 version = "0.0.0"
 dependencies = [
+ "rustc_lexer",
  "syntax_pos",
 ]
 
@@ -2372,7 +2373,7 @@ version = "0.4.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
 dependencies = [
- "unicode-xid",
+ "unicode-xid 0.1.0",
 ]
 
 [[package]]
@@ -3290,7 +3291,7 @@ dependencies = [
 name = "rustc_lexer"
 version = "0.1.0"
 dependencies = [
- "unicode-xid",
+ "unicode-xid 0.2.0",
 ]
 
 [[package]]
@@ -3368,6 +3369,7 @@ dependencies = [
  "rustc_apfloat",
  "rustc_data_structures",
  "rustc_errors",
+ "rustc_lexer",
  "rustc_target",
  "serialize",
  "smallvec",
@@ -3976,7 +3978,7 @@ checksum = "641e117d55514d6d918490e47102f7e08d096fdde360247e4a10f7a91a8478d3"
 dependencies = [
  "proc-macro2",
  "quote",
- "unicode-xid",
+ "unicode-xid 0.1.0",
 ]
 
 [[package]]
@@ -3988,7 +3990,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "syn",
- "unicode-xid",
+ "unicode-xid 0.1.0",
 ]
 
 [[package]]
@@ -4017,6 +4019,7 @@ dependencies = [
  "log",
  "rustc_data_structures",
  "rustc_errors",
+ "rustc_lexer",
  "rustc_target",
  "smallvec",
  "syntax",
@@ -4532,6 +4535,12 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
 
+[[package]]
+name = "unicode-xid"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
+
 [[package]]
 name = "unicode_categories"
 version = "0.1.1"
diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs
index e91bf53c5b418..a69eb0f6d4b20 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -547,29 +547,6 @@ impl char {
         }
     }
 
-    /// Returns `true` if this `char` satisfies the `XID_Start` Unicode property, and false
-    /// otherwise.
-    ///
-    /// `XID_Start` is a Unicode Derived Property specified in
-    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-    /// mostly similar to `ID_Start` but modified for closure under `NFKx`.
-    #[unstable(feature = "unicode_internals", issue = "0")]
-    pub fn is_xid_start(self) -> bool {
-        derived_property::XID_Start(self)
-    }
-
-    /// Returns `true` if this `char` satisfies the `XID_Continue` Unicode property, and false
-    /// otherwise.
-    ///
-    /// `XID_Continue` is a Unicode Derived Property specified in
-    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-    /// mostly similar to `ID_Continue` but modified for closure under NFKx.
-    #[unstable(feature = "unicode_internals", issue = "0")]
-    #[inline]
-    pub fn is_xid_continue(self) -> bool {
-        derived_property::XID_Continue(self)
-    }
-
     /// Returns `true` if this `char` is lowercase.
     ///
     /// 'Lowercase' is defined according to the terms of the Unicode Derived Core
diff --git a/src/libcore/unicode/mod.rs b/src/libcore/unicode/mod.rs
index 272727def61d6..a3ec9fd51f064 100644
--- a/src/libcore/unicode/mod.rs
+++ b/src/libcore/unicode/mod.rs
@@ -13,8 +13,3 @@ pub mod derived_property {
 pub mod conversions {
     pub use crate::unicode::tables::conversions::{to_lower, to_upper};
 }
-
-// For use in libsyntax
-pub mod property {
-    pub use crate::unicode::tables::property::Pattern_White_Space;
-}
diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs
index 3fae3a46ada6b..5b5be48543121 100644
--- a/src/libcore/unicode/tables.rs
+++ b/src/libcore/unicode/tables.rs
@@ -890,384 +890,9 @@ pub(crate) mod derived_property {
         Uppercase_table.lookup(c)
     }
 
-    const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
-        r1: [
-            0x03ff000000000000, 0x07fffffe87fffffe, 0x04a0040000000000, 0xff7fffffff7fffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3,
-            0xffffffffffffffff, 0xb8dfffffffffffff, 0xfffffffbffffd7c0, 0xffbfffffffffffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffcfb, 0xffffffffffffffff,
-            0xfffeffffffffffff, 0xffffffff027fffff, 0xbffffffffffe01ff, 0x000787ffffff00b6,
-            0xffffffff07ff0000, 0xffffc3ffffffffff, 0xffffffffffffffff, 0x9ffffdff9fefffff,
-            0xffffffffffff0000, 0xffffffffffffe7ff, 0x0003ffffffffffff, 0x243fffffffffffff
-        ],
-        r2: [
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
-            24, 25, 26, 27, 28, 29, 30, 31, 4, 32, 33, 34, 4, 4, 4, 4, 4, 35, 36, 37, 38, 39, 40,
-            41, 42, 4, 4, 4, 4, 4, 4, 4, 4, 43, 44, 45, 46, 47, 4, 48, 49, 50, 51, 52, 53, 54, 55,
-            56, 57, 58, 59, 60, 4, 61, 4, 62, 63, 64, 65, 66, 4, 4, 4, 67, 4, 4, 4, 4, 68, 69, 70,
-            71, 72, 73, 74, 75, 76, 77, 78, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 79, 80, 4, 81, 82, 83, 84, 85, 60, 60, 60, 60, 60, 60, 60, 60, 86,
-            42, 87, 88, 89, 4, 90, 91, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 52, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 92, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 93, 94, 4, 4, 4, 4, 95, 96, 4, 97, 98, 4, 99, 100, 101, 62, 4, 102, 103,
-            104, 4, 105, 106, 107, 4, 108, 109, 110, 4, 111, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 112, 113, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 103, 4, 114,
-            115, 116, 97, 117, 4, 118, 4, 4, 119, 120, 121, 122, 123, 124, 4, 125, 126, 127, 128,
-            129
-        ],
-        r3: &[
-            0x00003fffffffffff, 0x000007ff0fffffff, 0x3fdfffff00000000, 0xfffffffbfff80000,
-            0xffffffffffffffff, 0xfffeffcfffffffff, 0xf3c5fdfffff99fef, 0x5003ffcfb080799f,
-            0xd36dfdfffff987ee, 0x003fffc05e023987, 0xf3edfdfffffbbfee, 0xfe00ffcf00013bbf,
-            0xf3edfdfffff99fee, 0x0002ffcfb0c0399f, 0xc3ffc718d63dc7ec, 0x0000ffc000813dc7,
-            0xe3fffdfffffddfff, 0x0000ffcf07603ddf, 0xf3effdfffffddfef, 0x0006ffcf40603ddf,
-            0xfffffffffffddfef, 0xfc00ffcf80f07ddf, 0x2ffbfffffc7fffec, 0x000cffc0ff5f847f,
-            0x07fffffffffffffe, 0x0000000003ff7fff, 0x3fffffaffffff7d6, 0x00000000f3ff3f5f,
-            0xc2a003ff03000001, 0xfffe1ffffffffeff, 0x1ffffffffeffffdf, 0x0000000000000040,
-            0xffffffffffff03ff, 0xffffffff3fffffff, 0xf7ffffffffff20bf, 0xffffffff3d7f3dff,
-            0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0003fe00e7ffffff,
-            0xffffffff0000ffff, 0x3f3fffffffffffff, 0xfffffffffffffffe, 0xffff9fffffffffff,
-            0xffffffff07fffffe, 0x01ffc7ffffffffff, 0x001fffff001fdfff, 0x000ddfff000fffff,
-            0x000003ff308fffff, 0xffffffff03ff3800, 0x01ffffffffffffff, 0xffff07ffffffffff,
-            0x003fffffffffffff, 0x0fff0fff7fffffff, 0x001f3fffffffffc0, 0xffff0fffffffffff,
-            0x0000000007ff03ff, 0xffffffff0fffffff, 0x9fffffff7fffffff, 0x3fff008003ff03ff,
-            0x0000000000000000, 0x000ff80003ff0fff, 0x000fffffffffffff, 0x00ffffffffffffff,
-            0x3fffffffffffe3ff, 0xe7ffffffffff01ff, 0x07fffffffff70000, 0xfbffffffffffffff,
-            0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc,
-            0x8000000000000000, 0x8002000000100001, 0x000000001fff0000, 0x0001ffe21fff0000,
-            0xf3fffd503f2ffc84, 0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff,
-            0xffffffff7fffffff, 0x000ff81fffffffff, 0xffff20bfffffffff, 0x800080ffffffffff,
-            0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x1f3efffe000000e0, 0xfffffffee67fffff,
-            0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000,
-            0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, 0x00000fffffff1fff,
-            0xbff0ffffffffffff, 0x0003ffffffffffff, 0xfffffffcff800000, 0xfffffffffffff9ff,
-            0xff8000000000007c, 0x000000ffffffffff, 0xe8ffffff03ff003f, 0xffff3fffffffffff,
-            0x1fffffff000fffff, 0x7fffffff03ff8001, 0x007fffffffffffff, 0xfc7fffff03ff3fff,
-            0x007cffff38000007, 0xffff7f7f007e7e7e, 0xffff00fff7ffffff, 0x03ff37ffffffffff,
-            0xffff000fffffffff, 0x0ffffffffffff87f, 0x0000000003ffffff, 0x5f7ffdffe0f8007f,
-            0xffffffffffffffdb, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff,
-            0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0x0018ffff0000ffff,
-            0xaa8a00000000e000, 0x1fffffffffffffff, 0x87fffffe03ff0000, 0xffffffc007fffffe,
-            0x7fffffffffffffff, 0x000000001cfcfcfc
-        ],
-        r4: [
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 13,
-            14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-        ],
-        r5: &[
-            0, 1, 2, 3, 4, 5, 4, 6, 4, 4, 7, 8, 9, 10, 11, 12, 2, 2, 13, 14, 15, 16, 4, 4, 2, 2, 2,
-            2, 17, 18, 4, 4, 19, 20, 21, 22, 23, 4, 24, 4, 25, 26, 27, 28, 29, 30, 31, 4, 2, 32, 33,
-            33, 34, 4, 4, 4, 4, 4, 4, 4, 35, 36, 4, 37, 2, 38, 3, 39, 40, 41, 2, 42, 43, 4, 44, 45,
-            46, 47, 4, 4, 2, 48, 2, 49, 4, 4, 50, 51, 2, 52, 53, 54, 55, 4, 4, 4, 3, 4, 56, 57, 4,
-            4, 58, 59, 60, 61, 62, 53, 4, 4, 4, 4, 63, 64, 65, 4, 66, 67, 68, 4, 4, 4, 4, 37, 4, 4,
-            4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 2, 70, 2, 2, 2, 71, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 72, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 2, 2, 2, 2, 2, 2, 2, 2, 53, 73, 4, 74, 17, 75, 76, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
-            4, 4, 2, 77, 78, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 80, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 81, 2, 2, 2, 2,
-            2, 82, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 83, 84, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 85, 86, 4, 4, 87, 4, 4, 4, 4, 4, 4, 2, 88, 89, 90, 91, 92, 2, 2, 2, 2, 93, 94, 95,
-            96, 97, 98, 4, 4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 102, 4, 4, 4, 103, 104, 4, 4, 4, 4, 4, 105, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 106, 2, 107, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 109, 110, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 111, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 112, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 113, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 114, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 115, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
-        ],
-        r6: &[
-            0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
-            0x0000000000000000, 0x001fffffffffffff, 0x2000000000000000, 0xffffffff1fffffff,
-            0x000000010001ffff, 0xffffe000ffffffff, 0x07ffffffffff07ff, 0xffffffff3fffffff,
-            0x00000000003eff0f, 0xffff03ff3fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff,
-            0x0000000fffffffff, 0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f,
-            0x007fffff003fffff, 0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff,
-            0xc0ffffffffffffff, 0x873ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff,
-            0x0000007ffffffeff, 0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff,
-            0x00000000000001ff, 0x0007ffffffffffff, 0x03ff00ffffffffff, 0xffff00801fffffff,
-            0x000000000001ffff, 0x007fffff00000000, 0x8000ffc00000007f, 0x03ff01ffffff0000,
-            0xffdfffffffffffff, 0x004fffffffff0070, 0x0000000017ff1e1f, 0x40fffffffffbffff,
-            0xffff01ffbfffbd7f, 0x03ff07ffffffffff, 0xfbedfdfffff99fef, 0x001f1fcfe081399f,
-            0x00000000c3ff07ff, 0x0000000003ff00bf, 0xff3fffffffffffff, 0x000000003f000001,
-            0x0000000003ff0011, 0x01ffffffffffffff, 0x00000000000003ff, 0x03ff0fffe7ffffff,
-            0xffffffff00000000, 0x800003ffffffffff, 0xfffffcff00000000, 0x0000001bfcffffff,
-            0x7fffffffffffffff, 0xffffffffffff0080, 0x0000000023ffffff, 0xff7ffffffffffdff,
-            0xfffc000003ff0001, 0x007ffefffffcffff, 0xb47ffffffffffb7f, 0xfffffdbf03ff00ff,
-            0x000003ff01fb7fff, 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f,
-            0x000000000000007f, 0x000003ff7fffffff, 0x001f3fffffff0000, 0xe0fffff803ff000f,
-            0x000000000000ffff, 0xffffffffffff87ff, 0x00000000ffff80ff, 0x0000000b00000000,
-            0x00ffffffffffffff, 0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff,
-            0x0000000063ff01ff, 0xf807e3e000000000, 0x00003c0000000fe7, 0x000000000000001c,
-            0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
-            0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
-            0xffff7fffffff7fff, 0xfffffdfffffffdff, 0xffffffffffffcff7, 0xf87fffffffffffff,
-            0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, 0x3fff1fffffffffff,
-            0x00000000000043ff, 0x03ffffffffffffff, 0x00000000007f001f, 0x0000000003ff0fff,
-            0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff,
-            0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff, 0x0000ffffffffffff
-        ],
-    };
-
-    pub fn XID_Continue(c: char) -> bool {
-        XID_Continue_table.lookup(c)
-    }
-
-    const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
-        r1: [
-            0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3,
-            0x0000000000000000, 0xb8df000000000000, 0xfffffffbffffd740, 0xffbfffffffffffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff,
-            0xfffeffffffffffff, 0xffffffff027fffff, 0x00000000000001ff, 0x000787ffffff0000,
-            0xffffffff00000000, 0xfffec000000007ff, 0xffffffffffffffff, 0x9c00c060002fffff,
-            0x0000fffffffd0000, 0xffffffffffffe000, 0x0002003fffffffff, 0x043007fffffffc00
-        ],
-        r2: [
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
-            24, 23, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 34, 34, 34, 34, 35, 36, 37, 38, 39,
-            40, 41, 42, 34, 34, 34, 34, 34, 34, 34, 34, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
-            54, 55, 56, 57, 58, 59, 60, 3, 61, 62, 63, 64, 65, 66, 67, 68, 34, 34, 34, 3, 34, 34,
-            34, 34, 69, 70, 71, 72, 3, 73, 74, 3, 75, 76, 77, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 78,
-            79, 34, 80, 81, 82, 83, 84, 3, 3, 3, 3, 3, 3, 3, 3, 85, 42, 86, 87, 88, 34, 89, 90, 3,
-            3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 53, 3, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 91, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 92, 93, 34, 34, 34, 34, 94,
-            95, 96, 91, 97, 34, 98, 99, 100, 48, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
-            111, 112, 34, 113, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 114, 115, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34,
-            116, 34, 117, 118, 119, 120, 121, 34, 122, 34, 34, 123, 124, 125, 126, 3, 127, 34, 128,
-            129, 130, 131, 132
-        ],
-        r3: &[
-            0x00000110043fffff, 0x000007ff01ffffff, 0x3fdfffff00000000, 0x0000000000000000,
-            0x23fffffffffffff0, 0xfffe0003ff010000, 0x23c5fdfffff99fe1, 0x10030003b0004000,
-            0x036dfdfffff987e0, 0x001c00005e000000, 0x23edfdfffffbbfe0, 0x0200000300010000,
-            0x23edfdfffff99fe0, 0x00020003b0000000, 0x03ffc718d63dc7e8, 0x0000000000010000,
-            0x23fffdfffffddfe0, 0x0000000307000000, 0x23effdfffffddfe1, 0x0006000340000000,
-            0x27fffffffffddfe0, 0xfc00000380704000, 0x2ffbfffffc7fffe0, 0x000000000000007f,
-            0x0005fffffffffffe, 0x2005ffaffffff7d6, 0x00000000f000005f, 0x0000000000000001,
-            0x00001ffffffffeff, 0x0000000000001f00, 0x800007ffffffffff, 0xffe1c0623c3f0000,
-            0xffffffff00004003, 0xf7ffffffffff20bf, 0xffffffffffffffff, 0xffffffff3d7f3dff,
-            0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0000000007ffffff,
-            0xffffffff0000ffff, 0x3f3fffffffffffff, 0xfffffffffffffffe, 0xffff9fffffffffff,
-            0xffffffff07fffffe, 0x01ffc7ffffffffff, 0x0003ffff0003dfff, 0x0001dfff0003ffff,
-            0x000fffffffffffff, 0x0000000010800000, 0xffffffff00000000, 0x01ffffffffffffff,
-            0xffff05ffffffffff, 0x003fffffffffffff, 0x000000007fffffff, 0x001f3fffffff0000,
-            0xffff0fffffffffff, 0x00000000000003ff, 0xffffffff007fffff, 0x00000000001fffff,
-            0x0000008000000000, 0x000fffffffffffe0, 0x0000000000000fe0, 0xfc00c001fffffff8,
-            0x0000003fffffffff, 0x0000000fffffffff, 0x3ffffffffc00e000, 0xe7ffffffffff01ff,
-            0x046fde0000000000, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff,
-            0x1fdc1fff0fcf1fdc, 0x8002000000000000, 0x000000001fff0000, 0xf3fffd503f2ffc84,
-            0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff, 0xffffffff7fffffff,
-            0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff,
-            0x000000007f7f7f7f, 0x1f3e03fe000000e0, 0xfffffffee07fffff, 0xf7ffffffffffffff,
-            0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000, 0x0000ffffffffffff,
-            0x0000000000001fff, 0x3fffffffffff0000, 0x00000c00ffff1fff, 0x80007fffffffffff,
-            0xffffffff3fffffff, 0xfffffffcff800000, 0xfffffffffffff9ff, 0xff8000000000007c,
-            0x00000007fffff7bb, 0x000ffffffffffffc, 0x68fc000000000000, 0xffff003ffffffc00,
-            0x1fffffff0000007f, 0x0007fffffffffff0, 0x7c00ffdf00008000, 0x000001ffffffffff,
-            0xc47fffff00000ff7, 0x3e62ffffffffffff, 0x001c07ff38000005, 0xffff7f7f007e7e7e,
-            0xffff00fff7ffffff, 0x00000007ffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f,
-            0xffff3fffffffffff, 0x0000000003ffffff, 0x5f7ffdffa0f8007f, 0xffffffffffffffdb,
-            0x0003ffffffffffff, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff,
-            0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0xaa8a000000000000,
-            0x1fffffffffffffff, 0x07fffffe00000000, 0xffffffc007fffffe, 0x7fffffff3fffffff,
-            0x000000001cfcfcfc
-        ],
-        r4: [
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 13,
-            14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-        ],
-        r5: &[
-            0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2,
-            2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32,
-            32, 15, 4, 4, 4, 4, 4, 4, 4, 33, 34, 4, 35, 36, 4, 37, 38, 39, 40, 41, 42, 43, 4, 44,
-            20, 45, 46, 4, 4, 5, 47, 48, 49, 4, 4, 50, 51, 48, 52, 53, 4, 54, 4, 4, 4, 55, 4, 56,
-            57, 4, 4, 58, 59, 60, 61, 62, 63, 4, 4, 4, 4, 64, 65, 66, 4, 67, 68, 69, 4, 4, 4, 4, 70,
-            4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 2, 50, 2, 2, 2, 72, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 73, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 63, 20, 4, 74, 48, 75, 66, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 2, 4, 4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 80, 2,
-            2, 2, 2, 2, 81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 85, 86, 87, 88, 2, 2, 2, 2, 89, 90,
-            91, 92, 93, 94, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 95, 96, 4, 4, 4, 4, 4, 55, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 97, 2, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 102, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 103,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 104, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 105, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
-        ],
-        r6: &[
-            0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
-            0x0000000000000000, 0x001fffffffffffff, 0xffffffff1fffffff, 0x000000000001ffff,
-            0xffffe000ffffffff, 0x003fffffffff07ff, 0xffffffff3fffffff, 0x00000000003eff0f,
-            0xffff00003fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff, 0x0000000fffffffff,
-            0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f, 0x007fffff003fffff,
-            0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff, 0xc0ffffffffffffff,
-            0x003ffffffeef0001, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff,
-            0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff,
-            0x0007ffffffffffff, 0xffff00801fffffff, 0x000000000000003f, 0x007fffff00000000,
-            0x00fffffffffffff8, 0x0000fffffffffff8, 0x000001ffffff0000, 0x0000007ffffffff8,
-            0x0047ffffffff0010, 0x0007fffffffffff8, 0x000000001400001e, 0x00000ffffffbffff,
-            0xffff01ffbfffbd7f, 0x23edfdfffff99fe0, 0x00000003e0010000, 0x0000000080000780,
-            0x0000ffffffffffff, 0x00000000000000b0, 0x00007fffffffffff, 0x000000000f000000,
-            0x0000000000000010, 0x010007ffffffffff, 0x0000000007ffffff, 0x00000fffffffffff,
-            0xffffffff00000000, 0x80000000ffffffff, 0xfffffcff00000000, 0x0000000a0001ffff,
-            0x0407fffffffff801, 0xfffffffff0010000, 0x00000000200003ff, 0x01ffffffffffffff,
-            0x00007ffffffffdff, 0xfffc000000000001, 0x000000000000ffff, 0x0001fffffffffb7f,
-            0xfffffdbf00000040, 0x00000000010003ff, 0x0007ffff00000000, 0x0000000003ffffff,
-            0x000000000000000f, 0x000000000000007f, 0x00003fffffff0000, 0xe0fffff80000000f,
-            0x00000000000107ff, 0x00000000fff80000, 0x0000000b00000000, 0x00ffffffffffffff,
-            0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000003ff01ff,
-            0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
-            0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
-            0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x3f801fffffffffff,
-            0x0000000000004000, 0x000000000000001f, 0x000000000000080f, 0x0af7fe96ffffffef,
-            0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff, 0xffff0003ffffffff,
-            0x00000001ffffffff, 0x000000003fffffff
-        ],
-    };
-
-    pub fn XID_Start(c: char) -> bool {
-        XID_Start_table.lookup(c)
-    }
-
 }
 
 pub(crate) mod property {
-    const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
-        r1: &[
-            0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
-        ],
-        r2: &[
-            0x0000000100003e00, 0x0000000000000000, 0x0000000000000020, 0x000003000000c000
-        ],
-    };
-
-    pub fn Pattern_White_Space(c: char) -> bool {
-        Pattern_White_Space_table.lookup(c)
-    }
-
     const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
         r1: &[
             0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index 6de5d9e033b93..89894f7932d79 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -728,7 +728,7 @@ def generate_property_module(mod, grouped_categories, category_subset):
 
     yield "pub(crate) mod %s {\n" % mod
     for cat in sorted(category_subset):
-        if cat in ("Cc", "White_Space", "Pattern_White_Space"):
+        if cat in ("Cc", "White_Space"):
             generator = generate_small_bool_trie("%s_table" % cat, grouped_categories[cat])
         else:
             generator = generate_bool_trie("%s_table" % cat, grouped_categories[cat])
@@ -841,19 +841,18 @@ def main():
     unicode_data = load_unicode_data(get_path(UnicodeFiles.UNICODE_DATA))
     load_special_casing(get_path(UnicodeFiles.SPECIAL_CASING), unicode_data)
 
-    want_derived = {"XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase",
+    want_derived = {"Alphabetic", "Lowercase", "Uppercase",
                     "Cased", "Case_Ignorable", "Grapheme_Extend"}
     derived = load_properties(get_path(UnicodeFiles.DERIVED_CORE_PROPERTIES), want_derived)
 
     props = load_properties(get_path(UnicodeFiles.PROPS),
-                            {"White_Space", "Join_Control", "Noncharacter_Code_Point",
-                             "Pattern_White_Space"})
+                            {"White_Space", "Join_Control", "Noncharacter_Code_Point"})
 
     # Category tables
     for (name, categories, category_subset) in (
             ("general_category", unicode_data.general_categories, ["N", "Cc"]),
             ("derived_property", derived, want_derived),
-            ("property", props, ["White_Space", "Pattern_White_Space"])
+            ("property", props, ["White_Space"])
     ):
         for fragment in generate_property_module(name, categories, category_subset):
             buf.write(fragment)
diff --git a/src/libfmt_macros/Cargo.toml b/src/libfmt_macros/Cargo.toml
index 82a9e34c065b1..fff4ec716dfda 100644
--- a/src/libfmt_macros/Cargo.toml
+++ b/src/libfmt_macros/Cargo.toml
@@ -10,4 +10,4 @@ path = "lib.rs"
 
 [dependencies]
 syntax_pos = { path = "../libsyntax_pos" }
-
+rustc_lexer = { path = "../librustc_lexer" }
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index 985abaf2c1bd5..98fa2bd061516 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -23,6 +23,7 @@ use std::string;
 use std::iter;
 
 use syntax_pos::{InnerSpan, Symbol};
+use rustc_lexer::character_properties::{is_id_start, is_id_continue};
 
 #[derive(Copy, Clone)]
 struct InnerOffset(usize);
@@ -597,12 +598,11 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parses a word starting at the current position. A word is considered to
-    /// be an alphabetic character followed by any number of alphanumeric
-    /// characters.
+    /// Parses a word starting at the current position. A word is the same as
+    /// Rust identifier, except that it can't start with `_` character.
     fn word(&mut self) -> &'a str {
         let start = match self.cur.peek() {
-            Some(&(pos, c)) if c.is_xid_start() => {
+            Some(&(pos, c)) if c != '_' && is_id_start(c) => {
                 self.cur.next();
                 pos
             }
@@ -611,7 +611,7 @@ impl<'a> Parser<'a> {
             }
         };
         while let Some(&(pos, c)) = self.cur.peek() {
-            if c.is_xid_continue() {
+            if is_id_continue(c) {
                 self.cur.next();
             } else {
                 return &self.input[start..pos];
diff --git a/src/librustc_lexer/Cargo.toml b/src/librustc_lexer/Cargo.toml
index 0dbcda618ecac..675d3065c5b28 100644
--- a/src/librustc_lexer/Cargo.toml
+++ b/src/librustc_lexer/Cargo.toml
@@ -4,12 +4,12 @@ name = "rustc_lexer"
 version = "0.1.0"
 edition = "2018"
 
-# Note that this crate purposefully does not depend on other rustc crates
-[dependencies]
-unicode-xid = { version = "0.1.0", optional = true }
-
 # Note: do not remove this blank `[lib]` section.
 # This will be used when publishing this crate as `rustc-ap-rustc_lexer`.
 [lib]
 doctest = false
 name = "rustc_lexer"
+
+# Note that this crate purposefully does not depend on other rustc crates
+[dependencies]
+unicode-xid = "0.2.0"
diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs
index 41b47befaf141..26e5e6fc8c4b1 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/src/librustc_lexer/src/lib.rs
@@ -1,6 +1,5 @@
-// We want to be able to build this crate with a stable compiler, so feature
-// flags should be optional.
-#![cfg_attr(not(feature = "unicode-xid"), feature(unicode_internals))]
+// We want to be able to build this crate with a stable compiler, so no
+// `#![feature]` attributes should be added.
 
 mod cursor;
 pub mod unescape;
@@ -507,23 +506,39 @@ impl Cursor<'_> {
 }
 
 pub mod character_properties {
-    // this is Pattern_White_Space
-    #[cfg(feature = "unicode-xid")]
+    // See [UAX #31](http://unicode.org/reports/tr31) for definitions of these
+    // classes.
+
+    // This is Pattern_White_Space.
+    //
+    // Note that this set is stable (ie, it doesn't change with different
+    // Unicode versions), so it's ok to just hard-code the values.
     pub fn is_whitespace(c: char) -> bool {
         match c {
-            '\u{0009}' | '\u{000A}' | '\u{000B}' | '\u{000C}' | '\u{000D}' | '\u{0020}'
-            | '\u{0085}' | '\u{200E}' | '\u{200F}' | '\u{2028}' | '\u{2029}' => true,
+            // Usual ASCII suspects
+            | '\u{0009}' // \t
+            | '\u{000A}' // \n
+            | '\u{000B}' // vertical tab
+            | '\u{000C}' // form feed
+            | '\u{000D}' // \r
+            | '\u{0020}' // space
+
+            // NEXT LINE from latin1
+            | '\u{0085}'
+
+            // Bidi markers
+            | '\u{200E}' // LEFT-TO-RIGHT MARK
+            | '\u{200F}' // RIGHT-TO-LEFT MARK
+
+            // Dedicated whitespace characters from Unicode
+            | '\u{2028}' // LINE SEPARATOR
+            | '\u{2029}' // PARAGRAPH SEPARATOR
+              => true,
             _ => false,
         }
     }
 
-    #[cfg(not(feature = "unicode-xid"))]
-    pub fn is_whitespace(c: char) -> bool {
-        core::unicode::property::Pattern_White_Space(c)
-    }
-
-    // this is XID_Start OR '_' (which formally is not a XID_Start)
-    #[cfg(feature = "unicode-xid")]
+    // This is XID_Start OR '_' (which formally is not a XID_Start).
     pub fn is_id_start(c: char) -> bool {
         ('a' <= c && c <= 'z')
             || ('A' <= c && c <= 'Z')
@@ -531,16 +546,7 @@ pub mod character_properties {
             || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_start(c))
     }
 
-    #[cfg(not(feature = "unicode-xid"))]
-    pub fn is_id_start(c: char) -> bool {
-        ('a' <= c && c <= 'z')
-            || ('A' <= c && c <= 'Z')
-            || c == '_'
-            || (c > '\x7f' && c.is_xid_start())
-    }
-
-    // this is XID_Continue
-    #[cfg(feature = "unicode-xid")]
+    // This is XID_Continue.
     pub fn is_id_continue(c: char) -> bool {
         ('a' <= c && c <= 'z')
             || ('A' <= c && c <= 'Z')
@@ -548,13 +554,4 @@ pub mod character_properties {
             || c == '_'
             || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
     }
-
-    #[cfg(not(feature = "unicode-xid"))]
-    pub fn is_id_continue(c: char) -> bool {
-        ('a' <= c && c <= 'z')
-            || ('A' <= c && c <= 'Z')
-            || ('0' <= c && c <= '9')
-            || c == '_'
-            || (c > '\x7f' && c.is_xid_continue())
-    }
 }
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index 21008c737289f..4e68708adfc3e 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -20,6 +20,7 @@ rustc = { path = "../librustc" }
 rustc_target = { path = "../librustc_target" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
+rustc_lexer = { path = "../librustc_lexer" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index f10ff71b15e68..abcb70b719741 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -1,8 +1,7 @@
-use core::unicode::property::Pattern_White_Space;
-
 use rustc::mir::*;
 use rustc::ty;
 use rustc_errors::{DiagnosticBuilder,Applicability};
+use rustc_lexer::character_properties::is_whitespace;
 use syntax_pos::Span;
 
 use crate::borrow_check::MirBorrowckCtxt;
@@ -526,7 +525,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         let suggestion;
                         let to_remove;
                         if pat_snippet.starts_with("mut")
-                            && pat_snippet["mut".len()..].starts_with(Pattern_White_Space)
+                            && pat_snippet["mut".len()..].starts_with(is_whitespace)
                         {
                             suggestion = pat_snippet["mut".len()..].trim_start();
                             to_remove = "&mut";
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 5a5534922aa8a..32bf82c8bcde3 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -1,4 +1,4 @@
-use core::unicode::property::Pattern_White_Space;
+use rustc_lexer::character_properties::is_whitespace;
 use rustc::hir;
 use rustc::hir::Node;
 use rustc::mir::{self, BindingForm, ClearCrossCrate, Local, Location, Body};
@@ -715,7 +715,7 @@ fn annotate_struct_field(
 fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<String> {
     let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).ok()?;
     if hi_src.starts_with("ref")
-        && hi_src["ref".len()..].starts_with(Pattern_White_Space)
+        && hi_src["ref".len()..].starts_with(is_whitespace)
     {
         let replacement = format!("ref mut{}", &hi_src["ref".len()..]);
         Some(replacement)
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index dfa0db0d23b74..301946733dc55 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -33,6 +33,7 @@ extern crate rustc_interface;
 extern crate rustc_metadata;
 extern crate rustc_target;
 extern crate rustc_typeck;
+extern crate rustc_lexer;
 extern crate serialize;
 extern crate syntax;
 extern crate syntax_pos;
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index adcc9930b6c33..1105e47d74824 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -4,6 +4,7 @@ use rustc::hir;
 use rustc::hir::intravisit;
 use rustc::session::{self, config, DiagnosticOutput};
 use rustc::util::common::ErrorReported;
+use rustc_lexer::character_properties::{is_id_start, is_id_continue};
 use syntax::ast;
 use syntax::with_globals;
 use syntax::source_map::SourceMap;
@@ -763,8 +764,8 @@ impl Tester for Collector {
             // We use these headings as test names, so it's good if
             // they're valid identifiers.
             let name = name.chars().enumerate().map(|(i, c)| {
-                    if (i == 0 && c.is_xid_start()) ||
-                        (i != 0 && c.is_xid_continue()) {
+                    if (i == 0 && is_id_start(c)) ||
+                        (i != 0 && is_id_continue(c)) {
                         c
                     } else {
                         '_'
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index 1a26b17dac782..35feb6680f9cc 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -6,6 +6,7 @@ use crate::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}
 
 use errors::{Diagnostic, DiagnosticBuilder};
 use rustc_data_structures::sync::Lrc;
+use rustc_lexer::character_properties::{is_id_start, is_id_continue};
 use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
 use syntax_pos::symbol::{kw, sym, Symbol};
 
@@ -322,8 +323,7 @@ impl Ident {
     fn is_valid(string: &str) -> bool {
         let mut chars = string.chars();
         if let Some(start) = chars.next() {
-            (start == '_' || start.is_xid_start())
-                && chars.all(|cont| cont == '_' || cont.is_xid_continue())
+            is_id_start(start) && chars.all(is_id_continue)
         } else {
             false
         }
diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml
index 73310df305b32..791ee94b4fa77 100644
--- a/src/libsyntax_ext/Cargo.toml
+++ b/src/libsyntax_ext/Cargo.toml
@@ -18,3 +18,4 @@ rustc_target = { path = "../librustc_target" }
 smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
+rustc_lexer = { path = "../librustc_lexer" }

From 78908f2e0963ceed461e9961020226d3e12c5978 Mon Sep 17 00:00:00 2001
From: Tim Vermeulen <tvermeulen@me.com>
Date: Tue, 3 Sep 2019 11:56:08 +0200
Subject: [PATCH 476/943] Override `StepBy::{try_fold, try_rfold}`

---
 src/libcore/iter/adapters/mod.rs | 44 +++++++++++++++++++++++++++++++-
 src/libcore/tests/iter.rs        | 35 +++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index f50781890ab22..7c9dde81a48fb 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -5,7 +5,7 @@ use crate::usize;
 use crate::intrinsics;
 
 use super::{Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen};
-use super::LoopState;
+use super::{LoopState, from_fn};
 
 mod chain;
 mod flatten;
@@ -541,6 +541,26 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
             self.iter.nth(nth - 1);
         }
     }
+
+    fn try_fold<Acc, F, R>(&mut self, mut acc: Acc, mut f: F) -> R
+    where
+        F: FnMut(Acc, Self::Item) -> R,
+        R: Try<Ok = Acc>,
+    {
+        #[inline]
+        fn nth<I: Iterator>(iter: &mut I, step: usize) -> impl FnMut() -> Option<I::Item> + '_ {
+            move || iter.nth(step)
+        }
+
+        if self.first_take {
+            self.first_take = false;
+            match self.iter.next() {
+                None => return Try::from_ok(acc),
+                Some(x) => acc = f(acc, x)?,
+            }
+        }
+        from_fn(nth(&mut self.iter, self.step)).try_fold(acc, f)
+    }
 }
 
 impl<I> StepBy<I> where I: ExactSizeIterator {
@@ -574,6 +594,28 @@ impl<I> DoubleEndedIterator for StepBy<I> where I: DoubleEndedIterator + ExactSi
             .saturating_add(self.next_back_index());
         self.iter.nth_back(n)
     }
+
+    fn try_rfold<Acc, F, R>(&mut self, init: Acc, mut f: F) -> R
+    where
+        F: FnMut(Acc, Self::Item) -> R,
+        R: Try<Ok = Acc>,
+    {
+        #[inline]
+        fn nth_back<I: DoubleEndedIterator>(
+            iter: &mut I,
+            step: usize,
+        ) -> impl FnMut() -> Option<I::Item> + '_ {
+            move || iter.nth_back(step)
+        }
+
+        match self.next_back() {
+            None => Try::from_ok(init),
+            Some(x) => {
+                let acc = f(init, x)?;
+                from_fn(nth_back(&mut self.iter, self.step)).try_fold(acc, f)
+            }
+        }
+    }
 }
 
 // StepBy can only make the iterator shorter, so the len will still fit.
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 3a4f76852a0d7..f52899b500a3a 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -329,6 +329,23 @@ fn test_iterator_step_by_nth_overflow() {
     assert_eq!(it.0, (usize::MAX as Bigger) * 1);
 }
 
+#[test]
+fn test_iterator_step_by_nth_try_fold() {
+    let mut it = (0..).step_by(10);
+    assert_eq!(it.try_fold(0, i8::checked_add), None);
+    assert_eq!(it.next(), Some(60));
+    assert_eq!(it.try_fold(0, i8::checked_add), None);
+    assert_eq!(it.next(), Some(90));
+
+    let mut it = (100..).step_by(10);
+    assert_eq!(it.try_fold(50, i8::checked_add), None);
+    assert_eq!(it.next(), Some(110));
+
+    let mut it = (100..=100).step_by(10);
+    assert_eq!(it.next(), Some(100));
+    assert_eq!(it.try_fold(0, i8::checked_add), Some(0));
+}
+
 #[test]
 fn test_iterator_step_by_nth_back() {
     let mut it = (0..16).step_by(5);
@@ -354,6 +371,24 @@ fn test_iterator_step_by_nth_back() {
     assert_eq!(it().nth_back(42), None);
 }
 
+#[test]
+fn test_iterator_step_by_nth_try_rfold() {
+    let mut it = (0..100).step_by(10);
+    assert_eq!(it.try_rfold(0, i8::checked_add), None);
+    assert_eq!(it.next_back(), Some(70));
+    assert_eq!(it.next(), Some(0));
+    assert_eq!(it.try_rfold(0, i8::checked_add), None);
+    assert_eq!(it.next_back(), Some(30));
+
+    let mut it = (0..100).step_by(10);
+    assert_eq!(it.try_rfold(50, i8::checked_add), None);
+    assert_eq!(it.next_back(), Some(80));
+
+    let mut it = (100..=100).step_by(10);
+    assert_eq!(it.next_back(), Some(100));
+    assert_eq!(it.try_fold(0, i8::checked_add), Some(0));
+}
+
 #[test]
 #[should_panic]
 fn test_iterator_step_by_zero() {

From 206fe8e1c37d55d0bf3a82baaa23eb5fb148880b Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Wed, 4 Sep 2019 13:16:36 +0300
Subject: [PATCH 477/943] flatten rustc_lexer::character_properties module

On the call site, `rustc_lexer::is_whitespace` reads much better than
`character_properties::is_whitespace`.
---
 src/libfmt_macros/lib.rs                      |   5 +-
 src/librustc_lexer/src/lib.rs                 | 135 +++++++++---------
 src/librustc_mir/borrow_check/move_errors.rs  |   3 +-
 .../borrow_check/mutability_errors.rs         |   3 +-
 src/librustdoc/test.rs                        |   5 +-
 src/libsyntax/ext/proc_macro_server.rs        |   3 +-
 src/libsyntax/tests.rs                        |  14 +-
 7 files changed, 82 insertions(+), 86 deletions(-)

diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index 98fa2bd061516..f9c1be20b8bc1 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -23,7 +23,6 @@ use std::string;
 use std::iter;
 
 use syntax_pos::{InnerSpan, Symbol};
-use rustc_lexer::character_properties::{is_id_start, is_id_continue};
 
 #[derive(Copy, Clone)]
 struct InnerOffset(usize);
@@ -602,7 +601,7 @@ impl<'a> Parser<'a> {
     /// Rust identifier, except that it can't start with `_` character.
     fn word(&mut self) -> &'a str {
         let start = match self.cur.peek() {
-            Some(&(pos, c)) if c != '_' && is_id_start(c) => {
+            Some(&(pos, c)) if c != '_' && rustc_lexer::is_id_start(c) => {
                 self.cur.next();
                 pos
             }
@@ -611,7 +610,7 @@ impl<'a> Parser<'a> {
             }
         };
         while let Some(&(pos, c)) = self.cur.peek() {
-            if is_id_continue(c) {
+            if rustc_lexer::is_id_continue(c) {
                 self.cur.next();
             } else {
                 return &self.input[start..pos];
diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs
index 26e5e6fc8c4b1..30a5175d8cdb0 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/src/librustc_lexer/src/lib.rs
@@ -102,6 +102,62 @@ pub fn tokenize(mut input: &str) -> impl Iterator<Item = Token> + '_ {
     })
 }
 
+// See [UAX #31](http://unicode.org/reports/tr31) for definitions of these
+// classes.
+
+/// True if `c` is considered a whitespace according to Rust language definition.
+pub fn is_whitespace(c: char) -> bool {
+    // This is Pattern_White_Space.
+    //
+    // Note that this set is stable (ie, it doesn't change with different
+    // Unicode versions), so it's ok to just hard-code the values.
+
+    match c {
+        // Usual ASCII suspects
+        | '\u{0009}' // \t
+        | '\u{000A}' // \n
+        | '\u{000B}' // vertical tab
+        | '\u{000C}' // form feed
+        | '\u{000D}' // \r
+        | '\u{0020}' // space
+
+        // NEXT LINE from latin1
+        | '\u{0085}'
+
+        // Bidi markers
+        | '\u{200E}' // LEFT-TO-RIGHT MARK
+        | '\u{200F}' // RIGHT-TO-LEFT MARK
+
+        // Dedicated whitespace characters from Unicode
+        | '\u{2028}' // LINE SEPARATOR
+        | '\u{2029}' // PARAGRAPH SEPARATOR
+            => true,
+        _ => false,
+    }
+}
+
+/// True if `c` is valid as a first character of an identifier.
+pub fn is_id_start(c: char) -> bool {
+    // This is XID_Start OR '_' (which formally is not a XID_Start).
+    // We also add fast-path for ascii idents
+    ('a' <= c && c <= 'z')
+        || ('A' <= c && c <= 'Z')
+        || c == '_'
+        || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_start(c))
+}
+
+/// True if `c` is valid as a non-first character of an identifier.
+pub fn is_id_continue(c: char) -> bool {
+    // This is exactly XID_Continue.
+    // We also add fast-path for ascii idents
+    ('a' <= c && c <= 'z')
+        || ('A' <= c && c <= 'Z')
+        || ('0' <= c && c <= '9')
+        || c == '_'
+        || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
+}
+
+
 impl Cursor<'_> {
     fn advance_token(&mut self) -> Token {
         let first_char = self.bump().unwrap();
@@ -111,9 +167,9 @@ impl Cursor<'_> {
                 '*' => self.block_comment(),
                 _ => Slash,
             },
-            c if character_properties::is_whitespace(c) => self.whitespace(),
+            c if is_whitespace(c) => self.whitespace(),
             'r' => match (self.nth_char(0), self.nth_char(1)) {
-                ('#', c1) if character_properties::is_id_start(c1) => self.raw_ident(),
+                ('#', c1) if is_id_start(c1) => self.raw_ident(),
                 ('#', _) | ('"', _) => {
                     let (n_hashes, started, terminated) = self.raw_double_quoted_string();
                     let suffix_start = self.len_consumed();
@@ -158,7 +214,7 @@ impl Cursor<'_> {
                 }
                 _ => self.ident(),
             },
-            c if character_properties::is_id_start(c) => self.ident(),
+            c if is_id_start(c) => self.ident(),
             c @ '0'..='9' => {
                 let literal_kind = self.number(c);
                 let suffix_start = self.len_consumed();
@@ -246,8 +302,8 @@ impl Cursor<'_> {
     }
 
     fn whitespace(&mut self) -> TokenKind {
-        debug_assert!(character_properties::is_whitespace(self.prev()));
-        while character_properties::is_whitespace(self.nth_char(0)) {
+        debug_assert!(is_whitespace(self.prev()));
+        while is_whitespace(self.nth_char(0)) {
             self.bump();
         }
         Whitespace
@@ -257,19 +313,19 @@ impl Cursor<'_> {
         debug_assert!(
             self.prev() == 'r'
                 && self.nth_char(0) == '#'
-                && character_properties::is_id_start(self.nth_char(1))
+                && is_id_start(self.nth_char(1))
         );
         self.bump();
         self.bump();
-        while character_properties::is_id_continue(self.nth_char(0)) {
+        while is_id_continue(self.nth_char(0)) {
             self.bump();
         }
         RawIdent
     }
 
     fn ident(&mut self) -> TokenKind {
-        debug_assert!(character_properties::is_id_start(self.prev()));
-        while character_properties::is_id_continue(self.nth_char(0)) {
+        debug_assert!(is_id_start(self.prev()));
+        while is_id_continue(self.nth_char(0)) {
             self.bump();
         }
         Ident
@@ -314,7 +370,7 @@ impl Cursor<'_> {
             // integer literal followed by field/method access or a range pattern
             // (`0..2` and `12.foo()`)
             '.' if self.nth_char(1) != '.'
-                && !character_properties::is_id_start(self.nth_char(1)) =>
+                && !is_id_start(self.nth_char(1)) =>
             {
                 // might have stuff after the ., and if it does, it needs to start
                 // with a number
@@ -344,7 +400,7 @@ impl Cursor<'_> {
     fn lifetime_or_char(&mut self) -> TokenKind {
         debug_assert!(self.prev() == '\'');
         let mut starts_with_number = false;
-        if (character_properties::is_id_start(self.nth_char(0))
+        if (is_id_start(self.nth_char(0))
             || self.nth_char(0).is_digit(10) && {
                 starts_with_number = true;
                 true
@@ -352,7 +408,7 @@ impl Cursor<'_> {
             && self.nth_char(1) != '\''
         {
             self.bump();
-            while character_properties::is_id_continue(self.nth_char(0)) {
+            while is_id_continue(self.nth_char(0)) {
                 self.bump();
             }
 
@@ -494,64 +550,13 @@ impl Cursor<'_> {
     }
 
     fn eat_literal_suffix(&mut self) {
-        if !character_properties::is_id_start(self.nth_char(0)) {
+        if !is_id_start(self.nth_char(0)) {
             return;
         }
         self.bump();
 
-        while character_properties::is_id_continue(self.nth_char(0)) {
+        while is_id_continue(self.nth_char(0)) {
             self.bump();
         }
     }
 }
-
-pub mod character_properties {
-    // See [UAX #31](http://unicode.org/reports/tr31) for definitions of these
-    // classes.
-
-    // This is Pattern_White_Space.
-    //
-    // Note that this set is stable (ie, it doesn't change with different
-    // Unicode versions), so it's ok to just hard-code the values.
-    pub fn is_whitespace(c: char) -> bool {
-        match c {
-            // Usual ASCII suspects
-            | '\u{0009}' // \t
-            | '\u{000A}' // \n
-            | '\u{000B}' // vertical tab
-            | '\u{000C}' // form feed
-            | '\u{000D}' // \r
-            | '\u{0020}' // space
-
-            // NEXT LINE from latin1
-            | '\u{0085}'
-
-            // Bidi markers
-            | '\u{200E}' // LEFT-TO-RIGHT MARK
-            | '\u{200F}' // RIGHT-TO-LEFT MARK
-
-            // Dedicated whitespace characters from Unicode
-            | '\u{2028}' // LINE SEPARATOR
-            | '\u{2029}' // PARAGRAPH SEPARATOR
-              => true,
-            _ => false,
-        }
-    }
-
-    // This is XID_Start OR '_' (which formally is not a XID_Start).
-    pub fn is_id_start(c: char) -> bool {
-        ('a' <= c && c <= 'z')
-            || ('A' <= c && c <= 'Z')
-            || c == '_'
-            || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_start(c))
-    }
-
-    // This is XID_Continue.
-    pub fn is_id_continue(c: char) -> bool {
-        ('a' <= c && c <= 'z')
-            || ('A' <= c && c <= 'Z')
-            || ('0' <= c && c <= '9')
-            || c == '_'
-            || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
-    }
-}
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index abcb70b719741..0d13db2f5a413 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -1,7 +1,6 @@
 use rustc::mir::*;
 use rustc::ty;
 use rustc_errors::{DiagnosticBuilder,Applicability};
-use rustc_lexer::character_properties::is_whitespace;
 use syntax_pos::Span;
 
 use crate::borrow_check::MirBorrowckCtxt;
@@ -525,7 +524,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         let suggestion;
                         let to_remove;
                         if pat_snippet.starts_with("mut")
-                            && pat_snippet["mut".len()..].starts_with(is_whitespace)
+                            && pat_snippet["mut".len()..].starts_with(rustc_lexer::is_whitespace)
                         {
                             suggestion = pat_snippet["mut".len()..].trim_start();
                             to_remove = "&mut";
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 32bf82c8bcde3..8f2ce80aafa22 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -1,4 +1,3 @@
-use rustc_lexer::character_properties::is_whitespace;
 use rustc::hir;
 use rustc::hir::Node;
 use rustc::mir::{self, BindingForm, ClearCrossCrate, Local, Location, Body};
@@ -715,7 +714,7 @@ fn annotate_struct_field(
 fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<String> {
     let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).ok()?;
     if hi_src.starts_with("ref")
-        && hi_src["ref".len()..].starts_with(is_whitespace)
+        && hi_src["ref".len()..].starts_with(rustc_lexer::is_whitespace)
     {
         let replacement = format!("ref mut{}", &hi_src["ref".len()..]);
         Some(replacement)
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 1105e47d74824..000d2843adce3 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -4,7 +4,6 @@ use rustc::hir;
 use rustc::hir::intravisit;
 use rustc::session::{self, config, DiagnosticOutput};
 use rustc::util::common::ErrorReported;
-use rustc_lexer::character_properties::{is_id_start, is_id_continue};
 use syntax::ast;
 use syntax::with_globals;
 use syntax::source_map::SourceMap;
@@ -764,8 +763,8 @@ impl Tester for Collector {
             // We use these headings as test names, so it's good if
             // they're valid identifiers.
             let name = name.chars().enumerate().map(|(i, c)| {
-                    if (i == 0 && is_id_start(c)) ||
-                        (i != 0 && is_id_continue(c)) {
+                    if (i == 0 && rustc_lexer::is_id_start(c)) ||
+                        (i != 0 && rustc_lexer::is_id_continue(c)) {
                         c
                     } else {
                         '_'
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index 35feb6680f9cc..544ec789d80a9 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -6,7 +6,6 @@ use crate::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint}
 
 use errors::{Diagnostic, DiagnosticBuilder};
 use rustc_data_structures::sync::Lrc;
-use rustc_lexer::character_properties::{is_id_start, is_id_continue};
 use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
 use syntax_pos::symbol::{kw, sym, Symbol};
 
@@ -323,7 +322,7 @@ impl Ident {
     fn is_valid(string: &str) -> bool {
         let mut chars = string.chars();
         if let Some(start) = chars.next() {
-            is_id_start(start) && chars.all(is_id_continue)
+            rustc_lexer::is_id_start(start) && chars.all(rustc_lexer::is_id_continue)
         } else {
             false
         }
diff --git a/src/libsyntax/tests.rs b/src/libsyntax/tests.rs
index c472212bc2096..9b90b31f2d2a2 100644
--- a/src/libsyntax/tests.rs
+++ b/src/libsyntax/tests.rs
@@ -63,7 +63,7 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
             (None, None) => return true,
             (None, _) => return false,
             (Some(&a), None) => {
-                if is_pattern_whitespace(a) {
+                if rustc_lexer::is_whitespace(a) {
                     break // trailing whitespace check is out of loop for borrowck
                 } else {
                     return false
@@ -72,11 +72,11 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
             (Some(&a), Some(&b)) => (a, b)
         };
 
-        if is_pattern_whitespace(a) && is_pattern_whitespace(b) {
+        if rustc_lexer::is_whitespace(a) && rustc_lexer::is_whitespace(b) {
             // skip whitespace for a and b
             scan_for_non_ws_or_end(&mut a_iter);
             scan_for_non_ws_or_end(&mut b_iter);
-        } else if is_pattern_whitespace(a) {
+        } else if rustc_lexer::is_whitespace(a) {
             // skip whitespace for a
             scan_for_non_ws_or_end(&mut a_iter);
         } else if a == b {
@@ -88,20 +88,16 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
     }
 
     // check if a has *only* trailing whitespace
-    a_iter.all(is_pattern_whitespace)
+    a_iter.all(rustc_lexer::is_whitespace)
 }
 
 /// Advances the given peekable `Iterator` until it reaches a non-whitespace character
 fn scan_for_non_ws_or_end<I: Iterator<Item = char>>(iter: &mut Peekable<I>) {
-    while iter.peek().copied().map(|c| is_pattern_whitespace(c)) == Some(true) {
+    while iter.peek().copied().map(|c| rustc_lexer::is_whitespace(c)) == Some(true) {
         iter.next();
     }
 }
 
-fn is_pattern_whitespace(c: char) -> bool {
-    rustc_lexer::character_properties::is_whitespace(c)
-}
-
 /// Identify a position in the text by the Nth occurrence of a string.
 struct Position {
     string: &'static str,

From cb84aa4744c7a6120d8311806912240275d04960 Mon Sep 17 00:00:00 2001
From: Shiqing <shiqing-thu18@yandex.com>
Date: Mon, 2 Sep 2019 21:03:35 +0800
Subject: [PATCH 478/943] Improve searching in rustdoc and add tests

---
 src/librustdoc/html/static/main.js        | 16 ++----
 src/test/rustdoc-js-std/vec-new.js        |  1 +
 src/test/rustdoc-js/exact-match.js        |  9 +++
 src/test/rustdoc-js/exact-match.rs        | 68 +++++++++++++++++++++++
 src/test/rustdoc-js/module-substring.js   |  9 +++
 src/test/rustdoc-js/module-substring.rs   | 68 +++++++++++++++++++++++
 src/test/rustdoc-js/search-short-types.js |  2 +
 src/test/rustdoc-js/search-short-types.rs |  6 ++
 8 files changed, 169 insertions(+), 10 deletions(-)
 create mode 100644 src/test/rustdoc-js/exact-match.js
 create mode 100644 src/test/rustdoc-js/exact-match.rs
 create mode 100644 src/test/rustdoc-js/module-substring.js
 create mode 100644 src/test/rustdoc-js/module-substring.rs

diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 637c6ef8e8e0b..5cb2456fefdb2 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -547,6 +547,11 @@ if (!DOMTokenList.prototype.remove) {
                 results.sort(function(aaa, bbb) {
                     var a, b;
 
+                    // sort by exact match with regard to the last word (mismatch goes later)
+                    a = (aaa.word !== val);
+                    b = (bbb.word !== val);
+                    if (a !== b) { return a - b; }
+
                     // Sort by non levenshtein results and then levenshtein results by the distance
                     // (less changes required to match means higher rankings)
                     a = (aaa.lev);
@@ -558,11 +563,6 @@ if (!DOMTokenList.prototype.remove) {
                     b = (bbb.item.crate !== window.currentCrate);
                     if (a !== b) { return a - b; }
 
-                    // sort by exact match (mismatch goes later)
-                    a = (aaa.word !== valLower);
-                    b = (bbb.word !== valLower);
-                    if (a !== b) { return a - b; }
-
                     // sort by item name length (longer goes later)
                     a = aaa.word.length;
                     b = bbb.word.length;
@@ -1028,7 +1028,7 @@ if (!DOMTokenList.prototype.remove) {
                         if (lev > MAX_LEV_DISTANCE) {
                             continue;
                         } else if (lev > 0) {
-                            lev_add = 1;
+                            lev_add = lev / 10;
                         }
                     }
 
@@ -1099,10 +1099,6 @@ if (!DOMTokenList.prototype.remove) {
                     if (index !== -1 || lev <= MAX_LEV_DISTANCE) {
                         if (index !== -1 && paths.length < 2) {
                             lev = 0;
-                        } else if (searchWords[j] === val) {
-                            // Small trick to fix when you're looking for a one letter type
-                            // and there are other short named types.
-                            lev = -1;
                         }
                         if (results[fullId] === undefined) {
                             results[fullId] = {
diff --git a/src/test/rustdoc-js-std/vec-new.js b/src/test/rustdoc-js-std/vec-new.js
index e4daa5065d233..e1a3256876bde 100644
--- a/src/test/rustdoc-js-std/vec-new.js
+++ b/src/test/rustdoc-js-std/vec-new.js
@@ -4,5 +4,6 @@ const EXPECTED = {
     'others': [
         { 'path': 'std::vec::Vec', 'name': 'new' },
         { 'path': 'std::vec::Vec', 'name': 'ne' },
+        { 'path': 'std::rc::Rc', 'name': 'ne' },
     ],
 };
diff --git a/src/test/rustdoc-js/exact-match.js b/src/test/rustdoc-js/exact-match.js
new file mode 100644
index 0000000000000..b0a411bee5829
--- /dev/null
+++ b/src/test/rustdoc-js/exact-match.js
@@ -0,0 +1,9 @@
+const QUERY = 'si::pc';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'exact_match::Si', 'name': 'pc' },
+        { 'path': 'exact_match::Psi', 'name': 'pc' },
+        { 'path': 'exact_match::Si', 'name': 'pa' },
+    ],
+};
diff --git a/src/test/rustdoc-js/exact-match.rs b/src/test/rustdoc-js/exact-match.rs
new file mode 100644
index 0000000000000..2eacc0a358284
--- /dev/null
+++ b/src/test/rustdoc-js/exact-match.rs
@@ -0,0 +1,68 @@
+macro_rules! imp {
+    ($name:ident) => {
+        pub struct $name {
+            pub op: usize,
+        }
+        impl $name {
+            pub fn op() {}
+            pub fn cmp() {}
+            pub fn map() {}
+            pub fn pop() {}
+            pub fn ptr() {}
+            pub fn rpo() {}
+            pub fn drop() {}
+            pub fn copy() {}
+            pub fn zip() {}
+            pub fn sup() {}
+            pub fn pa() {}
+            pub fn pb() {}
+            pub fn pc() {}
+            pub fn pd() {}
+            pub fn pe() {}
+            pub fn pf() {}
+            pub fn pg() {}
+            pub fn ph() {}
+            pub fn pi() {}
+            pub fn pj() {}
+            pub fn pk() {}
+            pub fn pl() {}
+            pub fn pm() {}
+            pub fn pn() {}
+            pub fn po() {}
+        }
+    };
+    ($name:ident, $($names:ident),*) => {
+        imp!($name);
+        imp!($($names),*);
+    };
+}
+macro_rules! en {
+    ($name:ident) => {
+        pub enum $name {
+            Ptr,
+            Rp,
+            Rpo,
+            Pt,
+            Drop,
+            Dr,
+            Dro,
+            Sup,
+            Op,
+            Cmp,
+            Map,
+            Mp,
+        }
+    };
+    ($name:ident, $($names:ident),*) => {
+        en!($name);
+        en!($($names),*);
+    };
+}
+
+imp!(Ot, Foo, Cmp, Map, Loc, Lac, Toc, Si, Sig, Sip, Psy, Psi, Py, Pi, Pa, Pb, Pc, Pd);
+imp!(Pe, Pf, Pg, Ph, Pj, Pk, Pl, Pm, Pn, Po, Pq, Pr, Ps, Pt, Pu, Pv, Pw, Px, Pz, Ap, Bp, Cp);
+imp!(Dp, Ep, Fp, Gp, Hp, Ip, Jp, Kp, Lp, Mp, Np, Op, Pp, Qp, Rp, Sp, Tp, Up, Vp, Wp, Xp, Yp, Zp);
+
+en!(Place, Plac, Plae, Plce, Pace, Scalar, Scalr, Scaar, Sclar, Salar);
+
+pub struct P;
diff --git a/src/test/rustdoc-js/module-substring.js b/src/test/rustdoc-js/module-substring.js
new file mode 100644
index 0000000000000..a446c39ebad57
--- /dev/null
+++ b/src/test/rustdoc-js/module-substring.js
@@ -0,0 +1,9 @@
+const QUERY = 'ig::pc';
+
+const EXPECTED = {
+    'others': [
+        { 'path': 'module_substring::Sig', 'name': 'pc' },
+        { 'path': 'module_substring::Si', 'name': 'pc' },
+        { 'path': 'module_substring::Si', 'name': 'pa' },
+    ],
+};
diff --git a/src/test/rustdoc-js/module-substring.rs b/src/test/rustdoc-js/module-substring.rs
new file mode 100644
index 0000000000000..2eacc0a358284
--- /dev/null
+++ b/src/test/rustdoc-js/module-substring.rs
@@ -0,0 +1,68 @@
+macro_rules! imp {
+    ($name:ident) => {
+        pub struct $name {
+            pub op: usize,
+        }
+        impl $name {
+            pub fn op() {}
+            pub fn cmp() {}
+            pub fn map() {}
+            pub fn pop() {}
+            pub fn ptr() {}
+            pub fn rpo() {}
+            pub fn drop() {}
+            pub fn copy() {}
+            pub fn zip() {}
+            pub fn sup() {}
+            pub fn pa() {}
+            pub fn pb() {}
+            pub fn pc() {}
+            pub fn pd() {}
+            pub fn pe() {}
+            pub fn pf() {}
+            pub fn pg() {}
+            pub fn ph() {}
+            pub fn pi() {}
+            pub fn pj() {}
+            pub fn pk() {}
+            pub fn pl() {}
+            pub fn pm() {}
+            pub fn pn() {}
+            pub fn po() {}
+        }
+    };
+    ($name:ident, $($names:ident),*) => {
+        imp!($name);
+        imp!($($names),*);
+    };
+}
+macro_rules! en {
+    ($name:ident) => {
+        pub enum $name {
+            Ptr,
+            Rp,
+            Rpo,
+            Pt,
+            Drop,
+            Dr,
+            Dro,
+            Sup,
+            Op,
+            Cmp,
+            Map,
+            Mp,
+        }
+    };
+    ($name:ident, $($names:ident),*) => {
+        en!($name);
+        en!($($names),*);
+    };
+}
+
+imp!(Ot, Foo, Cmp, Map, Loc, Lac, Toc, Si, Sig, Sip, Psy, Psi, Py, Pi, Pa, Pb, Pc, Pd);
+imp!(Pe, Pf, Pg, Ph, Pj, Pk, Pl, Pm, Pn, Po, Pq, Pr, Ps, Pt, Pu, Pv, Pw, Px, Pz, Ap, Bp, Cp);
+imp!(Dp, Ep, Fp, Gp, Hp, Ip, Jp, Kp, Lp, Mp, Np, Op, Pp, Qp, Rp, Sp, Tp, Up, Vp, Wp, Xp, Yp, Zp);
+
+en!(Place, Plac, Plae, Plce, Pace, Scalar, Scalr, Scaar, Sclar, Salar);
+
+pub struct P;
diff --git a/src/test/rustdoc-js/search-short-types.js b/src/test/rustdoc-js/search-short-types.js
index 0ebf4860cfa58..d14672af71fd6 100644
--- a/src/test/rustdoc-js/search-short-types.js
+++ b/src/test/rustdoc-js/search-short-types.js
@@ -3,6 +3,8 @@ const QUERY = 'P';
 const EXPECTED = {
     'others': [
         { 'path': 'search_short_types', 'name': 'P' },
+        { 'path': 'search_short_types::VeryLongTypeName', 'name': 'p' },
         { 'path': 'search_short_types', 'name': 'Ap' },
+        { 'path': 'search_short_types::VeryLongTypeName', 'name': 'ap' },
     ],
 };
diff --git a/src/test/rustdoc-js/search-short-types.rs b/src/test/rustdoc-js/search-short-types.rs
index 2eacc0a358284..a4083f9a76401 100644
--- a/src/test/rustdoc-js/search-short-types.rs
+++ b/src/test/rustdoc-js/search-short-types.rs
@@ -66,3 +66,9 @@ imp!(Dp, Ep, Fp, Gp, Hp, Ip, Jp, Kp, Lp, Mp, Np, Op, Pp, Qp, Rp, Sp, Tp, Up, Vp,
 en!(Place, Plac, Plae, Plce, Pace, Scalar, Scalr, Scaar, Sclar, Salar);
 
 pub struct P;
+
+pub struct VeryLongTypeName;
+impl VeryLongTypeName {
+    pub fn p() {}
+    pub fn ap() {}
+}

From b6f9523dc662ebc23f72356999ae263de9616a2d Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Wed, 4 Sep 2019 13:52:28 +0000
Subject: [PATCH 479/943] Fix doc links in `std::cmp` module

These links are rendered in `core::cmp` but not in `std::cmp`.
---
 src/libcore/cmp.rs | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 607427a85d67a..7ec2295f97e36 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -9,14 +9,22 @@
 //! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and
 //!   partial orderings between values, respectively. Implementing them overloads
 //!   the `<`, `<=`, `>`, and `>=` operators.
-//! * [`Ordering`][cmp::Ordering] is an enum returned by the
-//!   main functions of [`Ord`] and [`PartialOrd`], and describes an ordering.
-//! * [`Reverse`][cmp::Reverse] is a struct that allows you to easily reverse
-//!   an ordering.
-//! * [`max`][cmp::max] and [`min`][cmp::min] are functions that build off of
-//!   [`Ord`] and allow you to find the maximum or minimum of two values.
+//! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and
+//!   [`PartialOrd`], and describes an ordering.
+//! * [`Reverse`] is a struct that allows you to easily reverse an ordering.
+//! * [`max`] and [`min`] are functions that build off of [`Ord`] and allow you
+//!   to find the maximum or minimum of two values.
 //!
 //! For more details, see the respective documentation of each item in the list.
+//!
+//! [`Eq`]: trait.Eq.html
+//! [`PartialEq`]: trait.PartialEq.html
+//! [`Ord`]: trait.Ord.html
+//! [`PartialOrd`]: trait.PartialOrd.html
+//! [`Ordering`]: enum.Ordering.html
+//! [`Reverse`]: struct.Reverse.html
+//! [`max`]: fn.max.html
+//! [`min`]: fn.min.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
 

From 8e067243e450528c9c61f8f0e5f91e3fc7ec707d Mon Sep 17 00:00:00 2001
From: Guanqun Lu <guanqun.lu@gmail.com>
Date: Wed, 4 Sep 2019 23:25:51 +0800
Subject: [PATCH 480/943] fix a few typos in comments

---
 src/librustc_llvm/build.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
index 40ddd65164290..62a3757757b80 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -54,7 +54,7 @@ fn main() {
     // LLVM are compiled the same way, but for us that's typically the case.
     //
     // We *want* detect this cross compiling situation by asking llvm-config
-    // what it's host-target is. If that's not the TARGET, then we're cross
+    // what its host-target is. If that's not the TARGET, then we're cross
     // compiling. Unfortunately `llvm-config` seems either be buggy, or we're
     // misconfiguring it, because the `i686-pc-windows-gnu` build of LLVM will
     // report itself with a `--host-target` of `x86_64-pc-windows-gnu`. This
@@ -62,7 +62,7 @@ fn main() {
     // havoc ensues.
     //
     // In any case, if we're cross compiling, this generally just means that we
-    // can't trust all the output of llvm-config becaues it might be targeted
+    // can't trust all the output of llvm-config because it might be targeted
     // for the host rather than the target. As a result a bunch of blocks below
     // are gated on `if !is_crossed`
     let target = env::var("TARGET").expect("TARGET was not set");
@@ -166,7 +166,7 @@ fn main() {
 
     let (llvm_kind, llvm_link_arg) = detect_llvm_link();
 
-    // Link in all LLVM libraries, if we're uwring the "wrong" llvm-config then
+    // Link in all LLVM libraries, if we're using the "wrong" llvm-config then
     // we don't pick up system libs because unfortunately they're for the host
     // of llvm-config, not the target that we're attempting to link.
     let mut cmd = Command::new(&llvm_config);

From 74ccd08401f1350554272a1b7bdbcf6789166daa Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Wed, 4 Sep 2019 08:35:52 -0700
Subject: [PATCH 481/943] Update cargo, books

---
 src/doc/embedded-book   | 2 +-
 src/doc/reference       | 2 +-
 src/doc/rust-by-example | 2 +-
 src/tools/cargo         | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/doc/embedded-book b/src/doc/embedded-book
index 432ca26686c11..5ca585c4a7552 160000
--- a/src/doc/embedded-book
+++ b/src/doc/embedded-book
@@ -1 +1 @@
-Subproject commit 432ca26686c11d396eed6a59499f93ce1bf2433c
+Subproject commit 5ca585c4a7552efb546e7681c3de0712f4ae4fdc
diff --git a/src/doc/reference b/src/doc/reference
index d191a0cdd3b92..090c015f79396 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit d191a0cdd3b92648e0f1e53b13140a14677cc65b
+Subproject commit 090c015f7939665866432c334957bd536c811870
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index 580839d90aacd..e76be6b2dc84c 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit 580839d90aacd537f0293697096fa8355bc4e673
+Subproject commit e76be6b2dc84c6a992e186157efe29d625e29b94
diff --git a/src/tools/cargo b/src/tools/cargo
index 22f7dd0495cd7..fe0e5a48b75da 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 22f7dd0495cd72ce2082d318d5a9b4dccb9c5b8c
+Subproject commit fe0e5a48b75da2b405c8ce1ba2674e174ae11d5d

From 4a2094c9f61836214d9e37fa042761948483c2d9 Mon Sep 17 00:00:00 2001
From: Dario Gonzalez <dario.gonzalez@fortanix.com>
Date: Tue, 27 Aug 2019 15:44:11 -0700
Subject: [PATCH 482/943] address rebase changes

---
 src/librustdoc/core.rs     |  1 -
 src/librustdoc/markdown.rs |  3 ++-
 src/librustdoc/test.rs     | 20 +++++++++++---------
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 66a32c73e0f16..57b016a08c2fe 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -293,7 +293,6 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
         }
     }).collect();
 
-    let host_triple = TargetTriple::from_triple(config::host_triple());
     let crate_types = if proc_macro_crate {
         vec![config::CrateType::ProcMacro]
     } else {
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 67faec6bd3d0c..b06b368469fc1 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -143,7 +143,8 @@ pub fn test(mut options: Options, diag: &errors::Handler) -> i32 {
     opts.no_crate_inject = true;
     opts.display_warnings = options.display_warnings;
     let mut collector = Collector::new(options.input.display().to_string(), options.clone(),
-                                       true, opts, None, Some(options.input));
+                                       true, opts, None, Some(options.input),
+                                       options.enable_per_target_ignores);
     collector.set_position(DUMMY_SP);
     let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
 
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 840eeda9ad7ca..aefe4d3ea3f43 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -45,7 +45,7 @@ pub fn run(options: Options) -> i32 {
         vec![config::CrateType::Dylib]
     };
 
-    let mut sessopts = config::Options {
+    let sessopts = config::Options {
         maybe_sysroot: options.maybe_sysroot.clone(),
         search_paths: options.libs.clone(),
         crate_types,
@@ -84,6 +84,7 @@ pub fn run(options: Options) -> i32 {
 
         let mut opts = scrape_test_config(lower_to_hir.peek().0.borrow().krate());
         opts.display_warnings |= options.display_warnings;
+        let enable_per_target_ignores = options.enable_per_target_ignores;
         let mut collector = Collector::new(
             compiler.crate_name()?.peek().to_string(),
             options,
@@ -91,6 +92,7 @@ pub fn run(options: Options) -> i32 {
             opts,
             Some(compiler.source_map().clone()),
             None,
+            enable_per_target_ignores,
         );
 
         let mut global_ctxt = compiler.global_ctxt()?.take();
@@ -275,6 +277,7 @@ fn run_test(
     if no_run {
         compiler.arg("--emit=metadata");
     }
+    compiler.arg("--target").arg(target.to_string());
 
     compiler.arg("-");
     compiler.stdin(Stdio::piped());
@@ -616,6 +619,7 @@ pub struct Collector {
 
     options: Options,
     use_headers: bool,
+    enable_per_target_ignores: bool,
     cratename: String,
     opts: TestOptions,
     position: Span,
@@ -625,12 +629,14 @@ pub struct Collector {
 
 impl Collector {
     pub fn new(cratename: String, options: Options, use_headers: bool, opts: TestOptions,
-               source_map: Option<Lrc<SourceMap>>, filename: Option<PathBuf>,) -> Collector {
+               source_map: Option<Lrc<SourceMap>>, filename: Option<PathBuf>,
+               enable_per_target_ignores: bool) -> Collector {
         Collector {
             tests: Vec::new(),
             names: Vec::new(),
             options,
             use_headers,
+            enable_per_target_ignores,
             cratename,
             opts,
             position: DUMMY_SP,
@@ -674,13 +680,9 @@ impl Tester for Collector {
         let opts = self.opts.clone();
         let edition = config.edition.unwrap_or(self.options.edition.clone());
         let options = self.options.clone();
-        let maybe_sysroot = self.maybe_sysroot.clone();
-        let linker = self.linker.clone();
-        let edition = config.edition.unwrap_or(self.edition);
-        let persist_doctests = self.persist_doctests.clone();
-        let runtool = self.runtool.clone();
-        let runtool_args = self.runtool_args.clone();
-        let target = self.target.clone();
+        let runtool = self.options.runtool.clone();
+        let runtool_args = self.options.runtool_args.clone();
+        let target = self.options.target.clone();
         let target_str = target.to_string();
 
         debug!("creating test {}: {}", name, test);

From c86ea34639b0962858f053e900fe7c7de1008c5f Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 2 Sep 2019 14:23:41 -0400
Subject: [PATCH 483/943] Ensure all warnings are emitted even on warnings=warn

---
 src/bootstrap/bin/rustc.rs | 13 +++++++------
 src/bootstrap/bootstrap.py |  3 ++-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index 8cb48df14bfef..84415baa3a140 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -119,17 +119,18 @@ fn main() {
         cmd.arg(format!("-Cdebuginfo={}", debuginfo_level));
     }
 
-    if env::var_os("RUSTC_DENY_WARNINGS").is_some() &&
-       env::var_os("RUSTC_EXTERNAL_TOOL").is_none() {
+    if env::var_os("RUSTC_EXTERNAL_TOOL").is_none() {
         // When extending this list, add the new lints to the RUSTFLAGS of the
         // build_bootstrap function of src/bootstrap/bootstrap.py as well as
         // some code doesn't go through this `rustc` wrapper.
-        cmd.arg("-Dwarnings");
-        cmd.arg("-Drust_2018_idioms");
-        cmd.arg("-Dunused_lifetimes");
+        cmd.arg("-Wrust_2018_idioms");
+        cmd.arg("-Wunused_lifetimes");
         if use_internal_lints(crate_name) {
             cmd.arg("-Zunstable-options");
-            cmd.arg("-Drustc::internal");
+            cmd.arg("-Wrustc::internal");
+        }
+        if env::var_os("RUSTC_DENY_WARNINGS").is_some() {
+            cmd.arg("-Dwarnings");
         }
     }
 
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 4162fe1df5086..03f02ea217ddf 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -631,8 +631,9 @@ def build_bootstrap(self):
         target_linker = self.get_toml("linker", build_section)
         if target_linker is not None:
             env["RUSTFLAGS"] += "-C linker=" + target_linker + " "
+        env["RUSTFLAGS"] += " -Wrust_2018_idioms -Wunused_lifetimes "
         if self.get_toml("deny-warnings", "rust") != "false":
-            env["RUSTFLAGS"] += "-Dwarnings -Drust_2018_idioms -Dunused_lifetimes "
+            env["RUSTFLAGS"] += "-Dwarnings "
 
         env["PATH"] = os.path.join(self.bin_root(), "bin") + \
             os.pathsep + env["PATH"]

From fda251b966ec5a8d1c3c001242777861f15b95e2 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 2 Sep 2019 14:24:40 -0400
Subject: [PATCH 484/943] Rename --warnings=allow to --warnings=warn

We never allowed the warnings, only made them not denied.
---
 src/bootstrap/flags.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 828865f10ffba..d9580b598155e 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -36,7 +36,7 @@ pub struct Flags {
     // This overrides the deny-warnings configuation option,
     // which passes -Dwarnings to the compiler invocations.
     //
-    // true => deny, false => allow
+    // true => deny, false => warn
     pub deny_warnings: Option<bool>,
 }
 
@@ -556,10 +556,10 @@ fn split(s: &[String]) -> Vec<String> {
 fn parse_deny_warnings(matches: &getopts::Matches) -> Option<bool> {
     match matches.opt_str("warnings").as_ref().map(|v| v.as_str()) {
         Some("deny") => Some(true),
-        Some("allow") => Some(false),
+        Some("warn") => Some(false),
         Some(value) => {
             eprintln!(
-                r#"invalid value for --warnings: {:?}, expected "allow" or "deny""#,
+                r#"invalid value for --warnings: {:?}, expected "warn" or "deny""#,
                 value,
                 );
             process::exit(1);

From 843fba3ed18b9aa9e3f6a2bfa030e1df8179503b Mon Sep 17 00:00:00 2001
From: Vitaly _Vi Shukela <vi0oss@gmail.com>
Date: Mon, 22 Jul 2019 00:54:42 +0300
Subject: [PATCH 485/943] Stabilize checked_duration_since for 1.39.0

Resolves #58402.
---
 src/libstd/lib.rs  | 1 -
 src/libstd/time.rs | 6 ++----
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index c3882bacf87eb..71050b0dcd1f5 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -244,7 +244,6 @@
 #![feature(cfg_target_has_atomic)]
 #![feature(cfg_target_thread_local)]
 #![feature(char_error_internals)]
-#![feature(checked_duration_since)]
 #![feature(clamp)]
 #![feature(compiler_builtins_lib)]
 #![feature(concat_idents)]
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 98371b9ba3d7e..d59085cd44a6f 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -221,7 +221,6 @@ impl Instant {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(checked_duration_since)]
     /// use std::time::{Duration, Instant};
     /// use std::thread::sleep;
     ///
@@ -231,7 +230,7 @@ impl Instant {
     /// println!("{:?}", new_now.checked_duration_since(now));
     /// println!("{:?}", now.checked_duration_since(new_now)); // None
     /// ```
-    #[unstable(feature = "checked_duration_since", issue = "58402")]
+    #[stable(feature = "checked_duration_since", since = "1.39.0")]
     pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
         self.0.checked_sub_instant(&earlier.0)
     }
@@ -242,7 +241,6 @@ impl Instant {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(checked_duration_since)]
     /// use std::time::{Duration, Instant};
     /// use std::thread::sleep;
     ///
@@ -252,7 +250,7 @@ impl Instant {
     /// println!("{:?}", new_now.saturating_duration_since(now));
     /// println!("{:?}", now.saturating_duration_since(new_now)); // 0ns
     /// ```
-    #[unstable(feature = "checked_duration_since", issue = "58402")]
+    #[stable(feature = "checked_duration_since", since = "1.39.0")]
     pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
         self.checked_duration_since(earlier).unwrap_or(Duration::new(0, 0))
     }

From 5545582a6f6111872cdda54d18f43a7da24661f4 Mon Sep 17 00:00:00 2001
From: Vitaly _Vi Shukela <vi0oss@gmail.com>
Date: Thu, 5 Sep 2019 01:25:07 +0300
Subject: [PATCH 486/943] Avoid feature name 'checked_duration_since' in a Tidy
 test

---
 src/tools/tidy/src/features/tests.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/tools/tidy/src/features/tests.rs b/src/tools/tidy/src/features/tests.rs
index fa7a931ec865c..994523ac1abce 100644
--- a/src/tools/tidy/src/features/tests.rs
+++ b/src/tools/tidy/src/features/tests.rs
@@ -2,8 +2,8 @@ use super::*;
 
 #[test]
 fn test_find_attr_val() {
-    let s = r#"#[unstable(feature = "checked_duration_since", issue = "58402")]"#;
-    assert_eq!(find_attr_val(s, "feature"), Some("checked_duration_since"));
+    let s = r#"#[unstable(feature = "tidy_test_never_used_anywhere_else", issue = "58402")]"#;
+    assert_eq!(find_attr_val(s, "feature"), Some("tidy_test_never_used_anywhere_else"));
     assert_eq!(find_attr_val(s, "issue"), Some("58402"));
     assert_eq!(find_attr_val(s, "since"), None);
 }

From 53fe76479aab03b1fbe5b7184f45484886f769b1 Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Wed, 4 Sep 2019 16:02:31 -0700
Subject: [PATCH 487/943] Assume non-git LLVM is fresh if the stamp file exists

Rustbuild usually writes the LLVM submodule commit in a stamp file, so
we can avoid rebuilding it unnecessarily. However, for builds from a
source tarball (non-git), we were assuming a rebuild is always needed.
This can cause a lot of extra work if any environment like `CFLAGS`
changed between steps like build and install, which are often separate
in distro builds.

Now we also write an empty stamp file if the git commit is unknown, and
its presence is trusted to indicate that no rebuild is needed. An info
message reports that this is happening, along with the stamp file path
that can be deleted to force a rebuild anyway.
---
 src/bootstrap/native.rs | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index f02def3e1b05d..7bf9ea2688f4c 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -81,26 +81,29 @@ impl Step for Llvm {
             (info, "src/llvm-project/llvm", builder.llvm_out(target), dir.join("bin"))
         };
 
-        if !llvm_info.is_git() {
-            println!(
-                "git could not determine the LLVM submodule commit hash. \
-                Assuming that an LLVM build is necessary.",
-            );
-        }
-
         let build_llvm_config = llvm_config_ret_dir
             .join(exe("llvm-config", &*builder.config.build));
         let done_stamp = out_dir.join("llvm-finished-building");
 
-        if let Some(llvm_commit) = llvm_info.sha() {
-            if done_stamp.exists() {
+        if done_stamp.exists() {
+            if let Some(llvm_commit) = llvm_info.sha() {
                 let done_contents = t!(fs::read(&done_stamp));
 
                 // If LLVM was already built previously and the submodule's commit didn't change
                 // from the previous build, then no action is required.
                 if done_contents == llvm_commit.as_bytes() {
-                    return build_llvm_config
+                    return build_llvm_config;
                 }
+            } else {
+                builder.info(
+                    "Could not determine the LLVM submodule commit hash. \
+                     Assuming that an LLVM rebuild is not necessary.",
+                );
+                builder.info(&format!(
+                    "To force LLVM to rebuild, remove the file `{}`",
+                    done_stamp.display()
+                ));
+                return build_llvm_config;
             }
         }
 
@@ -303,9 +306,7 @@ impl Step for Llvm {
 
         cfg.build();
 
-        if let Some(llvm_commit) = llvm_info.sha() {
-            t!(fs::write(&done_stamp, llvm_commit));
-        }
+        t!(fs::write(&done_stamp, llvm_info.sha().unwrap_or("")));
 
         build_llvm_config
     }

From 290f5b22752f98071bbc25530fc10a7169e671a3 Mon Sep 17 00:00:00 2001
From: Taylor Cramer <cramertj@google.com>
Date: Wed, 4 Sep 2019 12:14:34 -0700
Subject: [PATCH 488/943] Use backtrace formatting from the backtrace crate

---
 Cargo.lock                         |   4 +-
 src/libstd/Cargo.toml              |   2 +-
 src/libstd/panicking.rs            |   8 +-
 src/libstd/sys_common/backtrace.rs | 235 +++++++++++------------------
 4 files changed, 96 insertions(+), 153 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index e0d30647809a9..db83aacc69e45 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -109,9 +109,9 @@ dependencies = [
 
 [[package]]
 name = "backtrace"
-version = "0.3.35"
+version = "0.3.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1371048253fa3bac6704bfd6bbfc922ee9bdcee8881330d40f308b81cc5adc55"
+checksum = "5180c5a20655b14a819b652fd2378fa5f1697b6c9ddad3e695c2f9cedf6df4e2"
 dependencies = [
  "backtrace-sys",
  "cfg-if",
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 157faa0af9bca..02a54e9fa72c6 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -26,7 +26,7 @@ unwind = { path = "../libunwind" }
 hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] }
 
 [dependencies.backtrace]
-version = "0.3.35"
+version = "0.3.37"
 default-features = false # don't use coresymbolication on OSX
 features = [
   "rustc-dep-of-std", # enable build support for integrating into libstd
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 952fd9ebfdf07..db4089c294812 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -158,7 +158,7 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> {
 
 fn default_hook(info: &PanicInfo<'_>) {
     #[cfg(feature = "backtrace")]
-    use crate::sys_common::backtrace;
+    use crate::sys_common::{backtrace as backtrace_mod};
 
     // If this is a double panic, make sure that we print a backtrace
     // for this panic. Otherwise only print it if logging is enabled.
@@ -167,9 +167,9 @@ fn default_hook(info: &PanicInfo<'_>) {
         let panics = update_panic_count(0);
 
         if panics >= 2 {
-            Some(backtrace::PrintFormat::Full)
+            Some(backtrace::PrintFmt::Full)
         } else {
-            backtrace::log_enabled()
+            backtrace_mod::log_enabled()
         }
     };
 
@@ -197,7 +197,7 @@ fn default_hook(info: &PanicInfo<'_>) {
             static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
 
             if let Some(format) = log_backtrace {
-                let _ = backtrace::print(err, format);
+                let _ = backtrace_mod::print(err, format);
             } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) {
                 let _ = writeln!(err, "note: run with `RUST_BACKTRACE=1` \
                                        environment variable to display a backtrace.");
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index bf37ff7ddbd3a..f434b62aced67 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -2,23 +2,20 @@
 /// supported platforms.
 
 use crate::env;
+use crate::fmt;
 use crate::io;
 use crate::io::prelude::*;
-use crate::mem;
 use crate::path::{self, Path};
-use crate::ptr;
 use crate::sync::atomic::{self, Ordering};
 use crate::sys::mutex::Mutex;
 
-use backtrace::{BytesOrWideString, Frame, Symbol};
-
-pub const HEX_WIDTH: usize = 2 + 2 * mem::size_of::<usize>();
+use backtrace::{BacktraceFmt, BytesOrWideString, PrintFmt};
 
 /// Max number of frames to print.
 const MAX_NB_FRAMES: usize = 100;
 
 /// Prints the current backtrace.
-pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
+pub fn print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
     static LOCK: Mutex = Mutex::new();
 
     // There are issues currently linking libbacktrace into tests, and in
@@ -39,26 +36,66 @@ pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
     }
 }
 
-fn _print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
-    writeln!(w, "stack backtrace:")?;
+fn _print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
+    struct DisplayBacktrace {
+        format: PrintFmt,
+    }
+    impl fmt::Display for DisplayBacktrace {
+        fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+            _print_fmt(fmt, self.format)
+        }
+    }
+    write!(w, "{}", DisplayBacktrace { format })
+}
 
-    let mut printer = Printer::new(format, w);
+fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::Result {
+    let mut print_path = move |fmt: &mut fmt::Formatter<'_>, bows: BytesOrWideString<'_>| {
+        output_filename(fmt, bows, print_fmt)
+    };
+    let mut bt_fmt = BacktraceFmt::new(fmt, print_fmt, &mut print_path);
+    bt_fmt.add_context()?;
+    let mut skipped = false;
     unsafe {
+        let mut idx = 0;
+        let mut res = Ok(());
         backtrace::trace_unsynchronized(|frame| {
+            if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {
+                skipped = true;
+                return false;
+            }
+
             let mut hit = false;
+            let mut stop = false;
             backtrace::resolve_frame_unsynchronized(frame, |symbol| {
                 hit = true;
-                printer.output(frame, Some(symbol));
+                if print_fmt == PrintFmt::Short {
+                    if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
+                        if sym.contains("__rust_begin_short_backtrace") {
+                            skipped = true;
+                            stop = true;
+                            return;
+                        }
+                    }
+                }
+
+                res = bt_fmt.frame().symbol(frame, symbol);
             });
+            if stop {
+                return false;
+            }
             if !hit {
-                printer.output(frame, None);
+                res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
             }
-            !printer.done
+
+            idx += 1;
+            res.is_ok()
         });
+        res?;
     }
-    if printer.skipped {
+    bt_fmt.finish()?;
+    if skipped {
         writeln!(
-            w,
+            fmt,
             "note: Some details are omitted, \
              run with `RUST_BACKTRACE=full` for a verbose backtrace."
         )?;
@@ -77,33 +114,24 @@ where
     f()
 }
 
-/// Controls how the backtrace should be formatted.
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
-pub enum PrintFormat {
-    /// Show only relevant data from the backtrace.
-    Short = 2,
-    /// Show all the frames with absolute path for files.
-    Full = 3,
-}
-
 // For now logging is turned off by default, and this function checks to see
 // whether the magical environment variable is present to see if it's turned on.
-pub fn log_enabled() -> Option<PrintFormat> {
+pub fn log_enabled() -> Option<PrintFmt> {
     static ENABLED: atomic::AtomicIsize = atomic::AtomicIsize::new(0);
     match ENABLED.load(Ordering::SeqCst) {
         0 => {}
         1 => return None,
-        2 => return Some(PrintFormat::Short),
-        _ => return Some(PrintFormat::Full),
+        2 => return Some(PrintFmt::Short),
+        _ => return Some(PrintFmt::Full),
     }
 
     let val = env::var_os("RUST_BACKTRACE").and_then(|x| {
         if &x == "0" {
             None
         } else if &x == "full" {
-            Some(PrintFormat::Full)
+            Some(PrintFmt::Full)
         } else {
-            Some(PrintFormat::Short)
+            Some(PrintFmt::Short)
         }
     });
     ENABLED.store(
@@ -116,130 +144,45 @@ pub fn log_enabled() -> Option<PrintFormat> {
     val
 }
 
-struct Printer<'a, 'b> {
-    format: PrintFormat,
-    done: bool,
-    skipped: bool,
-    idx: usize,
-    out: &'a mut (dyn Write + 'b),
-}
-
-impl<'a, 'b> Printer<'a, 'b> {
-    fn new(format: PrintFormat, out: &'a mut (dyn Write + 'b)) -> Printer<'a, 'b> {
-        Printer { format, done: false, skipped: false, idx: 0, out }
-    }
-
-    /// Prints the symbol of the backtrace frame.
-    ///
-    /// These output functions should now be used everywhere to ensure consistency.
-    /// You may want to also use `output_fileline`.
-    fn output(&mut self, frame: &Frame, symbol: Option<&Symbol>) {
-        if self.idx > MAX_NB_FRAMES {
-            self.done = true;
-            self.skipped = true;
-            return;
-        }
-        if self._output(frame, symbol).is_err() {
-            self.done = true;
-        }
-        self.idx += 1;
-    }
-
-    fn _output(&mut self, frame: &Frame, symbol: Option<&Symbol>) -> io::Result<()> {
-        if self.format == PrintFormat::Short {
-            if let Some(sym) = symbol.and_then(|s| s.name()).and_then(|s| s.as_str()) {
-                if sym.contains("__rust_begin_short_backtrace") {
-                    self.skipped = true;
-                    self.done = true;
-                    return Ok(());
-                }
-            }
-
-            // Remove the `17: 0x0 - <unknown>` line.
-            if self.format == PrintFormat::Short && frame.ip() == ptr::null_mut() {
-                self.skipped = true;
-                return Ok(());
-            }
-        }
-
-        match self.format {
-            PrintFormat::Full => {
-                write!(self.out, "  {:2}: {:2$?} - ", self.idx, frame.ip(), HEX_WIDTH)?
-            }
-            PrintFormat::Short => write!(self.out, "  {:2}: ", self.idx)?,
-        }
-
-        match symbol.and_then(|s| s.name()) {
-            Some(symbol) => {
-                match self.format {
-                    PrintFormat::Full => write!(self.out, "{}", symbol)?,
-                    // Strip the trailing hash if short mode.
-                    PrintFormat::Short => write!(self.out, "{:#}", symbol)?,
-                }
-            }
-            None => self.out.write_all(b"<unknown>")?,
+/// Prints the filename of the backtrace frame.
+///
+/// See also `output`.
+fn output_filename(
+    fmt: &mut fmt::Formatter<'_>,
+    bows: BytesOrWideString<'_>,
+    print_fmt: PrintFmt,
+) -> fmt::Result {
+    #[cfg(windows)]
+    let path_buf;
+    let file = match bows {
+        #[cfg(unix)]
+        BytesOrWideString::Bytes(bytes) => {
+            use crate::os::unix::prelude::*;
+            Path::new(crate::ffi::OsStr::from_bytes(bytes))
         }
-        self.out.write_all(b"\n")?;
-        if let Some(sym) = symbol {
-            self.output_fileline(sym)?;
+        #[cfg(not(unix))]
+        BytesOrWideString::Bytes(bytes) => {
+            Path::new(crate::str::from_utf8(bytes).unwrap_or("<unknown>"))
         }
-        Ok(())
-    }
-
-    /// Prints the filename and line number of the backtrace frame.
-    ///
-    /// See also `output`.
-    fn output_fileline(&mut self, symbol: &Symbol) -> io::Result<()> {
         #[cfg(windows)]
-        let path_buf;
-        let file = match symbol.filename_raw() {
-            #[cfg(unix)]
-            Some(BytesOrWideString::Bytes(bytes)) => {
-                use crate::os::unix::prelude::*;
-                Path::new(crate::ffi::OsStr::from_bytes(bytes))
-            }
-            #[cfg(not(unix))]
-            Some(BytesOrWideString::Bytes(bytes)) => {
-                Path::new(crate::str::from_utf8(bytes).unwrap_or("<unknown>"))
-            }
-            #[cfg(windows)]
-            Some(BytesOrWideString::Wide(wide)) => {
-                use crate::os::windows::prelude::*;
-                path_buf = crate::ffi::OsString::from_wide(wide);
-                Path::new(&path_buf)
-            }
-            #[cfg(not(windows))]
-            Some(BytesOrWideString::Wide(_wide)) => {
-                Path::new("<unknown>")
-            }
-            None => return Ok(()),
-        };
-        let line = match symbol.lineno() {
-            Some(line) => line,
-            None => return Ok(()),
-        };
-        // prior line: "  ##: {:2$} - func"
-        self.out.write_all(b"")?;
-        match self.format {
-            PrintFormat::Full => write!(self.out, "           {:1$}", "", HEX_WIDTH)?,
-            PrintFormat::Short => write!(self.out, "           ")?,
+        BytesOrWideString::Wide(wide) => {
+            use crate::os::windows::prelude::*;
+            path_buf = crate::ffi::OsString::from_wide(wide);
+            Path::new(&path_buf)
         }
-
-        let mut already_printed = false;
-        if self.format == PrintFormat::Short && file.is_absolute() {
-            if let Ok(cwd) = env::current_dir() {
-                if let Ok(stripped) = file.strip_prefix(&cwd) {
-                    if let Some(s) = stripped.to_str() {
-                        write!(self.out, "  at .{}{}:{}", path::MAIN_SEPARATOR, s, line)?;
-                        already_printed = true;
-                    }
+        #[cfg(not(windows))]
+        BytesOrWideString::Wide(_wide) => {
+            Path::new("<unknown>")
+        }
+    };
+    if print_fmt == PrintFmt::Short && file.is_absolute() {
+        if let Ok(cwd) = env::current_dir() {
+            if let Ok(stripped) = file.strip_prefix(&cwd) {
+                if let Some(s) = stripped.to_str() {
+                    return write!(fmt, ".{}{}", path::MAIN_SEPARATOR, s);
                 }
             }
         }
-        if !already_printed {
-            write!(self.out, "  at {}:{}", file.display(), line)?;
-        }
-
-        self.out.write_all(b"\n")
     }
+    fmt::Display::fmt(&file.display(), fmt)
 }

From 21e7e3f1e903f6d6f2e6eacbbe5848fcd894db9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 4 Sep 2019 19:04:26 -0700
Subject: [PATCH 489/943] Point at variant on pattern field count mismatch

---
 src/librustc_typeck/check/pat.rs                      | 2 ++
 src/test/ui/error-codes/E0023.stderr                  | 9 +++++++++
 src/test/ui/match/match-pattern-field-mismatch.stderr | 3 +++
 src/test/ui/pattern/pat-tuple-overfield.stderr        | 6 ++++++
 src/test/ui/pattern/pattern-error-continue.stderr     | 3 +++
 5 files changed, 23 insertions(+)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 4cf0df308fb4c..9a3f5e9e1b5d8 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -677,12 +677,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         } else {
             let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
             let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
+            let span = tcx.def_span(res.def_id());
             struct_span_err!(tcx.sess, pat.span, E0023,
                              "this pattern has {} field{}, but the corresponding {} has {} field{}",
                              subpats.len(), subpats_ending, res.descr(),
                              variant.fields.len(),  fields_ending)
                 .span_label(pat.span, format!("expected {} field{}, found {}",
                                               variant.fields.len(), fields_ending, subpats.len()))
+                .span_label(span, format!("{} defined here", res.descr()))
                 .emit();
             on_error();
             return tcx.types.err;
diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr
index 1bc90a995fe30..d04e494c2585c 100644
--- a/src/test/ui/error-codes/E0023.stderr
+++ b/src/test/ui/error-codes/E0023.stderr
@@ -1,18 +1,27 @@
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
   --> $DIR/E0023.rs:10:9
    |
+LL |     Apple(String, String),
+   |     --------------------- tuple variant defined here
+...
 LL |         Fruit::Apple(a) => {},
    |         ^^^^^^^^^^^^^^^ expected 2 fields, found 1
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
   --> $DIR/E0023.rs:11:9
    |
+LL |     Apple(String, String),
+   |     --------------------- tuple variant defined here
+...
 LL |         Fruit::Apple(a, b, c) => {},
    |         ^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
   --> $DIR/E0023.rs:12:9
    |
+LL |     Pear(u32),
+   |     --------- tuple variant defined here
+...
 LL |         Fruit::Pear(1, 2) => {},
    |         ^^^^^^^^^^^^^^^^^ expected 1 field, found 2
 
diff --git a/src/test/ui/match/match-pattern-field-mismatch.stderr b/src/test/ui/match/match-pattern-field-mismatch.stderr
index 663cd2cd24d56..c2298d6fbbf02 100644
--- a/src/test/ui/match/match-pattern-field-mismatch.stderr
+++ b/src/test/ui/match/match-pattern-field-mismatch.stderr
@@ -1,6 +1,9 @@
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields
   --> $DIR/match-pattern-field-mismatch.rs:10:11
    |
+LL |         Rgb(usize, usize, usize),
+   |         ------------------------ tuple variant defined here
+...
 LL |           Color::Rgb(_, _) => { }
    |           ^^^^^^^^^^^^^^^^ expected 3 fields, found 2
 
diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr
index 0430897510b85..e64b6efb08da8 100644
--- a/src/test/ui/pattern/pat-tuple-overfield.stderr
+++ b/src/test/ui/pattern/pat-tuple-overfield.stderr
@@ -19,12 +19,18 @@ LL |         (1, 2, .., 3, 4) => {}
 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
   --> $DIR/pat-tuple-overfield.rs:10:9
    |
+LL | struct S(u8, u8, u8);
+   | --------------------- tuple struct defined here
+...
 LL |         S(1, 2, 3, 4) => {}
    |         ^^^^^^^^^^^^^ expected 3 fields, found 4
 
 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
   --> $DIR/pat-tuple-overfield.rs:12:9
    |
+LL | struct S(u8, u8, u8);
+   | --------------------- tuple struct defined here
+...
 LL |         S(1, 2, .., 3, 4) => {}
    |         ^^^^^^^^^^^^^^^^^ expected 3 fields, found 4
 
diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr
index a581f07496e6c..4fbc630644baa 100644
--- a/src/test/ui/pattern/pattern-error-continue.stderr
+++ b/src/test/ui/pattern/pattern-error-continue.stderr
@@ -15,6 +15,9 @@ LL |         A::D(_) => (),
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
   --> $DIR/pattern-error-continue.rs:17:9
    |
+LL |     B(isize, isize),
+   |     --------------- tuple variant defined here
+...
 LL |         A::B(_, _, _) => (),
    |         ^^^^^^^^^^^^^ expected 2 fields, found 3
 

From 9483db5052415464fcb59ab480479afdd35710a5 Mon Sep 17 00:00:00 2001
From: Giles Cope <gilescope@gmail.com>
Date: Thu, 5 Sep 2019 00:08:52 +0100
Subject: [PATCH 490/943] Opaque type locations in error message for clarity.

---
 src/librustc/infer/error_reporting/mod.rs        | 11 +++++++++--
 src/test/ui/suggestions/opaque-type-error.stderr |  4 ++--
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 9be73cf3c6d16..fdadda92010a5 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1136,12 +1136,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         if let Some((expected, found)) = expected_found {
             match (terr, is_simple_error, expected == found) {
                 (&TypeError::Sorts(ref values), false, true) => {
+                    let sort_string = | a_type: Ty<'tcx> |
+                        if let ty::Opaque(def_id, _) = a_type.sty {
+                            format!(" (opaque type at {})", self.tcx.sess.source_map()
+                                .mk_substr_filename(self.tcx.def_span(def_id)))
+                        } else {
+                            format!(" ({})", a_type.sort_string(self.tcx))
+                        };
                     diag.note_expected_found_extra(
                         &"type",
                         expected,
                         found,
-                        &format!(" ({})", values.expected.sort_string(self.tcx)),
-                        &format!(" ({})", values.found.sort_string(self.tcx)),
+                        &sort_string(values.expected),
+                        &sort_string(values.found),
                     );
                 }
                 (_, false, _) => {
diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr
index 3c9ea05aeceb2..450cbd4799fdc 100644
--- a/src/test/ui/suggestions/opaque-type-error.stderr
+++ b/src/test/ui/suggestions/opaque-type-error.stderr
@@ -10,8 +10,8 @@ LL | |         thing_two()
 LL | |     }.await
    | |_____- if and else have incompatible types
    |
-   = note: expected type `impl std::future::Future` (opaque type)
-              found type `impl std::future::Future` (opaque type)
+   = note: expected type `impl std::future::Future` (opaque type at <$DIR/opaque-type-error.rs:8:19>)
+              found type `impl std::future::Future` (opaque type at <$DIR/opaque-type-error.rs:12:19>)
    = note: distinct uses of `impl Trait` result in different opaque types
    = help: if both `Future`s have the same `Output` type, consider `.await`ing on both of them
 

From af06bfb84c47add51a41153f6f71fc07d4c60a8d Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 07:20:54 +0200
Subject: [PATCH 491/943] resolve: extract `resolve_params`.

---
 src/librustc_resolve/late.rs | 35 +++++++++++++++--------------------
 1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index e15d02a9f7ec7..4595b1ff3f1cb 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -425,14 +425,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
         self.label_ribs.push(Rib::new(rib_kind));
 
         // Add each argument to the rib.
-        let mut bindings_list = FxHashMap::default();
-        for argument in &declaration.inputs {
-            self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
-
-            self.visit_ty(&argument.ty);
+        self.resolve_params(&declaration.inputs);
 
-            debug!("(resolving function) recorded argument");
-        }
         visit::walk_fn_ret_ty(self, &declaration.output);
 
         // Resolve the function body, potentially inside the body of an async closure
@@ -1135,6 +1129,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         }
     }
 
+    fn resolve_params(&mut self, params: &[Arg]) {
+        let mut bindings_list = FxHashMap::default();
+        for param in params {
+            self.resolve_pattern(&param.pat, PatternSource::FnParam, &mut bindings_list);
+            self.visit_ty(&param.ty);
+            debug!("(resolving function / closure) recorded parameter");
+        }
+    }
+
     fn resolve_local(&mut self, local: &Local) {
         // Resolve the type.
         walk_list!(self, visit_ty, &local.ty);
@@ -1860,20 +1863,12 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             // `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to
             // resolve the arguments within the proper scopes so that usages of them inside the
             // closure are detected as upvars rather than normal closure arg usages.
-            ExprKind::Closure(
-                _, IsAsync::Async { .. }, _,
-                ref fn_decl, ref body, _span,
-            ) => {
-                let rib_kind = NormalRibKind;
-                self.ribs[ValueNS].push(Rib::new(rib_kind));
+            ExprKind::Closure(_, IsAsync::Async { .. }, _, ref fn_decl, ref body, _span) => {
+                self.ribs[ValueNS].push(Rib::new(NormalRibKind));
                 // Resolve arguments:
-                let mut bindings_list = FxHashMap::default();
-                for argument in &fn_decl.inputs {
-                    self.resolve_pattern(&argument.pat, PatternSource::FnParam, &mut bindings_list);
-                    self.visit_ty(&argument.ty);
-                }
-                // No need to resolve return type-- the outer closure return type is
-                // FunctionRetTy::Default
+                self.resolve_params(&fn_decl.inputs);
+                // No need to resolve return type --
+                // the outer closure return type is `FunctionRetTy::Default`.
 
                 // Now resolve the inner closure
                 {

From f8835eeaf898430dcf056791a210facfc60e9980 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 08:48:10 +0200
Subject: [PATCH 492/943] resolve: cleanup using `with_rib`, etc.

---
 src/librustc_resolve/late.rs | 263 ++++++++++++++++-------------------
 1 file changed, 118 insertions(+), 145 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 4595b1ff3f1cb..5029d61d6e4e1 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -406,44 +406,32 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
             visit::walk_foreign_item(this, foreign_item);
         });
     }
-    fn visit_fn(&mut self,
-                function_kind: FnKind<'tcx>,
-                declaration: &'tcx FnDecl,
-                _: Span,
-                _: NodeId)
-    {
+    fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, _: Span, _: NodeId) {
         debug!("(resolving function) entering function");
-        let rib_kind = match function_kind {
+        let rib_kind = match fn_kind {
             FnKind::ItemFn(..) => FnItemRibKind,
             FnKind::Method(..) | FnKind::Closure(_) => NormalRibKind,
         };
 
         // Create a value rib for the function.
-        self.ribs[ValueNS].push(Rib::new(rib_kind));
-
-        // Create a label rib for the function.
-        self.label_ribs.push(Rib::new(rib_kind));
-
-        // Add each argument to the rib.
-        self.resolve_params(&declaration.inputs);
-
-        visit::walk_fn_ret_ty(self, &declaration.output);
-
-        // Resolve the function body, potentially inside the body of an async closure
-        match function_kind {
-            FnKind::ItemFn(.., body) |
-            FnKind::Method(.., body) => {
-                self.visit_block(body);
-            }
-            FnKind::Closure(body) => {
-                self.visit_expr(body);
-            }
-        };
-
-        debug!("(resolving function) leaving function");
-
-        self.label_ribs.pop();
-        self.ribs[ValueNS].pop();
+        self.with_rib(ValueNS, rib_kind, |this| {
+            // Create a label rib for the function.
+            this.with_label_rib(rib_kind, |this| {
+                // Add each argument to the rib.
+                this.resolve_params(&declaration.inputs);
+
+                visit::walk_fn_ret_ty(this, &declaration.output);
+
+                // Resolve the function body, potentially inside the body of an async closure
+                match fn_kind {
+                    FnKind::ItemFn(.., body) |
+                    FnKind::Method(.., body) => this.visit_block(body),
+                    FnKind::Closure(body) => this.visit_expr(body),
+                };
+
+                debug!("(resolving function) leaving function");
+            })
+        });
     }
 
     fn visit_generics(&mut self, generics: &'tcx Generics) {
@@ -522,13 +510,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         // although it may be useful to track other components as well for diagnostics.
         let graph_root = resolver.graph_root;
         let parent_scope = ParentScope::module(graph_root);
+        let start_rib_kind = ModuleRibKind(graph_root);
         LateResolutionVisitor {
             r: resolver,
             parent_scope,
             ribs: PerNS {
-                value_ns: vec![Rib::new(ModuleRibKind(graph_root))],
-                type_ns: vec![Rib::new(ModuleRibKind(graph_root))],
-                macro_ns: vec![Rib::new(ModuleRibKind(graph_root))],
+                value_ns: vec![Rib::new(start_rib_kind)],
+                type_ns: vec![Rib::new(start_rib_kind)],
+                macro_ns: vec![Rib::new(start_rib_kind)],
             },
             label_ribs: Vec::new(),
             current_trait_ref: None,
@@ -582,23 +571,32 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     // generate a fake "implementation scope" containing all the
     // implementations thus found, for compatibility with old resolve pass.
 
-    fn with_scope<F, T>(&mut self, id: NodeId, f: F) -> T
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T
-    {
+    /// Do some `work` within a new innermost rib of the given `kind` in the given namespace (`ns`).
+    fn with_rib<T>(
+        &mut self,
+        ns: Namespace,
+        kind: RibKind<'a>,
+        work: impl FnOnce(&mut Self) -> T,
+    ) -> T {
+        self.ribs[ns].push(Rib::new(kind));
+        let ret = work(self);
+        self.ribs[ns].pop();
+        ret
+    }
+
+    fn with_scope<T>(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T {
         let id = self.r.definitions.local_def_id(id);
         let module = self.r.module_map.get(&id).cloned(); // clones a reference
         if let Some(module) = module {
             // Move down in the graph.
             let orig_module = replace(&mut self.parent_scope.module, module);
-            self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module)));
-            self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module)));
-
-            let ret = f(self);
-
-            self.parent_scope.module = orig_module;
-            self.ribs[ValueNS].pop();
-            self.ribs[TypeNS].pop();
-            ret
+            self.with_rib(ValueNS, ModuleRibKind(module), |this| {
+                this.with_rib(TypeNS, ModuleRibKind(module), |this| {
+                    let ret = f(this);
+                    this.parent_scope.module = orig_module;
+                    ret
+                })
+            })
         } else {
             f(self)
         }
@@ -802,7 +800,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     }
 
     fn with_generic_param_rib<'c, F>(&'c mut self, generic_params: GenericParameters<'a, 'c>, f: F)
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>)
+        where F: FnOnce(&mut Self)
     {
         debug!("with_generic_param_rib");
         match generic_params {
@@ -888,38 +886,24 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         }
     }
 
-    fn with_label_rib<F>(&mut self, f: F)
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>)
-    {
-        self.label_ribs.push(Rib::new(NormalRibKind));
+    fn with_label_rib(&mut self, kind: RibKind<'a>, f: impl FnOnce(&mut Self)) {
+        self.label_ribs.push(Rib::new(kind));
         f(self);
         self.label_ribs.pop();
     }
 
-    fn with_item_rib<F>(&mut self, f: F)
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>)
-    {
-        self.ribs[ValueNS].push(Rib::new(ItemRibKind));
-        self.ribs[TypeNS].push(Rib::new(ItemRibKind));
-        f(self);
-        self.ribs[TypeNS].pop();
-        self.ribs[ValueNS].pop();
+    fn with_item_rib(&mut self, f: impl FnOnce(&mut Self)) {
+        self.with_rib(ValueNS, ItemRibKind, |this| this.with_rib(TypeNS, ItemRibKind, f))
     }
 
-    fn with_constant_rib<F>(&mut self, f: F)
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>)
-    {
+    fn with_constant_rib(&mut self, f: impl FnOnce(&mut Self)) {
         debug!("with_constant_rib");
-        self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind));
-        self.label_ribs.push(Rib::new(ConstantItemRibKind));
-        f(self);
-        self.label_ribs.pop();
-        self.ribs[ValueNS].pop();
+        self.with_rib(ValueNS, ConstantItemRibKind, |this| {
+            this.with_label_rib(ConstantItemRibKind, f);
+        });
     }
 
-    fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T
-    {
+    fn with_current_self_type<T>(&mut self, self_type: &Ty, f: impl FnOnce(&mut Self) -> T) -> T {
         // Handle nested impls (inside fn bodies)
         let previous_value = replace(&mut self.current_self_type, Some(self_type.clone()));
         let result = f(self);
@@ -927,9 +911,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         result
     }
 
-    fn with_current_self_item<T, F>(&mut self, self_item: &Item, f: F) -> T
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T
-    {
+    fn with_current_self_item<T>(&mut self, self_item: &Item, f: impl FnOnce(&mut Self) -> T) -> T {
         let previous_value = replace(&mut self.current_self_item, Some(self_item.id));
         let result = f(self);
         self.current_self_item = previous_value;
@@ -937,9 +919,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     }
 
     /// When evaluating a `trait` use its associated types' idents for suggestionsa in E0412.
-    fn with_trait_items<T, F>(&mut self, trait_items: &Vec<TraitItem>, f: F) -> T
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T
-    {
+    fn with_trait_items<T>(
+        &mut self,
+        trait_items: &Vec<TraitItem>,
+        f: impl FnOnce(&mut Self) -> T,
+    ) -> T {
         let trait_assoc_types = replace(
             &mut self.current_trait_assoc_types,
             trait_items.iter().filter_map(|item| match &item.node {
@@ -953,9 +937,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     }
 
     /// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`).
-    fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>, Option<DefId>) -> T
-    {
+    fn with_optional_trait_ref<T>(
+        &mut self,
+        opt_trait_ref: Option<&TraitRef>,
+        f: impl FnOnce(&mut Self, Option<DefId>) -> T
+    ) -> T {
         let mut new_val = None;
         let mut new_id = None;
         if let Some(trait_ref) = opt_trait_ref {
@@ -990,27 +976,18 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         result
     }
 
-    fn with_self_rib<F>(&mut self, self_res: Res, f: F)
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>)
-    {
+    fn with_self_rib_ns(&mut self, ns: Namespace, self_res: Res, f: impl FnOnce(&mut Self)) {
         let mut self_type_rib = Rib::new(NormalRibKind);
 
         // Plain insert (no renaming, since types are not currently hygienic)
         self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res);
-        self.ribs[TypeNS].push(self_type_rib);
+        self.ribs[ns].push(self_type_rib);
         f(self);
-        self.ribs[TypeNS].pop();
+        self.ribs[ns].pop();
     }
 
-    fn with_self_struct_ctor_rib<F>(&mut self, impl_id: DefId, f: F)
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>)
-    {
-        let self_res = Res::SelfCtor(impl_id);
-        let mut self_type_rib = Rib::new(NormalRibKind);
-        self_type_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), self_res);
-        self.ribs[ValueNS].push(self_type_rib);
-        f(self);
-        self.ribs[ValueNS].pop();
+    fn with_self_rib(&mut self, self_res: Res, f: impl FnOnce(&mut Self)) {
+        self.with_self_rib_ns(TypeNS, self_res, f)
     }
 
     fn resolve_implementation(&mut self,
@@ -1038,8 +1015,8 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                         this.visit_generics(generics);
                         // Resolve the items within the impl.
                         this.with_current_self_type(self_type, |this| {
-                            this.with_self_struct_ctor_rib(item_def_id, |this| {
-                                debug!("resolve_implementation with_self_struct_ctor_rib");
+                            this.with_self_rib_ns(ValueNS, Res::SelfCtor(item_def_id), |this| {
+                                debug!("resolve_implementation with_self_rib_ns(ValueNS, ...)");
                                 for impl_item in impl_items {
                                     // We also need a new scope for the impl item type parameters.
                                     let generic_params = HasGenericParams(&impl_item.generics,
@@ -1231,16 +1208,13 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     }
 
     fn resolve_arm(&mut self, arm: &Arm) {
-        self.ribs[ValueNS].push(Rib::new(NormalRibKind));
-
-        self.resolve_pats(&arm.pats, PatternSource::Match);
-
-        if let Some(ref expr) = arm.guard {
-            self.visit_expr(expr)
-        }
-        self.visit_expr(&arm.body);
-
-        self.ribs[ValueNS].pop();
+        self.with_rib(ValueNS, NormalRibKind, |this| {
+            this.resolve_pats(&arm.pats, PatternSource::Match);
+            if let Some(ref expr) = arm.guard {
+                this.visit_expr(expr)
+            }
+            this.visit_expr(&arm.body);
+        });
     }
 
     /// Arising from `source`, resolve a sequence of patterns (top level or-patterns).
@@ -1333,7 +1307,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                         pat_src == PatternSource::Let => {
                 // `Variant1(a) | Variant2(a)`, ok
                 // Reuse definition from the first `a`.
-                res = self.ribs[ValueNS].last_mut().unwrap().bindings[&ident];
+                res = self.innermost_rib_bindings(ValueNS)[&ident];
             }
             Some(..) => {
                 span_bug!(ident.span, "two bindings with the same name from \
@@ -1343,7 +1317,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 // A completely fresh binding, add to the lists if it's valid.
                 if ident.name != kw::Invalid {
                     bindings.insert(ident, outer_pat_id);
-                    self.ribs[ValueNS].last_mut().unwrap().bindings.insert(ident, res);
+                    self.innermost_rib_bindings(ValueNS).insert(ident, res);
                 }
             }
         }
@@ -1351,6 +1325,10 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         res
     }
 
+    fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut FxHashMap<Ident, Res> {
+        &mut self.ribs[ns].last_mut().unwrap().bindings
+    }
+
     fn resolve_pattern(&mut self,
                        pat: &Pat,
                        pat_src: PatternSource,
@@ -1726,12 +1704,10 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         Some(result)
     }
 
-    fn with_resolved_label<F>(&mut self, label: Option<Label>, id: NodeId, f: F)
-        where F: FnOnce(&mut LateResolutionVisitor<'_, '_>)
-    {
+    fn with_resolved_label(&mut self, label: Option<Label>, id: NodeId, f: impl FnOnce(&mut Self)) {
         if let Some(label) = label {
             self.unused_labels.insert(id, label.ident.span);
-            self.with_label_rib(|this| {
+            self.with_label_rib(NormalRibKind, |this| {
                 let ident = label.ident.modern_and_legacy();
                 this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
                 f(this);
@@ -1805,33 +1781,30 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             }
 
             ExprKind::If(ref cond, ref then, ref opt_else) => {
-                self.ribs[ValueNS].push(Rib::new(NormalRibKind));
-                self.visit_expr(cond);
-                self.visit_block(then);
-                self.ribs[ValueNS].pop();
-
+                self.with_rib(ValueNS, NormalRibKind, |this| {
+                    this.visit_expr(cond);
+                    this.visit_block(then);
+                });
                 opt_else.as_ref().map(|expr| self.visit_expr(expr));
             }
 
             ExprKind::Loop(ref block, label) => self.resolve_labeled_block(label, expr.id, &block),
 
-            ExprKind::While(ref subexpression, ref block, label) => {
+            ExprKind::While(ref cond, ref block, label) => {
                 self.with_resolved_label(label, expr.id, |this| {
-                    this.ribs[ValueNS].push(Rib::new(NormalRibKind));
-                    this.visit_expr(subexpression);
-                    this.visit_block(block);
-                    this.ribs[ValueNS].pop();
+                    this.with_rib(ValueNS, NormalRibKind, |this| {
+                        this.visit_expr(cond);
+                        this.visit_block(block);
+                    })
                 });
             }
 
-            ExprKind::ForLoop(ref pattern, ref subexpression, ref block, label) => {
-                self.visit_expr(subexpression);
-                self.ribs[ValueNS].push(Rib::new(NormalRibKind));
-                self.resolve_pattern(pattern, PatternSource::For, &mut FxHashMap::default());
-
-                self.resolve_labeled_block(label, expr.id, block);
-
-                self.ribs[ValueNS].pop();
+            ExprKind::ForLoop(ref pat, ref iter_expr, ref block, label) => {
+                self.visit_expr(iter_expr);
+                self.with_rib(ValueNS, NormalRibKind, |this| {
+                    this.resolve_pattern(pat, PatternSource::For, &mut FxHashMap::default());
+                    this.resolve_labeled_block(label, expr.id, block);
+                });
             }
 
             ExprKind::Block(ref block, label) => self.resolve_labeled_block(label, block.id, block),
@@ -1864,21 +1837,21 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             // resolve the arguments within the proper scopes so that usages of them inside the
             // closure are detected as upvars rather than normal closure arg usages.
             ExprKind::Closure(_, IsAsync::Async { .. }, _, ref fn_decl, ref body, _span) => {
-                self.ribs[ValueNS].push(Rib::new(NormalRibKind));
-                // Resolve arguments:
-                self.resolve_params(&fn_decl.inputs);
-                // No need to resolve return type --
-                // the outer closure return type is `FunctionRetTy::Default`.
-
-                // Now resolve the inner closure
-                {
-                    // No need to resolve arguments: the inner closure has none.
-                    // Resolve the return type:
-                    visit::walk_fn_ret_ty(self, &fn_decl.output);
-                    // Resolve the body
-                    self.visit_expr(body);
-                }
-                self.ribs[ValueNS].pop();
+                self.with_rib(ValueNS, NormalRibKind, |this| {
+                    // Resolve arguments:
+                    this.resolve_params(&fn_decl.inputs);
+                    // No need to resolve return type --
+                    // the outer closure return type is `FunctionRetTy::Default`.
+
+                    // Now resolve the inner closure
+                    {
+                        // No need to resolve arguments: the inner closure has none.
+                        // Resolve the return type:
+                        visit::walk_fn_ret_ty(this, &fn_decl.output);
+                        // Resolve the body
+                        this.visit_expr(body);
+                    }
+                });
             }
             _ => {
                 visit::walk_expr(self, expr);

From 6d537d4020f96588986a62d6f61d4779fd208f1a Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 08:51:41 +0200
Subject: [PATCH 493/943] resolve: simplify `resolve_arm`.

---
 src/librustc_resolve/late.rs | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 5029d61d6e4e1..82971094ae7b7 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -1210,9 +1210,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     fn resolve_arm(&mut self, arm: &Arm) {
         self.with_rib(ValueNS, NormalRibKind, |this| {
             this.resolve_pats(&arm.pats, PatternSource::Match);
-            if let Some(ref expr) = arm.guard {
-                this.visit_expr(expr)
-            }
+            walk_list!(this, visit_expr, &arm.guard);
             this.visit_expr(&arm.body);
         });
     }

From 219ddde26b151baf2046cf6d593ffc0dcd858f9b Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 10:10:10 +0200
Subject: [PATCH 494/943] resolve: extract `try_resolve_as_non_binding`.

---
 src/librustc_resolve/late.rs | 125 +++++++++++++++++++----------------
 src/librustc_resolve/lib.rs  |   1 +
 2 files changed, 69 insertions(+), 57 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 82971094ae7b7..20a12a4ae938e 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -9,7 +9,7 @@ use GenericParameters::*;
 use RibKind::*;
 
 use crate::{path_names_to_string, BindingError, CrateLint, LexicalScopeBinding};
-use crate::{Module, ModuleOrUniformRoot, NameBinding, NameBindingKind, ParentScope, PathResult};
+use crate::{Module, ModuleOrUniformRoot, NameBindingKind, ParentScope, PathResult};
 use crate::{ResolutionError, Resolver, Segment, UseError};
 
 use log::debug;
@@ -1327,78 +1327,37 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         &mut self.ribs[ns].last_mut().unwrap().bindings
     }
 
-    fn resolve_pattern(&mut self,
-                       pat: &Pat,
-                       pat_src: PatternSource,
-                       // Maps idents to the node ID for the
-                       // outermost pattern that binds them.
-                       bindings: &mut FxHashMap<Ident, NodeId>) {
+    fn resolve_pattern(
+        &mut self,
+        pat: &Pat,
+        pat_src: PatternSource,
+        // Maps idents to the node ID for the outermost pattern that binds them.
+        bindings: &mut FxHashMap<Ident, NodeId>,
+    ) {
         // Visit all direct subpatterns of this pattern.
         let outer_pat_id = pat.id;
         pat.walk(&mut |pat| {
             debug!("resolve_pattern pat={:?} node={:?}", pat, pat.node);
             match pat.node {
-                PatKind::Ident(bmode, ident, ref opt_pat) => {
-                    // First try to resolve the identifier as some existing
-                    // entity, then fall back to a fresh binding.
-                    let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS,
-                                                                      None, pat.span)
-                                      .and_then(LexicalScopeBinding::item);
-                    let res = binding.map(NameBinding::res).and_then(|res| {
-                        let is_syntactic_ambiguity = opt_pat.is_none() &&
-                            bmode == BindingMode::ByValue(Mutability::Immutable);
-                        match res {
-                            Res::Def(DefKind::Ctor(_, CtorKind::Const), _) |
-                            Res::Def(DefKind::Const, _) if is_syntactic_ambiguity => {
-                                // Disambiguate in favor of a unit struct/variant
-                                // or constant pattern.
-                                self.r.record_use(ident, ValueNS, binding.unwrap(), false);
-                                Some(res)
-                            }
-                            Res::Def(DefKind::Ctor(..), _)
-                            | Res::Def(DefKind::Const, _)
-                            | Res::Def(DefKind::Static, _) => {
-                                // This is unambiguously a fresh binding, either syntactically
-                                // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
-                                // to something unusable as a pattern (e.g., constructor function),
-                                // but we still conservatively report an error, see
-                                // issues/33118#issuecomment-233962221 for one reason why.
-                                self.r.report_error(
-                                    ident.span,
-                                    ResolutionError::BindingShadowsSomethingUnacceptable(
-                                        pat_src.descr(), ident.name, binding.unwrap())
-                                );
-                                None
-                            }
-                            Res::Def(DefKind::Fn, _) | Res::Err => {
-                                // These entities are explicitly allowed
-                                // to be shadowed by fresh bindings.
-                                None
-                            }
-                            res => {
-                                span_bug!(ident.span, "unexpected resolution for an \
-                                                       identifier in pattern: {:?}", res);
-                            }
-                        }
-                    }).unwrap_or_else(|| {
-                        self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
-                    });
-
+                PatKind::Ident(bmode, ident, ref sub) => {
+                    // First try to resolve the identifier as some existing entity,
+                    // then fall back to a fresh binding.
+                    let has_sub = sub.is_some();
+                    let res = self.try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub)
+                        .unwrap_or_else(|| {
+                            self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
+                        });
                     self.r.record_partial_res(pat.id, PartialRes::new(res));
                 }
-
                 PatKind::TupleStruct(ref path, ..) => {
                     self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct);
                 }
-
                 PatKind::Path(ref qself, ref path) => {
                     self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat);
                 }
-
                 PatKind::Struct(ref path, ..) => {
                     self.smart_resolve_path(pat.id, None, path, PathSource::Struct);
                 }
-
                 _ => {}
             }
             true
@@ -1407,6 +1366,58 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         visit::walk_pat(self, pat);
     }
 
+    fn try_resolve_as_non_binding(
+        &mut self,
+        pat_src: PatternSource,
+        pat: &Pat,
+        bm: BindingMode,
+        ident: Ident,
+        has_sub: bool,
+    ) -> Option<Res> {
+        let binding = self.resolve_ident_in_lexical_scope(ident, ValueNS, None, pat.span)?.item()?;
+        let res = binding.res();
+
+        // An immutable (no `mut`) by-value (no `ref`) binding pattern without
+        // a sub pattern (no `@ $pat`) is syntactically ambiguous as it could
+        // also be interpreted as a path to e.g. a constant, variant, etc.
+        let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Immutable);
+
+        match res {
+            Res::Def(DefKind::Ctor(_, CtorKind::Const), _) |
+            Res::Def(DefKind::Const, _) if is_syntactic_ambiguity => {
+                // Disambiguate in favor of a unit struct/variant or constant pattern.
+                self.r.record_use(ident, ValueNS, binding, false);
+                Some(res)
+            }
+            Res::Def(DefKind::Ctor(..), _)
+            | Res::Def(DefKind::Const, _)
+            | Res::Def(DefKind::Static, _) => {
+                // This is unambiguously a fresh binding, either syntactically
+                // (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
+                // to something unusable as a pattern (e.g., constructor function),
+                // but we still conservatively report an error, see
+                // issues/33118#issuecomment-233962221 for one reason why.
+                self.r.report_error(
+                    ident.span,
+                    ResolutionError::BindingShadowsSomethingUnacceptable(
+                        pat_src.descr(),
+                        ident.name,
+                        binding,
+                    ),
+                );
+                None
+            }
+            Res::Def(DefKind::Fn, _) | Res::Err => {
+                // These entities are explicitly allowed to be shadowed by fresh bindings.
+                None
+            }
+            res => {
+                span_bug!(ident.span, "unexpected resolution for an \
+                                        identifier in pattern: {:?}", res);
+            }
+        }
+    }
+
     // High-level and context dependent path resolution routine.
     // Resolves the path and records the resolution into definition map.
     // If resolution fails tries several techniques to find likely
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 875ae449d94e0..9b92bb7698aaa 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -9,6 +9,7 @@
 
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
+#![feature(inner_deref)]
 #![feature(crate_visibility_modifier)]
 #![feature(label_break_value)]
 #![feature(mem_take)]

From f343e84f402fa25e45f29606398fb50d69a9a07e Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 10:18:23 +0200
Subject: [PATCH 495/943] resolve: add `type IdentMap<T>` alias.

---
 src/librustc_resolve/late.rs | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 20a12a4ae938e..29264b3eedce1 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -35,8 +35,10 @@ mod diagnostics;
 
 type Res = def::Res<NodeId>;
 
+type IdentMap<T> = FxHashMap<Ident, T>;
+
 /// Map from the name in a pattern to its binding mode.
-type BindingMap = FxHashMap<Ident, BindingInfo>;
+type BindingMap = IdentMap<BindingInfo>;
 
 #[derive(Copy, Clone, Debug)]
 struct BindingInfo {
@@ -143,7 +145,7 @@ impl RibKind<'_> {
 /// resolving, the name is looked up from inside out.
 #[derive(Debug)]
 crate struct Rib<'a, R = Res> {
-    pub bindings: FxHashMap<Ident, R>,
+    pub bindings: IdentMap<R>,
     pub kind: RibKind<'a>,
 }
 
@@ -1275,7 +1277,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                      pat_id: NodeId,
                      outer_pat_id: NodeId,
                      pat_src: PatternSource,
-                     bindings: &mut FxHashMap<Ident, NodeId>)
+                     bindings: &mut IdentMap<NodeId>)
                      -> Res {
         // Add the binding to the local ribs, if it
         // doesn't already exist in the bindings map. (We
@@ -1323,7 +1325,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         res
     }
 
-    fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut FxHashMap<Ident, Res> {
+    fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut IdentMap<Res> {
         &mut self.ribs[ns].last_mut().unwrap().bindings
     }
 
@@ -1332,7 +1334,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         pat: &Pat,
         pat_src: PatternSource,
         // Maps idents to the node ID for the outermost pattern that binds them.
-        bindings: &mut FxHashMap<Ident, NodeId>,
+        bindings: &mut IdentMap<NodeId>,
     ) {
         // Visit all direct subpatterns of this pattern.
         let outer_pat_id = pat.id;

From fd3b44184650b12ce30900e49e4d3ecb462ea540 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 10:27:40 +0200
Subject: [PATCH 496/943] resolve: move `fresh_binding`.

---
 src/librustc_resolve/late.rs | 107 +++++++++++++++++------------------
 1 file changed, 52 insertions(+), 55 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 29264b3eedce1..1b550bd7b0f56 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -1272,18 +1272,56 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         debug!("(resolving block) leaving block");
     }
 
-    fn fresh_binding(&mut self,
-                     ident: Ident,
-                     pat_id: NodeId,
-                     outer_pat_id: NodeId,
-                     pat_src: PatternSource,
-                     bindings: &mut IdentMap<NodeId>)
-                     -> Res {
-        // Add the binding to the local ribs, if it
-        // doesn't already exist in the bindings map. (We
-        // must not add it if it's in the bindings map
-        // because that breaks the assumptions later
-        // passes make about or-patterns.)
+    fn resolve_pattern(
+        &mut self,
+        pat: &Pat,
+        pat_src: PatternSource,
+        // Maps idents to the node ID for the outermost pattern that binds them.
+        bindings: &mut IdentMap<NodeId>,
+    ) {
+        // Visit all direct subpatterns of this pattern.
+        let outer_pat_id = pat.id;
+        pat.walk(&mut |pat| {
+            debug!("resolve_pattern pat={:?} node={:?}", pat, pat.node);
+            match pat.node {
+                PatKind::Ident(bmode, ident, ref sub) => {
+                    // First try to resolve the identifier as some existing entity,
+                    // then fall back to a fresh binding.
+                    let has_sub = sub.is_some();
+                    let res = self.try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub)
+                        .unwrap_or_else(|| {
+                            self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
+                        });
+                    self.r.record_partial_res(pat.id, PartialRes::new(res));
+                }
+                PatKind::TupleStruct(ref path, ..) => {
+                    self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct);
+                }
+                PatKind::Path(ref qself, ref path) => {
+                    self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat);
+                }
+                PatKind::Struct(ref path, ..) => {
+                    self.smart_resolve_path(pat.id, None, path, PathSource::Struct);
+                }
+                _ => {}
+            }
+            true
+        });
+
+        visit::walk_pat(self, pat);
+    }
+
+    fn fresh_binding(
+        &mut self,
+        ident: Ident,
+        pat_id: NodeId,
+        outer_pat_id: NodeId,
+        pat_src: PatternSource,
+        bindings: &mut IdentMap<NodeId>,
+    ) -> Res {
+        // Add the binding to the local ribs, if it doesn't already exist in the bindings map.
+        // (We must not add it if it's in the bindings map because that breaks the assumptions
+        // later passes make about or-patterns.)
         let ident = ident.modern_and_legacy();
         let mut res = Res::Local(pat_id);
         match bindings.get(&ident).cloned() {
@@ -1291,16 +1329,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 // `Variant(a, a)`, error
                 self.r.report_error(
                     ident.span,
-                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
-                        &ident.as_str())
+                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(&ident.as_str()),
                 );
             }
             Some(..) if pat_src == PatternSource::FnParam => {
                 // `fn f(a: u8, a: u8)`, error
                 self.r.report_error(
                     ident.span,
-                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
-                        &ident.as_str())
+                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(&ident.as_str()),
                 );
             }
             Some(..) if pat_src == PatternSource::Match ||
@@ -1329,45 +1365,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         &mut self.ribs[ns].last_mut().unwrap().bindings
     }
 
-    fn resolve_pattern(
-        &mut self,
-        pat: &Pat,
-        pat_src: PatternSource,
-        // Maps idents to the node ID for the outermost pattern that binds them.
-        bindings: &mut IdentMap<NodeId>,
-    ) {
-        // Visit all direct subpatterns of this pattern.
-        let outer_pat_id = pat.id;
-        pat.walk(&mut |pat| {
-            debug!("resolve_pattern pat={:?} node={:?}", pat, pat.node);
-            match pat.node {
-                PatKind::Ident(bmode, ident, ref sub) => {
-                    // First try to resolve the identifier as some existing entity,
-                    // then fall back to a fresh binding.
-                    let has_sub = sub.is_some();
-                    let res = self.try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub)
-                        .unwrap_or_else(|| {
-                            self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
-                        });
-                    self.r.record_partial_res(pat.id, PartialRes::new(res));
-                }
-                PatKind::TupleStruct(ref path, ..) => {
-                    self.smart_resolve_path(pat.id, None, path, PathSource::TupleStruct);
-                }
-                PatKind::Path(ref qself, ref path) => {
-                    self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat);
-                }
-                PatKind::Struct(ref path, ..) => {
-                    self.smart_resolve_path(pat.id, None, path, PathSource::Struct);
-                }
-                _ => {}
-            }
-            true
-        });
-
-        visit::walk_pat(self, pat);
-    }
-
     fn try_resolve_as_non_binding(
         &mut self,
         pat_src: PatternSource,

From dc91e229d25b7074f5062662a089a66d627d292b Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 10:59:15 +0200
Subject: [PATCH 497/943] resolve: move `resolve_block` to a better place.

---
 src/librustc_resolve/late.rs | 86 ++++++++++++++++++------------------
 1 file changed, 43 insertions(+), 43 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 1b550bd7b0f56..c2513c2c76976 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -1229,49 +1229,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         }
     }
 
-    fn resolve_block(&mut self, block: &Block) {
-        debug!("(resolving block) entering block");
-        // Move down in the graph, if there's an anonymous module rooted here.
-        let orig_module = self.parent_scope.module;
-        let anonymous_module = self.r.block_map.get(&block.id).cloned(); // clones a reference
-
-        let mut num_macro_definition_ribs = 0;
-        if let Some(anonymous_module) = anonymous_module {
-            debug!("(resolving block) found anonymous module, moving down");
-            self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
-            self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
-            self.parent_scope.module = anonymous_module;
-        } else {
-            self.ribs[ValueNS].push(Rib::new(NormalRibKind));
-        }
-
-        // Descend into the block.
-        for stmt in &block.stmts {
-            if let StmtKind::Item(ref item) = stmt.node {
-                if let ItemKind::MacroDef(..) = item.node {
-                    num_macro_definition_ribs += 1;
-                    let res = self.r.definitions.local_def_id(item.id);
-                    self.ribs[ValueNS].push(Rib::new(MacroDefinition(res)));
-                    self.label_ribs.push(Rib::new(MacroDefinition(res)));
-                }
-            }
-
-            self.visit_stmt(stmt);
-        }
-
-        // Move back up.
-        self.parent_scope.module = orig_module;
-        for _ in 0 .. num_macro_definition_ribs {
-            self.ribs[ValueNS].pop();
-            self.label_ribs.pop();
-        }
-        self.ribs[ValueNS].pop();
-        if anonymous_module.is_some() {
-            self.ribs[TypeNS].pop();
-        }
-        debug!("(resolving block) leaving block");
-    }
-
     fn resolve_pattern(
         &mut self,
         pat: &Pat,
@@ -1729,6 +1686,49 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         self.with_resolved_label(label, id, |this| this.visit_block(block));
     }
 
+    fn resolve_block(&mut self, block: &Block) {
+        debug!("(resolving block) entering block");
+        // Move down in the graph, if there's an anonymous module rooted here.
+        let orig_module = self.parent_scope.module;
+        let anonymous_module = self.r.block_map.get(&block.id).cloned(); // clones a reference
+
+        let mut num_macro_definition_ribs = 0;
+        if let Some(anonymous_module) = anonymous_module {
+            debug!("(resolving block) found anonymous module, moving down");
+            self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
+            self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
+            self.parent_scope.module = anonymous_module;
+        } else {
+            self.ribs[ValueNS].push(Rib::new(NormalRibKind));
+        }
+
+        // Descend into the block.
+        for stmt in &block.stmts {
+            if let StmtKind::Item(ref item) = stmt.node {
+                if let ItemKind::MacroDef(..) = item.node {
+                    num_macro_definition_ribs += 1;
+                    let res = self.r.definitions.local_def_id(item.id);
+                    self.ribs[ValueNS].push(Rib::new(MacroDefinition(res)));
+                    self.label_ribs.push(Rib::new(MacroDefinition(res)));
+                }
+            }
+
+            self.visit_stmt(stmt);
+        }
+
+        // Move back up.
+        self.parent_scope.module = orig_module;
+        for _ in 0 .. num_macro_definition_ribs {
+            self.ribs[ValueNS].pop();
+            self.label_ribs.pop();
+        }
+        self.ribs[ValueNS].pop();
+        if anonymous_module.is_some() {
+            self.ribs[TypeNS].pop();
+        }
+        debug!("(resolving block) leaving block");
+    }
+
     fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) {
         // First, record candidate traits for this expression if it could
         // result in the invocation of a method call.

From 70cae78387034d04a5a43360744266d3657a1884 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 07:13:34 +0200
Subject: [PATCH 498/943] resolve: already-bound-check: account for
 or-patterns.

Also document `ast::Pat::walk`.
---
 src/librustc_resolve/late.rs                  | 120 +++++++++++-------
 src/libsyntax/ast.rs                          |  20 +--
 .../shadowing-in-the-same-pattern.stderr      |   7 +-
 3 files changed, 88 insertions(+), 59 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index c2513c2c76976..8e4771d26d8f3 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -19,6 +19,7 @@ use rustc::hir::def::Namespace::{self, *};
 use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc::hir::TraitCandidate;
 use rustc::util::nodemap::FxHashMap;
+use rustc_data_structures::fx::FxIndexMap;
 use smallvec::{smallvec, SmallVec};
 use syntax::{unwrap_or, walk_list};
 use syntax::ast::*;
@@ -408,7 +409,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
             visit::walk_foreign_item(this, foreign_item);
         });
     }
-    fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, _: Span, _: NodeId) {
+    fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, _: Span, id: NodeId) {
         debug!("(resolving function) entering function");
         let rib_kind = match fn_kind {
             FnKind::ItemFn(..) => FnItemRibKind,
@@ -420,7 +421,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
             // Create a label rib for the function.
             this.with_label_rib(rib_kind, |this| {
                 // Add each argument to the rib.
-                this.resolve_params(&declaration.inputs);
+                this.resolve_params(&declaration.inputs, id);
 
                 visit::walk_fn_ret_ty(this, &declaration.output);
 
@@ -1108,11 +1109,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         }
     }
 
-    fn resolve_params(&mut self, params: &[Arg]) {
-        let mut bindings_list = FxHashMap::default();
-        for param in params {
-            self.resolve_pattern(&param.pat, PatternSource::FnParam, &mut bindings_list);
-            self.visit_ty(&param.ty);
+    fn resolve_params(&mut self, params: &[Param], id: NodeId) {
+        let mut bindings = FxIndexMap::default();
+        for Param { pat, ty, .. } in params {
+            self.resolve_pattern(pat, PatternSource::FnParam, &mut smallvec![id], &mut bindings);
+            self.visit_ty(ty);
             debug!("(resolving function / closure) recorded parameter");
         }
     }
@@ -1125,7 +1126,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         walk_list!(self, visit_expr, &local.init);
 
         // Resolve the pattern.
-        self.resolve_pattern(&local.pat, PatternSource::Let, &mut FxHashMap::default());
+        self.resolve_pattern_top(&local.pat, PatternSource::Let);
     }
 
     // build a map from pattern identifiers to binding-info's.
@@ -1219,9 +1220,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
     /// Arising from `source`, resolve a sequence of patterns (top level or-patterns).
     fn resolve_pats(&mut self, pats: &[P<Pat>], source: PatternSource) {
-        let mut bindings_list = FxHashMap::default();
+        let mut bindings_list = FxIndexMap::default();
         for pat in pats {
-            self.resolve_pattern(pat, source, &mut bindings_list);
+            self.resolve_pattern(pat, source, &mut smallvec![pat.id], &mut bindings_list);
         }
         // This has to happen *after* we determine which pat_idents are variants
         if pats.len() > 1 {
@@ -1229,15 +1230,29 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         }
     }
 
+    fn resolve_pattern_top(&mut self, pat: &Pat, pat_src: PatternSource) {
+        self.resolve_pattern(pat, pat_src, &mut smallvec![pat.id], &mut FxIndexMap::default());
+    }
+
     fn resolve_pattern(
         &mut self,
         pat: &Pat,
         pat_src: PatternSource,
-        // Maps idents to the node ID for the outermost pattern that binds them.
-        bindings: &mut IdentMap<NodeId>,
+        prod_ids: &mut SmallVec<[NodeId; 1]>,
+        bindings: &mut FxIndexMap<Ident, NodeId>,
+    ) {
+        self.resolve_pattern_inner(pat, pat_src, prod_ids, bindings);
+        visit::walk_pat(self, pat);
+    }
+
+    fn resolve_pattern_inner(
+        &mut self,
+        pat: &Pat,
+        pat_src: PatternSource,
+        prod_ids: &mut SmallVec<[NodeId; 1]>,
+        bindings: &mut FxIndexMap<Ident, NodeId>,
     ) {
         // Visit all direct subpatterns of this pattern.
-        let outer_pat_id = pat.id;
         pat.walk(&mut |pat| {
             debug!("resolve_pattern pat={:?} node={:?}", pat, pat.node);
             match pat.node {
@@ -1247,7 +1262,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                     let has_sub = sub.is_some();
                     let res = self.try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub)
                         .unwrap_or_else(|| {
-                            self.fresh_binding(ident, pat.id, outer_pat_id, pat_src, bindings)
+                            self.fresh_binding(ident, pat.id, pat_src, prod_ids, bindings)
                         });
                     self.r.record_partial_res(pat.id, PartialRes::new(res));
                 }
@@ -1260,59 +1275,70 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 PatKind::Struct(ref path, ..) => {
                     self.smart_resolve_path(pat.id, None, path, PathSource::Struct);
                 }
+                PatKind::Or(ref ps) => {
+                    let len_before = bindings.len();
+                    for p in ps {
+                        // We need to change `prod_ids.last()` at this point so that overlapping
+                        // bindings across the summands in the or-pattern do not result in an error.
+                        // The idea is that in `V1(a) | V2(a)`, the `a` in `V1` will be inserted
+                        // with a different id than the one in `V2`. As a result, `V1(a) | V2(a)`
+                        // compiles as it should. We will later check or-patterns for consistency.
+                        prod_ids.push(p.id);
+                        self.resolve_pattern_inner(p, pat_src, prod_ids, bindings);
+                        prod_ids.pop();
+                    }
+
+                    // We've rejected overlap in each product in the sum.
+                    // Now we must account for the possibility that the or-pattern is a factor
+                    // in a product. A basic case to reject here is `(V1(a) | V2(a), a)`.
+                    let last_id = *prod_ids.last().unwrap();
+                    bindings.values_mut().skip(len_before).for_each(|val| *val = last_id);
+
+                    // Prevent visiting `ps` as we've already done so above.
+                    return false;
+                }
                 _ => {}
             }
             true
         });
-
-        visit::walk_pat(self, pat);
     }
 
     fn fresh_binding(
         &mut self,
         ident: Ident,
         pat_id: NodeId,
-        outer_pat_id: NodeId,
         pat_src: PatternSource,
-        bindings: &mut IdentMap<NodeId>,
+        prod_ids: &[NodeId],
+        bindings: &mut FxIndexMap<Ident, NodeId>,
     ) -> Res {
         // Add the binding to the local ribs, if it doesn't already exist in the bindings map.
         // (We must not add it if it's in the bindings map because that breaks the assumptions
         // later passes make about or-patterns.)
         let ident = ident.modern_and_legacy();
-        let mut res = Res::Local(pat_id);
+        let res = Res::Local(pat_id);
         match bindings.get(&ident).cloned() {
-            Some(id) if id == outer_pat_id => {
-                // `Variant(a, a)`, error
-                self.r.report_error(
-                    ident.span,
-                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(&ident.as_str()),
-                );
-            }
-            Some(..) if pat_src == PatternSource::FnParam => {
-                // `fn f(a: u8, a: u8)`, error
-                self.r.report_error(
-                    ident.span,
-                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(&ident.as_str()),
-                );
+            Some(id) if prod_ids.contains(&id) => {
+                // We have some overlap in a product pattern, e.g. `(a, a)` which is not allowed.
+                use ResolutionError::*;
+                let error = match pat_src {
+                    // `fn f(a: u8, a: u8)`:
+                    PatternSource::FnParam => IdentifierBoundMoreThanOnceInParameterList,
+                    // `Variant(a, a)`:
+                    _ => IdentifierBoundMoreThanOnceInSamePattern,
+                };
+                self.r.report_error(ident.span, error(&ident.as_str()));
             }
-            Some(..) if pat_src == PatternSource::Match ||
-                        pat_src == PatternSource::Let => {
+            Some(..) => {
                 // `Variant1(a) | Variant2(a)`, ok
                 // Reuse definition from the first `a`.
-                res = self.innermost_rib_bindings(ValueNS)[&ident];
+                return self.innermost_rib_bindings(ValueNS)[&ident];
             }
-            Some(..) => {
-                span_bug!(ident.span, "two bindings with the same name from \
-                                       unexpected pattern source {:?}", pat_src);
-            }
-            None => {
-                // A completely fresh binding, add to the lists if it's valid.
-                if ident.name != kw::Invalid {
-                    bindings.insert(ident, outer_pat_id);
-                    self.innermost_rib_bindings(ValueNS).insert(ident, res);
-                }
+            // A completely fresh binding, add to the lists if it's valid.
+            None if ident.name != kw::Invalid => {
+                bindings.insert(ident, *prod_ids.last().unwrap());
+                self.innermost_rib_bindings(ValueNS).insert(ident, res);
             }
+            None => {}
         }
 
         res
@@ -1810,7 +1836,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             ExprKind::ForLoop(ref pat, ref iter_expr, ref block, label) => {
                 self.visit_expr(iter_expr);
                 self.with_rib(ValueNS, NormalRibKind, |this| {
-                    this.resolve_pattern(pat, PatternSource::For, &mut FxHashMap::default());
+                    this.resolve_pattern_top(pat, PatternSource::For);
                     this.resolve_labeled_block(label, expr.id, block);
                 });
             }
@@ -1847,7 +1873,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             ExprKind::Closure(_, IsAsync::Async { .. }, _, ref fn_decl, ref body, _span) => {
                 self.with_rib(ValueNS, NormalRibKind, |this| {
                     // Resolve arguments:
-                    this.resolve_params(&fn_decl.inputs);
+                    this.resolve_params(&fn_decl.inputs, expr.id);
                     // No need to resolve return type --
                     // the outer closure return type is `FunctionRetTy::Default`.
 
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 6be00bcef45c0..8b5532df61fd2 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -561,29 +561,31 @@ impl Pat {
         }))
     }
 
-    pub fn walk<F>(&self, it: &mut F) -> bool
-    where
-        F: FnMut(&Pat) -> bool,
-    {
+    /// Walk top-down and call `it` in each place where a pattern occurs
+    /// starting with the root pattern `walk` is called on. If `it` returns
+    /// false then we will decend no further but siblings will be processed.
+    pub fn walk(&self, it: &mut impl FnMut(&Pat) -> bool) {
         if !it(self) {
-            return false;
+            return;
         }
 
         match &self.node {
             PatKind::Ident(_, _, Some(p)) => p.walk(it),
-            PatKind::Struct(_, fields, _) => fields.iter().all(|field| field.pat.walk(it)),
+            PatKind::Struct(_, fields, _) => fields.iter().for_each(|field| field.pat.walk(it)),
             PatKind::TupleStruct(_, s)
             | PatKind::Tuple(s)
             | PatKind::Slice(s)
-            | PatKind::Or(s) => s.iter().all(|p| p.walk(it)),
-            PatKind::Box(s) | PatKind::Ref(s, _) | PatKind::Paren(s) => s.walk(it),
+            | PatKind::Or(s) => s.iter().for_each(|p| p.walk(it)),
+            PatKind::Box(s)
+            | PatKind::Ref(s, _)
+            | PatKind::Paren(s) => s.walk(it),
             PatKind::Wild
             | PatKind::Rest
             | PatKind::Lit(_)
             | PatKind::Range(..)
             | PatKind::Ident(..)
             | PatKind::Path(..)
-            | PatKind::Mac(_) => true,
+            | PatKind::Mac(_) => {},
         }
     }
 
diff --git a/src/test/ui/shadowed/shadowing-in-the-same-pattern.stderr b/src/test/ui/shadowed/shadowing-in-the-same-pattern.stderr
index 71197efcaba54..1c51653db6abf 100644
--- a/src/test/ui/shadowed/shadowing-in-the-same-pattern.stderr
+++ b/src/test/ui/shadowed/shadowing-in-the-same-pattern.stderr
@@ -1,8 +1,8 @@
-error[E0416]: identifier `a` is bound more than once in the same pattern
+error[E0415]: identifier `a` is bound more than once in this parameter list
   --> $DIR/shadowing-in-the-same-pattern.rs:3:10
    |
 LL | fn f((a, a): (isize, isize)) {}
-   |          ^ used in a pattern more than once
+   |          ^ used as parameter more than once
 
 error[E0416]: identifier `a` is bound more than once in the same pattern
   --> $DIR/shadowing-in-the-same-pattern.rs:6:13
@@ -12,4 +12,5 @@ LL |     let (a, a) = (1, 1);
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0416`.
+Some errors have detailed explanations: E0415, E0416.
+For more information about an error, try `rustc --explain E0415`.

From 166a558da6793a040657efdcb5fad13cedc6ea15 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 1 Sep 2019 17:35:45 +0200
Subject: [PATCH 499/943] resolve: revamp already-bound check -- fix some bugs.

---
 src/librustc_resolve/late.rs | 138 ++++++++++++++++++++---------------
 1 file changed, 79 insertions(+), 59 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 8e4771d26d8f3..0b5d926d83d69 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -18,8 +18,7 @@ use rustc::hir::def::{self, PartialRes, DefKind, CtorKind, PerNS};
 use rustc::hir::def::Namespace::{self, *};
 use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc::hir::TraitCandidate;
-use rustc::util::nodemap::FxHashMap;
-use rustc_data_structures::fx::FxIndexMap;
+use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use smallvec::{smallvec, SmallVec};
 use syntax::{unwrap_or, walk_list};
 use syntax::ast::*;
@@ -409,7 +408,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
             visit::walk_foreign_item(this, foreign_item);
         });
     }
-    fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, _: Span, id: NodeId) {
+    fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, _: Span, _: NodeId) {
         debug!("(resolving function) entering function");
         let rib_kind = match fn_kind {
             FnKind::ItemFn(..) => FnItemRibKind,
@@ -421,7 +420,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
             // Create a label rib for the function.
             this.with_label_rib(rib_kind, |this| {
                 // Add each argument to the rib.
-                this.resolve_params(&declaration.inputs, id);
+                this.resolve_params(&declaration.inputs);
 
                 visit::walk_fn_ret_ty(this, &declaration.output);
 
@@ -1109,10 +1108,10 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         }
     }
 
-    fn resolve_params(&mut self, params: &[Param], id: NodeId) {
-        let mut bindings = FxIndexMap::default();
+    fn resolve_params(&mut self, params: &[Param]) {
+        let mut bindings = smallvec![(false, <_>::default())];
         for Param { pat, ty, .. } in params {
-            self.resolve_pattern(pat, PatternSource::FnParam, &mut smallvec![id], &mut bindings);
+            self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
             self.visit_ty(ty);
             debug!("(resolving function / closure) recorded parameter");
         }
@@ -1220,9 +1219,12 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
     /// Arising from `source`, resolve a sequence of patterns (top level or-patterns).
     fn resolve_pats(&mut self, pats: &[P<Pat>], source: PatternSource) {
-        let mut bindings_list = FxIndexMap::default();
+        let mut bindings = smallvec![(true, <_>::default())];
         for pat in pats {
-            self.resolve_pattern(pat, source, &mut smallvec![pat.id], &mut bindings_list);
+            bindings.push((false, <_>::default()));
+            self.resolve_pattern(pat, source, &mut bindings);
+            let collected = bindings.pop().unwrap().1;
+            bindings.last_mut().unwrap().1.extend(collected);
         }
         // This has to happen *after* we determine which pat_idents are variants
         if pats.len() > 1 {
@@ -1231,17 +1233,16 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     }
 
     fn resolve_pattern_top(&mut self, pat: &Pat, pat_src: PatternSource) {
-        self.resolve_pattern(pat, pat_src, &mut smallvec![pat.id], &mut FxIndexMap::default());
+        self.resolve_pattern(pat, pat_src, &mut smallvec![(false, <_>::default())]);
     }
 
     fn resolve_pattern(
         &mut self,
         pat: &Pat,
         pat_src: PatternSource,
-        prod_ids: &mut SmallVec<[NodeId; 1]>,
-        bindings: &mut FxIndexMap<Ident, NodeId>,
+        bindings: &mut SmallVec<[(bool, FxHashSet<Ident>); 1]>,
     ) {
-        self.resolve_pattern_inner(pat, pat_src, prod_ids, bindings);
+        self.resolve_pattern_inner(pat, pat_src, bindings);
         visit::walk_pat(self, pat);
     }
 
@@ -1249,8 +1250,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         &mut self,
         pat: &Pat,
         pat_src: PatternSource,
-        prod_ids: &mut SmallVec<[NodeId; 1]>,
-        bindings: &mut FxIndexMap<Ident, NodeId>,
+        bindings: &mut SmallVec<[(bool, FxHashSet<Ident>); 1]>,
     ) {
         // Visit all direct subpatterns of this pattern.
         pat.walk(&mut |pat| {
@@ -1261,9 +1261,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                     // then fall back to a fresh binding.
                     let has_sub = sub.is_some();
                     let res = self.try_resolve_as_non_binding(pat_src, pat, bmode, ident, has_sub)
-                        .unwrap_or_else(|| {
-                            self.fresh_binding(ident, pat.id, pat_src, prod_ids, bindings)
-                        });
+                        .unwrap_or_else(|| self.fresh_binding(ident, pat.id, pat_src, bindings));
                     self.r.record_partial_res(pat.id, PartialRes::new(res));
                 }
                 PatKind::TupleStruct(ref path, ..) => {
@@ -1276,23 +1274,26 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                     self.smart_resolve_path(pat.id, None, path, PathSource::Struct);
                 }
                 PatKind::Or(ref ps) => {
-                    let len_before = bindings.len();
+                    // Add a new set of bindings to the stack. `true` here records that when a
+                    // binding already exists in this set, it should not result in an error because
+                    // `V1(a) | V2(a)` must be allowed and are checked for consistency later.
+                    bindings.push((true, <_>::default()));
                     for p in ps {
-                        // We need to change `prod_ids.last()` at this point so that overlapping
-                        // bindings across the summands in the or-pattern do not result in an error.
-                        // The idea is that in `V1(a) | V2(a)`, the `a` in `V1` will be inserted
-                        // with a different id than the one in `V2`. As a result, `V1(a) | V2(a)`
-                        // compiles as it should. We will later check or-patterns for consistency.
-                        prod_ids.push(p.id);
-                        self.resolve_pattern_inner(p, pat_src, prod_ids, bindings);
-                        prod_ids.pop();
+                        // Now we need to switch back to a product context so that each
+                        // part of the or-pattern internally rejects already bound names.
+                        // For example, `V1(a) | V2(a, a)` and `V1(a, a) | V2(a)` are bad.
+                        bindings.push((false, <_>::default()));
+                        self.resolve_pattern_inner(p, pat_src, bindings);
+                        // Move up the non-overlapping bindings to the or-pattern.
+                        // Existing bindings just get "merged".
+                        let collected = bindings.pop().unwrap().1;
+                        bindings.last_mut().unwrap().1.extend(collected);
                     }
-
-                    // We've rejected overlap in each product in the sum.
-                    // Now we must account for the possibility that the or-pattern is a factor
-                    // in a product. A basic case to reject here is `(V1(a) | V2(a), a)`.
-                    let last_id = *prod_ids.last().unwrap();
-                    bindings.values_mut().skip(len_before).for_each(|val| *val = last_id);
+                    // This or-pattern itself can itself be part of a product,
+                    // e.g. `(V1(a) | V2(a), a)` or `(a, V1(a) | V2(a))`.
+                    // Both cases bind `a` again in a product pattern and must be rejected.
+                    let collected = bindings.pop().unwrap().1;
+                    bindings.last_mut().unwrap().1.extend(collected);
 
                     // Prevent visiting `ps` as we've already done so above.
                     return false;
@@ -1308,40 +1309,59 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         ident: Ident,
         pat_id: NodeId,
         pat_src: PatternSource,
-        prod_ids: &[NodeId],
-        bindings: &mut FxIndexMap<Ident, NodeId>,
+        bindings: &mut SmallVec<[(bool, FxHashSet<Ident>); 1]>,
     ) -> Res {
         // Add the binding to the local ribs, if it doesn't already exist in the bindings map.
         // (We must not add it if it's in the bindings map because that breaks the assumptions
         // later passes make about or-patterns.)
         let ident = ident.modern_and_legacy();
-        let res = Res::Local(pat_id);
-        match bindings.get(&ident).cloned() {
-            Some(id) if prod_ids.contains(&id) => {
-                // We have some overlap in a product pattern, e.g. `(a, a)` which is not allowed.
-                use ResolutionError::*;
-                let error = match pat_src {
-                    // `fn f(a: u8, a: u8)`:
-                    PatternSource::FnParam => IdentifierBoundMoreThanOnceInParameterList,
-                    // `Variant(a, a)`:
-                    _ => IdentifierBoundMoreThanOnceInSamePattern,
-                };
-                self.r.report_error(ident.span, error(&ident.as_str()));
-            }
-            Some(..) => {
-                // `Variant1(a) | Variant2(a)`, ok
-                // Reuse definition from the first `a`.
-                return self.innermost_rib_bindings(ValueNS)[&ident];
+
+        // Walk outwards the stack of products / or-patterns and
+        // find out if the identifier has been bound in any of these.
+        let mut already_bound_and = false;
+        let mut already_bound_or = false;
+        for (is_sum, set) in bindings.iter_mut().rev() {
+            match (is_sum, set.get(&ident).cloned()) {
+                // Already bound in a product pattern, e.g. `(a, a)` which is not allowed.
+                (false, Some(..)) => already_bound_and = true,
+                // Already bound in an or-pattern, e.g. `V1(a) | V2(a)`.
+                // This is *required* for consistency which is checked later.
+                (true, Some(..)) => already_bound_or = true,
+                // Not already bound here.
+                _ => {}
             }
-            // A completely fresh binding, add to the lists if it's valid.
-            None if ident.name != kw::Invalid => {
-                bindings.insert(ident, *prod_ids.last().unwrap());
+        }
+
+        if already_bound_and {
+            // Overlap in a product pattern somewhere; report an error.
+            use ResolutionError::*;
+            let error = match pat_src {
+                // `fn f(a: u8, a: u8)`:
+                PatternSource::FnParam => IdentifierBoundMoreThanOnceInParameterList,
+                // `Variant(a, a)`:
+                _ => IdentifierBoundMoreThanOnceInSamePattern,
+            };
+            self.r.report_error(ident.span, error(&ident.as_str()));
+        }
+
+        // Record as bound if it's valid:
+        let ident_valid = ident.name != kw::Invalid;
+        if ident_valid {
+            bindings.last_mut().unwrap().1.insert(ident);
+        }
+
+        if already_bound_or {
+            // `Variant1(a) | Variant2(a)`, ok
+            // Reuse definition from the first `a`.
+            self.innermost_rib_bindings(ValueNS)[&ident]
+        } else {
+            let res = Res::Local(pat_id);
+            if ident_valid {
+                // A completely fresh binding add to the set if it's valid.
                 self.innermost_rib_bindings(ValueNS).insert(ident, res);
             }
-            None => {}
+            res
         }
-
-        res
     }
 
     fn innermost_rib_bindings(&mut self, ns: Namespace) -> &mut IdentMap<Res> {
@@ -1873,7 +1893,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             ExprKind::Closure(_, IsAsync::Async { .. }, _, ref fn_decl, ref body, _span) => {
                 self.with_rib(ValueNS, NormalRibKind, |this| {
                     // Resolve arguments:
-                    this.resolve_params(&fn_decl.inputs, expr.id);
+                    this.resolve_params(&fn_decl.inputs);
                     // No need to resolve return type --
                     // the outer closure return type is `FunctionRetTy::Default`.
 

From 498ec5952062bac854eae7cb4e5152bb648dfe35 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 1 Sep 2019 17:36:04 +0200
Subject: [PATCH 500/943] resolve: add tests for already-bound check.

---
 src/test/ui/or-patterns/already-bound-name.rs | 45 +++++++++
 .../ui/or-patterns/already-bound-name.stderr  | 91 +++++++++++++++++++
 2 files changed, 136 insertions(+)
 create mode 100644 src/test/ui/or-patterns/already-bound-name.rs
 create mode 100644 src/test/ui/or-patterns/already-bound-name.stderr

diff --git a/src/test/ui/or-patterns/already-bound-name.rs b/src/test/ui/or-patterns/already-bound-name.rs
new file mode 100644
index 0000000000000..67e1fffdb0bcc
--- /dev/null
+++ b/src/test/ui/or-patterns/already-bound-name.rs
@@ -0,0 +1,45 @@
+// This test ensures that the "already bound identifier in a product pattern"
+// correctly accounts for or-patterns.
+
+#![allow(warnings)]
+#![feature(or_patterns)]
+
+enum E<T> { A(T, T), B(T) }
+
+use E::*;
+
+fn main() {
+    let (a, a) = (0, 1); // Standard duplication without an or-pattern.
+    //~^ ERROR identifier `a` is bound more than once in the same pattern
+
+    let (a, A(a, _) | B(a)) = (0, A(1, 2));
+    //~^ ERROR identifier `a` is bound more than once in the same pattern
+    //~| ERROR identifier `a` is bound more than once in the same pattern
+
+    let (A(a, _) | B(a), a) = (A(0, 1), 2);
+    //~^ ERROR identifier `a` is bound more than once in the same pattern
+
+    let A(a, a) | B(a) = A(0, 1);
+    //~^ ERROR identifier `a` is bound more than once in the same pattern
+
+    let B(a) | A(a, a) = A(0, 1);
+    //~^ ERROR identifier `a` is bound more than once in the same pattern
+
+    match A(0, 1) {
+        B(a) | A(a, a) => {} // Let's ensure `match` has no funny business.
+        //~^ ERROR identifier `a` is bound more than once in the same pattern
+    }
+
+    let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
+    //~^ ERROR identifier `a` is bound more than once in the same pattern
+    //~| ERROR identifier `a` is bound more than once in the same pattern
+    //~| ERROR mismatched types
+
+    let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
+    //~^ ERROR identifier `a` is bound more than once in the same pattern
+    //~| ERROR identifier `a` is bound more than once in the same pattern
+
+    let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
+    //~^ ERROR identifier `a` is bound more than once in the same pattern
+    //~| ERROR identifier `a` is bound more than once in the same pattern
+}
diff --git a/src/test/ui/or-patterns/already-bound-name.stderr b/src/test/ui/or-patterns/already-bound-name.stderr
new file mode 100644
index 0000000000000..1f8eccec9dbdd
--- /dev/null
+++ b/src/test/ui/or-patterns/already-bound-name.stderr
@@ -0,0 +1,91 @@
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:12:13
+   |
+LL |     let (a, a) = (0, 1); // Standard duplication without an or-pattern.
+   |             ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:15:15
+   |
+LL |     let (a, A(a, _) | B(a)) = (0, A(1, 2));
+   |               ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:15:25
+   |
+LL |     let (a, A(a, _) | B(a)) = (0, A(1, 2));
+   |                         ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:19:26
+   |
+LL |     let (A(a, _) | B(a), a) = (A(0, 1), 2);
+   |                          ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:22:14
+   |
+LL |     let A(a, a) | B(a) = A(0, 1);
+   |              ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:25:21
+   |
+LL |     let B(a) | A(a, a) = A(0, 1);
+   |                     ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:29:21
+   |
+LL |         B(a) | A(a, a) => {} // Let's ensure `match` has no funny business.
+   |                     ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:33:36
+   |
+LL |     let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
+   |                                    ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:33:46
+   |
+LL |     let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
+   |                                              ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:38:36
+   |
+LL |     let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
+   |                                    ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:38:46
+   |
+LL |     let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
+   |                                              ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:42:49
+   |
+LL |     let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
+   |                                                 ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/already-bound-name.rs:42:59
+   |
+LL |     let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
+   |                                                           ^ used in a pattern more than once
+
+error[E0308]: mismatched types
+  --> $DIR/already-bound-name.rs:33:31
+   |
+LL |     let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
+   |                               ^ expected integer, found enum `E`
+   |
+   = note: expected type `{integer}`
+              found type `E<{integer}>`
+
+error: aborting due to 14 previous errors
+
+Some errors have detailed explanations: E0308, E0416.
+For more information about an error, try `rustc --explain E0308`.

From 896a1c7fcdda7398d242ac6faace1c547349d3d6 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 1 Sep 2019 22:52:02 +0200
Subject: [PATCH 501/943] resolve: account for general or-patterns in
 consistency checking.

---
 src/librustc_resolve/late.rs                  | 127 +++++++++++-------
 src/test/ui/or-patterns/already-bound-name.rs |   1 +
 .../ui/or-patterns/already-bound-name.stderr  |  14 +-
 3 files changed, 93 insertions(+), 49 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 0b5d926d83d69..ac5ae327e5ba1 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -1112,6 +1112,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         let mut bindings = smallvec![(false, <_>::default())];
         for Param { pat, ty, .. } in params {
             self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
+            self.check_consistent_bindings_top(pat);
             self.visit_ty(ty);
             debug!("(resolving function / closure) recorded parameter");
         }
@@ -1128,69 +1129,90 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         self.resolve_pattern_top(&local.pat, PatternSource::Let);
     }
 
-    // build a map from pattern identifiers to binding-info's.
-    // this is done hygienically. This could arise for a macro
-    // that expands into an or-pattern where one 'x' was from the
-    // user and one 'x' came from the macro.
+    /// build a map from pattern identifiers to binding-info's.
+    /// this is done hygienically. This could arise for a macro
+    /// that expands into an or-pattern where one 'x' was from the
+    /// user and one 'x' came from the macro.
     fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap {
         let mut binding_map = FxHashMap::default();
 
         pat.walk(&mut |pat| {
-            if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node {
-                if sub_pat.is_some() || match self.r.partial_res_map.get(&pat.id)
-                                                                  .map(|res| res.base_res()) {
-                    Some(Res::Local(..)) => true,
-                    _ => false,
-                } {
-                    let binding_info = BindingInfo { span: ident.span, binding_mode: binding_mode };
-                    binding_map.insert(ident, binding_info);
+            match pat.node {
+                PatKind::Ident(binding_mode, ident, ref sub_pat)
+                    if sub_pat.is_some() || self.is_base_res_local(pat.id) =>
+                {
+                    binding_map.insert(ident, BindingInfo { span: ident.span, binding_mode });
+                }
+                PatKind::Or(ref ps) => {
+                    // Check the consistency of this or-pattern and
+                    // then add all bindings to the larger map.
+                    for bm in self.check_consistent_bindings(ps) {
+                        binding_map.extend(bm);
+                    }
+                    return false;
                 }
+                _ => {}
             }
+
             true
         });
 
         binding_map
     }
 
-    // Checks that all of the arms in an or-pattern have exactly the
-    // same set of bindings, with the same binding modes for each.
-    fn check_consistent_bindings(&mut self, pats: &[P<Pat>]) {
+    fn is_base_res_local(&self, nid: NodeId) -> bool {
+        match self.r.partial_res_map.get(&nid).map(|res| res.base_res()) {
+            Some(Res::Local(..)) => true,
+            _ => false,
+        }
+    }
+
+    /// Checks that all of the arms in an or-pattern have exactly the
+    /// same set of bindings, with the same binding modes for each.
+    fn check_consistent_bindings(&mut self, pats: &[P<Pat>]) -> Vec<BindingMap> {
         let mut missing_vars = FxHashMap::default();
         let mut inconsistent_vars = FxHashMap::default();
 
-        for pat_outer in pats.iter() {
-            let map_outer = self.binding_mode_map(&pat_outer);
-
-            for pat_inner in pats.iter().filter(|pat| pat.id != pat_outer.id) {
-                let map_inner = self.binding_mode_map(&pat_inner);
-
-                for (&key_inner, &binding_inner) in map_inner.iter() {
-                    match map_outer.get(&key_inner) {
-                        None => {  // missing binding
-                            let binding_error = missing_vars
-                                .entry(key_inner.name)
-                                .or_insert(BindingError {
-                                    name: key_inner.name,
-                                    origin: BTreeSet::new(),
-                                    target: BTreeSet::new(),
-                                    could_be_path:
-                                        key_inner.name.as_str().starts_with(char::is_uppercase)
-                                });
-                            binding_error.origin.insert(binding_inner.span);
-                            binding_error.target.insert(pat_outer.span);
-                        }
-                        Some(binding_outer) => {  // check consistent binding
-                            if binding_outer.binding_mode != binding_inner.binding_mode {
-                                inconsistent_vars
-                                    .entry(key_inner.name)
-                                    .or_insert((binding_inner.span, binding_outer.span));
-                            }
+        // 1) Compute the binding maps of all arms.
+        let maps = pats.iter()
+            .map(|pat| self.binding_mode_map(pat))
+            .collect::<Vec<_>>();
+
+        // 2) Record any missing bindings or binding mode inconsistencies.
+        for (map_outer, pat_outer) in pats.iter().enumerate().map(|(idx, pat)| (&maps[idx], pat)) {
+            // Check against all arms except for the same pattern which is always self-consistent.
+            let inners = pats.iter().enumerate()
+                .filter(|(_, pat)| pat.id != pat_outer.id)
+                .flat_map(|(idx, _)| maps[idx].iter())
+                .map(|(key, binding)| (key.name, map_outer.get(&key), binding));
+
+            for (name, info, &binding_inner) in inners {
+                match info {
+                    None => { // The inner binding is missing in the outer.
+                        let binding_error = missing_vars
+                            .entry(name)
+                            .or_insert_with(|| BindingError {
+                                name,
+                                origin: BTreeSet::new(),
+                                target: BTreeSet::new(),
+                                could_be_path: name.as_str().starts_with(char::is_uppercase),
+                            });
+                        binding_error.origin.insert(binding_inner.span);
+                        binding_error.target.insert(pat_outer.span);
+                    }
+                    Some(binding_outer) => {
+                        if binding_outer.binding_mode != binding_inner.binding_mode {
+                            // The binding modes in the outer and inner bindings differ.
+                            inconsistent_vars
+                                .entry(name)
+                                .or_insert((binding_inner.span, binding_outer.span));
                         }
                     }
                 }
             }
         }
 
+        // 3) Report all missing variables we found.
         let mut missing_vars = missing_vars.iter_mut().collect::<Vec<_>>();
         missing_vars.sort();
         for (name, mut v) in missing_vars {
@@ -1202,11 +1224,26 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 ResolutionError::VariableNotBoundInPattern(v));
         }
 
+        // 4) Report all inconsistencies in binding modes we found.
         let mut inconsistent_vars = inconsistent_vars.iter().collect::<Vec<_>>();
         inconsistent_vars.sort();
         for (name, v) in inconsistent_vars {
             self.r.report_error(v.0, ResolutionError::VariableBoundWithDifferentMode(*name, v.1));
         }
+
+        // 5) Finally bubble up all the binding maps.
+        maps
+    }
+
+    /// Check the consistency of the outermost or-patterns.
+    fn check_consistent_bindings_top(&mut self, pat: &Pat) {
+        pat.walk(&mut |pat| match pat.node {
+            PatKind::Or(ref ps) => {
+                self.check_consistent_bindings(ps);
+                false
+            },
+            _ => true,
+        })
     }
 
     fn resolve_arm(&mut self, arm: &Arm) {
@@ -1227,13 +1264,13 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             bindings.last_mut().unwrap().1.extend(collected);
         }
         // This has to happen *after* we determine which pat_idents are variants
-        if pats.len() > 1 {
-            self.check_consistent_bindings(pats);
-        }
+        self.check_consistent_bindings(pats);
     }
 
     fn resolve_pattern_top(&mut self, pat: &Pat, pat_src: PatternSource) {
         self.resolve_pattern(pat, pat_src, &mut smallvec![(false, <_>::default())]);
+        // This has to happen *after* we determine which pat_idents are variants:
+        self.check_consistent_bindings_top(pat);
     }
 
     fn resolve_pattern(
diff --git a/src/test/ui/or-patterns/already-bound-name.rs b/src/test/ui/or-patterns/already-bound-name.rs
index 67e1fffdb0bcc..44bd22effd322 100644
--- a/src/test/ui/or-patterns/already-bound-name.rs
+++ b/src/test/ui/or-patterns/already-bound-name.rs
@@ -38,6 +38,7 @@ fn main() {
     let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
     //~^ ERROR identifier `a` is bound more than once in the same pattern
     //~| ERROR identifier `a` is bound more than once in the same pattern
+    //~| ERROR variable `a` is not bound in all patterns
 
     let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
     //~^ ERROR identifier `a` is bound more than once in the same pattern
diff --git a/src/test/ui/or-patterns/already-bound-name.stderr b/src/test/ui/or-patterns/already-bound-name.stderr
index 1f8eccec9dbdd..f140b36f2b66f 100644
--- a/src/test/ui/or-patterns/already-bound-name.stderr
+++ b/src/test/ui/or-patterns/already-bound-name.stderr
@@ -64,14 +64,20 @@ error[E0416]: identifier `a` is bound more than once in the same pattern
 LL |     let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
    |                                              ^ used in a pattern more than once
 
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/already-bound-name.rs:38:9
+   |
+LL |     let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
+   |         ^^^^ pattern doesn't bind `a`        - variable not in all patterns
+
 error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/already-bound-name.rs:42:49
+  --> $DIR/already-bound-name.rs:43:49
    |
 LL |     let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
    |                                                 ^ used in a pattern more than once
 
 error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/already-bound-name.rs:42:59
+  --> $DIR/already-bound-name.rs:43:59
    |
 LL |     let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
    |                                                           ^ used in a pattern more than once
@@ -85,7 +91,7 @@ LL |     let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
    = note: expected type `{integer}`
               found type `E<{integer}>`
 
-error: aborting due to 14 previous errors
+error: aborting due to 15 previous errors
 
-Some errors have detailed explanations: E0308, E0416.
+Some errors have detailed explanations: E0308, E0408, E0416.
 For more information about an error, try `rustc --explain E0308`.

From 33317c7baad5000ff34449f5c8a55b48e6296453 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 1 Sep 2019 22:52:51 +0200
Subject: [PATCH 502/943] resolve: add test for missing bindings in
 or-patterns.

---
 src/test/ui/or-patterns/missing-bindings.rs   |  82 ++++++
 .../ui/or-patterns/missing-bindings.stderr    | 242 ++++++++++++++++++
 2 files changed, 324 insertions(+)
 create mode 100644 src/test/ui/or-patterns/missing-bindings.rs
 create mode 100644 src/test/ui/or-patterns/missing-bindings.stderr

diff --git a/src/test/ui/or-patterns/missing-bindings.rs b/src/test/ui/or-patterns/missing-bindings.rs
new file mode 100644
index 0000000000000..a75632278752d
--- /dev/null
+++ b/src/test/ui/or-patterns/missing-bindings.rs
@@ -0,0 +1,82 @@
+// This test ensures that or patterns do not allow missing bindings in any of the arms.
+
+// edition:2018
+
+#![feature(or_patterns)]
+#![allow(incomplete_features, non_camel_case_types)]
+
+fn main() {}
+
+fn check_handling_of_paths() {
+    mod bar {
+        pub enum foo {
+            alpha,
+            beta,
+            charlie
+        }
+    }
+
+    use bar::foo::{alpha, charlie};
+    let alpha | beta | charlie = alpha; //~  ERROR variable `beta` is not bound in all patterns
+    match Some(alpha) {
+        Some(alpha | beta) => {} //~ ERROR variable `beta` is not bound in all patterns
+    }
+}
+
+fn check_misc_nesting() {
+    enum E<T> { A(T, T), B(T) }
+    use E::*;
+    enum Vars3<S, T, U> { V1(S), V2(T), V3(U) }
+    use Vars3::*;
+
+    // One level:
+    const X: E<u8> = B(0);
+    let A(a, _) | _ = X; //~ ERROR variable `a` is not bound in all patterns
+    let _ | B(a) = X; //~ ERROR variable `a` is not bound in all patterns
+    let A(..) | B(a) = X; //~ ERROR variable `a` is not bound in all patterns
+    let A(a, _) | B(_) = X; //~ ERROR variable `a` is not bound in all patterns
+    let A(_, a) | B(_) = X; //~ ERROR variable `a` is not bound in all patterns
+    let A(a, b) | B(a) = X; //~ ERROR variable `b` is not bound in all patterns
+
+    // Two levels:
+    const Y: E<E<u8>> = B(B(0));
+    let A(A(..) | B(_), _) | B(a) = Y; //~ ERROR variable `a` is not bound in all patterns
+    let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y;
+    //~^ ERROR variable `a` is not bound in all patterns
+    let A(A(a, b) | B(c), d) | B(e) = Y;
+    //~^ ERROR variable `a` is not bound in all patterns
+    //~| ERROR variable `a` is not bound in all patterns
+    //~| ERROR variable `b` is not bound in all patterns
+    //~| ERROR variable `b` is not bound in all patterns
+    //~| ERROR variable `c` is not bound in all patterns
+    //~| ERROR variable `c` is not bound in all patterns
+    //~| ERROR variable `d` is not bound in all patterns
+    //~| ERROR variable `e` is not bound in all patterns
+
+    // Three levels:
+    let (
+            V1(
+            //~^ ERROR variable `b` is not bound in all patterns
+            //~| ERROR variable `c` is not bound in all patterns
+                A(
+                    Ok(a) | Err(_), //~ ERROR variable `a` is not bound in all patterns
+                    _
+                ) |
+                B(Ok(a) | Err(a))
+            ) |
+            V2(
+                A(
+                    A(_, a) | //~ ERROR variable `b` is not bound in all patterns
+                    B(b), //~ ERROR variable `a` is not bound in all patterns
+                    _
+                ) |
+                B(_)
+                //~^ ERROR variable `a` is not bound in all patterns
+                //~| ERROR variable `b` is not bound in all patterns
+            ) |
+            V3(c),
+            //~^ ERROR variable `a` is not bound in all patterns
+        )
+        : (Vars3<E<Result<u8, u8>>, E<E<u8>>, u8>,)
+        = (V3(0),);
+}
diff --git a/src/test/ui/or-patterns/missing-bindings.stderr b/src/test/ui/or-patterns/missing-bindings.stderr
new file mode 100644
index 0000000000000..57270e4412351
--- /dev/null
+++ b/src/test/ui/or-patterns/missing-bindings.stderr
@@ -0,0 +1,242 @@
+error[E0408]: variable `beta` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:20:9
+   |
+LL |     let alpha | beta | charlie = alpha;
+   |         ^^^^^   ----   ^^^^^^^ pattern doesn't bind `beta`
+   |         |       |
+   |         |       variable not in all patterns
+   |         pattern doesn't bind `beta`
+
+error[E0408]: variable `beta` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:22:14
+   |
+LL |         Some(alpha | beta) => {}
+   |              ^^^^^   ---- variable not in all patterns
+   |              |
+   |              pattern doesn't bind `beta`
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:34:19
+   |
+LL |     let A(a, _) | _ = X;
+   |           -       ^ pattern doesn't bind `a`
+   |           |
+   |           variable not in all patterns
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:35:9
+   |
+LL |     let _ | B(a) = X;
+   |         ^     - variable not in all patterns
+   |         |
+   |         pattern doesn't bind `a`
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:36:9
+   |
+LL |     let A(..) | B(a) = X;
+   |         ^^^^^     - variable not in all patterns
+   |         |
+   |         pattern doesn't bind `a`
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:37:19
+   |
+LL |     let A(a, _) | B(_) = X;
+   |           -       ^^^^ pattern doesn't bind `a`
+   |           |
+   |           variable not in all patterns
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:38:19
+   |
+LL |     let A(_, a) | B(_) = X;
+   |              -    ^^^^ pattern doesn't bind `a`
+   |              |
+   |              variable not in all patterns
+
+error[E0408]: variable `b` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:39:19
+   |
+LL |     let A(a, b) | B(a) = X;
+   |              -    ^^^^ pattern doesn't bind `b`
+   |              |
+   |              variable not in all patterns
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:43:9
+   |
+LL |     let A(A(..) | B(_), _) | B(a) = Y;
+   |         ^^^^^^^^^^^^^^^^^^     - variable not in all patterns
+   |         |
+   |         pattern doesn't bind `a`
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:44:11
+   |
+LL |     let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y;
+   |           ^^^^^     - variable not in all patterns
+   |           |
+   |           pattern doesn't bind `a`
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:46:21
+   |
+LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
+   |             -       ^^^^ pattern doesn't bind `a`
+   |             |
+   |             variable not in all patterns
+
+error[E0408]: variable `b` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:46:21
+   |
+LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
+   |                -    ^^^^ pattern doesn't bind `b`
+   |                |
+   |                variable not in all patterns
+
+error[E0408]: variable `c` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:46:11
+   |
+LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
+   |           ^^^^^^^     - variable not in all patterns
+   |           |
+   |           pattern doesn't bind `c`
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:46:32
+   |
+LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
+   |             -                  ^^^^ pattern doesn't bind `a`
+   |             |
+   |             variable not in all patterns
+
+error[E0408]: variable `b` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:46:32
+   |
+LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
+   |                -               ^^^^ pattern doesn't bind `b`
+   |                |
+   |                variable not in all patterns
+
+error[E0408]: variable `c` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:46:32
+   |
+LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
+   |                       -        ^^^^ pattern doesn't bind `c`
+   |                       |
+   |                       variable not in all patterns
+
+error[E0408]: variable `d` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:46:32
+   |
+LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
+   |                           -    ^^^^ pattern doesn't bind `d`
+   |                           |
+   |                           variable not in all patterns
+
+error[E0408]: variable `e` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:46:9
+   |
+LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
+   |         ^^^^^^^^^^^^^^^^^^^^     - variable not in all patterns
+   |         |
+   |         pattern doesn't bind `e`
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:62:29
+   |
+LL |                     Ok(a) | Err(_),
+   |                        -    ^^^^^^ pattern doesn't bind `a`
+   |                        |
+   |                        variable not in all patterns
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:70:21
+   |
+LL |                     A(_, a) |
+   |                          - variable not in all patterns
+LL |                     B(b),
+   |                     ^^^^ pattern doesn't bind `a`
+
+error[E0408]: variable `b` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:69:21
+   |
+LL |                     A(_, a) |
+   |                     ^^^^^^^ pattern doesn't bind `b`
+LL |                     B(b),
+   |                       - variable not in all patterns
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:73:17
+   |
+LL |                     A(_, a) |
+   |                          - variable not in all patterns
+...
+LL |                 B(_)
+   |                 ^^^^ pattern doesn't bind `a`
+
+error[E0408]: variable `b` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:73:17
+   |
+LL |                     B(b),
+   |                       - variable not in all patterns
+...
+LL |                 B(_)
+   |                 ^^^^ pattern doesn't bind `b`
+
+error[E0408]: variable `a` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:77:13
+   |
+LL |                 B(Ok(a) | Err(a))
+   |                               - variable not in all patterns
+...
+LL |                     A(_, a) |
+   |                          - variable not in all patterns
+...
+LL |             V3(c),
+   |             ^^^^^ pattern doesn't bind `a`
+
+error[E0408]: variable `b` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:58:13
+   |
+LL | /             V1(
+LL | |
+LL | |
+LL | |                 A(
+...  |
+LL | |                 B(Ok(a) | Err(a))
+LL | |             ) |
+   | |_____________^ pattern doesn't bind `b`
+...
+LL |                       B(b),
+   |                         - variable not in all patterns
+...
+LL |               V3(c),
+   |               ^^^^^ pattern doesn't bind `b`
+
+error[E0408]: variable `c` is not bound in all patterns
+  --> $DIR/missing-bindings.rs:58:13
+   |
+LL | /             V1(
+LL | |
+LL | |
+LL | |                 A(
+...  |
+LL | |                 B(Ok(a) | Err(a))
+LL | |             ) |
+   | |_____________^ pattern doesn't bind `c`
+LL | /             V2(
+LL | |                 A(
+LL | |                     A(_, a) |
+LL | |                     B(b),
+...  |
+LL | |
+LL | |             ) |
+   | |_____________^ pattern doesn't bind `c`
+LL |               V3(c),
+   |                  - variable not in all patterns
+
+error: aborting due to 26 previous errors
+
+For more information about this error, try `rustc --explain E0408`.

From aa7a02b02966d464bb06560c581f92355825fc56 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 1 Sep 2019 23:24:07 +0200
Subject: [PATCH 503/943] resolve: test binding mode consistency for
 or-patterns.

---
 src/test/ui/or-patterns/inconsistent-modes.rs | 26 +++++++
 .../ui/or-patterns/inconsistent-modes.stderr  | 72 +++++++++++++++++++
 2 files changed, 98 insertions(+)
 create mode 100644 src/test/ui/or-patterns/inconsistent-modes.rs
 create mode 100644 src/test/ui/or-patterns/inconsistent-modes.stderr

diff --git a/src/test/ui/or-patterns/inconsistent-modes.rs b/src/test/ui/or-patterns/inconsistent-modes.rs
new file mode 100644
index 0000000000000..a13596a9c8b1e
--- /dev/null
+++ b/src/test/ui/or-patterns/inconsistent-modes.rs
@@ -0,0 +1,26 @@
+// This test ensures that or patterns require binding mode consistency across arms.
+
+#![feature(or_patterns)]
+#![allow(incomplete_features, non_camel_case_types)]
+fn main() {
+    // One level:
+    let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
+    //~^ ERROR variable `a` is bound in inconsistent ways
+    let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0);
+    //~^ ERROR variable `a` is bound in inconsistent ways
+    let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
+    //~^ ERROR variable `a` is bound in inconsistent ways
+    //~| ERROR mismatched types
+    let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
+    //~^ ERROR variable `a` is bound in inconsistent ways
+    //~| ERROR variable `b` is bound in inconsistent ways
+    //~| ERROR mismatched types
+
+    // Two levels:
+    let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0);
+    //~^ ERROR variable `a` is bound in inconsistent ways
+
+    // Three levels:
+    let Ok([ Ok((Ok(ref a) | Err(a),)) | Err(a) ]) | Err(a) = Err(&1);
+    //~^ ERROR variable `a` is bound in inconsistent ways
+}
diff --git a/src/test/ui/or-patterns/inconsistent-modes.stderr b/src/test/ui/or-patterns/inconsistent-modes.stderr
new file mode 100644
index 0000000000000..a34a4fe138753
--- /dev/null
+++ b/src/test/ui/or-patterns/inconsistent-modes.stderr
@@ -0,0 +1,72 @@
+error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
+  --> $DIR/inconsistent-modes.rs:7:25
+   |
+LL |     let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
+   |            -            ^ bound in different ways
+   |            |
+   |            first binding
+
+error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
+  --> $DIR/inconsistent-modes.rs:9:29
+   |
+LL |     let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0);
+   |                    -        ^ bound in different ways
+   |                    |
+   |                    first binding
+
+error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
+  --> $DIR/inconsistent-modes.rs:11:33
+   |
+LL |     let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
+   |                - first binding  ^ bound in different ways
+
+error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
+  --> $DIR/inconsistent-modes.rs:14:39
+   |
+LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
+   |                 - first binding       ^ bound in different ways
+
+error[E0409]: variable `b` is bound in inconsistent ways within the same match arm
+  --> $DIR/inconsistent-modes.rs:14:46
+   |
+LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
+   |                    - first binding           ^ bound in different ways
+
+error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
+  --> $DIR/inconsistent-modes.rs:20:38
+   |
+LL |     let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0);
+   |                        -             ^ bound in different ways
+   |                        |
+   |                        first binding
+
+error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
+  --> $DIR/inconsistent-modes.rs:24:34
+   |
+LL |     let Ok([ Ok((Ok(ref a) | Err(a),)) | Err(a) ]) | Err(a) = Err(&1);
+   |                         -        ^ bound in different ways
+   |                         |
+   |                         first binding
+
+error[E0308]: mismatched types
+  --> $DIR/inconsistent-modes.rs:11:25
+   |
+LL |     let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
+   |                         ^^^^^^^^^ types differ in mutability
+   |
+   = note: expected type `&&u8`
+              found type `&mut &mut u8`
+
+error[E0308]: mismatched types
+  --> $DIR/inconsistent-modes.rs:14:31
+   |
+LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
+   |                               ^^^^^^^^^ types differ in mutability
+   |
+   = note: expected type `&{integer}`
+              found type `&mut _`
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0308, E0409.
+For more information about an error, try `rustc --explain E0308`.

From dbe68733875b13805f1a262288f9981d9cef4841 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 3 Sep 2019 04:32:50 +0200
Subject: [PATCH 504/943] resolve: test consistent or-patterns being allowed.

---
 src/test/ui/or-patterns/already-bound-name.rs |  2 +-
 .../ui/or-patterns/already-bound-name.stderr  |  8 +++
 .../ui/or-patterns/consistent-bindings.rs     | 46 ++++++++++++++
 .../ui/or-patterns/consistent-bindings.stderr | 20 +++++++
 src/test/ui/or-patterns/inconsistent-modes.rs |  4 +-
 .../ui/or-patterns/inconsistent-modes.stderr  | 26 +++++---
 src/test/ui/or-patterns/missing-bindings.rs   |  4 +-
 .../ui/or-patterns/missing-bindings.stderr    | 60 +++++++++++--------
 8 files changed, 132 insertions(+), 38 deletions(-)
 create mode 100644 src/test/ui/or-patterns/consistent-bindings.rs
 create mode 100644 src/test/ui/or-patterns/consistent-bindings.stderr

diff --git a/src/test/ui/or-patterns/already-bound-name.rs b/src/test/ui/or-patterns/already-bound-name.rs
index 44bd22effd322..3ebf59c643735 100644
--- a/src/test/ui/or-patterns/already-bound-name.rs
+++ b/src/test/ui/or-patterns/already-bound-name.rs
@@ -1,8 +1,8 @@
 // This test ensures that the "already bound identifier in a product pattern"
 // correctly accounts for or-patterns.
 
-#![allow(warnings)]
 #![feature(or_patterns)]
+//~^ WARN the feature `or_patterns` is incomplete
 
 enum E<T> { A(T, T), B(T) }
 
diff --git a/src/test/ui/or-patterns/already-bound-name.stderr b/src/test/ui/or-patterns/already-bound-name.stderr
index f140b36f2b66f..360699a873938 100644
--- a/src/test/ui/or-patterns/already-bound-name.stderr
+++ b/src/test/ui/or-patterns/already-bound-name.stderr
@@ -82,6 +82,14 @@ error[E0416]: identifier `a` is bound more than once in the same pattern
 LL |     let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
    |                                                           ^ used in a pattern more than once
 
+warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
+  --> $DIR/already-bound-name.rs:4:12
+   |
+LL | #![feature(or_patterns)]
+   |            ^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
 error[E0308]: mismatched types
   --> $DIR/already-bound-name.rs:33:31
    |
diff --git a/src/test/ui/or-patterns/consistent-bindings.rs b/src/test/ui/or-patterns/consistent-bindings.rs
new file mode 100644
index 0000000000000..0eb539dca4cba
--- /dev/null
+++ b/src/test/ui/or-patterns/consistent-bindings.rs
@@ -0,0 +1,46 @@
+// Check that or-patterns with consistent bindings across arms are allowed.
+
+// edition:2018
+
+#![feature(or_patterns)]
+//~^ WARN the feature `or_patterns` is incomplete
+
+fn main() {
+    // One level:
+    let Ok(a) | Err(a) = Ok(0);
+    let Ok(ref a) | Err(ref a) = Ok(0);
+    let Ok(ref mut a) | Err(ref mut a) = Ok(0);
+
+    // Two levels:
+    enum Tri<S, T, U> { V1(S), V2(T), V3(U) }
+    use Tri::*;
+
+    let Ok((V1(a) | V2(a) | V3(a), b)) | Err(Ok((a, b)) | Err((a, b)))
+        : Result<_, Result<_, _>>
+        = Ok((V1(1), 1));
+
+    let Ok((V1(a) | V2(a) | V3(a), ref b)) | Err(Ok((a, ref b)) | Err((a, ref b)))
+        : Result<_, Result<_, _>>
+        = Ok((V1(1), 1));
+
+    // Three levels:
+    let (
+            a,
+            Err((ref mut b, ref c, d)) |
+            Ok((
+                Ok(
+                    V1((ref c, d)) |
+                    V2((d, ref c)) |
+                    V3((ref c, Ok((_, d)) | Err((d, _))))
+                ) |
+                Err((ref c, d)),
+                ref mut b
+            ))
+        ) =
+        (1, Ok((Ok(V3((1, Ok((1, 1))))), 1)));
+
+    // FIXME(or_patterns; Centril | dlrobertson): remove this line below and
+    // change this test to check-pass once MIR can handle or-patterns with bindings.
+    let () = 0;
+    //~^ ERROR mismatched types
+}
diff --git a/src/test/ui/or-patterns/consistent-bindings.stderr b/src/test/ui/or-patterns/consistent-bindings.stderr
new file mode 100644
index 0000000000000..7f5e670c257ce
--- /dev/null
+++ b/src/test/ui/or-patterns/consistent-bindings.stderr
@@ -0,0 +1,20 @@
+warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
+  --> $DIR/consistent-bindings.rs:5:12
+   |
+LL | #![feature(or_patterns)]
+   |            ^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+  --> $DIR/consistent-bindings.rs:44:9
+   |
+LL |     let () = 0;
+   |         ^^ expected integer, found ()
+   |
+   = note: expected type `{integer}`
+              found type `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/or-patterns/inconsistent-modes.rs b/src/test/ui/or-patterns/inconsistent-modes.rs
index a13596a9c8b1e..44836893ea2b2 100644
--- a/src/test/ui/or-patterns/inconsistent-modes.rs
+++ b/src/test/ui/or-patterns/inconsistent-modes.rs
@@ -1,7 +1,9 @@
 // This test ensures that or patterns require binding mode consistency across arms.
 
 #![feature(or_patterns)]
-#![allow(incomplete_features, non_camel_case_types)]
+//~^ WARN the feature `or_patterns` is incomplete
+
+#![allow(non_camel_case_types)]
 fn main() {
     // One level:
     let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
diff --git a/src/test/ui/or-patterns/inconsistent-modes.stderr b/src/test/ui/or-patterns/inconsistent-modes.stderr
index a34a4fe138753..0a36ed5548e5b 100644
--- a/src/test/ui/or-patterns/inconsistent-modes.stderr
+++ b/src/test/ui/or-patterns/inconsistent-modes.stderr
@@ -1,5 +1,5 @@
 error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
-  --> $DIR/inconsistent-modes.rs:7:25
+  --> $DIR/inconsistent-modes.rs:9:25
    |
 LL |     let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
    |            -            ^ bound in different ways
@@ -7,7 +7,7 @@ LL |     let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
    |            first binding
 
 error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
-  --> $DIR/inconsistent-modes.rs:9:29
+  --> $DIR/inconsistent-modes.rs:11:29
    |
 LL |     let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0);
    |                    -        ^ bound in different ways
@@ -15,25 +15,25 @@ LL |     let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0);
    |                    first binding
 
 error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
-  --> $DIR/inconsistent-modes.rs:11:33
+  --> $DIR/inconsistent-modes.rs:13:33
    |
 LL |     let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
    |                - first binding  ^ bound in different ways
 
 error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
-  --> $DIR/inconsistent-modes.rs:14:39
+  --> $DIR/inconsistent-modes.rs:16:39
    |
 LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
    |                 - first binding       ^ bound in different ways
 
 error[E0409]: variable `b` is bound in inconsistent ways within the same match arm
-  --> $DIR/inconsistent-modes.rs:14:46
+  --> $DIR/inconsistent-modes.rs:16:46
    |
 LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
    |                    - first binding           ^ bound in different ways
 
 error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
-  --> $DIR/inconsistent-modes.rs:20:38
+  --> $DIR/inconsistent-modes.rs:22:38
    |
 LL |     let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0);
    |                        -             ^ bound in different ways
@@ -41,15 +41,23 @@ LL |     let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0);
    |                        first binding
 
 error[E0409]: variable `a` is bound in inconsistent ways within the same match arm
-  --> $DIR/inconsistent-modes.rs:24:34
+  --> $DIR/inconsistent-modes.rs:26:34
    |
 LL |     let Ok([ Ok((Ok(ref a) | Err(a),)) | Err(a) ]) | Err(a) = Err(&1);
    |                         -        ^ bound in different ways
    |                         |
    |                         first binding
 
+warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
+  --> $DIR/inconsistent-modes.rs:3:12
+   |
+LL | #![feature(or_patterns)]
+   |            ^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
 error[E0308]: mismatched types
-  --> $DIR/inconsistent-modes.rs:11:25
+  --> $DIR/inconsistent-modes.rs:13:25
    |
 LL |     let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
    |                         ^^^^^^^^^ types differ in mutability
@@ -58,7 +66,7 @@ LL |     let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
               found type `&mut &mut u8`
 
 error[E0308]: mismatched types
-  --> $DIR/inconsistent-modes.rs:14:31
+  --> $DIR/inconsistent-modes.rs:16:31
    |
 LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
    |                               ^^^^^^^^^ types differ in mutability
diff --git a/src/test/ui/or-patterns/missing-bindings.rs b/src/test/ui/or-patterns/missing-bindings.rs
index a75632278752d..b065028e7a5a4 100644
--- a/src/test/ui/or-patterns/missing-bindings.rs
+++ b/src/test/ui/or-patterns/missing-bindings.rs
@@ -3,7 +3,9 @@
 // edition:2018
 
 #![feature(or_patterns)]
-#![allow(incomplete_features, non_camel_case_types)]
+//~^ WARN the feature `or_patterns` is incomplete
+
+#![allow(non_camel_case_types)]
 
 fn main() {}
 
diff --git a/src/test/ui/or-patterns/missing-bindings.stderr b/src/test/ui/or-patterns/missing-bindings.stderr
index 57270e4412351..c73af7a42eec0 100644
--- a/src/test/ui/or-patterns/missing-bindings.stderr
+++ b/src/test/ui/or-patterns/missing-bindings.stderr
@@ -1,5 +1,5 @@
 error[E0408]: variable `beta` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:20:9
+  --> $DIR/missing-bindings.rs:22:9
    |
 LL |     let alpha | beta | charlie = alpha;
    |         ^^^^^   ----   ^^^^^^^ pattern doesn't bind `beta`
@@ -8,7 +8,7 @@ LL |     let alpha | beta | charlie = alpha;
    |         pattern doesn't bind `beta`
 
 error[E0408]: variable `beta` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:22:14
+  --> $DIR/missing-bindings.rs:24:14
    |
 LL |         Some(alpha | beta) => {}
    |              ^^^^^   ---- variable not in all patterns
@@ -16,7 +16,7 @@ LL |         Some(alpha | beta) => {}
    |              pattern doesn't bind `beta`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:34:19
+  --> $DIR/missing-bindings.rs:36:19
    |
 LL |     let A(a, _) | _ = X;
    |           -       ^ pattern doesn't bind `a`
@@ -24,7 +24,7 @@ LL |     let A(a, _) | _ = X;
    |           variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:35:9
+  --> $DIR/missing-bindings.rs:37:9
    |
 LL |     let _ | B(a) = X;
    |         ^     - variable not in all patterns
@@ -32,7 +32,7 @@ LL |     let _ | B(a) = X;
    |         pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:36:9
+  --> $DIR/missing-bindings.rs:38:9
    |
 LL |     let A(..) | B(a) = X;
    |         ^^^^^     - variable not in all patterns
@@ -40,7 +40,7 @@ LL |     let A(..) | B(a) = X;
    |         pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:37:19
+  --> $DIR/missing-bindings.rs:39:19
    |
 LL |     let A(a, _) | B(_) = X;
    |           -       ^^^^ pattern doesn't bind `a`
@@ -48,7 +48,7 @@ LL |     let A(a, _) | B(_) = X;
    |           variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:38:19
+  --> $DIR/missing-bindings.rs:40:19
    |
 LL |     let A(_, a) | B(_) = X;
    |              -    ^^^^ pattern doesn't bind `a`
@@ -56,7 +56,7 @@ LL |     let A(_, a) | B(_) = X;
    |              variable not in all patterns
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:39:19
+  --> $DIR/missing-bindings.rs:41:19
    |
 LL |     let A(a, b) | B(a) = X;
    |              -    ^^^^ pattern doesn't bind `b`
@@ -64,7 +64,7 @@ LL |     let A(a, b) | B(a) = X;
    |              variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:43:9
+  --> $DIR/missing-bindings.rs:45:9
    |
 LL |     let A(A(..) | B(_), _) | B(a) = Y;
    |         ^^^^^^^^^^^^^^^^^^     - variable not in all patterns
@@ -72,7 +72,7 @@ LL |     let A(A(..) | B(_), _) | B(a) = Y;
    |         pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:44:11
+  --> $DIR/missing-bindings.rs:46:11
    |
 LL |     let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y;
    |           ^^^^^     - variable not in all patterns
@@ -80,7 +80,7 @@ LL |     let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y;
    |           pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:21
+  --> $DIR/missing-bindings.rs:48:21
    |
 LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |             -       ^^^^ pattern doesn't bind `a`
@@ -88,7 +88,7 @@ LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |             variable not in all patterns
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:21
+  --> $DIR/missing-bindings.rs:48:21
    |
 LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |                -    ^^^^ pattern doesn't bind `b`
@@ -96,7 +96,7 @@ LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |                variable not in all patterns
 
 error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:11
+  --> $DIR/missing-bindings.rs:48:11
    |
 LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |           ^^^^^^^     - variable not in all patterns
@@ -104,7 +104,7 @@ LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |           pattern doesn't bind `c`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:32
+  --> $DIR/missing-bindings.rs:48:32
    |
 LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |             -                  ^^^^ pattern doesn't bind `a`
@@ -112,7 +112,7 @@ LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |             variable not in all patterns
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:32
+  --> $DIR/missing-bindings.rs:48:32
    |
 LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |                -               ^^^^ pattern doesn't bind `b`
@@ -120,7 +120,7 @@ LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |                variable not in all patterns
 
 error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:32
+  --> $DIR/missing-bindings.rs:48:32
    |
 LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |                       -        ^^^^ pattern doesn't bind `c`
@@ -128,7 +128,7 @@ LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |                       variable not in all patterns
 
 error[E0408]: variable `d` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:32
+  --> $DIR/missing-bindings.rs:48:32
    |
 LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |                           -    ^^^^ pattern doesn't bind `d`
@@ -136,7 +136,7 @@ LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |                           variable not in all patterns
 
 error[E0408]: variable `e` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:9
+  --> $DIR/missing-bindings.rs:48:9
    |
 LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |         ^^^^^^^^^^^^^^^^^^^^     - variable not in all patterns
@@ -144,7 +144,7 @@ LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
    |         pattern doesn't bind `e`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:62:29
+  --> $DIR/missing-bindings.rs:64:29
    |
 LL |                     Ok(a) | Err(_),
    |                        -    ^^^^^^ pattern doesn't bind `a`
@@ -152,7 +152,7 @@ LL |                     Ok(a) | Err(_),
    |                        variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:70:21
+  --> $DIR/missing-bindings.rs:72:21
    |
 LL |                     A(_, a) |
    |                          - variable not in all patterns
@@ -160,7 +160,7 @@ LL |                     B(b),
    |                     ^^^^ pattern doesn't bind `a`
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:69:21
+  --> $DIR/missing-bindings.rs:71:21
    |
 LL |                     A(_, a) |
    |                     ^^^^^^^ pattern doesn't bind `b`
@@ -168,7 +168,7 @@ LL |                     B(b),
    |                       - variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:73:17
+  --> $DIR/missing-bindings.rs:75:17
    |
 LL |                     A(_, a) |
    |                          - variable not in all patterns
@@ -177,7 +177,7 @@ LL |                 B(_)
    |                 ^^^^ pattern doesn't bind `a`
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:73:17
+  --> $DIR/missing-bindings.rs:75:17
    |
 LL |                     B(b),
    |                       - variable not in all patterns
@@ -186,7 +186,7 @@ LL |                 B(_)
    |                 ^^^^ pattern doesn't bind `b`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:77:13
+  --> $DIR/missing-bindings.rs:79:13
    |
 LL |                 B(Ok(a) | Err(a))
    |                               - variable not in all patterns
@@ -198,7 +198,7 @@ LL |             V3(c),
    |             ^^^^^ pattern doesn't bind `a`
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:58:13
+  --> $DIR/missing-bindings.rs:60:13
    |
 LL | /             V1(
 LL | |
@@ -216,7 +216,7 @@ LL |               V3(c),
    |               ^^^^^ pattern doesn't bind `b`
 
 error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:58:13
+  --> $DIR/missing-bindings.rs:60:13
    |
 LL | /             V1(
 LL | |
@@ -237,6 +237,14 @@ LL | |             ) |
 LL |               V3(c),
    |                  - variable not in all patterns
 
+warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
+  --> $DIR/missing-bindings.rs:5:12
+   |
+LL | #![feature(or_patterns)]
+   |            ^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
 error: aborting due to 26 previous errors
 
 For more information about this error, try `rustc --explain E0408`.

From ca968a10d8d5155a067d9f9da98a90a3abf741cb Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 00:57:15 +0200
Subject: [PATCH 505/943] or-patterns: syntax: simplify `Arm.pats` and
 `ExprKind::Let.0`.

---
 src/libsyntax/ast.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 8b5532df61fd2..e0eaad0d1a78e 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -930,7 +930,7 @@ pub struct Local {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Arm {
     pub attrs: Vec<Attribute>,
-    pub pats: Vec<P<Pat>>,
+    pub pat: P<Pat>,
     pub guard: Option<P<Expr>>,
     pub body: P<Expr>,
     pub span: Span,
@@ -1148,12 +1148,12 @@ pub enum ExprKind {
     Cast(P<Expr>, P<Ty>),
     /// A type ascription (e.g., `42: usize`).
     Type(P<Expr>, P<Ty>),
-    /// A `let pats = expr` expression that is only semantically allowed in the condition
+    /// A `let pat = expr` expression that is only semantically allowed in the condition
     /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
     ///
     /// The `Vec<P<Pat>>` is for or-patterns at the top level.
     /// FIXME(54883): Change this to just `P<Pat>`.
-    Let(Vec<P<Pat>>, P<Expr>),
+    Let(P<Pat>, P<Expr>),
     /// An `if` block, with an optional `else` block.
     ///
     /// `if expr { block } else { expr }`

From 998060ba3f7149145db095bc01e7bd2e396f3f2f Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 00:57:50 +0200
Subject: [PATCH 506/943] or-patterns: syntax: adjust `visit` and `mut_visit`.

---
 src/libsyntax/mut_visit.rs | 13 +++++--------
 src/libsyntax/visit.rs     | 17 ++++++++---------
 2 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index e14ca4b06a09e..6023c5149d05b 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -402,14 +402,11 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
     vis.visit_span(span);
 }
 
-pub fn noop_flat_map_arm<T: MutVisitor>(
-    mut arm: Arm,
-    vis: &mut T,
-) -> SmallVec<[Arm; 1]> {
-    let Arm { attrs, pats, guard, body, span, id } = &mut arm;
+pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> {
+    let Arm { attrs, pat, guard, body, span, id } = &mut arm;
     visit_attrs(attrs, vis);
     vis.visit_id(id);
-    visit_vec(pats, |pat| vis.visit_pat(pat));
+    vis.visit_pat(pat);
     visit_opt(guard, |guard| vis.visit_expr(guard));
     vis.visit_expr(body);
     vis.visit_span(span);
@@ -1132,8 +1129,8 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
             vis.visit_ty(ty);
         }
         ExprKind::AddrOf(_m, ohs) => vis.visit_expr(ohs),
-        ExprKind::Let(pats, scrutinee) => {
-            visit_vec(pats, |pat| vis.visit_pat(pat));
+        ExprKind::Let(pat, scrutinee) => {
+            vis.visit_pat(pat);
             vis.visit_expr(scrutinee);
         }
         ExprKind::If(cond, tr, fl) => {
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index ce1568316f8d4..e64123c238232 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -678,9 +678,8 @@ pub fn walk_anon_const<'a, V: Visitor<'a>>(visitor: &mut V, constant: &'a AnonCo
 }
 
 pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
-    for attr in expression.attrs.iter() {
-        visitor.visit_attribute(attr);
-    }
+    walk_list!(visitor, visit_attribute, expression.attrs.iter());
+
     match expression.node {
         ExprKind::Box(ref subexpression) => {
             visitor.visit_expr(subexpression)
@@ -719,8 +718,8 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
             visitor.visit_expr(subexpression);
             visitor.visit_ty(typ)
         }
-        ExprKind::Let(ref pats, ref scrutinee) => {
-            walk_list!(visitor, visit_pat, pats);
+        ExprKind::Let(ref pat, ref scrutinee) => {
+            visitor.visit_pat(pat);
             visitor.visit_expr(scrutinee);
         }
         ExprKind::If(ref head_expression, ref if_block, ref optional_else) => {
@@ -831,10 +830,10 @@ pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) {
 }
 
 pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) {
-    walk_list!(visitor, visit_pat, &arm.pats);
-    if let Some(ref e) = &arm.guard {
-        visitor.visit_expr(e);
-    }
+    visitor.visit_pat(&arm.pat);
+    // HACK(or_patterns; Centril | dlrobertson):
+    // If you change this, also change the hack in `lowering.rs`.
+    walk_list!(visitor, visit_expr, &arm.guard);
     visitor.visit_expr(&arm.body);
     walk_list!(visitor, visit_attribute, &arm.attrs);
 }

From ad3db726d118184780f0ba3703c0c60126db50a7 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 01:06:33 +0200
Subject: [PATCH 507/943] or-patterns: syntax: adjust parser removing a hack.

Fuse `parse_top_pat` and `parse_top_pat_unpack` into just `parse_top_pat`.
---
 src/libsyntax/parse/parser/expr.rs |  8 +++-----
 src/libsyntax/parse/parser/pat.rs  | 10 ----------
 2 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index e502a08f4b253..3db9c899dba40 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -1250,8 +1250,7 @@ impl<'a> Parser<'a> {
     /// The `let` token has already been eaten.
     fn parse_let_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         let lo = self.prev_span;
-        // FIXME(or_patterns, Centril | dlrobertson): use `parse_top_pat` instead.
-        let pat = self.parse_top_pat_unpack(GateOr::No)?;
+        let pat = self.parse_top_pat(GateOr::No)?;
         self.expect(&token::Eq)?;
         let expr = self.with_res(
             Restrictions::NO_STRUCT_LITERAL,
@@ -1393,8 +1392,7 @@ impl<'a> Parser<'a> {
     crate fn parse_arm(&mut self) -> PResult<'a, Arm> {
         let attrs = self.parse_outer_attributes()?;
         let lo = self.token.span;
-        // FIXME(or_patterns, Centril | dlrobertson): use `parse_top_pat` instead.
-        let pat = self.parse_top_pat_unpack(GateOr::No)?;
+        let pat = self.parse_top_pat(GateOr::No)?;
         let guard = if self.eat_keyword(kw::If) {
             Some(self.parse_expr()?)
         } else {
@@ -1455,7 +1453,7 @@ impl<'a> Parser<'a> {
 
         Ok(ast::Arm {
             attrs,
-            pats: pat, // FIXME(or_patterns, Centril | dlrobertson): this should just be `pat,`.
+            pat,
             guard,
             body: expr,
             span: lo.to(hi),
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 823f880337d13..669f657160b3e 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -36,16 +36,6 @@ impl<'a> Parser<'a> {
         self.parse_pat_with_range_pat(true, expected)
     }
 
-    // FIXME(or_patterns, Centril | dlrobertson):
-    // remove this and use `parse_top_pat` everywhere it is used instead.
-    pub(super) fn parse_top_pat_unpack(&mut self, gate_or: GateOr) -> PResult<'a, Vec<P<Pat>>> {
-        self.parse_top_pat(gate_or)
-            .map(|pat| pat.and_then(|pat| match pat.node {
-                PatKind::Or(pats) => pats,
-                node => vec![self.mk_pat(pat.span, node)],
-            }))
-    }
-
     /// Entry point to the main pattern parser.
     /// Corresponds to `top_pat` in RFC 2535 and allows or-pattern at the top level.
     pub(super) fn parse_top_pat(&mut self, gate_or: GateOr) -> PResult<'a, P<Pat>> {

From 424492acc863bb83dc70eee5847b9f3d677f5e14 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 01:15:33 +0200
Subject: [PATCH 508/943] or-patterns: syntax: adjust pretty printing.

---
 src/libsyntax/print/pprust.rs | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index bead941b20d5a..6755709d79488 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1714,11 +1714,11 @@ impl<'a> State<'a> {
         self.ann.post(self, AnnNode::Block(blk))
     }
 
-    /// Print a `let pats = scrutinee` expression.
-    crate fn print_let(&mut self, pats: &[P<ast::Pat>], scrutinee: &ast::Expr) {
+    /// Print a `let pat = scrutinee` expression.
+    crate fn print_let(&mut self, pat: &ast::Pat, scrutinee: &ast::Expr) {
         self.s.word("let ");
 
-        self.print_pats(pats);
+        self.print_pat(pat);
         self.s.space();
 
         self.word_space("=");
@@ -2044,8 +2044,8 @@ impl<'a> State<'a> {
                 self.word_space(":");
                 self.print_type(ty);
             }
-            ast::ExprKind::Let(ref pats, ref scrutinee) => {
-                self.print_let(pats, scrutinee);
+            ast::ExprKind::Let(ref pat, ref scrutinee) => {
+                self.print_let(pat, scrutinee);
             }
             ast::ExprKind::If(ref test, ref blk, ref elseopt) => {
                 self.print_if(test, blk, elseopt.as_ref().map(|e| &**e));
@@ -2455,21 +2455,16 @@ impl<'a> State<'a> {
         self.ann.post(self, AnnNode::Pat(pat))
     }
 
-    fn print_pats(&mut self, pats: &[P<ast::Pat>]) {
-        self.strsep("|", true, Inconsistent, pats, |s, p| s.print_pat(p));
-    }
-
     fn print_arm(&mut self, arm: &ast::Arm) {
-        // I have no idea why this check is necessary, but here it
-        // is :(
+        // I have no idea why this check is necessary, but here it is :(
         if arm.attrs.is_empty() {
             self.s.space();
         }
         self.cbox(INDENT_UNIT);
         self.ibox(0);
-        self.maybe_print_comment(arm.pats[0].span.lo());
+        self.maybe_print_comment(arm.pat.span.lo());
         self.print_outer_attributes(&arm.attrs);
-        self.print_pats(&arm.pats);
+        self.print_pat(&arm.pat);
         self.s.space();
         if let Some(ref e) = arm.guard {
             self.word_space("if");

From 76625eb0cc1491520348220c180a6dd3def83bb9 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 01:16:35 +0200
Subject: [PATCH 509/943] or-patterns: syntax: adjust derive, format, and
 building.

---
 src/libsyntax/ext/build.rs                    | 10 +++++-----
 src/libsyntax_ext/deriving/cmp/ord.rs         |  6 ++----
 src/libsyntax_ext/deriving/cmp/partial_ord.rs |  4 ++--
 src/libsyntax_ext/deriving/decodable.rs       |  4 +---
 src/libsyntax_ext/deriving/generic/mod.rs     |  6 +++---
 src/libsyntax_ext/format.rs                   |  2 +-
 6 files changed, 14 insertions(+), 18 deletions(-)

diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index e894fd17ff587..dc6cbfcf6ad5c 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -537,9 +537,9 @@ impl<'a> ExtCtxt<'a> {
         let err_expr = self.expr(sp, ast::ExprKind::Ret(Some(err_inner_expr)));
 
         // `Ok(__try_var) => __try_var`
-        let ok_arm = self.arm(sp, vec![ok_pat], binding_expr);
+        let ok_arm = self.arm(sp, ok_pat, binding_expr);
         // `Err(__try_var) => return Err(__try_var)`
-        let err_arm = self.arm(sp, vec![err_pat], err_expr);
+        let err_arm = self.arm(sp, err_pat, err_expr);
 
         // `match head { Ok() => ..., Err() => ... }`
         self.expr_match(sp, head, vec![ok_arm, err_arm])
@@ -606,10 +606,10 @@ impl<'a> ExtCtxt<'a> {
         self.pat_tuple_struct(span, path, vec![pat])
     }
 
-    pub fn arm(&self, span: Span, pats: Vec<P<ast::Pat>>, expr: P<ast::Expr>) -> ast::Arm {
+    pub fn arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm {
         ast::Arm {
             attrs: vec![],
-            pats,
+            pat,
             guard: None,
             body: expr,
             span,
@@ -618,7 +618,7 @@ impl<'a> ExtCtxt<'a> {
     }
 
     pub fn arm_unreachable(&self, span: Span) -> ast::Arm {
-        self.arm(span, vec![self.pat_wild(span)], self.expr_unreachable(span))
+        self.arm(span, self.pat_wild(span), self.expr_unreachable(span))
     }
 
     pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> {
diff --git a/src/libsyntax_ext/deriving/cmp/ord.rs b/src/libsyntax_ext/deriving/cmp/ord.rs
index 55687c3175b9d..1f4f5aa37099f 100644
--- a/src/libsyntax_ext/deriving/cmp/ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/ord.rs
@@ -95,11 +95,9 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<
                     cx.expr_call_global(span, cmp_path.clone(), args)
                 };
 
-                let eq_arm = cx.arm(span,
-                                    vec![cx.pat_path(span, equals_path.clone())],
-                                    old);
+                let eq_arm = cx.arm(span, cx.pat_path(span, equals_path.clone()), old);
                 let neq_arm = cx.arm(span,
-                                     vec![cx.pat_ident(span, test_id)],
+                                     cx.pat_ident(span, test_id),
                                      cx.expr_ident(span, test_id));
 
                 cx.expr_match(span, new, vec![eq_arm, neq_arm])
diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
index 740b92a9b7978..debdc300e6495 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
@@ -160,10 +160,10 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
                 };
 
                 let eq_arm = cx.arm(span,
-                                    vec![cx.pat_some(span, cx.pat_path(span, ordering.clone()))],
+                                    cx.pat_some(span, cx.pat_path(span, ordering.clone())),
                                     old);
                 let neq_arm = cx.arm(span,
-                                    vec![cx.pat_ident(span, test_id)],
+                                    cx.pat_ident(span, test_id),
                                     cx.expr_ident(span, test_id));
 
                 cx.expr_match(span, new, vec![eq_arm, neq_arm])
diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs
index 9b6f8518de046..d3d604b72521d 100644
--- a/src/libsyntax_ext/deriving/decodable.rs
+++ b/src/libsyntax_ext/deriving/decodable.rs
@@ -119,9 +119,7 @@ fn decodable_substructure(cx: &mut ExtCtxt<'_>,
                                                     vec![idx, exprdecode.clone()]))
                 });
 
-                arms.push(cx.arm(v_span,
-                                 vec![cx.pat_lit(v_span, cx.expr_usize(v_span, i))],
-                                 decoded));
+                arms.push(cx.arm(v_span, cx.pat_lit(v_span, cx.expr_usize(v_span, i)), decoded));
             }
 
             arms.push(cx.arm_unreachable(trait_span));
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 6fd763f5a9100..893d89f06a168 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -1071,7 +1071,7 @@ impl<'a> MethodDef<'a> {
         for (arg_expr, pat) in self_args.iter().zip(patterns) {
             body = cx.expr_match(trait_.span,
                                  arg_expr.clone(),
-                                 vec![cx.arm(trait_.span, vec![pat.clone()], body)])
+                                 vec![cx.arm(trait_.span, pat.clone(), body)])
         }
 
         body
@@ -1311,7 +1311,7 @@ impl<'a> MethodDef<'a> {
                                                              nonself_args,
                                                              &substructure);
 
-                cx.arm(sp, vec![single_pat], arm_expr)
+                cx.arm(sp, single_pat, arm_expr)
             })
             .collect();
 
@@ -1337,7 +1337,7 @@ impl<'a> MethodDef<'a> {
             _ => None,
         };
         if let Some(arm) = default {
-            match_arms.push(cx.arm(sp, vec![cx.pat_wild(sp)], arm));
+            match_arms.push(cx.arm(sp, cx.pat_wild(sp), arm));
         }
 
         // We will usually need the catch-all after matching the
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 47394c02b4186..9012bafad4155 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -716,7 +716,7 @@ impl<'a, 'b> Context<'a, 'b> {
         // But the nested match expression is proved to perform not as well
         // as series of let's; the first approach does.
         let pat = self.ecx.pat_tuple(self.fmtsp, pats);
-        let arm = self.ecx.arm(self.fmtsp, vec![pat], args_array);
+        let arm = self.ecx.arm(self.fmtsp, pat, args_array);
         let head = self.ecx.expr(self.fmtsp, ast::ExprKind::Tup(heads));
         let result = self.ecx.expr_match(self.fmtsp, head, vec![arm]);
 

From 3fccbac4d3810534b41d325f2dc132417d3e0d57 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 01:57:58 +0200
Subject: [PATCH 510/943] or-patterns: adjust librustc_lint.

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

diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 26e7b789f8f90..aecf5c5b52dba 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -772,7 +772,7 @@ impl EarlyLintPass for UnusedDocComment {
     }
 
     fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
-        let arm_span = arm.pats[0].span.with_hi(arm.body.span.hi());
+        let arm_span = arm.pat.span.with_hi(arm.body.span.hi());
         self.warn_if_doc(cx, arm_span, "match arms", false, &arm.attrs);
     }
 

From d8ef907886e34fe314f1aacc342c4a49cb34ad6a Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 28 Aug 2019 06:45:54 +0200
Subject: [PATCH 511/943] or-patterns: adjust lowering of `ast::Arm` &
 `ast::ExprKind::Let`.

Introduces a temporary hack to keep `Vec<P<Pat>>` in
`hir::Arm.pats` so that we keep the changes more incremental.
---
 src/librustc/hir/lowering.rs      | 41 ++++++++++++----
 src/librustc/hir/lowering/expr.rs | 77 ++++++++++++++++---------------
 2 files changed, 72 insertions(+), 46 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 5e2aebfd3187b..190b50b10b281 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -425,19 +425,44 @@ impl<'a> LoweringContext<'a> {
 
         impl<'tcx, 'interner> Visitor<'tcx> for MiscCollector<'tcx, 'interner> {
             fn visit_pat(&mut self, p: &'tcx Pat) {
-                match p.node {
+                if let PatKind::Paren(..) | PatKind::Rest = p.node {
                     // Doesn't generate a HIR node
-                    PatKind::Paren(..) | PatKind::Rest => {},
-                    _ => {
-                        if let Some(owner) = self.hir_id_owner {
-                            self.lctx.lower_node_id_with_owner(p.id, owner);
-                        }
-                    }
-                };
+                } else if let Some(owner) = self.hir_id_owner {
+                    self.lctx.lower_node_id_with_owner(p.id, owner);
+                }
 
                 visit::walk_pat(self, p)
             }
 
+            // HACK(or_patterns; Centril | dlrobertson): Avoid creating
+            // HIR  nodes for `PatKind::Or` for the top level of a `ast::Arm`.
+            // This is a temporary hack that should go away once we push down
+            // `arm.pats: HirVec<P<Pat>>` -> `arm.pat: P<Pat>` to HIR. // Centril
+            fn visit_arm(&mut self, arm: &'tcx Arm) {
+                match &arm.pat.node {
+                    PatKind::Or(pats) => pats.iter().for_each(|p| self.visit_pat(p)),
+                    _ => self.visit_pat(&arm.pat),
+                }
+                walk_list!(self, visit_expr, &arm.guard);
+                self.visit_expr(&arm.body);
+                walk_list!(self, visit_attribute, &arm.attrs);
+            }
+
+            // HACK(or_patterns; Centril | dlrobertson): Same as above. // Centril
+            fn visit_expr(&mut self, e: &'tcx Expr) {
+                if let ExprKind::Let(pat, scrutinee) = &e.node {
+                    walk_list!(self, visit_attribute, e.attrs.iter());
+                    match &pat.node {
+                        PatKind::Or(pats) => pats.iter().for_each(|p| self.visit_pat(p)),
+                        _ => self.visit_pat(&pat),
+                    }
+                    self.visit_expr(scrutinee);
+                    self.visit_expr_post(e);
+                    return;
+                }
+                visit::walk_expr(self, e)
+            }
+
             fn visit_item(&mut self, item: &'tcx Item) {
                 let hir_id = self.lctx.allocate_hir_id_counter(item.id);
 
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index bd217831faabf..0d8986ddec3c7 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -68,7 +68,7 @@ impl LoweringContext<'_> {
                 let ohs = P(self.lower_expr(ohs));
                 hir::ExprKind::AddrOf(m, ohs)
             }
-            ExprKind::Let(ref pats, ref scrutinee) => self.lower_expr_let(e.span, pats, scrutinee),
+            ExprKind::Let(ref pat, ref scrutinee) => self.lower_expr_let(e.span, pat, scrutinee),
             ExprKind::If(ref cond, ref then, ref else_opt) => {
                 self.lower_expr_if(e.span, cond, then, else_opt.as_deref())
             }
@@ -227,16 +227,11 @@ impl LoweringContext<'_> {
         }
     }
 
-    /// Emit an error and lower `ast::ExprKind::Let(pats, scrutinee)` into:
+    /// Emit an error and lower `ast::ExprKind::Let(pat, scrutinee)` into:
     /// ```rust
     /// match scrutinee { pats => true, _ => false }
     /// ```
-    fn lower_expr_let(
-        &mut self,
-        span: Span,
-        pats: &[AstP<Pat>],
-        scrutinee: &Expr
-    ) -> hir::ExprKind {
+    fn lower_expr_let(&mut self, span: Span, pat: &Pat, scrutinee: &Expr) -> hir::ExprKind {
         // If we got here, the `let` expression is not allowed.
         self.sess
             .struct_span_err(span, "`let` expressions are not supported here")
@@ -246,23 +241,23 @@ impl LoweringContext<'_> {
 
         // For better recovery, we emit:
         // ```
-        // match scrutinee { pats => true, _ => false }
+        // match scrutinee { pat => true, _ => false }
         // ```
         // While this doesn't fully match the user's intent, it has key advantages:
         // 1. We can avoid using `abort_if_errors`.
-        // 2. We can typeck both `pats` and `scrutinee`.
-        // 3. `pats` is allowed to be refutable.
+        // 2. We can typeck both `pat` and `scrutinee`.
+        // 3. `pat` is allowed to be refutable.
         // 4. The return type of the block is `bool` which seems like what the user wanted.
         let scrutinee = self.lower_expr(scrutinee);
         let then_arm = {
-            let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
+            let pat = self.lower_pat_top_hack(pat);
             let expr = self.expr_bool(span, true);
-            self.arm(pats, P(expr))
+            self.arm(pat, P(expr))
         };
         let else_arm = {
-            let pats = hir_vec![self.pat_wild(span)];
+            let pat = self.pat_wild(span);
             let expr = self.expr_bool(span, false);
-            self.arm(pats, P(expr))
+            self.arm(hir_vec![pat], P(expr))
         };
         hir::ExprKind::Match(
             P(scrutinee),
@@ -291,13 +286,12 @@ impl LoweringContext<'_> {
         // Handle then + scrutinee:
         let then_blk = self.lower_block(then, false);
         let then_expr = self.expr_block(then_blk, ThinVec::new());
-        let (then_pats, scrutinee, desugar) = match cond.node {
+        let (then_pat, scrutinee, desugar) = match cond.node {
             // `<pat> => <then>`:
-            ExprKind::Let(ref pats, ref scrutinee) => {
+            ExprKind::Let(ref pat, ref scrutinee) => {
                 let scrutinee = self.lower_expr(scrutinee);
-                let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
-                let desugar = hir::MatchSource::IfLetDesugar { contains_else_clause };
-                (pats, scrutinee, desugar)
+                let pat = self.lower_pat_top_hack(pat);
+                (pat, scrutinee, hir::MatchSource::IfLetDesugar { contains_else_clause })
             }
             // `true => <then>`:
             _ => {
@@ -312,13 +306,11 @@ impl LoweringContext<'_> {
                 // to preserve drop semantics since `if cond { ... }` does not
                 // let temporaries live outside of `cond`.
                 let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new());
-
-                let desugar = hir::MatchSource::IfDesugar { contains_else_clause };
-                let pats = hir_vec![self.pat_bool(span, true)];
-                (pats, cond, desugar)
+                let pat = self.pat_bool(span, true);
+                (hir_vec![pat], cond, hir::MatchSource::IfDesugar { contains_else_clause })
             }
         };
-        let then_arm = self.arm(then_pats, P(then_expr));
+        let then_arm = self.arm(then_pat, P(then_expr));
 
         hir::ExprKind::Match(P(scrutinee), vec![then_arm, else_arm].into(), desugar)
     }
@@ -345,8 +337,8 @@ impl LoweringContext<'_> {
         // Handle then + scrutinee:
         let then_blk = self.lower_block(body, false);
         let then_expr = self.expr_block(then_blk, ThinVec::new());
-        let (then_pats, scrutinee, desugar, source) = match cond.node {
-            ExprKind::Let(ref pats, ref scrutinee) => {
+        let (then_pat, scrutinee, desugar, source) = match cond.node {
+            ExprKind::Let(ref pat, ref scrutinee) => {
                 // to:
                 //
                 //   [opt_ident]: loop {
@@ -356,9 +348,8 @@ impl LoweringContext<'_> {
                 //     }
                 //   }
                 let scrutinee = self.with_loop_condition_scope(|t| t.lower_expr(scrutinee));
-                let pats = pats.iter().map(|pat| self.lower_pat(pat)).collect();
-                let desugar = hir::MatchSource::WhileLetDesugar;
-                (pats, scrutinee, desugar, hir::LoopSource::WhileLet)
+                let pat = self.lower_pat_top_hack(pat);
+                (pat, scrutinee, hir::MatchSource::WhileLetDesugar, hir::LoopSource::WhileLet)
             }
             _ => {
                 // We desugar: `'label: while $cond $body` into:
@@ -383,14 +374,12 @@ impl LoweringContext<'_> {
                 // to preserve drop semantics since `while cond { ... }` does not
                 // let temporaries live outside of `cond`.
                 let cond = self.expr_drop_temps(span_block, P(cond), ThinVec::new());
-
-                let desugar = hir::MatchSource::WhileDesugar;
                 // `true => <then>`:
-                let pats = hir_vec![self.pat_bool(span, true)];
-                (pats, cond, desugar, hir::LoopSource::While)
+                let pat = self.pat_bool(span, true);
+                (hir_vec![pat], cond, hir::MatchSource::WhileDesugar, hir::LoopSource::While)
             }
         };
-        let then_arm = self.arm(then_pats, P(then_expr));
+        let then_arm = self.arm(then_pat, P(then_expr));
 
         // `match <scrutinee> { ... }`
         let match_expr = self.expr_match(
@@ -440,7 +429,7 @@ impl LoweringContext<'_> {
         hir::Arm {
             hir_id: self.next_id(),
             attrs: self.lower_attrs(&arm.attrs),
-            pats: arm.pats.iter().map(|x| self.lower_pat(x)).collect(),
+            pats: self.lower_pat_top_hack(&arm.pat),
             guard: match arm.guard {
                 Some(ref x) => Some(hir::Guard::If(P(self.lower_expr(x)))),
                 _ => None,
@@ -450,6 +439,16 @@ impl LoweringContext<'_> {
         }
     }
 
+    /// HACK(or_patterns; Centril | dlrobertson): For now we don't push down top level or-patterns
+    /// `p | q` into `hir::PatKind::Or(...)` as post-lowering bits of the compiler are not ready
+    /// to deal with it. This should by fixed by pushing it down to HIR and then HAIR.
+    fn lower_pat_top_hack(&mut self, pat: &Pat) -> HirVec<P<hir::Pat>> {
+        match pat.node {
+            PatKind::Or(ref ps) => ps.iter().map(|x| self.lower_pat(x)).collect(),
+            _ => hir_vec![self.lower_pat(pat)],
+        }
+    }
+
     pub(super) fn make_async_expr(
         &mut self,
         capture_clause: CaptureBy,
@@ -1255,7 +1254,6 @@ impl LoweringContext<'_> {
                 ThinVec::from(attrs.clone()),
             ));
             let ok_pat = self.pat_ok(span, val_pat);
-
             self.arm(hir_vec![ok_pat], val_expr)
         };
 
@@ -1486,7 +1484,10 @@ impl LoweringContext<'_> {
         }
     }
 
-    fn arm(&mut self, pats: hir::HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
+    /// HACK(or_patterns; Centril | dlrobertson): For now we don't push down top level or-patterns
+    /// `p | q` into `hir::PatKind::Or(...)` as post-lowering bits of the compiler are not ready
+    /// to deal with it. This should by fixed by pushing it down to HIR and then HAIR.
+    fn arm(&mut self, pats: HirVec<P<hir::Pat>>, expr: P<hir::Expr>) -> hir::Arm {
         hir::Arm {
             hir_id: self.next_id(),
             attrs: hir_vec![],

From a867c5f9cc0dcab87d9f1b591873a4681fd627cb Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 1 Sep 2019 23:52:32 +0200
Subject: [PATCH 512/943] resolve: merge `resolve_pats` and
 `resolve_pattern_top`.

---
 src/librustc_resolve/late.rs | 25 ++++++-------------------
 1 file changed, 6 insertions(+), 19 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index ac5ae327e5ba1..2056e7b910465 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -1112,7 +1112,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         let mut bindings = smallvec![(false, <_>::default())];
         for Param { pat, ty, .. } in params {
             self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
-            self.check_consistent_bindings_top(pat);
             self.visit_ty(ty);
             debug!("(resolving function / closure) recorded parameter");
         }
@@ -1248,29 +1247,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
     fn resolve_arm(&mut self, arm: &Arm) {
         self.with_rib(ValueNS, NormalRibKind, |this| {
-            this.resolve_pats(&arm.pats, PatternSource::Match);
+            this.resolve_pattern_top(&arm.pat, PatternSource::Match);
             walk_list!(this, visit_expr, &arm.guard);
             this.visit_expr(&arm.body);
         });
     }
 
-    /// Arising from `source`, resolve a sequence of patterns (top level or-patterns).
-    fn resolve_pats(&mut self, pats: &[P<Pat>], source: PatternSource) {
-        let mut bindings = smallvec![(true, <_>::default())];
-        for pat in pats {
-            bindings.push((false, <_>::default()));
-            self.resolve_pattern(pat, source, &mut bindings);
-            let collected = bindings.pop().unwrap().1;
-            bindings.last_mut().unwrap().1.extend(collected);
-        }
-        // This has to happen *after* we determine which pat_idents are variants
-        self.check_consistent_bindings(pats);
-    }
-
+    /// Arising from `source`, resolve a top level pattern.
     fn resolve_pattern_top(&mut self, pat: &Pat, pat_src: PatternSource) {
         self.resolve_pattern(pat, pat_src, &mut smallvec![(false, <_>::default())]);
-        // This has to happen *after* we determine which pat_idents are variants:
-        self.check_consistent_bindings_top(pat);
     }
 
     fn resolve_pattern(
@@ -1280,6 +1265,8 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         bindings: &mut SmallVec<[(bool, FxHashSet<Ident>); 1]>,
     ) {
         self.resolve_pattern_inner(pat, pat_src, bindings);
+        // This has to happen *after* we determine which pat_idents are variants:
+        self.check_consistent_bindings_top(pat);
         visit::walk_pat(self, pat);
     }
 
@@ -1866,9 +1853,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 visit::walk_expr(self, expr);
             }
 
-            ExprKind::Let(ref pats, ref scrutinee) => {
+            ExprKind::Let(ref pat, ref scrutinee) => {
                 self.visit_expr(scrutinee);
-                self.resolve_pats(pats, PatternSource::Let);
+                self.resolve_pattern_top(pat, PatternSource::Let);
             }
 
             ExprKind::If(ref cond, ref then, ref opt_else) => {

From be95dee5a11126f3da96d59c9bdbcc1874c82007 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 2 Sep 2019 02:00:44 +0200
Subject: [PATCH 513/943] or-patterns: adjust save_analysis wrt.
 `process_var_decl{_multi}`.

---
 src/librustc_save_analysis/dump_visitor.rs | 97 ++++------------------
 src/librustc_save_analysis/lib.rs          |  1 +
 2 files changed, 15 insertions(+), 83 deletions(-)

diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index d1fd51a97f683..12c5ce12a0e8b 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -897,32 +897,23 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         }
     }
 
-    fn process_var_decl_multi(&mut self, pats: &'l [P<ast::Pat>]) {
+    fn process_var_decl(&mut self, pat: &'l ast::Pat) {
+        // The pattern could declare multiple new vars,
+        // we must walk the pattern and collect them all.
         let mut collector = PathCollector::new();
-        for pattern in pats {
-            // collect paths from the arm's patterns
-            collector.visit_pat(&pattern);
-            self.visit_pat(&pattern);
-        }
+        collector.visit_pat(&pat);
+        self.visit_pat(&pat);
 
-        // process collected paths
-        for (id, ident, immut) in collector.collected_idents {
+        // Process collected paths.
+        for (id, ident, _) in collector.collected_idents {
             match self.save_ctxt.get_path_res(id) {
                 Res::Local(hir_id) => {
-                    let mut value = if immut == ast::Mutability::Immutable {
-                        self.span.snippet(ident.span)
-                    } else {
-                        "<mutable>".to_owned()
-                    };
                     let id = self.tcx.hir().hir_to_node_id(hir_id);
-                    let typ = self.save_ctxt
-                        .tables
-                        .node_type_opt(hir_id)
+                    let typ = self.save_ctxt.tables.node_type_opt(hir_id)
                         .map(|t| t.to_string())
                         .unwrap_or_default();
-                    value.push_str(": ");
-                    value.push_str(&typ);
 
+                    // Rust uses the id of the pattern for var lookups, so we'll use it too.
                     if !self.span.filter_generated(ident.span) {
                         let qualname = format!("{}${}", ident.to_string(), id);
                         let id = id_from_node_id(id, &self.save_ctxt);
@@ -972,61 +963,6 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         }
     }
 
-    fn process_var_decl(&mut self, p: &'l ast::Pat, value: String) {
-        // The local could declare multiple new vars, we must walk the
-        // pattern and collect them all.
-        let mut collector = PathCollector::new();
-        collector.visit_pat(&p);
-        self.visit_pat(&p);
-
-        for (id, ident, immut) in collector.collected_idents {
-            let mut value = match immut {
-                ast::Mutability::Immutable => value.to_string(),
-                _ => String::new(),
-            };
-            let hir_id = self.tcx.hir().node_to_hir_id(id);
-            let typ = match self.save_ctxt.tables.node_type_opt(hir_id) {
-                Some(typ) => {
-                    let typ = typ.to_string();
-                    if !value.is_empty() {
-                        value.push_str(": ");
-                    }
-                    value.push_str(&typ);
-                    typ
-                }
-                None => String::new(),
-            };
-
-            // Rust uses the id of the pattern for var lookups, so we'll use it too.
-            if !self.span.filter_generated(ident.span) {
-                let qualname = format!("{}${}", ident.to_string(), id);
-                let id = id_from_node_id(id, &self.save_ctxt);
-                let span = self.span_from_span(ident.span);
-
-                self.dumper.dump_def(
-                    &Access {
-                        public: false,
-                        reachable: false,
-                    },
-                    Def {
-                        kind: DefKind::Local,
-                        id,
-                        span,
-                        name: ident.to_string(),
-                        qualname,
-                        value: typ,
-                        parent: None,
-                        children: vec![],
-                        decl_id: None,
-                        docs: String::new(),
-                        sig: None,
-                        attributes: vec![],
-                    },
-                );
-            }
-        }
-    }
-
     /// Extracts macro use and definition information from the AST node defined
     /// by the given NodeId, using the expansion information from the node's
     /// span.
@@ -1565,14 +1501,13 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
                 });
             }
             ast::ExprKind::ForLoop(ref pattern, ref subexpression, ref block, _) => {
-                let value = self.span.snippet(subexpression.span);
-                self.process_var_decl(pattern, value);
+                self.process_var_decl(pattern);
                 debug!("for loop, walk sub-expr: {:?}", subexpression.node);
                 self.visit_expr(subexpression);
                 visit::walk_block(self, block);
             }
-            ast::ExprKind::Let(ref pats, ref scrutinee) => {
-                self.process_var_decl_multi(pats);
+            ast::ExprKind::Let(ref pat, ref scrutinee) => {
+                self.process_var_decl(pat);
                 self.visit_expr(scrutinee);
             }
             ast::ExprKind::Repeat(ref element, ref count) => {
@@ -1599,7 +1534,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
     }
 
     fn visit_arm(&mut self, arm: &'l ast::Arm) {
-        self.process_var_decl_multi(&arm.pats);
+        self.process_var_decl(&arm.pat);
         if let Some(expr) = &arm.guard {
             self.visit_expr(expr);
         }
@@ -1617,11 +1552,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
 
     fn visit_local(&mut self, l: &'l ast::Local) {
         self.process_macro_use(l.span);
-        let value = l.init
-            .as_ref()
-            .map(|i| self.span.snippet(i.span))
-            .unwrap_or_default();
-        self.process_var_decl(&l.pat, value);
+        self.process_var_decl(&l.pat);
 
         // Just walk the initialiser and type (don't want to walk the pattern again).
         walk_list!(self, visit_ty, &l.ty);
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 92ccd4f49f6b9..4bc098db68611 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -1,5 +1,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![feature(nll)]
+#![feature(inner_deref)]
 
 #![recursion_limit="256"]
 

From d70b0c5d42e9c3cf6580a399c30d87fde48c1919 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 3 Sep 2019 06:58:09 +0200
Subject: [PATCH 514/943] or-patterns: fix pprust-expr-roundtrip due to AST
 change.

---
 src/test/ui-fulldeps/pprust-expr-roundtrip.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index 09f58521e5d5c..b4c154e5d95f7 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -150,12 +150,12 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
                 iter_exprs(depth - 1, &mut |e| g(ExprKind::Try(e)));
             },
             19 => {
-                let ps = vec![P(Pat {
+                let pat = P(Pat {
                     id: DUMMY_NODE_ID,
                     node: PatKind::Wild,
                     span: DUMMY_SP,
-                })];
-                iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(ps.clone(), e)))
+                });
+                iter_exprs(depth - 1, &mut |e| g(ExprKind::Let(pat.clone(), e)))
             },
             _ => panic!("bad counter value in iter_exprs"),
         }

From a7db1a4861e33f89181511a2e19aaa38e37e7f7a Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Wed, 4 Sep 2019 02:43:49 +0200
Subject: [PATCH 515/943] or-patterns: address review comments.

---
 src/librustc_resolve/late.rs | 27 +++++++++++++++++++++++----
 src/libsyntax/ast.rs         |  5 +----
 src/libsyntax/visit.rs       |  2 +-
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index 2056e7b910465..f3c70462512af 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -1109,7 +1109,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     }
 
     fn resolve_params(&mut self, params: &[Param]) {
-        let mut bindings = smallvec![(false, <_>::default())];
+        let mut bindings = smallvec![(false, Default::default())];
         for Param { pat, ty, .. } in params {
             self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
             self.visit_ty(ty);
@@ -1255,7 +1255,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
     /// Arising from `source`, resolve a top level pattern.
     fn resolve_pattern_top(&mut self, pat: &Pat, pat_src: PatternSource) {
-        self.resolve_pattern(pat, pat_src, &mut smallvec![(false, <_>::default())]);
+        self.resolve_pattern(pat, pat_src, &mut smallvec![(false, Default::default())]);
     }
 
     fn resolve_pattern(
@@ -1270,6 +1270,25 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         visit::walk_pat(self, pat);
     }
 
+    /// Resolve bindings in a pattern. This is a helper to `resolve_pattern`.
+    ///
+    /// ### `bindings`
+    ///
+    /// A stack of sets of bindings accumulated.
+    ///
+    /// In each set, `false` denotes that a found binding in it should be interpreted as
+    /// re-binding an already bound binding. This results in an error. Meanwhile, `true`
+    /// denotes that a found binding in the set should result in reusing this binding
+    /// rather  than creating a fresh one. In other words, `false` and `true` correspond
+    /// to product (e.g., `(a, b)`) and sum/or contexts (e.g., `p_0 | ... | p_i`) respectively.
+    ///
+    /// When called at the top level, the stack should have a single element with `false`.
+    /// Otherwise, pushing to the stack happens as or-patterns are encountered and the
+    /// context needs to be switched to `true` and then `false` for each `p_i.
+    /// When each `p_i` has been dealt with, the top set is merged with its parent.
+    /// When a whole or-pattern has been dealt with, the thing happens.
+    ///
+    /// See the implementation and `fresh_binding` for more details.
     fn resolve_pattern_inner(
         &mut self,
         pat: &Pat,
@@ -1301,12 +1320,12 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                     // Add a new set of bindings to the stack. `true` here records that when a
                     // binding already exists in this set, it should not result in an error because
                     // `V1(a) | V2(a)` must be allowed and are checked for consistency later.
-                    bindings.push((true, <_>::default()));
+                    bindings.push((true, Default::default()));
                     for p in ps {
                         // Now we need to switch back to a product context so that each
                         // part of the or-pattern internally rejects already bound names.
                         // For example, `V1(a) | V2(a, a)` and `V1(a, a) | V2(a)` are bad.
-                        bindings.push((false, <_>::default()));
+                        bindings.push((false, Default::default()));
                         self.resolve_pattern_inner(p, pat_src, bindings);
                         // Move up the non-overlapping bindings to the or-pattern.
                         // Existing bindings just get "merged".
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e0eaad0d1a78e..c93e6d11ce711 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -563,7 +563,7 @@ impl Pat {
 
     /// Walk top-down and call `it` in each place where a pattern occurs
     /// starting with the root pattern `walk` is called on. If `it` returns
-    /// false then we will decend no further but siblings will be processed.
+    /// false then we will descend no further but siblings will be processed.
     pub fn walk(&self, it: &mut impl FnMut(&Pat) -> bool) {
         if !it(self) {
             return;
@@ -1150,9 +1150,6 @@ pub enum ExprKind {
     Type(P<Expr>, P<Ty>),
     /// A `let pat = expr` expression that is only semantically allowed in the condition
     /// of `if` / `while` expressions. (e.g., `if let 0 = x { .. }`).
-    ///
-    /// The `Vec<P<Pat>>` is for or-patterns at the top level.
-    /// FIXME(54883): Change this to just `P<Pat>`.
     Let(P<Pat>, P<Expr>),
     /// An `if` block, with an optional `else` block.
     ///
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index e64123c238232..421c327aa414d 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -831,7 +831,7 @@ pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) {
 
 pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) {
     visitor.visit_pat(&arm.pat);
-    // HACK(or_patterns; Centril | dlrobertson):
+    // NOTE(or_patterns; Centril | dlrobertson):
     // If you change this, also change the hack in `lowering.rs`.
     walk_list!(visitor, visit_expr, &arm.guard);
     visitor.visit_expr(&arm.body);

From 0341b78044a51b4883477234d2133c904b69ae68 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 5 Sep 2019 01:43:53 +0200
Subject: [PATCH 516/943] resolve: bool -> enum PatBoundCtx

---
 src/librustc_resolve/late.rs | 47 ++++++++++++++++++++++--------------
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index f3c70462512af..3ddaf2d94f9c8 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -75,6 +75,16 @@ impl PatternSource {
     }
 }
 
+/// Denotes whether the context for the set of already bound bindings is a `Product`
+/// or `Or` context. This is used in e.g., `fresh_binding` and `resolve_pattern_inner`.
+/// See those functions for more information.
+enum PatBoundCtx {
+    /// A product pattern context, e.g., `Variant(a, b)`.
+    Product,
+    /// An or-pattern context, e.g., `p_0 | ... | p_n`.
+    Or,
+}
+
 /// The rib kind restricts certain accesses,
 /// e.g. to a `Res::Local` of an outer item.
 #[derive(Copy, Clone, Debug)]
@@ -1109,7 +1119,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     }
 
     fn resolve_params(&mut self, params: &[Param]) {
-        let mut bindings = smallvec![(false, Default::default())];
+        let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
         for Param { pat, ty, .. } in params {
             self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
             self.visit_ty(ty);
@@ -1255,14 +1265,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
     /// Arising from `source`, resolve a top level pattern.
     fn resolve_pattern_top(&mut self, pat: &Pat, pat_src: PatternSource) {
-        self.resolve_pattern(pat, pat_src, &mut smallvec![(false, Default::default())]);
+        let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
+        self.resolve_pattern(pat, pat_src, &mut bindings);
     }
 
     fn resolve_pattern(
         &mut self,
         pat: &Pat,
         pat_src: PatternSource,
-        bindings: &mut SmallVec<[(bool, FxHashSet<Ident>); 1]>,
+        bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet<Ident>); 1]>,
     ) {
         self.resolve_pattern_inner(pat, pat_src, bindings);
         // This has to happen *after* we determine which pat_idents are variants:
@@ -1276,15 +1287,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     ///
     /// A stack of sets of bindings accumulated.
     ///
-    /// In each set, `false` denotes that a found binding in it should be interpreted as
-    /// re-binding an already bound binding. This results in an error. Meanwhile, `true`
-    /// denotes that a found binding in the set should result in reusing this binding
-    /// rather  than creating a fresh one. In other words, `false` and `true` correspond
-    /// to product (e.g., `(a, b)`) and sum/or contexts (e.g., `p_0 | ... | p_i`) respectively.
+    /// In each set, `PatBoundCtx::Product` denotes that a found binding in it should
+    /// be interpreted as re-binding an already bound binding. This results in an error.
+    /// Meanwhile, `PatBound::Or` denotes that a found binding in the set should result
+    /// in reusing this binding rather than creating a fresh one.
     ///
-    /// When called at the top level, the stack should have a single element with `false`.
-    /// Otherwise, pushing to the stack happens as or-patterns are encountered and the
-    /// context needs to be switched to `true` and then `false` for each `p_i.
+    /// When called at the top level, the stack must have a single element
+    /// with `PatBound::Product`. Otherwise, pushing to the stack happens as
+    /// or-patterns (`p_0 | ... | p_n`) are encountered and the context needs
+    /// to be switched to `PatBoundCtx::Or` and then `PatBoundCtx::Product` for each `p_i`.
     /// When each `p_i` has been dealt with, the top set is merged with its parent.
     /// When a whole or-pattern has been dealt with, the thing happens.
     ///
@@ -1293,7 +1304,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         &mut self,
         pat: &Pat,
         pat_src: PatternSource,
-        bindings: &mut SmallVec<[(bool, FxHashSet<Ident>); 1]>,
+        bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet<Ident>); 1]>,
     ) {
         // Visit all direct subpatterns of this pattern.
         pat.walk(&mut |pat| {
@@ -1317,15 +1328,15 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                     self.smart_resolve_path(pat.id, None, path, PathSource::Struct);
                 }
                 PatKind::Or(ref ps) => {
-                    // Add a new set of bindings to the stack. `true` here records that when a
+                    // Add a new set of bindings to the stack. `Or` here records that when a
                     // binding already exists in this set, it should not result in an error because
                     // `V1(a) | V2(a)` must be allowed and are checked for consistency later.
-                    bindings.push((true, Default::default()));
+                    bindings.push((PatBoundCtx::Or, Default::default()));
                     for p in ps {
                         // Now we need to switch back to a product context so that each
                         // part of the or-pattern internally rejects already bound names.
                         // For example, `V1(a) | V2(a, a)` and `V1(a, a) | V2(a)` are bad.
-                        bindings.push((false, Default::default()));
+                        bindings.push((PatBoundCtx::Product, Default::default()));
                         self.resolve_pattern_inner(p, pat_src, bindings);
                         // Move up the non-overlapping bindings to the or-pattern.
                         // Existing bindings just get "merged".
@@ -1352,7 +1363,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         ident: Ident,
         pat_id: NodeId,
         pat_src: PatternSource,
-        bindings: &mut SmallVec<[(bool, FxHashSet<Ident>); 1]>,
+        bindings: &mut SmallVec<[(PatBoundCtx, FxHashSet<Ident>); 1]>,
     ) -> Res {
         // Add the binding to the local ribs, if it doesn't already exist in the bindings map.
         // (We must not add it if it's in the bindings map because that breaks the assumptions
@@ -1366,10 +1377,10 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         for (is_sum, set) in bindings.iter_mut().rev() {
             match (is_sum, set.get(&ident).cloned()) {
                 // Already bound in a product pattern, e.g. `(a, a)` which is not allowed.
-                (false, Some(..)) => already_bound_and = true,
+                (PatBoundCtx::Product, Some(..)) => already_bound_and = true,
                 // Already bound in an or-pattern, e.g. `V1(a) | V2(a)`.
                 // This is *required* for consistency which is checked later.
-                (true, Some(..)) => already_bound_or = true,
+                (PatBoundCtx::Or, Some(..)) => already_bound_or = true,
                 // Not already bound here.
                 _ => {}
             }

From 24d0a01b75c034d52bdca10cca08e69538e871ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 4 Sep 2019 23:59:04 -0700
Subject: [PATCH 517/943] review comment

---
 src/librustc_typeck/check/pat.rs | 38 +++++++++++++++++++++++---------
 1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 9a3f5e9e1b5d8..24d0659391b04 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -675,23 +675,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.tcx.check_stability(variant.fields[i].did, Some(pat.hir_id), subpat.span);
             }
         } else {
-            let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
-            let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
-            let span = tcx.def_span(res.def_id());
-            struct_span_err!(tcx.sess, pat.span, E0023,
-                             "this pattern has {} field{}, but the corresponding {} has {} field{}",
-                             subpats.len(), subpats_ending, res.descr(),
-                             variant.fields.len(),  fields_ending)
-                .span_label(pat.span, format!("expected {} field{}, found {}",
-                                              variant.fields.len(), fields_ending, subpats.len()))
-                .span_label(span, format!("{} defined here", res.descr()))
-                .emit();
+            // Pattern has wrong number of fields.
+            self.e0023(pat.span, res, &subpats, &variant.fields);
             on_error();
             return tcx.types.err;
         }
         pat_ty
     }
 
+    fn e0023(&self, pat_span: Span, res: Res, subpats: &'tcx [P<Pat>], fields: &[ty::FieldDef]) {
+        let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
+        let fields_ending = if fields.len() == 1 { "" } else { "s" };
+        let res_span = self.tcx.def_span(res.def_id());
+        struct_span_err!(
+            self.tcx.sess,
+            pat_span,
+            E0023,
+            "this pattern has {} field{}, but the corresponding {} has {} field{}",
+            subpats.len(),
+            subpats_ending,
+            res.descr(),
+            fields.len(),
+            fields_ending,
+        )
+            .span_label(pat_span, format!(
+                "expected {} field{}, found {}",
+                fields.len(),
+                fields_ending,
+                subpats.len(),
+            ))
+            .span_label(res_span, format!("{} defined here", res.descr()))
+            .emit();
+    }
+
     fn check_pat_tuple(
         &self,
         span: Span,

From 485697bf42cc6a03712e82e69c8f2357a2576454 Mon Sep 17 00:00:00 2001
From: Ximin Luo <infinity0@pwned.gg>
Date: Thu, 5 Sep 2019 00:14:09 -0700
Subject: [PATCH 518/943] Better way of conditioning the sanitizer builds

Previously the build would take the presence of the LLVM_CONFIG envvar to
mean that the sanitizers should be built, but this is a common envvar that
could be set for reasons unrelated to the rustc sanitizers.

This commit adds a new envvar RUSTC_BUILD_SANITIZERS and uses it instead.
---
 src/bootstrap/compile.rs   | 1 +
 src/librustc_asan/build.rs | 3 +++
 src/librustc_lsan/build.rs | 3 +++
 src/librustc_msan/build.rs | 3 +++
 src/librustc_tsan/build.rs | 3 +++
 5 files changed, 13 insertions(+)

diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 9d57a4f00d780..9a964457ef285 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -212,6 +212,7 @@ pub fn std_cargo(builder: &Builder<'_>,
                 emscripten: false,
             });
             cargo.env("LLVM_CONFIG", llvm_config);
+            cargo.env("RUSTC_BUILD_SANITIZERS", "1");
         }
 
         cargo.arg("--features").arg(features)
diff --git a/src/librustc_asan/build.rs b/src/librustc_asan/build.rs
index a2b4b090efb4f..cc856ba68fbb7 100644
--- a/src/librustc_asan/build.rs
+++ b/src/librustc_asan/build.rs
@@ -4,6 +4,9 @@ use build_helper::sanitizer_lib_boilerplate;
 use cmake::Config;
 
 fn main() {
+    if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
+        return;
+    }
     if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
         build_helper::restore_library_path();
 
diff --git a/src/librustc_lsan/build.rs b/src/librustc_lsan/build.rs
index b8c7b7c2d5537..d5f3e37dea51c 100644
--- a/src/librustc_lsan/build.rs
+++ b/src/librustc_lsan/build.rs
@@ -4,6 +4,9 @@ use build_helper::sanitizer_lib_boilerplate;
 use cmake::Config;
 
 fn main() {
+    if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
+        return;
+    }
     if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
         build_helper::restore_library_path();
 
diff --git a/src/librustc_msan/build.rs b/src/librustc_msan/build.rs
index 1c66b0a9cd3cf..de1676f489a46 100644
--- a/src/librustc_msan/build.rs
+++ b/src/librustc_msan/build.rs
@@ -4,6 +4,9 @@ use build_helper::sanitizer_lib_boilerplate;
 use cmake::Config;
 
 fn main() {
+    if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
+        return;
+    }
     if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
         build_helper::restore_library_path();
 
diff --git a/src/librustc_tsan/build.rs b/src/librustc_tsan/build.rs
index ed9c37087c7e5..6df9691257455 100644
--- a/src/librustc_tsan/build.rs
+++ b/src/librustc_tsan/build.rs
@@ -4,6 +4,9 @@ use build_helper::sanitizer_lib_boilerplate;
 use cmake::Config;
 
 fn main() {
+    if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
+        return;
+    }
     if let Some(llvm_config) = env::var_os("LLVM_CONFIG") {
         build_helper::restore_library_path();
 

From 16ba5029a19eaa5968e61f4447a2d3ebf3367dc2 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 5 Sep 2019 09:17:19 +0200
Subject: [PATCH 519/943] or-patterns: fix fallout from #664128.

---
 src/librustc_lint/unused.rs                   | 10 ++--
 .../ui/lint/issue-54538-unused-parens-lint.rs |  2 -
 .../issue-54538-unused-parens-lint.stderr     | 51 +++++++------------
 3 files changed, 22 insertions(+), 41 deletions(-)

diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 39c0698aeec9f..561bf202dfeff 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -493,10 +493,8 @@ impl EarlyLintPass for UnusedParens {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
         use syntax::ast::ExprKind::*;
         let (value, msg, followed_by_block, left_pos, right_pos) = match e.node {
-            Let(ref pats, ..) => {
-                for p in pats {
-                    self.check_unused_parens_pat(cx, p, false, false);
-                }
+            Let(ref pat, ..) => {
+                self.check_unused_parens_pat(cx, pat, false, false);
                 return;
             }
 
@@ -594,9 +592,7 @@ impl EarlyLintPass for UnusedParens {
     }
 
     fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
-        for p in &arm.pats {
-            self.check_unused_parens_pat(cx, p, false, false);
-        }
+        self.check_unused_parens_pat(cx, &arm.pat, false, false);
     }
 }
 
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
index c442c39fe010e..1d8cce5228116 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
@@ -33,10 +33,8 @@ fn or_patterns_no_lint() {
     if let &mut (0 | 1) = &mut 0 {} // Same.
 
     fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now.
-    //~^ ERROR identifier `a` is bound more than once
 
     let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or.
-    //~^ ERROR identifier `a` is bound more than once
 }
 
 fn or_patterns_will_lint() {
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
index a3e0fb938b3c6..7d5e286416fe2 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
@@ -1,15 +1,3 @@
-error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:35:25
-   |
-LL |     fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now.
-   |                         ^ used in a pattern more than once
-
-error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:38:27
-   |
-LL |     let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or.
-   |                           ^ used in a pattern more than once
-
 warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
   --> $DIR/issue-54538-unused-parens-lint.rs:3:12
    |
@@ -61,113 +49,112 @@ LL |     let _ = |(a): u8| 0;
    |              ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:43:12
+  --> $DIR/issue-54538-unused-parens-lint.rs:41:12
    |
 LL |     if let (0 | 1) = 0 {}
    |            ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:44:13
+  --> $DIR/issue-54538-unused-parens-lint.rs:42:13
    |
 LL |     if let ((0 | 1),) = (0,) {}
    |             ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:45:13
+  --> $DIR/issue-54538-unused-parens-lint.rs:43:13
    |
 LL |     if let [(0 | 1)] = [0] {}
    |             ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:46:16
+  --> $DIR/issue-54538-unused-parens-lint.rs:44:16
    |
 LL |     if let 0 | (1 | 2) = 0 {}
    |                ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:48:15
+  --> $DIR/issue-54538-unused-parens-lint.rs:46:15
    |
 LL |     if let TS((0 | 1)) = TS(0) {}
    |               ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:50:20
+  --> $DIR/issue-54538-unused-parens-lint.rs:48:20
    |
 LL |     if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
    |                    ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:60:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:58:9
    |
 LL |         (_) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:61:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:59:9
    |
 LL |         (y) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:62:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:60:9
    |
 LL |         (ref r) => {}
    |         ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:63:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:61:9
    |
 LL |         (e @ 1...2) => {}
    |         ^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:69:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:67:9
    |
 LL |         (e @ &(1...2)) => {}
    |         ^^^^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:70:10
+  --> $DIR/issue-54538-unused-parens-lint.rs:68:10
    |
 LL |         &(_) => {}
    |          ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:81:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:79:9
    |
 LL |         (_) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:82:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:80:9
    |
 LL |         (y) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:83:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:81:9
    |
 LL |         (ref r) => {}
    |         ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:84:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:82:9
    |
 LL |         (e @ 1..=2) => {}
    |         ^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:90:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:88:9
    |
 LL |         (e @ &(1..=2)) => {}
    |         ^^^^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:91:10
+  --> $DIR/issue-54538-unused-parens-lint.rs:89:10
    |
 LL |         &(_) => {}
    |          ^^^ help: remove these parentheses
 
-error: aborting due to 26 previous errors
+error: aborting due to 24 previous errors
 
-For more information about this error, try `rustc --explain E0416`.

From bafff2d2c5492e1b6755d21c4145429bad97052c Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Thu, 5 Sep 2019 09:36:49 +0000
Subject: [PATCH 520/943] Update Clippy

---
 src/tools/clippy | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/clippy b/src/tools/clippy
index aeadf1562c024..5f28fda13efeb 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit aeadf1562c024d3c5421e61dc6b8d48c2d7902f5
+Subproject commit 5f28fda13efeb85097fe082af4b4827a58b0ecf6

From c9bd2f73a37df377e2c778690756f0dcf9f25ce1 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Thu, 5 Sep 2019 13:38:11 +0200
Subject: [PATCH 521/943] Add missing code examples on Iterator trait

---
 src/libcore/iter/traits/iterator.rs | 80 +++++++++++++++++++++++++++++
 1 file changed, 80 insertions(+)

diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs
index d644787d2c462..8fd5fe0653eed 100644
--- a/src/libcore/iter/traits/iterator.rs
+++ b/src/libcore/iter/traits/iterator.rs
@@ -2546,6 +2546,16 @@ pub trait Iterator {
 
     /// Lexicographically compares the elements of this `Iterator` with those
     /// of another.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::cmp::Ordering;
+    ///
+    /// assert_eq!([1].iter().cmp([1].iter()), Ordering::Equal);
+    /// assert_eq!([1].iter().cmp([1, 2].iter()), Ordering::Less);
+    /// assert_eq!([1, 2].iter().cmp([1].iter()), Ordering::Greater);
+    /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn cmp<I>(mut self, other: I) -> Ordering where
         I: IntoIterator<Item = Self::Item>,
@@ -2578,6 +2588,18 @@ pub trait Iterator {
 
     /// Lexicographically compares the elements of this `Iterator` with those
     /// of another.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::cmp::Ordering;
+    ///
+    /// assert_eq!([1.].iter().partial_cmp([1.].iter()), Some(Ordering::Equal));
+    /// assert_eq!([1.].iter().partial_cmp([1., 2.].iter()), Some(Ordering::Less));
+    /// assert_eq!([1., 2.].iter().partial_cmp([1.].iter()), Some(Ordering::Greater));
+    ///
+    /// assert_eq!([std::f64::NAN].iter().partial_cmp([1.].iter()), None);
+    /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn partial_cmp<I>(mut self, other: I) -> Option<Ordering> where
         I: IntoIterator,
@@ -2610,6 +2632,13 @@ pub trait Iterator {
 
     /// Determines if the elements of this `Iterator` are equal to those of
     /// another.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!([1].iter().eq([1].iter()), true);
+    /// assert_eq!([1].iter().eq([1, 2].iter()), false);
+    /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn eq<I>(mut self, other: I) -> bool where
         I: IntoIterator,
@@ -2635,6 +2664,13 @@ pub trait Iterator {
 
     /// Determines if the elements of this `Iterator` are unequal to those of
     /// another.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!([1].iter().ne([1].iter()), false);
+    /// assert_eq!([1].iter().ne([1, 2].iter()), true);
+    /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn ne<I>(self, other: I) -> bool where
         I: IntoIterator,
@@ -2646,6 +2682,14 @@ pub trait Iterator {
 
     /// Determines if the elements of this `Iterator` are lexicographically
     /// less than those of another.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!([1].iter().lt([1].iter()), false);
+    /// assert_eq!([1].iter().lt([1, 2].iter()), true);
+    /// assert_eq!([1, 2].iter().lt([1].iter()), false);
+    /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn lt<I>(self, other: I) -> bool where
         I: IntoIterator,
@@ -2657,6 +2701,14 @@ pub trait Iterator {
 
     /// Determines if the elements of this `Iterator` are lexicographically
     /// less or equal to those of another.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!([1].iter().le([1].iter()), true);
+    /// assert_eq!([1].iter().le([1, 2].iter()), true);
+    /// assert_eq!([1, 2].iter().le([1].iter()), false);
+    /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn le<I>(self, other: I) -> bool where
         I: IntoIterator,
@@ -2671,6 +2723,14 @@ pub trait Iterator {
 
     /// Determines if the elements of this `Iterator` are lexicographically
     /// greater than those of another.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!([1].iter().gt([1].iter()), false);
+    /// assert_eq!([1].iter().gt([1, 2].iter()), false);
+    /// assert_eq!([1, 2].iter().gt([1].iter()), true);
+    /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn gt<I>(self, other: I) -> bool where
         I: IntoIterator,
@@ -2682,6 +2742,14 @@ pub trait Iterator {
 
     /// Determines if the elements of this `Iterator` are lexicographically
     /// greater than or equal to those of another.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!([1].iter().ge([1].iter()), true);
+    /// assert_eq!([1].iter().ge([1, 2].iter()), false);
+    /// assert_eq!([1, 2].iter().ge([1].iter()), true);
+    /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
     fn ge<I>(self, other: I) -> bool where
         I: IntoIterator,
@@ -2730,6 +2798,18 @@ pub trait Iterator {
     /// function to determine the ordering of two elements. Apart from that, it's equivalent to
     /// [`is_sorted`]; see its documentation for more information.
     ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(is_sorted)]
+    ///
+    /// assert!([1, 2, 2, 9].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
+    /// assert!(![1, 3, 2, 4].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
+    /// assert!([0].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
+    /// assert!(std::iter::empty::<i32>().is_sorted_by(|a, b| a.partial_cmp(b)));
+    /// assert!(![0.0, 1.0, std::f32::NAN].iter().is_sorted_by(|a, b| a.partial_cmp(b)));
+    /// ```
+    ///
     /// [`is_sorted`]: trait.Iterator.html#method.is_sorted
     #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
     fn is_sorted_by<F>(mut self, mut compare: F) -> bool

From d4d5aa436d4e378feff27491b11f351806c578aa Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Thu, 5 Sep 2019 14:15:58 +0200
Subject: [PATCH 522/943] Fix invalid span generation when it should be div

---
 src/librustdoc/html/render.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index d5c47a15948fb..0e046b8cd4456 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -3554,7 +3554,7 @@ fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
             let ns_id = cx.derive_id(format!("{}.{}",
                                           variant.name.as_ref().unwrap(),
                                           ItemType::Variant.name_space()));
-            write!(w, "<span id=\"{id}\" class=\"variant small-section-header\">\
+            write!(w, "<div id=\"{id}\" class=\"variant small-section-header\">\
                        <a href=\"#{id}\" class=\"anchor field\"></a>\
                        <code id='{ns_id}'>{name}",
                    id = id,
@@ -3572,7 +3572,7 @@ fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                     write!(w, ")")?;
                 }
             }
-            write!(w, "</code></span>")?;
+            write!(w, "</code></div>")?;
             document(w, cx, variant)?;
             document_non_exhaustive(w, variant)?;
 
@@ -3583,7 +3583,7 @@ fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                 let variant_id = cx.derive_id(format!("{}.{}.fields",
                                                    ItemType::Variant,
                                                    variant.name.as_ref().unwrap()));
-                write!(w, "<span class='autohide sub-variant' id='{id}'>",
+                write!(w, "<div class='autohide sub-variant' id='{id}'>",
                        id = variant_id)?;
                 write!(w, "<h3>Fields of <b>{name}</b></h3><div>",
                        name = variant.name.as_ref().unwrap())?;
@@ -3609,7 +3609,7 @@ fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                         document(w, cx, field)?;
                     }
                 }
-                write!(w, "</div></span>")?;
+                write!(w, "</div></div>")?;
             }
             render_stability_since(w, variant, it)?;
         }

From 0133941f47b039d652f5d9f2617b7d3884298515 Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sun, 25 Aug 2019 19:59:51 +0100
Subject: [PATCH 523/943] Add an ExpnKind for AST passes

---
 src/librustc/ich/impls_syntax.rs |  8 ++++++++
 src/librustc/lint/mod.rs         |  2 +-
 src/libsyntax_pos/hygiene.rs     | 24 +++++++++++++++++++++++-
 src/libsyntax_pos/lib.rs         |  1 +
 4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 05e2c7854b49c..532485b5d77bb 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -411,9 +411,17 @@ impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData {
 impl_stable_hash_for!(enum ::syntax_pos::hygiene::ExpnKind {
     Root,
     Macro(kind, descr),
+    AstPass(kind),
     Desugaring(kind)
 });
 
+impl_stable_hash_for!(enum ::syntax_pos::hygiene::AstPass {
+    StdImports,
+    TestHarness,
+    ProcMacroHarness,
+    PluginMacroDefs,
+});
+
 impl_stable_hash_for!(enum ::syntax_pos::hygiene::DesugaringKind {
     CondTemporary,
     Async,
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 2b58627cdea56..1b133819a73bf 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -888,7 +888,7 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
     let expn_data = span.ctxt().outer_expn_data();
     match expn_data.kind {
         ExpnKind::Root | ExpnKind::Desugaring(DesugaringKind::ForLoop) => false,
-        ExpnKind::Desugaring(_) => true, // well, it's "external"
+        ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
         ExpnKind::Macro(MacroKind::Bang, _) => {
             if expn_data.def_site.is_dummy() {
                 // dummy span for the def_site means it's an external macro
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index 733f6f0449065..237a02f2f667a 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -639,8 +639,9 @@ pub enum ExpnKind {
     /// No expansion, aka root expansion. Only `ExpnId::root()` has this kind.
     Root,
     /// Expansion produced by a macro.
-    /// FIXME: Some code injected by the compiler before HIR lowering also gets this kind.
     Macro(MacroKind, Symbol),
+    /// Transform done by the compiler on the AST.
+    AstPass(AstPass),
     /// Desugaring done by the compiler during HIR lowering.
     Desugaring(DesugaringKind)
 }
@@ -650,6 +651,7 @@ impl ExpnKind {
         match *self {
             ExpnKind::Root => kw::PathRoot,
             ExpnKind::Macro(_, descr) => descr,
+            ExpnKind::AstPass(kind) => Symbol::intern(kind.descr()),
             ExpnKind::Desugaring(kind) => Symbol::intern(kind.descr()),
         }
     }
@@ -683,6 +685,26 @@ impl MacroKind {
     }
 }
 
+/// The kind of AST transform.
+#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable)]
+pub enum AstPass {
+    StdImports,
+    TestHarness,
+    ProcMacroHarness,
+    PluginMacroDefs,
+}
+
+impl AstPass {
+    fn descr(self) -> &'static str {
+        match self {
+            AstPass::StdImports => "standard library imports",
+            AstPass::TestHarness => "test harness",
+            AstPass::ProcMacroHarness => "proc macro harness",
+            AstPass::PluginMacroDefs => "plugin macro definitions",
+        }
+    }
+}
+
 /// The kind of compiler desugaring.
 #[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable)]
 pub enum DesugaringKind {
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 3d8bfc77a8950..d800109cf8531 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -442,6 +442,7 @@ impl Span {
                 let (pre, post) = match expn_data.kind {
                     ExpnKind::Root => break,
                     ExpnKind::Desugaring(..) => ("desugaring of ", ""),
+                    ExpnKind::AstPass(..) => ("", ""),
                     ExpnKind::Macro(macro_kind, _) => match macro_kind {
                         MacroKind::Bang => ("", "!"),
                         MacroKind::Attr => ("#[", "]"),

From 4082cd95a8de6c8244e9b44908f9859e75acdeea Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sun, 25 Aug 2019 20:58:03 +0100
Subject: [PATCH 524/943] Allow ast passes to create hygienic spans

---
 src/librustc_resolve/build_reduced_graph.rs |  3 +-
 src/librustc_resolve/lib.rs                 | 22 ++++++++++++
 src/librustc_resolve/macros.rs              | 39 ++++++++++++++++++++-
 src/libsyntax/ext/base.rs                   | 10 +++++-
 src/libsyntax_pos/hygiene.rs                |  2 +-
 5 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 9a794ade729c2..5a3b768301ce0 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -126,7 +126,8 @@ impl<'a> Resolver<'a> {
     crate fn macro_def_scope(&mut self, expn_id: ExpnId) -> Module<'a> {
         let def_id = match self.macro_defs.get(&expn_id) {
             Some(def_id) => *def_id,
-            None => return self.graph_root,
+            None => return self.ast_transform_scopes.get(&expn_id)
+                .unwrap_or(&self.graph_root),
         };
         if let Some(id) = self.definitions.as_local_node_id(def_id) {
             self.local_macro_def_scopes[&id]
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 875ae449d94e0..b12bf4521e098 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -879,6 +879,10 @@ pub struct Resolver<'a> {
     /// There will be an anonymous module created around `g` with the ID of the
     /// entry block for `f`.
     block_map: NodeMap<Module<'a>>,
+    /// A fake module that contains no definition and no prelude. Used so that
+    /// some AST passes can generate identifiers that only resolve to local or
+    /// language items.
+    empty_module: Module<'a>,
     module_map: FxHashMap<DefId, Module<'a>>,
     extern_module_map: FxHashMap<(DefId, bool /* MacrosOnly? */), Module<'a>>,
     binding_parent_modules: FxHashMap<PtrKey<'a, NameBinding<'a>>, Module<'a>>,
@@ -913,6 +917,7 @@ pub struct Resolver<'a> {
     non_macro_attrs: [Lrc<SyntaxExtension>; 2],
     macro_defs: FxHashMap<ExpnId, DefId>,
     local_macro_def_scopes: FxHashMap<NodeId, Module<'a>>,
+    ast_transform_scopes: FxHashMap<ExpnId, Module<'a>>,
     unused_macros: NodeMap<Span>,
     proc_macro_stubs: NodeSet,
     /// Traces collected during macro resolution and validated when it's complete.
@@ -1080,6 +1085,21 @@ impl<'a> Resolver<'a> {
             no_implicit_prelude: attr::contains_name(&krate.attrs, sym::no_implicit_prelude),
             ..ModuleData::new(None, root_module_kind, root_def_id, ExpnId::root(), krate.span)
         });
+        let empty_module_kind = ModuleKind::Def(
+            DefKind::Mod,
+            root_def_id,
+            kw::Invalid,
+        );
+        let empty_module = arenas.alloc_module(ModuleData {
+            no_implicit_prelude: true,
+            ..ModuleData::new(
+                Some(graph_root),
+                empty_module_kind,
+                root_def_id,
+                ExpnId::root(),
+                DUMMY_SP,
+            )
+        });
         let mut module_map = FxHashMap::default();
         module_map.insert(DefId::local(CRATE_DEF_INDEX), graph_root);
 
@@ -1139,10 +1159,12 @@ impl<'a> Resolver<'a> {
             label_res_map: Default::default(),
             export_map: FxHashMap::default(),
             trait_map: Default::default(),
+            empty_module,
             module_map,
             block_map: Default::default(),
             extern_module_map: FxHashMap::default(),
             binding_parent_modules: FxHashMap::default(),
+            ast_transform_scopes: FxHashMap::default(),
 
             glob_map: Default::default(),
 
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 719167eb057b2..fe7eae91945f7 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -8,6 +8,7 @@ use crate::{ModuleOrUniformRoot, KNOWN_TOOLS};
 use crate::Namespace::*;
 use crate::resolve_imports::ImportResolver;
 use rustc::hir::def::{self, DefKind, NonMacroAttrKind};
+use rustc::hir::def_id;
 use rustc::middle::stability;
 use rustc::{ty, lint, span_bug};
 use syntax::ast::{self, NodeId, Ident};
@@ -16,7 +17,7 @@ use syntax::edition::Edition;
 use syntax::ext::base::{self, Indeterminate, SpecialDerives};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
-use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind};
+use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind, Transparency};
 use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name};
 use syntax::feature_gate::GateIssue;
@@ -25,6 +26,7 @@ use syntax_pos::{Span, DUMMY_SP};
 
 use std::{mem, ptr};
 use rustc_data_structures::sync::Lrc;
+use syntax_pos::hygiene::AstPass;
 
 type Res = def::Res<NodeId>;
 
@@ -136,6 +138,41 @@ impl<'a> base::Resolver for Resolver<'a> {
         }
     }
 
+    // Create a Span with modern hygiene with a definition site of the provided
+    // module, or a fake empty `#[no_implicit_prelude]` module if no module is
+    // provided.
+    fn span_for_ast_pass(
+        &mut self,
+        base_span: Span,
+        pass: AstPass,
+        features: &[Symbol],
+        parent_module_id: Option<NodeId>,
+    ) -> Span {
+        let span = base_span.fresh_expansion_with_transparency(
+            ExpnData::allow_unstable(
+                ExpnKind::AstPass(pass),
+                base_span,
+                self.session.edition(),
+                features.into(),
+            ),
+            Transparency::Opaque,
+        );
+        let expn_id = span.ctxt().outer_expn();
+        let parent_scope = if let Some(module_id) = parent_module_id {
+            let parent_def_id = self.definitions.local_def_id(module_id);
+            self.definitions.add_parent_module_of_macro_def(expn_id, parent_def_id);
+            self.module_map[&parent_def_id]
+        } else {
+            self.definitions.add_parent_module_of_macro_def(
+                expn_id,
+                def_id::DefId::local(def_id::CRATE_DEF_INDEX),
+            );
+            self.empty_module
+        };
+        self.ast_transform_scopes.insert(expn_id, parent_scope);
+        span
+    }
+
     fn resolve_imports(&mut self) {
         ImportResolver { r: self }.resolve_imports()
     }
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index a63c4181d5e03..3d274af99083c 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -15,7 +15,7 @@ use crate::tokenstream::{self, TokenStream, TokenTree};
 use errors::{DiagnosticBuilder, DiagnosticId};
 use smallvec::{smallvec, SmallVec};
 use syntax_pos::{FileName, Span, MultiSpan, DUMMY_SP};
-use syntax_pos::hygiene::{ExpnData, ExpnKind};
+use syntax_pos::hygiene::{AstPass, ExpnData, ExpnKind};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{self, Lrc};
@@ -660,6 +660,14 @@ pub trait Resolver {
                                             extra_placeholders: &[NodeId]);
     fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension);
 
+    fn span_for_ast_pass(
+        &mut self,
+        span: Span,
+        pass: AstPass,
+        features: &[Symbol],
+        parent_module_id: Option<NodeId>,
+    ) -> Span;
+
     fn resolve_imports(&mut self);
 
     fn resolve_macro_invocation(
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index 237a02f2f667a..99afe57ef5497 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -550,7 +550,7 @@ impl Span {
     /// The returned span belongs to the created expansion and has the new properties,
     /// but its location is inherited from the current span.
     pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
-        self.fresh_expansion_with_transparency(expn_data, Transparency::SemiTransparent)
+        self.fresh_expansion_with_transparency(expn_data, Transparency::Transparent)
     }
 
     pub fn fresh_expansion_with_transparency(

From 6fcdb36ccb60cca5c26ac804770a47fc01e0c2dd Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sun, 25 Aug 2019 21:03:24 +0100
Subject: [PATCH 525/943] Make use of hygiene in AST passes

---
 src/librustc_interface/passes.rs              |  27 +--
 src/librustc_resolve/macros.rs                |  10 -
 src/libsyntax/ext/base.rs                     |   2 -
 src/libsyntax_ext/plugin_macro_defs.rs        |   4 +-
 src/libsyntax_ext/proc_macro_harness.rs       |  86 +++++----
 src/libsyntax_ext/standard_library_imports.rs | 130 +++++++++----
 src/libsyntax_ext/test.rs                     |  19 +-
 src/libsyntax_ext/test_harness.rs             | 175 +++++-------------
 src/test/ui/hygiene/auxiliary/not-libstd.rs   |   1 +
 src/test/ui/hygiene/prelude-import-hygiene.rs |  29 +++
 src/test/ui/imports/gensymed.rs               |   4 +-
 src/test/ui/inaccessible-test-modules.stderr  |  21 ---
 src/test/ui/test-attrs/decl-macro-test.rs     |  22 +++
 .../inaccessible-test-modules.rs              |   4 +-
 .../inaccessible-test-modules.stderr          |  21 +++
 15 files changed, 298 insertions(+), 257 deletions(-)
 create mode 100644 src/test/ui/hygiene/auxiliary/not-libstd.rs
 create mode 100644 src/test/ui/hygiene/prelude-import-hygiene.rs
 delete mode 100644 src/test/ui/inaccessible-test-modules.stderr
 create mode 100644 src/test/ui/test-attrs/decl-macro-test.rs
 rename src/test/ui/{ => test-attrs}/inaccessible-test-modules.rs (56%)
 create mode 100644 src/test/ui/test-attrs/inaccessible-test-modules.stderr

diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 8b0b5a5b7a2bd..649cc8a2fb515 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -233,7 +233,7 @@ pub fn register_plugins<'a>(
         syntax::attr::inject(krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr)
     });
 
-    let (mut krate, features) = syntax::config::features(
+    let (krate, features) = syntax::config::features(
         krate,
         &sess.parse_sess,
         sess.edition(),
@@ -268,16 +268,6 @@ pub fn register_plugins<'a>(
         middle::recursion_limit::update_limits(sess, &krate);
     });
 
-    krate = time(sess, "crate injection", || {
-        let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| &**s);
-        let (krate, name) =
-            syntax_ext::standard_library_imports::inject(krate, alt_std_name, sess.edition());
-        if let Some(name) = name {
-            sess.parse_sess.injected_crate_name.set(name);
-        }
-        krate
-    });
-
     let registrars = time(sess, "plugin loading", || {
         plugin::load::load_plugins(
             sess,
@@ -370,6 +360,21 @@ fn configure_and_expand_inner<'a>(
         &resolver_arenas,
     );
     syntax_ext::register_builtin_macros(&mut resolver, sess.edition());
+
+    krate = time(sess, "crate injection", || {
+        let alt_std_name = sess.opts.alt_std_name.as_ref().map(|s| Symbol::intern(s));
+        let (krate, name) = syntax_ext::standard_library_imports::inject(
+            krate,
+            &mut resolver,
+            alt_std_name,
+            sess.edition(),
+        );
+        if let Some(name) = name {
+            sess.parse_sess.injected_crate_name.set(name);
+        }
+        krate
+    });
+
     syntax_ext::plugin_macro_defs::inject(
         &mut krate, &mut resolver, plugin_info.syntax_exts, sess.edition()
     );
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index fe7eae91945f7..20d281f1e997a 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -97,16 +97,6 @@ impl<'a> base::Resolver for Resolver<'a> {
         self.session.next_node_id()
     }
 
-    fn get_module_scope(&mut self, id: NodeId) -> ExpnId {
-        let expn_id = ExpnId::fresh(Some(ExpnData::default(
-            ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition()
-        )));
-        let module = self.module_map[&self.definitions.local_def_id(id)];
-        self.invocation_parent_scopes.insert(expn_id, ParentScope::module(module));
-        self.definitions.set_invocation_parent(expn_id, module.def_id().unwrap().index);
-        expn_id
-    }
-
     fn resolve_dollar_crates(&mut self) {
         hygiene::update_dollar_crate_names(|ctxt| {
             let ident = Ident::new(kw::DollarCrate, DUMMY_SP.with_ctxt(ctxt));
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 3d274af99083c..962447e8cf07f 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -653,8 +653,6 @@ bitflags::bitflags! {
 pub trait Resolver {
     fn next_node_id(&mut self) -> NodeId;
 
-    fn get_module_scope(&mut self, id: NodeId) -> ExpnId;
-
     fn resolve_dollar_crates(&mut self);
     fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment,
                                             extra_placeholders: &[NodeId]);
diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs
index dbfd8fe98f389..ccdc5bd81a04b 100644
--- a/src/libsyntax_ext/plugin_macro_defs.rs
+++ b/src/libsyntax_ext/plugin_macro_defs.rs
@@ -11,7 +11,7 @@ use syntax::source_map::respan;
 use syntax::symbol::sym;
 use syntax::tokenstream::*;
 use syntax_pos::{Span, DUMMY_SP};
-use syntax_pos::hygiene::{ExpnData, ExpnKind, MacroKind};
+use syntax_pos::hygiene::{ExpnData, ExpnKind, AstPass};
 
 use std::mem;
 
@@ -44,7 +44,7 @@ pub fn inject(
     if !named_exts.is_empty() {
         let mut extra_items = Vec::new();
         let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
-            ExpnKind::Macro(MacroKind::Attr, sym::plugin), DUMMY_SP, edition,
+            ExpnKind::AstPass(AstPass::PluginMacroDefs), DUMMY_SP, edition,
             [sym::rustc_attrs][..].into(),
         ));
         for (name, ext) in named_exts {
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index e772eaf834964..1cdaa1190fae3 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -3,8 +3,7 @@ use std::mem;
 use smallvec::smallvec;
 use syntax::ast::{self, Ident};
 use syntax::attr;
-use syntax::source_map::{ExpnData, ExpnKind, respan};
-use syntax::ext::base::{ExtCtxt, MacroKind};
+use syntax::ext::base::ExtCtxt;
 use syntax::ext::expand::{AstFragment, ExpansionConfig};
 use syntax::ext::proc_macro::is_proc_macro_attr;
 use syntax::parse::ParseSess;
@@ -12,6 +11,7 @@ use syntax::ptr::P;
 use syntax::symbol::{kw, sym};
 use syntax::visit::{self, Visitor};
 use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::hygiene::AstPass;
 
 struct ProcMacroDerive {
     trait_name: ast::Name,
@@ -308,8 +308,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
 
 // Creates a new module which looks like:
 //
-//      #[doc(hidden)]
-//      mod $gensym {
+//      const _: () = {
 //          extern crate proc_macro;
 //
 //          use proc_macro::bridge::client::ProcMacro;
@@ -327,32 +326,29 @@ fn mk_decls(
     custom_attrs: &[ProcMacroDef],
     custom_macros: &[ProcMacroDef],
 ) -> P<ast::Item> {
-    let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
-        ExpnKind::Macro(MacroKind::Attr, sym::proc_macro), DUMMY_SP, cx.parse_sess.edition,
-        [sym::rustc_attrs, sym::proc_macro_internals][..].into(),
-    ));
-
-    let hidden = cx.meta_list_item_word(span, sym::hidden);
-    let doc = cx.meta_list(span, sym::doc, vec![hidden]);
-    let doc_hidden = cx.attribute(doc);
-
-    let proc_macro = Ident::with_dummy_span(sym::proc_macro);
+    let span = cx.resolver.span_for_ast_pass(
+        DUMMY_SP,
+        AstPass::ProcMacroHarness,
+        &[sym::rustc_attrs, sym::proc_macro_internals],
+        None,
+    );
+
+    let proc_macro = Ident::new(sym::proc_macro, span);
     let krate = cx.item(span,
                         proc_macro,
                         Vec::new(),
                         ast::ItemKind::ExternCrate(None));
 
-    let bridge = Ident::from_str("bridge");
-    let client = Ident::from_str("client");
-    let proc_macro_ty = Ident::from_str("ProcMacro");
-    let custom_derive = Ident::from_str("custom_derive");
-    let attr = Ident::from_str("attr");
-    let bang = Ident::from_str("bang");
-    let crate_kw = Ident::with_dummy_span(kw::Crate);
+    let bridge = Ident::from_str_and_span("bridge", span);
+    let client = Ident::from_str_and_span("client", span);
+    let proc_macro_ty = Ident::from_str_and_span("ProcMacro", span);
+    let custom_derive = Ident::from_str_and_span("custom_derive", span);
+    let attr = Ident::from_str_and_span("attr", span);
+    let bang = Ident::from_str_and_span("bang", span);
 
     let decls = {
         let local_path = |sp: Span, name| {
-            cx.expr_path(cx.path(sp.with_ctxt(span.ctxt()), vec![crate_kw, name]))
+            cx.expr_path(cx.path(sp.with_ctxt(span.ctxt()), vec![name]))
         };
         let proc_macro_ty_method_path = |method| cx.expr_path(cx.path(span, vec![
             proc_macro, bridge, client, proc_macro_ty, method,
@@ -381,7 +377,7 @@ fn mk_decls(
 
     let decls_static = cx.item_static(
         span,
-        Ident::from_str("_DECLS"),
+        Ident::from_str_and_span("_DECLS", span),
         cx.ty_rptr(span,
             cx.ty(span, ast::TyKind::Slice(
                 cx.ty_path(cx.path(span,
@@ -392,22 +388,44 @@ fn mk_decls(
     ).map(|mut i| {
         let attr = cx.meta_word(span, sym::rustc_proc_macro_decls);
         i.attrs.push(cx.attribute(attr));
-        i.vis = respan(span, ast::VisibilityKind::Public);
         i
     });
 
-    let module = cx.item_mod(
-        span,
+    let block = P(ast::Expr {
+        id: ast::DUMMY_NODE_ID,
+        attrs: syntax::ThinVec::new(),
+        node: ast::ExprKind::Block(P(ast::Block {
+            id: ast::DUMMY_NODE_ID,
+            rules: ast::BlockCheckMode::Default,
+            stmts: vec![
+                ast::Stmt {
+                    id: ast::DUMMY_NODE_ID,
+                    node: ast::StmtKind::Item(krate),
+                    span,
+                },
+                ast::Stmt {
+                    id: ast::DUMMY_NODE_ID,
+                    node: ast::StmtKind::Item(decls_static),
+                    span,
+                }
+            ],
+            span,
+        }), None),
         span,
-        ast::Ident::from_str("decls").gensym(),
-        vec![doc_hidden],
-        vec![krate, decls_static],
-    ).map(|mut i| {
-        i.vis = respan(span, ast::VisibilityKind::Public);
-        i
     });
 
+    let anon_constant = cx.item_const(
+        span,
+        ast::Ident::new(kw::Underscore, span),
+        P(ast::Ty {
+            id: ast::DUMMY_NODE_ID,
+            node: ast::TyKind::Tup(Vec::new()),
+            span,
+        }),
+        block,
+    );
+
     // Integrate the new module into existing module structures.
-    let module = AstFragment::Items(smallvec![module]);
-    cx.monotonic_expander().fully_expand_fragment(module).make_items().pop().unwrap()
+    let items = AstFragment::Items(smallvec![anon_constant]);
+    cx.monotonic_expander().fully_expand_fragment(items).make_items().pop().unwrap()
 }
diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs
index 8ca376341fcdb..61e423266fa05 100644
--- a/src/libsyntax_ext/standard_library_imports.rs
+++ b/src/libsyntax_ext/standard_library_imports.rs
@@ -1,52 +1,56 @@
 use syntax::{ast, attr};
 use syntax::edition::Edition;
-use syntax::ext::hygiene::MacroKind;
+use syntax::ext::hygiene::AstPass;
+use syntax::ext::base::Resolver;
 use syntax::ptr::P;
-use syntax::source_map::{ExpnData, ExpnKind, dummy_spanned, respan};
+use syntax::source_map::respan;
 use syntax::symbol::{Ident, Symbol, kw, sym};
 use syntax_pos::DUMMY_SP;
 
-use std::iter;
-
 pub fn inject(
-    mut krate: ast::Crate, alt_std_name: Option<&str>, edition: Edition
+    mut krate: ast::Crate,
+    resolver: &mut dyn Resolver,
+    alt_std_name: Option<Symbol>,
+    edition: Edition,
 ) -> (ast::Crate, Option<Symbol>) {
     let rust_2018 = edition >= Edition::Edition2018;
 
     // the first name in this list is the crate name of the crate with the prelude
-    let names: &[&str] = if attr::contains_name(&krate.attrs, sym::no_core) {
+    let names: &[Symbol] = if attr::contains_name(&krate.attrs, sym::no_core) {
         return (krate, None);
     } else if attr::contains_name(&krate.attrs, sym::no_std) {
         if attr::contains_name(&krate.attrs, sym::compiler_builtins) {
-            &["core"]
+            &[sym::core]
         } else {
-            &["core", "compiler_builtins"]
+            &[sym::core, sym::compiler_builtins]
         }
     } else {
-        &["std"]
+        &[sym::std]
     };
 
+    let span = resolver.span_for_ast_pass(
+        DUMMY_SP,
+        AstPass::StdImports,
+        &[sym::prelude_import],
+        None,
+    );
+
     // .rev() to preserve ordering above in combination with insert(0, ...)
-    let alt_std_name = alt_std_name.map(Symbol::intern);
-    for orig_name_str in names.iter().rev() {
-        // HACK(eddyb) gensym the injected crates on the Rust 2018 edition,
-        // so they don't accidentally interfere with the new import paths.
-        let orig_name_sym = Symbol::intern(orig_name_str);
-        let orig_name_ident = Ident::with_dummy_span(orig_name_sym);
+    for &orig_name_sym in names.iter().rev() {
         let (rename, orig_name) = if rust_2018 {
-            (orig_name_ident.gensym(), Some(orig_name_sym))
+            (Ident::new(kw::Underscore, span), Some(orig_name_sym))
         } else {
-            (orig_name_ident, None)
+            (Ident::with_dummy_span(orig_name_sym), None)
         };
         krate.module.items.insert(0, P(ast::Item {
             attrs: vec![attr::mk_attr_outer(
-                attr::mk_word_item(ast::Ident::with_dummy_span(sym::macro_use))
+                attr::mk_word_item(ast::Ident::new(sym::macro_use, span))
             )],
-            vis: dummy_spanned(ast::VisibilityKind::Inherited),
+            vis: respan(span, ast::VisibilityKind::Inherited),
             node: ast::ItemKind::ExternCrate(alt_std_name.or(orig_name)),
             ident: rename,
             id: ast::DUMMY_NODE_ID,
-            span: DUMMY_SP,
+            span,
             tokens: None,
         }));
     }
@@ -55,24 +59,22 @@ pub fn inject(
     // the prelude.
     let name = names[0];
 
-    let span = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
-        ExpnKind::Macro(MacroKind::Attr, sym::std_inject), DUMMY_SP, edition,
-        [sym::prelude_import][..].into(),
-    ));
+    let segments = if rust_2018 {
+        [name, sym::prelude, sym::v1].iter()
+            .map(|symbol| ast::PathSegment::from_ident(ast::Ident::new(*symbol, span)))
+            .collect()
+    } else {
+        [kw::PathRoot, name, sym::prelude, sym::v1].iter()
+            .map(|symbol| ast::PathSegment::from_ident(ast::Ident::with_dummy_span(*symbol)))
+            .collect()
+    };
 
-    krate.module.items.insert(0, P(ast::Item {
+    let use_item = P(ast::Item {
         attrs: vec![attr::mk_attr_outer(
             attr::mk_word_item(ast::Ident::new(sym::prelude_import, span)))],
         vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
         node: ast::ItemKind::Use(P(ast::UseTree {
-            prefix: ast::Path {
-                segments: iter::once(ast::Ident::with_dummy_span(kw::PathRoot))
-                    .chain(
-                        [name, "prelude", "v1"].iter().cloned()
-                            .map(ast::Ident::from_str)
-                    ).map(ast::PathSegment::from_ident).collect(),
-                span,
-            },
+            prefix: ast::Path { segments, span },
             kind: ast::UseTreeKind::Glob,
             span,
         })),
@@ -80,7 +82,65 @@ pub fn inject(
         ident: ast::Ident::invalid(),
         span,
         tokens: None,
-    }));
+    });
+
+    let prelude_import_item = if rust_2018 {
+        let hygienic_extern_crate = P(ast::Item {
+            attrs: vec![],
+            vis: respan(span, ast::VisibilityKind::Inherited),
+            node: ast::ItemKind::ExternCrate(alt_std_name),
+            ident: ast::Ident::new(name, span),
+            id: ast::DUMMY_NODE_ID,
+            span,
+            tokens: None,
+        });
+
+        // Use an anonymous const to hide `extern crate std as hygienic_std`
+        // FIXME: Once inter-crate hygiene exists, this can just be `use_item`.
+        P(ast::Item {
+            attrs: Vec::new(),
+            vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
+            node: ast::ItemKind::Const(
+                P(ast::Ty {
+                    id: ast::DUMMY_NODE_ID,
+                    node: ast::TyKind::Tup(Vec::new()),
+                    span,
+                }),
+                P(ast::Expr {
+                    id: ast::DUMMY_NODE_ID,
+                    attrs: syntax::ThinVec::new(),
+                    node: ast::ExprKind::Block(P(ast::Block {
+                        id: ast::DUMMY_NODE_ID,
+                        rules: ast::BlockCheckMode::Default,
+                        stmts: vec![
+                            ast::Stmt {
+                                id: ast::DUMMY_NODE_ID,
+                                node: ast::StmtKind::Item(use_item),
+                                span,
+                            },
+                            ast::Stmt {
+                                id: ast::DUMMY_NODE_ID,
+                                node: ast::StmtKind::Item(hygienic_extern_crate),
+                                span,
+                            }
+                        ],
+                        span,
+                    }), None),
+                    span,
+                })
+            ),
+            id: ast::DUMMY_NODE_ID,
+            ident: ast::Ident::new(kw::Underscore, span),
+            span,
+            tokens: None,
+        })
+    } else {
+        // Have `extern crate std` at the root, so don't need to create a named
+        // extern crate item.
+        use_item
+    };
+
+    krate.module.items.insert(0, prelude_import_item);
 
-    (krate, Some(Symbol::intern(name)))
+    (krate, Some(name))
 }
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index 5fd87d3a0e5c6..be5aca73f5cb1 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -28,11 +28,11 @@ pub fn expand_test_case(
 
     if !ecx.ecfg.should_test { return vec![]; }
 
-    let sp = ecx.with_legacy_ctxt(attr_sp);
+    let sp = ecx.with_def_site_ctxt(attr_sp);
     let mut item = anno_item.expect_item();
     item = item.map(|mut item| {
         item.vis = respan(item.vis.span, ast::VisibilityKind::Public);
-        item.ident = item.ident.gensym();
+        item.ident.span = item.ident.span.with_ctxt(sp.ctxt());
         item.attrs.push(
             ecx.attribute(ecx.meta_word(sp, sym::rustc_test_marker))
         );
@@ -92,10 +92,9 @@ pub fn expand_test_or_bench(
         return vec![Annotatable::Item(item)];
     }
 
-    let (sp, attr_sp) = (cx.with_legacy_ctxt(item.span), cx.with_legacy_ctxt(attr_sp));
+    let (sp, attr_sp) = (cx.with_def_site_ctxt(item.span), cx.with_def_site_ctxt(attr_sp));
 
-    // Gensym "test" so we can extern crate without conflicting with any local names
-    let test_id = cx.ident_of("test").gensym();
+    let test_id = ast::Ident::new(sym::test, attr_sp);
 
     // creates test::$name
     let test_path = |name| {
@@ -112,7 +111,7 @@ pub fn expand_test_or_bench(
 
     let test_fn = if is_bench {
         // A simple ident for a lambda
-        let b = cx.ident_of("b");
+        let b = ast::Ident::from_str_and_span("b", attr_sp);
 
         cx.expr_call(sp, cx.expr_path(test_path("StaticBenchFn")), vec![
             // |b| self::test::assert_test_result(
@@ -143,7 +142,7 @@ pub fn expand_test_or_bench(
         ])
     };
 
-    let mut test_const = cx.item(sp, ast::Ident::new(item.ident.name, sp).gensym(),
+    let mut test_const = cx.item(sp, ast::Ident::new(item.ident.name, sp),
         vec![
             // #[cfg(test)]
             cx.attribute(cx.meta_list(attr_sp, sym::cfg, vec![
@@ -192,17 +191,17 @@ pub fn expand_test_or_bench(
         ));
     test_const = test_const.map(|mut tc| { tc.vis.node = ast::VisibilityKind::Public; tc});
 
-    // extern crate test as test_gensym
+    // extern crate test
     let test_extern = cx.item(sp,
         test_id,
         vec![],
-        ast::ItemKind::ExternCrate(Some(sym::test))
+        ast::ItemKind::ExternCrate(None)
     );
 
     log::debug!("synthetic test item:\n{}\n", pprust::item_to_string(&test_const));
 
     vec![
-        // Access to libtest under a gensymed name
+        // Access to libtest under a hygienic name
         Annotatable::Item(test_extern),
         // The generated test case
         Annotatable::Item(test_const),
diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index 4a6ea0ebf85e5..6eb132979df8f 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -5,32 +5,29 @@ use smallvec::{smallvec, SmallVec};
 use syntax::ast::{self, Ident};
 use syntax::attr;
 use syntax::entry::{self, EntryPointType};
-use syntax::ext::base::{ExtCtxt, MacroKind, Resolver};
+use syntax::ext::base::{ExtCtxt, Resolver};
 use syntax::ext::expand::{AstFragment, ExpansionConfig};
 use syntax::feature_gate::Features;
 use syntax::mut_visit::{*, ExpectOne};
 use syntax::parse::ParseSess;
 use syntax::ptr::P;
-use syntax::source_map::{ExpnData, ExpnKind, dummy_spanned};
-use syntax::symbol::{kw, sym, Symbol};
+use syntax::source_map::respan;
+use syntax::symbol::{sym, Symbol};
 use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::hygiene::{AstPass, SyntaxContext, Transparency};
 
 use std::{iter, mem};
 
 struct Test {
     span: Span,
-    path: Vec<Ident>,
+    ident: Ident,
 }
 
 struct TestCtxt<'a> {
-    span_diagnostic: &'a errors::Handler,
-    path: Vec<Ident>,
     ext_cx: ExtCtxt<'a>,
     test_cases: Vec<Test>,
     reexport_test_harness_main: Option<Symbol>,
     test_runner: Option<ast::Path>,
-    // top-level re-export submodule, filled out after folding is finished
-    toplevel_reexport: Option<Ident>,
 }
 
 // Traverse the crate, collecting all the test functions, eliding any
@@ -43,8 +40,8 @@ pub fn inject(
     span_diagnostic: &errors::Handler,
     features: &Features,
 ) {
-    // Check for #[reexport_test_harness_main = "some_name"] which
-    // creates a `use __test::main as some_name;`. This needs to be
+    // Check for #![reexport_test_harness_main = "some_name"] which gives the
+    // main test function the name `some_name` without hygiene. This needs to be
     // unconditional, so that the attribute is still marked as used in
     // non-test builds.
     let reexport_test_harness_main =
@@ -56,16 +53,13 @@ pub fn inject(
 
     if should_test {
         generate_test_harness(sess, resolver, reexport_test_harness_main,
-                              krate, span_diagnostic, features, test_runner)
+                              krate, features, test_runner)
     }
 }
 
 struct TestHarnessGenerator<'a> {
     cx: TestCtxt<'a>,
-    tests: Vec<Ident>,
-
-    // submodule name, gensym'd identifier for re-exports
-    tested_submods: Vec<(Ident, Ident)>,
+    tests: Vec<Test>,
 }
 
 impl<'a> MutVisitor for TestHarnessGenerator<'a> {
@@ -77,49 +71,46 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
     }
 
     fn flat_map_item(&mut self, i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
-        let ident = i.ident;
-        if ident.name != kw::Invalid {
-            self.cx.path.push(ident);
-        }
-        debug!("current path: {}", path_name_i(&self.cx.path));
-
         let mut item = i.into_inner();
         if is_test_case(&item) {
             debug!("this is a test item");
 
             let test = Test {
                 span: item.span,
-                path: self.cx.path.clone(),
+                ident: item.ident,
             };
-            self.cx.test_cases.push(test);
-            self.tests.push(item.ident);
+            self.tests.push(test);
         }
 
         // We don't want to recurse into anything other than mods, since
         // mods or tests inside of functions will break things
         if let ast::ItemKind::Mod(mut module) = item.node {
             let tests = mem::take(&mut self.tests);
-            let tested_submods = mem::take(&mut self.tested_submods);
             noop_visit_mod(&mut module, self);
-            let tests = mem::replace(&mut self.tests, tests);
-            let tested_submods = mem::replace(&mut self.tested_submods, tested_submods);
+            let mut tests = mem::replace(&mut self.tests, tests);
 
-            if !tests.is_empty() || !tested_submods.is_empty() {
-                let (it, sym) = mk_reexport_mod(&mut self.cx, item.id, tests, tested_submods);
-                module.items.push(it);
-
-                if !self.cx.path.is_empty() {
-                    self.tested_submods.push((self.cx.path[self.cx.path.len()-1], sym));
+            if !tests.is_empty() {
+                let parent = if item.id == ast::DUMMY_NODE_ID {
+                    ast::CRATE_NODE_ID
                 } else {
-                    debug!("pushing nothing, sym: {:?}", sym);
-                    self.cx.toplevel_reexport = Some(sym);
+                    item.id
+                };
+                // Create an identifier that will hygienically resolve the test
+                // case name, even in another module.
+                let sp = self.cx.ext_cx.resolver.span_for_ast_pass(
+                    module.inner,
+                    AstPass::TestHarness,
+                    &[],
+                    Some(parent),
+                );
+                let expn = sp.ctxt().outer_expn();
+                for test in &mut tests {
+                    test.ident.span = test.ident.span.apply_mark(expn, Transparency::Opaque);
                 }
+                self.cx.test_cases.extend(tests);
             }
             item.node = ast::ItemKind::Mod(module);
         }
-        if ident.name != kw::Invalid {
-            self.cx.path.pop();
-        }
         smallvec![P(item)]
     }
 
@@ -181,59 +172,11 @@ impl MutVisitor for EntryPointCleaner {
     }
 }
 
-/// Creates an item (specifically a module) that "pub use"s the tests passed in.
-/// Each tested submodule will contain a similar reexport module that we will export
-/// under the name of the original module. That is, `submod::__test_reexports` is
-/// reexported like so `pub use submod::__test_reexports as submod`.
-fn mk_reexport_mod(cx: &mut TestCtxt<'_>,
-                   parent: ast::NodeId,
-                   tests: Vec<Ident>,
-                   tested_submods: Vec<(Ident, Ident)>)
-                   -> (P<ast::Item>, Ident) {
-    let super_ = Ident::with_dummy_span(kw::Super);
-
-    let items = tests.into_iter().map(|r| {
-        cx.ext_cx.item_use_simple(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public),
-                                  cx.ext_cx.path(DUMMY_SP, vec![super_, r]))
-    }).chain(tested_submods.into_iter().map(|(r, sym)| {
-        let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]);
-        cx.ext_cx.item_use_simple_(DUMMY_SP, dummy_spanned(ast::VisibilityKind::Public),
-                                   Some(r), path)
-    })).collect();
-
-    let reexport_mod = ast::Mod {
-        inline: true,
-        inner: DUMMY_SP,
-        items,
-    };
-
-    let name = Ident::from_str("__test_reexports").gensym();
-    let parent = if parent == ast::DUMMY_NODE_ID { ast::CRATE_NODE_ID } else { parent };
-    cx.ext_cx.current_expansion.id = cx.ext_cx.resolver.get_module_scope(parent);
-    let module = P(ast::Item {
-        ident: name,
-        attrs: Vec::new(),
-        id: ast::DUMMY_NODE_ID,
-        node: ast::ItemKind::Mod(reexport_mod),
-        vis: dummy_spanned(ast::VisibilityKind::Public),
-        span: DUMMY_SP,
-        tokens: None,
-    });
-
-    // Integrate the new module into existing module structures.
-    let module = AstFragment::Items(smallvec![module]);
-    let module =
-        cx.ext_cx.monotonic_expander().fully_expand_fragment(module).make_items().pop().unwrap();
-
-    (module, name)
-}
-
 /// Crawl over the crate, inserting test reexports and the test main function
 fn generate_test_harness(sess: &ParseSess,
                          resolver: &mut dyn Resolver,
                          reexport_test_harness_main: Option<Symbol>,
                          krate: &mut ast::Crate,
-                         sd: &errors::Handler,
                          features: &Features,
                          test_runner: Option<ast::Path>) {
     // Remove the entry points
@@ -244,19 +187,15 @@ fn generate_test_harness(sess: &ParseSess,
     econfig.features = Some(features);
 
     let cx = TestCtxt {
-        span_diagnostic: sd,
         ext_cx: ExtCtxt::new(sess, econfig, resolver),
-        path: Vec::new(),
         test_cases: Vec::new(),
         reexport_test_harness_main,
-        toplevel_reexport: None,
         test_runner
     };
 
     TestHarnessGenerator {
         cx,
         tests: Vec::new(),
-        tested_submods: Vec::new(),
     }.visit_crate(krate);
 }
 
@@ -268,12 +207,14 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     //            #![main]
     //            test::test_main_static(&[..tests]);
     //        }
-    let sp = DUMMY_SP.fresh_expansion(ExpnData::allow_unstable(
-        ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, cx.ext_cx.parse_sess.edition,
-        [sym::main, sym::test, sym::rustc_attrs][..].into(),
-    ));
+    let sp = cx.ext_cx.resolver.span_for_ast_pass(
+        DUMMY_SP,
+        AstPass::TestHarness,
+        &[sym::main, sym::test, sym::rustc_attrs],
+        None,
+    );
     let ecx = &cx.ext_cx;
-    let test_id = Ident::with_dummy_span(sym::test);
+    let test_id = Ident::new(sym::test, sp);
 
     // test::test_main_static(...)
     let mut test_runner = cx.test_runner.clone().unwrap_or(
@@ -285,14 +226,14 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
 
     let test_main_path_expr = ecx.expr_path(test_runner);
     let call_test_main = ecx.expr_call(sp, test_main_path_expr,
-                                       vec![mk_tests_slice(cx)]);
+                                       vec![mk_tests_slice(cx, sp)]);
     let call_test_main = ecx.stmt_expr(call_test_main);
 
     // #![main]
     let main_meta = ecx.meta_word(sp, sym::main);
     let main_attr = ecx.attribute(main_meta);
 
-    // extern crate test as test_gensym
+    // extern crate test
     let test_extern_stmt = ecx.stmt_item(sp, ecx.item(sp,
         test_id,
         vec![],
@@ -316,8 +257,8 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
 
     // Honor the reexport_test_harness_main attribute
     let main_id = match cx.reexport_test_harness_main {
-        Some(sym) => Ident::new(sym, sp),
-        None => Ident::from_str_and_span("main", sp).gensym(),
+        Some(sym) => Ident::new(sym, sp.with_ctxt(SyntaxContext::root())),
+        None => Ident::from_str_and_span("main", sp),
     };
 
     let main = P(ast::Item {
@@ -325,7 +266,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
         attrs: vec![main_attr],
         id: ast::DUMMY_NODE_ID,
         node: main,
-        vis: dummy_spanned(ast::VisibilityKind::Public),
+        vis: respan(sp, ast::VisibilityKind::Public),
         span: sp,
         tokens: None,
     });
@@ -335,44 +276,20 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     cx.ext_cx.monotonic_expander().fully_expand_fragment(main).make_items().pop().unwrap()
 }
 
-fn path_name_i(idents: &[Ident]) -> String {
-    let mut path_name = "".to_string();
-    let mut idents_iter = idents.iter().peekable();
-    while let Some(ident) = idents_iter.next() {
-        path_name.push_str(&ident.as_str());
-        if idents_iter.peek().is_some() {
-            path_name.push_str("::")
-        }
-    }
-    path_name
-}
-
 /// Creates a slice containing every test like so:
-/// &[path::to::test1, path::to::test2]
-fn mk_tests_slice(cx: &TestCtxt<'_>) -> P<ast::Expr> {
+/// &[test1, test2]
+fn mk_tests_slice(cx: &TestCtxt<'_>, sp: Span) -> P<ast::Expr> {
     debug!("building test vector from {} tests", cx.test_cases.len());
     let ref ecx = cx.ext_cx;
 
-    ecx.expr_vec_slice(DUMMY_SP,
+
+    ecx.expr_vec_slice(sp,
         cx.test_cases.iter().map(|test| {
             ecx.expr_addr_of(test.span,
-                ecx.expr_path(ecx.path(test.span, visible_path(cx, &test.path))))
+                ecx.expr_path(ecx.path(test.span, vec![test.ident])))
         }).collect())
 }
 
-/// Creates a path from the top-level __test module to the test via __test_reexports
-fn visible_path(cx: &TestCtxt<'_>, path: &[Ident]) -> Vec<Ident>{
-    let mut visible_path = vec![];
-    match cx.toplevel_reexport {
-        Some(id) => visible_path.push(id),
-        None => {
-            cx.span_diagnostic.bug("expected to find top-level re-export name, but found None");
-        }
-    }
-    visible_path.extend_from_slice(path);
-    visible_path
-}
-
 fn is_test_case(i: &ast::Item) -> bool {
     attr::contains_name(&i.attrs, sym::rustc_test_marker)
 }
diff --git a/src/test/ui/hygiene/auxiliary/not-libstd.rs b/src/test/ui/hygiene/auxiliary/not-libstd.rs
new file mode 100644
index 0000000000000..babba293d03bd
--- /dev/null
+++ b/src/test/ui/hygiene/auxiliary/not-libstd.rs
@@ -0,0 +1 @@
+pub fn not_in_lib_std() {}
diff --git a/src/test/ui/hygiene/prelude-import-hygiene.rs b/src/test/ui/hygiene/prelude-import-hygiene.rs
new file mode 100644
index 0000000000000..51e7bed6580b3
--- /dev/null
+++ b/src/test/ui/hygiene/prelude-import-hygiene.rs
@@ -0,0 +1,29 @@
+// Make sure that attribute used when injecting the prelude are resolved
+// hygienically.
+
+// check-pass
+// aux-build:not-libstd.rs
+
+//revisions: rust2015 rust2018
+//[rust2018] edition:2018
+
+// The prelude import shouldn't see these as candidates for when it's trying to
+// use the built-in macros.
+extern crate core;
+use core::prelude::v1::test as prelude_import;
+use core::prelude::v1::test as macro_use;
+
+// Should not be used for the prelude import - not a concern in the 2015 edition
+// because `std` is already declared in the crate root.
+#[cfg(rust2018)]
+extern crate not_libstd as std;
+
+#[cfg(rust2018)]
+mod x {
+    // The extern crate item should override `std` in the extern prelude.
+    fn f() {
+        std::not_in_lib_std();
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/imports/gensymed.rs b/src/test/ui/imports/gensymed.rs
index 613ccc0b24234..7b53f0c536ad9 100644
--- a/src/test/ui/imports/gensymed.rs
+++ b/src/test/ui/imports/gensymed.rs
@@ -1,7 +1,9 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 // edition:2018
 // aux-build:gensymed.rs
 
 extern crate gensymed;
 
+use gensymed::*;
+
 fn main() {}
diff --git a/src/test/ui/inaccessible-test-modules.stderr b/src/test/ui/inaccessible-test-modules.stderr
deleted file mode 100644
index b6a817e6b1d30..0000000000000
--- a/src/test/ui/inaccessible-test-modules.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0432]: unresolved import `__test`
-  --> $DIR/inaccessible-test-modules.rs:5:5
-   |
-LL | use __test as x;
-   |     ------^^^^^
-   |     |
-   |     no `__test` in the root
-   |     help: a similar name exists in the module: `test`
-
-error[E0432]: unresolved import `__test_reexports`
-  --> $DIR/inaccessible-test-modules.rs:6:5
-   |
-LL | use __test_reexports as y;
-   |     ----------------^^^^^
-   |     |
-   |     no `__test_reexports` in the root
-   |     help: a similar name exists in the module: `__test_reexports`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0432`.
diff --git a/src/test/ui/test-attrs/decl-macro-test.rs b/src/test/ui/test-attrs/decl-macro-test.rs
new file mode 100644
index 0000000000000..fcbe9f49e5564
--- /dev/null
+++ b/src/test/ui/test-attrs/decl-macro-test.rs
@@ -0,0 +1,22 @@
+// Check that declarative macros can declare tests
+
+// check-pass
+// compile-flags: --test
+
+#![feature(decl_macro)]
+
+macro create_test() {
+    #[test]
+    fn test() {}
+}
+
+macro create_module_test() {
+    mod x {
+        #[test]
+        fn test() {}
+    }
+}
+
+create_test!();
+create_test!();
+create_module_test!();
diff --git a/src/test/ui/inaccessible-test-modules.rs b/src/test/ui/test-attrs/inaccessible-test-modules.rs
similarity index 56%
rename from src/test/ui/inaccessible-test-modules.rs
rename to src/test/ui/test-attrs/inaccessible-test-modules.rs
index 7095ec290f8f2..f5b3479379480 100644
--- a/src/test/ui/inaccessible-test-modules.rs
+++ b/src/test/ui/test-attrs/inaccessible-test-modules.rs
@@ -2,8 +2,8 @@
 
 // the `--test` harness creates modules with these textual names, but
 // they should be inaccessible from normal code.
-use __test as x; //~ ERROR unresolved import `__test`
-use __test_reexports as y; //~ ERROR unresolved import `__test_reexports`
+use main as x; //~ ERROR unresolved import `main`
+use test as y; //~ ERROR unresolved import `test`
 
 #[test]
 fn baz() {}
diff --git a/src/test/ui/test-attrs/inaccessible-test-modules.stderr b/src/test/ui/test-attrs/inaccessible-test-modules.stderr
new file mode 100644
index 0000000000000..a94ea1e79bc51
--- /dev/null
+++ b/src/test/ui/test-attrs/inaccessible-test-modules.stderr
@@ -0,0 +1,21 @@
+error[E0432]: unresolved import `main`
+  --> $DIR/inaccessible-test-modules.rs:5:5
+   |
+LL | use main as x;
+   |     ----^^^^^
+   |     |
+   |     no `main` in the root
+   |     help: a similar name exists in the module: `main`
+
+error[E0432]: unresolved import `test`
+  --> $DIR/inaccessible-test-modules.rs:6:5
+   |
+LL | use test as y;
+   |     ----^^^^^
+   |     |
+   |     no `test` in the root
+   |     help: a similar name exists in the module: `test`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0432`.

From 2a82aec36ae86a1913473cb7e830a77b481641ea Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sun, 25 Aug 2019 21:21:07 +0100
Subject: [PATCH 526/943] Move tests for unit tests to their own directory

---
 .../ui/{test-shadowing => test-attrs}/auxiliary/test_macro.rs     | 0
 src/test/ui/{ => test-attrs}/test-allow-fail-attr.rs              | 0
 .../ui/{ => test-attrs}/test-attr-non-associated-functions.rs     | 0
 .../ui/{ => test-attrs}/test-attr-non-associated-functions.stderr | 0
 .../ui/{test-shadowing => test-attrs}/test-cant-be-shadowed.rs    | 0
 .../test-fn-signature-verification-for-explicit-return-type.rs    | 0
 src/test/ui/{ => test-attrs}/test-main-not-dead-attr.rs           | 0
 src/test/ui/{ => test-attrs}/test-main-not-dead.rs                | 0
 src/test/ui/{ => test-attrs}/test-on-macro.rs                     | 0
 src/test/ui/{ => test-attrs}/test-on-macro.stderr                 | 0
 src/test/ui/{ => test-attrs}/test-runner-hides-buried-main.rs     | 0
 src/test/ui/{ => test-attrs}/test-runner-hides-main.rs            | 0
 src/test/ui/{ => test-attrs}/test-runner-hides-start.rs           | 0
 src/test/ui/{ => test-attrs}/test-should-fail-good-message.rs     | 0
 src/test/ui/{ => test-attrs}/test-should-panic-attr.rs            | 0
 src/test/ui/{ => test-attrs}/test-should-panic-attr.stderr        | 0
 src/test/ui/{ => test-attrs}/test-vs-cfg-test.rs                  | 0
 src/test/ui/{ => test-attrs}/test-warns-dead-code.rs              | 0
 src/test/ui/{ => test-attrs}/test-warns-dead-code.stderr          | 0
 19 files changed, 0 insertions(+), 0 deletions(-)
 rename src/test/ui/{test-shadowing => test-attrs}/auxiliary/test_macro.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-allow-fail-attr.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-attr-non-associated-functions.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-attr-non-associated-functions.stderr (100%)
 rename src/test/ui/{test-shadowing => test-attrs}/test-cant-be-shadowed.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-fn-signature-verification-for-explicit-return-type.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-main-not-dead-attr.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-main-not-dead.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-on-macro.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-on-macro.stderr (100%)
 rename src/test/ui/{ => test-attrs}/test-runner-hides-buried-main.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-runner-hides-main.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-runner-hides-start.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-should-fail-good-message.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-should-panic-attr.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-should-panic-attr.stderr (100%)
 rename src/test/ui/{ => test-attrs}/test-vs-cfg-test.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-warns-dead-code.rs (100%)
 rename src/test/ui/{ => test-attrs}/test-warns-dead-code.stderr (100%)

diff --git a/src/test/ui/test-shadowing/auxiliary/test_macro.rs b/src/test/ui/test-attrs/auxiliary/test_macro.rs
similarity index 100%
rename from src/test/ui/test-shadowing/auxiliary/test_macro.rs
rename to src/test/ui/test-attrs/auxiliary/test_macro.rs
diff --git a/src/test/ui/test-allow-fail-attr.rs b/src/test/ui/test-attrs/test-allow-fail-attr.rs
similarity index 100%
rename from src/test/ui/test-allow-fail-attr.rs
rename to src/test/ui/test-attrs/test-allow-fail-attr.rs
diff --git a/src/test/ui/test-attr-non-associated-functions.rs b/src/test/ui/test-attrs/test-attr-non-associated-functions.rs
similarity index 100%
rename from src/test/ui/test-attr-non-associated-functions.rs
rename to src/test/ui/test-attrs/test-attr-non-associated-functions.rs
diff --git a/src/test/ui/test-attr-non-associated-functions.stderr b/src/test/ui/test-attrs/test-attr-non-associated-functions.stderr
similarity index 100%
rename from src/test/ui/test-attr-non-associated-functions.stderr
rename to src/test/ui/test-attrs/test-attr-non-associated-functions.stderr
diff --git a/src/test/ui/test-shadowing/test-cant-be-shadowed.rs b/src/test/ui/test-attrs/test-cant-be-shadowed.rs
similarity index 100%
rename from src/test/ui/test-shadowing/test-cant-be-shadowed.rs
rename to src/test/ui/test-attrs/test-cant-be-shadowed.rs
diff --git a/src/test/ui/test-fn-signature-verification-for-explicit-return-type.rs b/src/test/ui/test-attrs/test-fn-signature-verification-for-explicit-return-type.rs
similarity index 100%
rename from src/test/ui/test-fn-signature-verification-for-explicit-return-type.rs
rename to src/test/ui/test-attrs/test-fn-signature-verification-for-explicit-return-type.rs
diff --git a/src/test/ui/test-main-not-dead-attr.rs b/src/test/ui/test-attrs/test-main-not-dead-attr.rs
similarity index 100%
rename from src/test/ui/test-main-not-dead-attr.rs
rename to src/test/ui/test-attrs/test-main-not-dead-attr.rs
diff --git a/src/test/ui/test-main-not-dead.rs b/src/test/ui/test-attrs/test-main-not-dead.rs
similarity index 100%
rename from src/test/ui/test-main-not-dead.rs
rename to src/test/ui/test-attrs/test-main-not-dead.rs
diff --git a/src/test/ui/test-on-macro.rs b/src/test/ui/test-attrs/test-on-macro.rs
similarity index 100%
rename from src/test/ui/test-on-macro.rs
rename to src/test/ui/test-attrs/test-on-macro.rs
diff --git a/src/test/ui/test-on-macro.stderr b/src/test/ui/test-attrs/test-on-macro.stderr
similarity index 100%
rename from src/test/ui/test-on-macro.stderr
rename to src/test/ui/test-attrs/test-on-macro.stderr
diff --git a/src/test/ui/test-runner-hides-buried-main.rs b/src/test/ui/test-attrs/test-runner-hides-buried-main.rs
similarity index 100%
rename from src/test/ui/test-runner-hides-buried-main.rs
rename to src/test/ui/test-attrs/test-runner-hides-buried-main.rs
diff --git a/src/test/ui/test-runner-hides-main.rs b/src/test/ui/test-attrs/test-runner-hides-main.rs
similarity index 100%
rename from src/test/ui/test-runner-hides-main.rs
rename to src/test/ui/test-attrs/test-runner-hides-main.rs
diff --git a/src/test/ui/test-runner-hides-start.rs b/src/test/ui/test-attrs/test-runner-hides-start.rs
similarity index 100%
rename from src/test/ui/test-runner-hides-start.rs
rename to src/test/ui/test-attrs/test-runner-hides-start.rs
diff --git a/src/test/ui/test-should-fail-good-message.rs b/src/test/ui/test-attrs/test-should-fail-good-message.rs
similarity index 100%
rename from src/test/ui/test-should-fail-good-message.rs
rename to src/test/ui/test-attrs/test-should-fail-good-message.rs
diff --git a/src/test/ui/test-should-panic-attr.rs b/src/test/ui/test-attrs/test-should-panic-attr.rs
similarity index 100%
rename from src/test/ui/test-should-panic-attr.rs
rename to src/test/ui/test-attrs/test-should-panic-attr.rs
diff --git a/src/test/ui/test-should-panic-attr.stderr b/src/test/ui/test-attrs/test-should-panic-attr.stderr
similarity index 100%
rename from src/test/ui/test-should-panic-attr.stderr
rename to src/test/ui/test-attrs/test-should-panic-attr.stderr
diff --git a/src/test/ui/test-vs-cfg-test.rs b/src/test/ui/test-attrs/test-vs-cfg-test.rs
similarity index 100%
rename from src/test/ui/test-vs-cfg-test.rs
rename to src/test/ui/test-attrs/test-vs-cfg-test.rs
diff --git a/src/test/ui/test-warns-dead-code.rs b/src/test/ui/test-attrs/test-warns-dead-code.rs
similarity index 100%
rename from src/test/ui/test-warns-dead-code.rs
rename to src/test/ui/test-attrs/test-warns-dead-code.rs
diff --git a/src/test/ui/test-warns-dead-code.stderr b/src/test/ui/test-attrs/test-warns-dead-code.stderr
similarity index 100%
rename from src/test/ui/test-warns-dead-code.stderr
rename to src/test/ui/test-attrs/test-warns-dead-code.stderr

From beb2f5b8ff89f3e973e085ce338a59e5203fecb0 Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sun, 25 Aug 2019 21:31:42 +0100
Subject: [PATCH 527/943] Remove `Ident::{gensym, is_gensymed}`

`gensym_if_underscore` still exists. The symbol interner can still
create arbitray gensyms, this is just not exposed publicly.
---
 src/librustc_resolve/resolve_imports.rs |  8 ++------
 src/libsyntax_pos/symbol.rs             | 27 +++++++++++--------------
 2 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index fd222a132a3f8..4e33ea018a074 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -1307,12 +1307,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 None => continue,
             };
 
-            // Filter away ambiguous and gensymed imports. Gensymed imports
-            // (e.g. implicitly injected `std`) cannot be properly encoded in metadata,
-            // so they can cause name conflict errors downstream.
-            let is_good_import = binding.is_import() && !binding.is_ambiguity() &&
-                                 // Note that as_str() de-gensyms the Symbol
-                                 !(ident.is_gensymed() && ident.name.as_str() != "_");
+            // Filter away ambiguous imports.
+            let is_good_import = binding.is_import() && !binding.is_ambiguity();
             if is_good_import || binding.is_macro_def() {
                 let res = binding.res();
                 if res != Res::Err {
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 0b8f16bbc3b99..ce20e4407fe88 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -798,21 +798,15 @@ impl Ident {
         Ident::new(self.name, self.span.modern_and_legacy())
     }
 
-    /// Transforms an identifier into one with the same name, but gensymed.
-    pub fn gensym(self) -> Ident {
-        let name = with_interner(|interner| interner.gensymed(self.name));
-        Ident::new(name, self.span)
-    }
-
     /// Transforms an underscore identifier into one with the same name, but
     /// gensymed. Leaves non-underscore identifiers unchanged.
     pub fn gensym_if_underscore(self) -> Ident {
-        if self.name == kw::Underscore { self.gensym() } else { self }
-    }
-
-    // WARNING: this function is deprecated and will be removed in the future.
-    pub fn is_gensymed(self) -> bool {
-        with_interner(|interner| interner.is_gensymed(self.name))
+        if self.name == kw::Underscore {
+            let name = with_interner(|interner| interner.gensymed(self.name));
+            Ident::new(name, self.span)
+        } else {
+            self
+        }
     }
 
     pub fn as_str(self) -> LocalInternedString {
@@ -865,9 +859,12 @@ impl UseSpecializedDecodable for Ident {}
 ///
 /// Examples:
 /// ```
-/// assert_eq!(Ident::from_str("x"), Ident::from_str("x"))
-/// assert_ne!(Ident::from_str("x").gensym(), Ident::from_str("x"))
-/// assert_ne!(Ident::from_str("x").gensym(), Ident::from_str("x").gensym())
+/// assert_eq!(Ident::from_str("_"), Ident::from_str("_"))
+/// assert_ne!(Ident::from_str("_").gensym_if_underscore(), Ident::from_str("_"))
+/// assert_ne!(
+///     Ident::from_str("_").gensym_if_underscore(),
+///     Ident::from_str("_").gensym_if_underscore(),
+/// )
 /// ```
 /// Internally, a symbol is implemented as an index, and all operations
 /// (including hashing, equality, and ordering) operate on that index. The use

From 846df20578189260ed3f4c9c824d324b6c9b7eac Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sun, 25 Aug 2019 22:36:13 +0100
Subject: [PATCH 528/943] Fix 2018 edition expanded pretty printing

---
 src/libsyntax/print/pprust.rs | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 4dc00af486013..c18c8c18ae1f9 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -128,10 +128,14 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
         let fake_attr = attr::mk_attr_inner(list);
         s.print_attribute(&fake_attr);
 
-        // #![no_std]
-        let no_std_meta = attr::mk_word_item(ast::Ident::with_dummy_span(sym::no_std));
-        let fake_attr = attr::mk_attr_inner(no_std_meta);
-        s.print_attribute(&fake_attr);
+        // Currently on Rust 2018 we don't have `extern crate std;` at the crate
+        // root, so this is not needed, and actually breaks things.
+        if sess.edition == syntax_pos::edition::Edition::Edition2015 {
+            // #![no_std]
+            let no_std_meta = attr::mk_word_item(ast::Ident::with_dummy_span(sym::no_std));
+            let fake_attr = attr::mk_attr_inner(no_std_meta);
+            s.print_attribute(&fake_attr);
+        }
     }
 
     s.print_mod(&krate.module, &krate.attrs);

From 0b86782058c27ba694ec81ebe7108dceb0968a2b Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Tue, 27 Aug 2019 21:13:20 +0100
Subject: [PATCH 529/943] Don't call `diag_span_note_once` for suppressed lints

---
 src/librustc/lint/mod.rs | 44 ++++++++++++++++++++++------------------
 1 file changed, 24 insertions(+), 20 deletions(-)

diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 1b133819a73bf..fb7f14febf32e 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -666,6 +666,30 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
         (Level::Forbid, None) => sess.struct_err(msg),
     };
 
+    // Check for future incompatibility lints and issue a stronger warning.
+    let lints = sess.lint_store.borrow();
+    let lint_id = LintId::of(lint);
+    let future_incompatible = lints.future_incompatible(lint_id);
+
+    // If this code originates in a foreign macro, aka something that this crate
+    // did not itself author, then it's likely that there's nothing this crate
+    // can do about it. We probably want to skip the lint entirely.
+    if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) {
+        // Any suggestions made here are likely to be incorrect, so anything we
+        // emit shouldn't be automatically fixed by rustfix.
+        err.allow_suggestions(false);
+
+        // If this is a future incompatible lint it'll become a hard error, so
+        // we have to emit *something*. Also allow lints to whitelist themselves
+        // on a case-by-case basis for emission in a foreign macro.
+        if future_incompatible.is_none() && !lint.report_in_external_macro {
+            err.cancel();
+            // Don't continue further, since we don't want to have
+            // `diag_span_note_once` called for a diagnostic that isn't emitted.
+            return err;
+        }
+    }
+
     let name = lint.name_lower();
     match src {
         LintSource::Default => {
@@ -715,10 +739,6 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
 
     err.code(DiagnosticId::Lint(name));
 
-    // Check for future incompatibility lints and issue a stronger warning.
-    let lints = sess.lint_store.borrow();
-    let lint_id = LintId::of(lint);
-    let future_incompatible = lints.future_incompatible(lint_id);
     if let Some(future_incompatible) = future_incompatible {
         const STANDARD_MESSAGE: &str =
             "this was previously accepted by the compiler but is being phased out; \
@@ -743,22 +763,6 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
         err.note(&citation);
     }
 
-    // If this code originates in a foreign macro, aka something that this crate
-    // did not itself author, then it's likely that there's nothing this crate
-    // can do about it. We probably want to skip the lint entirely.
-    if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) {
-        // Any suggestions made here are likely to be incorrect, so anything we
-        // emit shouldn't be automatically fixed by rustfix.
-        err.allow_suggestions(false);
-
-        // If this is a future incompatible lint it'll become a hard error, so
-        // we have to emit *something*. Also allow lints to whitelist themselves
-        // on a case-by-case basis for emission in a foreign macro.
-        if future_incompatible.is_none() && !lint.report_in_external_macro {
-            err.cancel()
-        }
-    }
-
     return err
 }
 

From c8cf9f5a025bb475804b5a90f54aca310b952526 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Wed, 28 Aug 2019 12:41:29 +0300
Subject: [PATCH 530/943] Add `with_{def_site,call_site,legacy}_ctxt,` methods
 to `Span`

Use these to create call-site spans for AST passes when needed.
---
 src/librustc_resolve/macros.rs                | 27 +++---
 src/libsyntax/ext/base.rs                     | 14 +--
 src/libsyntax_ext/proc_macro_harness.rs       |  3 +-
 src/libsyntax_ext/standard_library_imports.rs |  8 +-
 src/libsyntax_ext/test_harness.rs             | 10 +-
 src/libsyntax_pos/hygiene.rs                  |  2 +-
 src/libsyntax_pos/lib.rs                      | 19 ++++
 .../dollar-crate-issue-57089.stdout           | 32 +++----
 .../dollar-crate-issue-62325.stdout           | 44 ++++-----
 src/test/ui/proc-macro/dollar-crate.stdout    | 96 +++++++++----------
 10 files changed, 138 insertions(+), 117 deletions(-)

diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 20d281f1e997a..02022c98c3502 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -17,7 +17,7 @@ use syntax::edition::Edition;
 use syntax::ext::base::{self, Indeterminate, SpecialDerives};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
-use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind, Transparency};
+use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind};
 use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name};
 use syntax::feature_gate::GateIssue;
@@ -131,23 +131,20 @@ impl<'a> base::Resolver for Resolver<'a> {
     // Create a Span with modern hygiene with a definition site of the provided
     // module, or a fake empty `#[no_implicit_prelude]` module if no module is
     // provided.
-    fn span_for_ast_pass(
+    fn expansion_for_ast_pass(
         &mut self,
-        base_span: Span,
+        call_site: Span,
         pass: AstPass,
         features: &[Symbol],
         parent_module_id: Option<NodeId>,
-    ) -> Span {
-        let span = base_span.fresh_expansion_with_transparency(
-            ExpnData::allow_unstable(
-                ExpnKind::AstPass(pass),
-                base_span,
-                self.session.edition(),
-                features.into(),
-            ),
-            Transparency::Opaque,
-        );
-        let expn_id = span.ctxt().outer_expn();
+    ) -> ExpnId {
+        let expn_id = ExpnId::fresh(Some(ExpnData::allow_unstable(
+            ExpnKind::AstPass(pass),
+            call_site,
+            self.session.edition(),
+            features.into(),
+        )));
+
         let parent_scope = if let Some(module_id) = parent_module_id {
             let parent_def_id = self.definitions.local_def_id(module_id);
             self.definitions.add_parent_module_of_macro_def(expn_id, parent_def_id);
@@ -160,7 +157,7 @@ impl<'a> base::Resolver for Resolver<'a> {
             self.empty_module
         };
         self.ast_transform_scopes.insert(expn_id, parent_scope);
-        span
+        expn_id
     }
 
     fn resolve_imports(&mut self) {
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 962447e8cf07f..4c146611deab6 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -3,7 +3,7 @@ use crate::attr::{HasAttrs, Stability, Deprecation};
 use crate::source_map::SourceMap;
 use crate::edition::Edition;
 use crate::ext::expand::{self, AstFragment, Invocation};
-use crate::ext::hygiene::{ExpnId, Transparency};
+use crate::ext::hygiene::ExpnId;
 use crate::mut_visit::{self, MutVisitor};
 use crate::parse::{self, parser, DirectoryOwnership};
 use crate::parse::token;
@@ -658,13 +658,13 @@ pub trait Resolver {
                                             extra_placeholders: &[NodeId]);
     fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension);
 
-    fn span_for_ast_pass(
+    fn expansion_for_ast_pass(
         &mut self,
-        span: Span,
+        call_site: Span,
         pass: AstPass,
         features: &[Symbol],
         parent_module_id: Option<NodeId>,
-    ) -> Span;
+    ) -> ExpnId;
 
     fn resolve_imports(&mut self);
 
@@ -750,20 +750,20 @@ impl<'a> ExtCtxt<'a> {
     /// Equivalent of `Span::def_site` from the proc macro API,
     /// except that the location is taken from the span passed as an argument.
     pub fn with_def_site_ctxt(&self, span: Span) -> Span {
-        span.with_ctxt_from_mark(self.current_expansion.id, Transparency::Opaque)
+        span.with_def_site_ctxt(self.current_expansion.id)
     }
 
     /// Equivalent of `Span::call_site` from the proc macro API,
     /// except that the location is taken from the span passed as an argument.
     pub fn with_call_site_ctxt(&self, span: Span) -> Span {
-        span.with_ctxt_from_mark(self.current_expansion.id, Transparency::Transparent)
+        span.with_call_site_ctxt(self.current_expansion.id)
     }
 
     /// Span with a context reproducing `macro_rules` hygiene (hygienic locals, unhygienic items).
     /// FIXME: This should be eventually replaced either with `with_def_site_ctxt` (preferably),
     /// or with `with_call_site_ctxt` (where necessary).
     pub fn with_legacy_ctxt(&self, span: Span) -> Span {
-        span.with_ctxt_from_mark(self.current_expansion.id, Transparency::SemiTransparent)
+        span.with_legacy_ctxt(self.current_expansion.id)
     }
 
     /// Returns span for the macro which originally caused the current expansion to happen.
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index 1cdaa1190fae3..8a4b78a3efa31 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -326,12 +326,13 @@ fn mk_decls(
     custom_attrs: &[ProcMacroDef],
     custom_macros: &[ProcMacroDef],
 ) -> P<ast::Item> {
-    let span = cx.resolver.span_for_ast_pass(
+    let expn_id = cx.resolver.expansion_for_ast_pass(
         DUMMY_SP,
         AstPass::ProcMacroHarness,
         &[sym::rustc_attrs, sym::proc_macro_internals],
         None,
     );
+    let span = DUMMY_SP.with_def_site_ctxt(expn_id);
 
     let proc_macro = Ident::new(sym::proc_macro, span);
     let krate = cx.item(span,
diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs
index 61e423266fa05..e5dded9ea5319 100644
--- a/src/libsyntax_ext/standard_library_imports.rs
+++ b/src/libsyntax_ext/standard_library_imports.rs
@@ -28,19 +28,21 @@ pub fn inject(
         &[sym::std]
     };
 
-    let span = resolver.span_for_ast_pass(
+    let expn_id = resolver.expansion_for_ast_pass(
         DUMMY_SP,
         AstPass::StdImports,
         &[sym::prelude_import],
         None,
     );
+    let span = DUMMY_SP.with_def_site_ctxt(expn_id);
+    let call_site = DUMMY_SP.with_call_site_ctxt(expn_id);
 
     // .rev() to preserve ordering above in combination with insert(0, ...)
     for &orig_name_sym in names.iter().rev() {
         let (rename, orig_name) = if rust_2018 {
             (Ident::new(kw::Underscore, span), Some(orig_name_sym))
         } else {
-            (Ident::with_dummy_span(orig_name_sym), None)
+            (Ident::new(orig_name_sym, call_site), None)
         };
         krate.module.items.insert(0, P(ast::Item {
             attrs: vec![attr::mk_attr_outer(
@@ -65,7 +67,7 @@ pub fn inject(
             .collect()
     } else {
         [kw::PathRoot, name, sym::prelude, sym::v1].iter()
-            .map(|symbol| ast::PathSegment::from_ident(ast::Ident::with_dummy_span(*symbol)))
+            .map(|symbol| ast::PathSegment::from_ident(ast::Ident::new(*symbol, call_site)))
             .collect()
     };
 
diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index 6eb132979df8f..eedd7fbee3806 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -97,15 +97,16 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
                 };
                 // Create an identifier that will hygienically resolve the test
                 // case name, even in another module.
-                let sp = self.cx.ext_cx.resolver.span_for_ast_pass(
+                let expn_id = self.cx.ext_cx.resolver.expansion_for_ast_pass(
                     module.inner,
                     AstPass::TestHarness,
                     &[],
                     Some(parent),
                 );
-                let expn = sp.ctxt().outer_expn();
                 for test in &mut tests {
-                    test.ident.span = test.ident.span.apply_mark(expn, Transparency::Opaque);
+                    // See the comment on `mk_main` for why we're using
+                    // `apply_mark` directly.
+                    test.ident.span = test.ident.span.apply_mark(expn_id, Transparency::Opaque);
                 }
                 self.cx.test_cases.extend(tests);
             }
@@ -207,12 +208,13 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     //            #![main]
     //            test::test_main_static(&[..tests]);
     //        }
-    let sp = cx.ext_cx.resolver.span_for_ast_pass(
+    let expn_id = cx.ext_cx.resolver.expansion_for_ast_pass(
         DUMMY_SP,
         AstPass::TestHarness,
         &[sym::main, sym::test, sym::rustc_attrs],
         None,
     );
+    let sp = DUMMY_SP.with_def_site_ctxt(expn_id);
     let ecx = &cx.ext_cx;
     let test_id = Ident::new(sym::test, sp);
 
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index 99afe57ef5497..f0e7344c1b986 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -360,7 +360,7 @@ impl SyntaxContext {
     }
 
     /// Extend a syntax context with a given expansion and transparency.
-    pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext {
+    crate fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext {
         HygieneData::with(|data| data.apply_mark(self, expn_id, transparency))
     }
 
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index d800109cf8531..9a296f17aaf4a 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -514,6 +514,25 @@ impl Span {
                   span.ctxt)
     }
 
+    /// Equivalent of `Span::def_site` from the proc macro API,
+    /// except that the location is taken from the `self` span.
+    pub fn with_def_site_ctxt(self, expn_id: ExpnId) -> Span {
+        self.with_ctxt_from_mark(expn_id, Transparency::Opaque)
+    }
+
+    /// Equivalent of `Span::call_site` from the proc macro API,
+    /// except that the location is taken from the `self` span.
+    pub fn with_call_site_ctxt(&self, expn_id: ExpnId) -> Span {
+        self.with_ctxt_from_mark(expn_id, Transparency::Transparent)
+    }
+
+    /// Span with a context reproducing `macro_rules` hygiene (hygienic locals, unhygienic items).
+    /// FIXME: This should be eventually replaced either with `with_def_site_ctxt` (preferably),
+    /// or with `with_call_site_ctxt` (where necessary).
+    pub fn with_legacy_ctxt(&self, expn_id: ExpnId) -> Span {
+        self.with_ctxt_from_mark(expn_id, Transparency::SemiTransparent)
+    }
+
     /// Produces a span with the same location as `self` and context produced by a macro with the
     /// given ID and transparency, assuming that macro was defined directly and not produced by
     /// some other macro (which is the case for built-in and procedural macros).
diff --git a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout
index 0fe02a9a34d18..ea06f6c1acaf9 100644
--- a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout
+++ b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout
@@ -2,40 +2,40 @@ PRINT-BANG INPUT (DISPLAY): struct M ($crate :: S) ;
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Ident {
         ident: "M",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Group {
         delimiter: Parenthesis,
         stream: TokenStream [
             Ident {
                 ident: "$crate",
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Ident {
                 ident: "S",
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
         ],
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Punct {
         ch: ';',
         spacing: Alone,
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): struct A(crate::S);
@@ -43,39 +43,39 @@ PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ($crate :: S) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Ident {
         ident: "A",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Group {
         delimiter: Parenthesis,
         stream: TokenStream [
             Ident {
                 ident: "$crate",
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Ident {
                 ident: "S",
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
         ],
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Punct {
         ch: ';',
         spacing: Alone,
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
 ]
diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
index a499e1362ec0b..7ee8078b2c5d2 100644
--- a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
+++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
@@ -3,55 +3,55 @@ PRINT-ATTR RE-COLLECTED (DISPLAY): struct A (identity ! ($crate :: S)) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Ident {
         ident: "A",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Group {
         delimiter: Parenthesis,
         stream: TokenStream [
             Ident {
                 ident: "identity",
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Punct {
                 ch: '!',
                 spacing: Alone,
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Group {
                 delimiter: Parenthesis,
                 stream: TokenStream [
                     Ident {
                         ident: "$crate",
-                        span: #2 bytes(LO..HI),
+                        span: #3 bytes(LO..HI),
                     },
                     Punct {
                         ch: ':',
                         spacing: Joint,
-                        span: #2 bytes(LO..HI),
+                        span: #3 bytes(LO..HI),
                     },
                     Punct {
                         ch: ':',
                         spacing: Alone,
-                        span: #2 bytes(LO..HI),
+                        span: #3 bytes(LO..HI),
                     },
                     Ident {
                         ident: "S",
-                        span: #2 bytes(LO..HI),
+                        span: #3 bytes(LO..HI),
                     },
                 ],
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
         ],
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Punct {
         ch: ';',
         spacing: Alone,
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): struct B(identity!(::dollar_crate_external :: S));
@@ -59,54 +59,54 @@ PRINT-ATTR RE-COLLECTED (DISPLAY): struct B (identity ! ($crate :: S)) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: #7 bytes(LO..HI),
+        span: #8 bytes(LO..HI),
     },
     Ident {
         ident: "B",
-        span: #7 bytes(LO..HI),
+        span: #8 bytes(LO..HI),
     },
     Group {
         delimiter: Parenthesis,
         stream: TokenStream [
             Ident {
                 ident: "identity",
-                span: #7 bytes(LO..HI),
+                span: #8 bytes(LO..HI),
             },
             Punct {
                 ch: '!',
                 spacing: Alone,
-                span: #7 bytes(LO..HI),
+                span: #8 bytes(LO..HI),
             },
             Group {
                 delimiter: Parenthesis,
                 stream: TokenStream [
                     Ident {
                         ident: "$crate",
-                        span: #7 bytes(LO..HI),
+                        span: #8 bytes(LO..HI),
                     },
                     Punct {
                         ch: ':',
                         spacing: Joint,
-                        span: #7 bytes(LO..HI),
+                        span: #8 bytes(LO..HI),
                     },
                     Punct {
                         ch: ':',
                         spacing: Alone,
-                        span: #7 bytes(LO..HI),
+                        span: #8 bytes(LO..HI),
                     },
                     Ident {
                         ident: "S",
-                        span: #7 bytes(LO..HI),
+                        span: #8 bytes(LO..HI),
                     },
                 ],
-                span: #7 bytes(LO..HI),
+                span: #8 bytes(LO..HI),
             },
         ],
-        span: #7 bytes(LO..HI),
+        span: #8 bytes(LO..HI),
     },
     Punct {
         ch: ';',
         spacing: Alone,
-        span: #7 bytes(LO..HI),
+        span: #8 bytes(LO..HI),
     },
 ]
diff --git a/src/test/ui/proc-macro/dollar-crate.stdout b/src/test/ui/proc-macro/dollar-crate.stdout
index da1d7549d0750..4f7e000265eb0 100644
--- a/src/test/ui/proc-macro/dollar-crate.stdout
+++ b/src/test/ui/proc-macro/dollar-crate.stdout
@@ -2,40 +2,40 @@ PRINT-BANG INPUT (DISPLAY): struct M ($crate :: S) ;
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Ident {
         ident: "M",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Group {
         delimiter: Parenthesis,
         stream: TokenStream [
             Ident {
                 ident: "$crate",
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Ident {
                 ident: "S",
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
         ],
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Punct {
         ch: ';',
         spacing: Alone,
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): struct A(crate::S);
@@ -43,40 +43,40 @@ PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ($crate :: S) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Ident {
         ident: "A",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Group {
         delimiter: Parenthesis,
         stream: TokenStream [
             Ident {
                 ident: "$crate",
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Ident {
                 ident: "S",
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
         ],
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Punct {
         ch: ';',
         spacing: Alone,
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
 ]
 PRINT-DERIVE INPUT (DISPLAY): struct D(crate::S);
@@ -84,80 +84,80 @@ PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ($crate :: S) ;
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Ident {
         ident: "D",
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Group {
         delimiter: Parenthesis,
         stream: TokenStream [
             Ident {
                 ident: "$crate",
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
             Ident {
                 ident: "S",
-                span: #2 bytes(LO..HI),
+                span: #3 bytes(LO..HI),
             },
         ],
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
     Punct {
         ch: ';',
         spacing: Alone,
-        span: #2 bytes(LO..HI),
+        span: #3 bytes(LO..HI),
     },
 ]
 PRINT-BANG INPUT (DISPLAY): struct M ($crate :: S) ;
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
     Ident {
         ident: "M",
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
     Group {
         delimiter: Parenthesis,
         stream: TokenStream [
             Ident {
                 ident: "$crate",
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
             Ident {
                 ident: "S",
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
         ],
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
     Punct {
         ch: ';',
         spacing: Alone,
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): struct A(::dollar_crate_external::S);
@@ -165,40 +165,40 @@ PRINT-ATTR RE-COLLECTED (DISPLAY): struct A ($crate :: S) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
     Ident {
         ident: "A",
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
     Group {
         delimiter: Parenthesis,
         stream: TokenStream [
             Ident {
                 ident: "$crate",
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
             Ident {
                 ident: "S",
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
         ],
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
     Punct {
         ch: ';',
         spacing: Alone,
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
 ]
 PRINT-DERIVE INPUT (DISPLAY): struct D(::dollar_crate_external::S);
@@ -206,39 +206,39 @@ PRINT-DERIVE RE-COLLECTED (DISPLAY): struct D ($crate :: S) ;
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
     Ident {
         ident: "D",
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
     Group {
         delimiter: Parenthesis,
         stream: TokenStream [
             Ident {
                 ident: "$crate",
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Joint,
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
             Punct {
                 ch: ':',
                 spacing: Alone,
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
             Ident {
                 ident: "S",
-                span: #9 bytes(LO..HI),
+                span: #10 bytes(LO..HI),
             },
         ],
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
     Punct {
         ch: ';',
         spacing: Alone,
-        span: #9 bytes(LO..HI),
+        span: #10 bytes(LO..HI),
     },
 ]

From e552840e79330f8a1f36fc676b71fa38b3123a50 Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Wed, 28 Aug 2019 22:47:52 +0100
Subject: [PATCH 531/943] Document test harness generation

Also ensure that we're consistently using the def-site span when
appropriate.
---
 src/libsyntax_ext/test_harness.rs | 82 +++++++++++++++++++++----------
 1 file changed, 55 insertions(+), 27 deletions(-)

diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index eedd7fbee3806..b93c11fad3823 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -25,6 +25,7 @@ struct Test {
 
 struct TestCtxt<'a> {
     ext_cx: ExtCtxt<'a>,
+    def_site: Span,
     test_cases: Vec<Test>,
     reexport_test_harness_main: Option<Symbol>,
     test_runner: Option<ast::Path>,
@@ -125,6 +126,7 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
 struct EntryPointCleaner {
     // Current depth in the ast
     depth: usize,
+    def_site: Span,
 }
 
 impl MutVisitor for EntryPointCleaner {
@@ -141,8 +143,10 @@ impl MutVisitor for EntryPointCleaner {
             EntryPointType::MainAttr |
             EntryPointType::Start =>
                 item.map(|ast::Item {id, ident, attrs, node, vis, span, tokens}| {
-                    let allow_ident = Ident::with_dummy_span(sym::allow);
-                    let dc_nested = attr::mk_nested_word_item(Ident::from_str("dead_code"));
+                    let allow_ident = Ident::new(sym::allow, self.def_site);
+                    let dc_nested = attr::mk_nested_word_item(
+                        Ident::from_str_and_span("dead_code", self.def_site),
+                    );
                     let allow_dead_code_item = attr::mk_list_item(allow_ident, vec![dc_nested]);
                     let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item);
 
@@ -180,15 +184,26 @@ fn generate_test_harness(sess: &ParseSess,
                          krate: &mut ast::Crate,
                          features: &Features,
                          test_runner: Option<ast::Path>) {
-    // Remove the entry points
-    let mut cleaner = EntryPointCleaner { depth: 0 };
-    cleaner.visit_crate(krate);
-
     let mut econfig = ExpansionConfig::default("test".to_string());
     econfig.features = Some(features);
 
+    let ext_cx = ExtCtxt::new(sess, econfig, resolver);
+
+    let expn_id = ext_cx.resolver.expansion_for_ast_pass(
+        DUMMY_SP,
+        AstPass::TestHarness,
+        &[sym::main, sym::test, sym::rustc_attrs],
+        None,
+    );
+    let def_site = DUMMY_SP.with_def_site_ctxt(expn_id);
+
+    // Remove the entry points
+    let mut cleaner = EntryPointCleaner { depth: 0, def_site };
+    cleaner.visit_crate(krate);
+
     let cx = TestCtxt {
-        ext_cx: ExtCtxt::new(sess, econfig, resolver),
+        ext_cx,
+        def_site,
         test_cases: Vec::new(),
         reexport_test_harness_main,
         test_runner
@@ -202,27 +217,40 @@ fn generate_test_harness(sess: &ParseSess,
 
 /// Creates a function item for use as the main function of a test build.
 /// This function will call the `test_runner` as specified by the crate attribute
+///
+/// By default this expands to
+///
+/// #[main]
+/// pub fn main() {
+///     extern crate test;
+///     test::test_main_static(&[
+///         &test_const1,
+///         &test_const2,
+///         &test_const3,
+///     ]);
+/// }
+///
+/// Most of the Ident have the usual def-site hygiene for the AST pass. The
+/// exception is the `test_const`s. These have a syntax context that has two
+/// opaque marks: one from the expansion of `test` or `test_case`, and one
+/// generated  in `TestHarnessGenerator::flat_map_item`. When resolving this
+/// identifier after failing to find a matching identifier in the root module
+/// we remove the outer mark, and try resolving at its def-site, which will
+/// then resolve to `test_const`.
+///
+/// The expansion here can be controlled by two attributes:
+///
+/// `reexport_test_harness_main` provides a different name for the `main`
+/// function and `test_runner` provides a path that replaces
+/// `test::test_main_static`.
 fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
-    // Writing this out by hand:
-    //        pub fn main() {
-    //            #![main]
-    //            test::test_main_static(&[..tests]);
-    //        }
-    let expn_id = cx.ext_cx.resolver.expansion_for_ast_pass(
-        DUMMY_SP,
-        AstPass::TestHarness,
-        &[sym::main, sym::test, sym::rustc_attrs],
-        None,
-    );
-    let sp = DUMMY_SP.with_def_site_ctxt(expn_id);
+    let sp = cx.def_site;
     let ecx = &cx.ext_cx;
     let test_id = Ident::new(sym::test, sp);
 
     // test::test_main_static(...)
     let mut test_runner = cx.test_runner.clone().unwrap_or(
-        ecx.path(sp, vec![
-            test_id, ecx.ident_of("test_main_static")
-        ]));
+        ecx.path(sp, vec![test_id, Ident::from_str_and_span("test_main_static", sp)]));
 
     test_runner.span = sp;
 
@@ -231,10 +259,6 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
                                        vec![mk_tests_slice(cx, sp)]);
     let call_test_main = ecx.stmt_expr(call_test_main);
 
-    // #![main]
-    let main_meta = ecx.meta_word(sp, sym::main);
-    let main_attr = ecx.attribute(main_meta);
-
     // extern crate test
     let test_extern_stmt = ecx.stmt_item(sp, ecx.item(sp,
         test_id,
@@ -242,6 +266,10 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
         ast::ItemKind::ExternCrate(None)
     ));
 
+    // #[main]
+    let main_meta = ecx.meta_word(sp, sym::main);
+    let main_attr = ecx.attribute(main_meta);
+
     // pub fn main() { ... }
     let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![]));
 
@@ -279,7 +307,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
 }
 
 /// Creates a slice containing every test like so:
-/// &[test1, test2]
+/// &[&test1, &test2]
 fn mk_tests_slice(cx: &TestCtxt<'_>, sp: Span) -> P<ast::Expr> {
     debug!("building test vector from {} tests", cx.test_cases.len());
     let ref ecx = cx.ext_cx;

From 74563b41666228e46f892e795108e06306b2b514 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Tue, 3 Sep 2019 21:25:06 -0400
Subject: [PATCH 532/943] Restrict error code length to 80 columns

The global restriction is 100, but since error codes are printed out via
--explain we want to restrict them to just 80 columns.
---
 src/librustc/error_codes.rs           | 18 +++++++++++-------
 src/librustc_metadata/error_codes.rs  |  3 ++-
 src/librustc_typeck/error_codes.rs    |  9 +++++----
 src/libsyntax/error_codes.rs          | 15 ++++++++++-----
 src/libsyntax/feature_gate/removed.rs |  5 +++++
 src/libsyntax_ext/error_codes.rs      |  7 ++++---
 src/tools/tidy/src/style.rs           | 26 ++++++++++++++++++++------
 7 files changed, 57 insertions(+), 26 deletions(-)

diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index 937a9ea6c1bd4..bde0fdf3b8ee6 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -1,7 +1,8 @@
 // Error messages for EXXXX errors.
-// Each message should start and end with a new line, and be wrapped to 80 characters.
-// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
-register_long_diagnostics! {
+// Each message should start and end with a new line, and be wrapped to 80
+// characters.  In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use
+// `:set tw=0` to disable.
+syntax::register_diagnostics! {
 E0038: r##"
 Trait objects like `Box<Trait>` can only be constructed when certain
 requirements are satisfied by the trait in question.
@@ -2206,7 +2207,8 @@ register_diagnostics! {
 //  E0305, // expected constant
     E0311, // thing may not live long enough
     E0312, // lifetime of reference outlives lifetime of borrowed content
-    E0313, // lifetime of borrowed pointer outlives lifetime of captured variable
+    E0313, // lifetime of borrowed pointer outlives lifetime of captured
+           // variable
     E0314, // closure outlives stack frame
     E0315, // cannot invoke closure outside of its lifetime
     E0316, // nested quantification of lifetimes
@@ -2223,12 +2225,13 @@ register_diagnostics! {
     E0483, // lifetime of operand does not outlive the operation
     E0484, // reference is not valid at the time of borrow
     E0485, // automatically reference is not valid at the time of borrow
-    E0486, // type of expression contains references that are not valid during...
+    E0486, // type of expression contains references that are not valid during..
     E0487, // unsafe use of destructor: destructor might be called while...
     E0488, // lifetime of variable does not enclose its declaration
     E0489, // type/lifetime parameter not in scope here
     E0490, // a value of type `..` is borrowed for too long
-    E0495, // cannot infer an appropriate lifetime due to conflicting requirements
+    E0495, // cannot infer an appropriate lifetime due to conflicting
+           // requirements
     E0566, // conflicting representation hints
     E0623, // lifetime mismatch where both parameters are anonymous regions
     E0628, // generators cannot have explicit parameters
@@ -2239,7 +2242,8 @@ register_diagnostics! {
     E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
     E0697, // closures cannot be static
     E0707, // multiple elided lifetimes used in arguments of `async fn`
-    E0708, // `async` non-`move` closures with parameters are not currently supported
+    E0708, // `async` non-`move` closures with parameters are not currently
+           // supported
     E0709, // multiple different lifetimes used in arguments of `async fn`
     E0710, // an unknown tool name found in scoped lint
     E0711, // a feature has been declared with conflicting stability attributes
diff --git a/src/librustc_metadata/error_codes.rs b/src/librustc_metadata/error_codes.rs
index 0708a6243bf29..4d2c0291ad39b 100644
--- a/src/librustc_metadata/error_codes.rs
+++ b/src/librustc_metadata/error_codes.rs
@@ -97,5 +97,6 @@ register_diagnostics! {
     E0464, // multiple matching crates for `..`
     E0465, // multiple .. candidates for `..` found
     E0519, // local crate and dependency have same (crate-name, disambiguator)
-    E0523, // two dependencies have same (crate-name, disambiguator) but different SVH
+    // two dependencies have same (crate-name, disambiguator) but different SVH
+    E0523,
 }
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index 093446d28533e..4d960b416fff0 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -4930,7 +4930,8 @@ register_diagnostics! {
 //  E0245, // not a trait
 //  E0246, // invalid recursive type
 //  E0247,
-//  E0248, // value used as a type, now reported earlier during resolution as E0412
+//  E0248, // value used as a type, now reported earlier during resolution
+           // as E0412
 //  E0249,
 //  E0319, // trait impls for defaulted traits allowed just for structs/enums
 //  E0372, // coherence not object safe
@@ -4938,7 +4939,7 @@ register_diagnostics! {
            // between structures with the same definition
 //  E0558, // replaced with a generic attribute input check
     E0533, // `{}` does not name a unit variant, unit struct or a constant
-//  E0563, // cannot determine a type for this `impl Trait`: {} // removed in 6383de15
+//  E0563, // cannot determine a type for this `impl Trait` removed in 6383de15
     E0564, // only named lifetimes are allowed in `impl Trait`,
            // but `{}` was found in the type `{}`
     E0587, // type has conflicting packed and align representation hints
@@ -4947,8 +4948,8 @@ register_diagnostics! {
 //  E0612, // merged into E0609
 //  E0613, // Removed (merged with E0609)
     E0627, // yield statement outside of generator literal
-    E0632, // cannot provide explicit type parameters when `impl Trait` is used in
-           // argument position.
+    E0632, // cannot provide explicit type parameters when `impl Trait` is used
+           // in argument position.
     E0634, // type has conflicting packed representaton hints
     E0640, // infer outlives requirements
     E0641, // cannot cast to/from a pointer with an unknown kind
diff --git a/src/libsyntax/error_codes.rs b/src/libsyntax/error_codes.rs
index 1ba29011f75a4..76b2575bfd688 100644
--- a/src/libsyntax/error_codes.rs
+++ b/src/libsyntax/error_codes.rs
@@ -1,7 +1,8 @@
 // Error messages for EXXXX errors.
-// Each message should start and end with a new line, and be wrapped to 80 characters.
-// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
-register_long_diagnostics! {
+// Each message should start and end with a new line, and be wrapped to 80
+// characters.  In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use
+// `:set tw=0` to disable.
+register_diagnostics! {
 
 E0178: r##"
 In types, the `+` type operator has low precedence, so it is often necessary
@@ -432,7 +433,9 @@ register_diagnostics! {
     E0546, // missing 'feature'
     E0547, // missing 'issue'
 //  E0548, // replaced with a generic attribute input check
-    E0549, // rustc_deprecated attribute must be paired with either stable or unstable attribute
+    // rustc_deprecated attribute must be paired with either stable or unstable
+    // attribute
+    E0549,
     E0550, // multiple deprecated attributes
     E0551, // incorrect meta item
     E0553, // multiple rustc_const_unstable attributes
@@ -440,7 +443,9 @@ register_diagnostics! {
     E0556, // malformed feature, expected just one word
     E0584, // file for module `..` found at both .. and ..
     E0629, // missing 'feature' (rustc_const_unstable)
-    E0630, // rustc_const_unstable attribute must be paired with stable/unstable attribute
+    // rustc_const_unstable attribute must be paired with stable/unstable
+    // attribute
+    E0630,
     E0693, // incorrect `repr(align)` attribute format
     E0694, // an unknown tool name found in scoped attributes
     E0703, // invalid ABI
diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs
index ad7d69b3e7372..2c29e1ebf1493 100644
--- a/src/libsyntax/feature_gate/removed.rs
+++ b/src/libsyntax/feature_gate/removed.rs
@@ -94,6 +94,11 @@ declare_features! (
     /// Allows defining `existential type`s.
     (removed, existential_type, "1.38.0", Some(63063), None,
      Some("removed in favor of `#![feature(type_alias_impl_trait)]`")),
+    /// Allows using the macros:
+    /// + `__diagnostic_used`
+    /// + `__register_diagnostic`
+    /// +`__build_diagnostic_array`
+    (removed, rustc_diagnostic_macros, "1.38.0", None, None, None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: removed features
diff --git a/src/libsyntax_ext/error_codes.rs b/src/libsyntax_ext/error_codes.rs
index 5982a4df226c2..49808fc0b60e2 100644
--- a/src/libsyntax_ext/error_codes.rs
+++ b/src/libsyntax_ext/error_codes.rs
@@ -1,9 +1,10 @@
 use syntax::register_long_diagnostics;
 
 // Error messages for EXXXX errors.
-// Each message should start and end with a new line, and be wrapped to 80 characters.
-// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
-register_long_diagnostics! {
+// Each message should start and end with a new line, and be wrapped to 80
+// characters.  In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use
+// `:set tw=0` to disable.
+syntax::register_diagnostics! {
 E0660: r##"
 The argument to the `asm` macro is not well-formed.
 
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 6a0d530e2362a..9302909968615 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -15,6 +15,7 @@
 
 use std::path::Path;
 
+const ERROR_CODE_COLS: usize = 80;
 const COLS: usize = 100;
 
 const LINES: usize = 3000;
@@ -51,7 +52,13 @@ enum LIUState {
 /// Lines of this form are allowed to be overlength, because Markdown
 /// offers no way to split a line in the middle of a URL, and the lengths
 /// of URLs to external references are beyond our control.
-fn line_is_url(line: &str) -> bool {
+fn line_is_url(columns: usize, line: &str) -> bool {
+    // more basic check for error_codes.rs, to avoid complexity in implementing two state machines
+    if columns == ERROR_CODE_COLS {
+        return line.starts_with("[") &&
+            line.contains("]:") && line.contains("http");
+    }
+
     use self::LIUState::*;
     let mut state: LIUState = EXP_COMMENT_START;
     let is_url = |w: &str| w.starts_with("http://") || w.starts_with("https://");
@@ -75,7 +82,7 @@ fn line_is_url(line: &str) -> bool {
                 => state = EXP_END,
 
             (_, w)
-                if w.len() > COLS && is_url(w)
+                if w.len() > columns && is_url(w)
                 => state = EXP_END,
 
             (_, _) => {}
@@ -88,8 +95,8 @@ fn line_is_url(line: &str) -> bool {
 /// Returns `true` if `line` is allowed to be longer than the normal limit.
 /// Currently there is only one exception, for long URLs, but more
 /// may be added in the future.
-fn long_line_is_ok(line: &str) -> bool {
-    if line_is_url(line) {
+fn long_line_is_ok(max_columns: usize, line: &str) -> bool {
+    if line_is_url(max_columns, line) {
         return true;
     }
 
@@ -144,6 +151,12 @@ pub fn check(path: &Path, bad: &mut bool) {
             tidy_error!(bad, "{}: empty file", file.display());
         }
 
+        let max_columns = if filename == "error_codes.rs" {
+            ERROR_CODE_COLS
+        } else {
+            COLS
+        };
+
         let can_contain = contents.contains("// ignore-tidy-") ||
             contents.contains("# ignore-tidy-");
         let mut skip_cr = contains_ignore_directive(can_contain, &contents, "cr");
@@ -162,11 +175,12 @@ pub fn check(path: &Path, bad: &mut bool) {
             let mut err = |msg: &str| {
                 tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg);
             };
-            if line.chars().count() > COLS && !long_line_is_ok(line) {
+            if line.chars().count() > max_columns &&
+                !long_line_is_ok(max_columns, line) {
                 suppressible_tidy_err!(
                     err,
                     skip_line_length,
-                    &format!("line longer than {} chars", COLS)
+                    &format!("line longer than {} chars", max_columns)
                 );
             }
             if line.contains('\t') {

From b437240ceefaad3cdf92ad7e9d1255b8da88dbb3 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Tue, 3 Sep 2019 21:15:18 -0400
Subject: [PATCH 533/943] Replace diagnostic plugins with macro_rules

---
 src/librustc/error_codes.rs              |   6 +-
 src/librustc/lib.rs                      |   5 -
 src/librustc_codegen_llvm/error_codes.rs |   2 +-
 src/librustc_codegen_llvm/lib.rs         |   4 +-
 src/librustc_codegen_ssa/error_codes.rs  |   2 +-
 src/librustc_codegen_ssa/lib.rs          |   4 -
 src/librustc_interface/passes.rs         |  15 +-
 src/librustc_interface/util.rs           |  18 +--
 src/librustc_lint/error_codes.rs         |   5 +-
 src/librustc_metadata/error_codes.rs     |   9 +-
 src/librustc_metadata/lib.rs             |   4 +-
 src/librustc_mir/error_codes.rs          |   6 +-
 src/librustc_mir/lib.rs                  |   4 +-
 src/librustc_passes/error_codes.rs       |  10 +-
 src/librustc_passes/lib.rs               |   4 +-
 src/librustc_plugin/error_codes.rs       |  11 +-
 src/librustc_plugin/lib.rs               |   4 +-
 src/librustc_privacy/error_codes.rs      |   5 +-
 src/librustc_privacy/lib.rs              |   4 +-
 src/librustc_resolve/error_codes.rs      |   9 +-
 src/librustc_resolve/late.rs             |  24 +--
 src/librustc_resolve/late/diagnostics.rs |   4 +-
 src/librustc_resolve/lib.rs              |   6 +-
 src/librustc_typeck/error_codes.rs       |   7 +-
 src/librustc_typeck/lib.rs               |   6 +-
 src/librustc_typeck/structured_errors.rs |   4 +-
 src/libsyntax/diagnostics/macros.rs      |  55 +++----
 src/libsyntax/diagnostics/plugin.rs      | 185 -----------------------
 src/libsyntax/error_codes.rs             |   5 +-
 src/libsyntax/lib.rs                     |   5 -
 src/libsyntax/parse/mod.rs               |   4 -
 src/libsyntax_ext/error_codes.rs         |   2 -
 32 files changed, 87 insertions(+), 351 deletions(-)
 delete mode 100644 src/libsyntax/diagnostics/plugin.rs

diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index bde0fdf3b8ee6..eee33846139e6 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -2184,11 +2184,7 @@ Examples of erroneous code:
 static X: u32 = 42;
 ```
 "##,
-
-}
-
-
-register_diagnostics! {
+;
 //  E0006, // merged with E0005
 //  E0101, // replaced with E0282
 //  E0102, // replaced with E0282
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 368f5bb64fe6c..c5d2b2d7e7f87 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -88,8 +88,6 @@ mod tests;
 #[macro_use]
 mod macros;
 
-// N.B., this module needs to be declared first so diagnostics are
-// registered before they are used.
 pub mod error_codes;
 
 #[macro_use]
@@ -143,6 +141,3 @@ pub mod util {
 
 // Allows macros to refer to this crate as `::rustc`
 extern crate self as rustc;
-
-// Build the diagnostics array at the end so that the metadata includes error use sites.
-__build_diagnostic_array! { librustc, DIAGNOSTICS }
diff --git a/src/librustc_codegen_llvm/error_codes.rs b/src/librustc_codegen_llvm/error_codes.rs
index c6b5dc03a6f0a..042e51ed2ba7a 100644
--- a/src/librustc_codegen_llvm/error_codes.rs
+++ b/src/librustc_codegen_llvm/error_codes.rs
@@ -1,4 +1,4 @@
-register_long_diagnostics! {
+register_diagnostics! {
 
 E0511: r##"
 Invalid monomorphization of an intrinsic function was used. Erroneous code
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 2fd78885bd01e..f032d0ff0464c 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -256,7 +256,7 @@ impl CodegenBackend for LlvmCodegenBackend {
     }
 
     fn diagnostics(&self) -> &[(&'static str, &'static str)] {
-        &DIAGNOSTICS
+        &error_codes::DIAGNOSTICS
     }
 
     fn target_features(&self, sess: &Session) -> Vec<Symbol> {
@@ -425,5 +425,3 @@ impl Drop for ModuleLlvm {
         }
     }
 }
-
-__build_diagnostic_array! { librustc_codegen_llvm, DIAGNOSTICS }
diff --git a/src/librustc_codegen_ssa/error_codes.rs b/src/librustc_codegen_ssa/error_codes.rs
index 8d46dcb7c09c3..8ff41c275a8f4 100644
--- a/src/librustc_codegen_ssa/error_codes.rs
+++ b/src/librustc_codegen_ssa/error_codes.rs
@@ -1,4 +1,4 @@
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 
 E0668: r##"
 Malformed inline assembly rejected by LLVM.
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index 68640abb0433e..0f98310722ee3 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -35,8 +35,6 @@ use rustc_data_structures::svh::Svh;
 use rustc::middle::cstore::{LibSource, CrateSource, NativeLibrary};
 use syntax_pos::symbol::Symbol;
 
-// N.B., this module needs to be declared first so diagnostics are
-// registered before they are used.
 mod error_codes;
 
 pub mod common;
@@ -158,5 +156,3 @@ pub struct CodegenResults {
     pub linker_info: back::linker::LinkerInfo,
     pub crate_info: CrateInfo,
 }
-
-__build_diagnostic_array! { librustc_codegen_ssa, DIAGNOSTICS }
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 24b44964e4fd2..bd9b240e24efa 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -34,7 +34,7 @@ use rustc_privacy;
 use rustc_resolve::{Resolver, ResolverArenas};
 use rustc_traits;
 use rustc_typeck as typeck;
-use syntax::{self, ast, diagnostics, visit};
+use syntax::{self, ast, visit};
 use syntax::early_buffered_lints::BufferedEarlyLint;
 use syntax::ext::base::{NamedSyntaxExtension, ExtCtxt};
 use syntax::mut_visit::MutVisitor;
@@ -292,18 +292,7 @@ pub fn register_plugins<'a>(
 
     time(sess, "plugin registration", || {
         if sess.features_untracked().rustc_diagnostic_macros {
-            registry.register_macro(
-                "__diagnostic_used",
-                diagnostics::plugin::expand_diagnostic_used,
-            );
-            registry.register_macro(
-                "__register_diagnostic",
-                diagnostics::plugin::expand_register_diagnostic,
-            );
-            registry.register_macro(
-                "__build_diagnostic_array",
-                diagnostics::plugin::expand_build_diagnostic_array,
-            );
+            // FIXME: remove feature gate
         }
 
         for registrar in registrars {
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index f007a0cf2abee..9eaf7b77716f3 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -43,17 +43,17 @@ use std::{thread, panic};
 
 pub fn diagnostics_registry() -> Registry {
     let mut all_errors = Vec::new();
-    all_errors.extend_from_slice(&rustc::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_typeck::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_resolve::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_privacy::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_typeck::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_resolve::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_privacy::error_codes::DIAGNOSTICS);
     // FIXME: need to figure out a way to get these back in here
     // all_errors.extend_from_slice(get_codegen_backend(sess).diagnostics());
-    all_errors.extend_from_slice(&rustc_metadata::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_passes::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_plugin::DIAGNOSTICS);
-    all_errors.extend_from_slice(&rustc_mir::DIAGNOSTICS);
-    all_errors.extend_from_slice(&syntax::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_metadata::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_passes::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_plugin::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&rustc_mir::error_codes::DIAGNOSTICS);
+    all_errors.extend_from_slice(&syntax::error_codes::DIAGNOSTICS);
 
     Registry::new(&all_errors)
 }
diff --git a/src/librustc_lint/error_codes.rs b/src/librustc_lint/error_codes.rs
index d7c39b780bfdf..ea2e1d9ecc53f 100644
--- a/src/librustc_lint/error_codes.rs
+++ b/src/librustc_lint/error_codes.rs
@@ -1,5 +1,4 @@
-use syntax::register_diagnostics;
-
-register_diagnostics! {
+syntax::register_diagnostics! {
+;
     E0721, // `await` keyword
 }
diff --git a/src/librustc_metadata/error_codes.rs b/src/librustc_metadata/error_codes.rs
index 4d2c0291ad39b..cd8e95e6c3a11 100644
--- a/src/librustc_metadata/error_codes.rs
+++ b/src/librustc_metadata/error_codes.rs
@@ -1,6 +1,4 @@
-use syntax::{register_diagnostics, register_long_diagnostics};
-
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 E0454: r##"
 A link name was given with an empty name. Erroneous code example:
 
@@ -84,10 +82,7 @@ You need to link your code to the relevant crate in order to be able to use it
 (through Cargo or the `-L` option of rustc example). Plugins are crates as
 well, and you link to them the same way.
 "##,
-
-}
-
-register_diagnostics! {
+;
     E0456, // plugin `..` is not available for triple `..`
     E0457, // plugin `..` only found in rlib format, but must be available...
     E0514, // metadata version mismatch
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index c96d02d9b37de..3ab7d372461b8 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -23,7 +23,7 @@ extern crate rustc;
 #[macro_use]
 extern crate rustc_data_structures;
 
-mod error_codes;
+pub mod error_codes;
 
 mod index;
 mod encoder;
@@ -68,5 +68,3 @@ pub fn validate_crate_name(
         sess.unwrap().abort_if_errors();
     }
 }
-
-__build_diagnostic_array! { librustc_metadata, DIAGNOSTICS }
diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs
index 86c263a447bb6..74b3eff0906ac 100644
--- a/src/librustc_mir/error_codes.rs
+++ b/src/librustc_mir/error_codes.rs
@@ -1,4 +1,4 @@
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 
 
 E0001: r##"
@@ -2448,9 +2448,9 @@ information.
 
 There are some known bugs that trigger this message.
 "##,
-}
 
-register_diagnostics! {
+;
+
 //  E0298, // cannot compare constants
 //  E0299, // mismatched types between arms
 //  E0471, // constant evaluation error (in pattern)
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index cccf7b9545bdb..7a5db4fc19d02 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -32,7 +32,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #[macro_use] extern crate rustc_data_structures;
 #[macro_use] extern crate syntax;
 
-mod error_codes;
+pub mod error_codes;
 
 mod borrow_check;
 mod build;
@@ -62,5 +62,3 @@ pub fn provide(providers: &mut Providers<'_>) {
     };
     providers.type_name = interpret::type_name;
 }
-
-__build_diagnostic_array! { librustc_mir, DIAGNOSTICS }
diff --git a/src/librustc_passes/error_codes.rs b/src/librustc_passes/error_codes.rs
index a30cd8a627fe3..af07c790e2a87 100644
--- a/src/librustc_passes/error_codes.rs
+++ b/src/librustc_passes/error_codes.rs
@@ -1,6 +1,4 @@
-use syntax::{register_diagnostics, register_long_diagnostics};
-
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 /*
 E0014: r##"
 Constants can only be initialized by a constant value or, in a future
@@ -320,10 +318,8 @@ async fn foo() {}
 ```
 
 Switch to the Rust 2018 edition to use `async fn`.
-"##
-}
-
-register_diagnostics! {
+"##,
+;
     E0226, // only a single explicit lifetime bound is permitted
     E0472, // asm! is unsupported on this target
     E0561, // patterns aren't allowed in function pointer types
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index 5614b570b927a..2070f306112a1 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -18,7 +18,7 @@ extern crate rustc;
 
 use rustc::ty::query::Providers;
 
-mod error_codes;
+pub mod error_codes;
 
 pub mod ast_validation;
 pub mod rvalue_promotion;
@@ -26,8 +26,6 @@ pub mod hir_stats;
 pub mod layout_test;
 pub mod loops;
 
-__build_diagnostic_array! { librustc_passes, DIAGNOSTICS }
-
 pub fn provide(providers: &mut Providers<'_>) {
     rvalue_promotion::provide(providers);
     loops::provide(providers);
diff --git a/src/librustc_plugin/error_codes.rs b/src/librustc_plugin/error_codes.rs
index b5f6a8d905d31..7b3f01c0ee111 100644
--- a/src/librustc_plugin/error_codes.rs
+++ b/src/librustc_plugin/error_codes.rs
@@ -1,9 +1,4 @@
-use syntax::{register_diagnostics, register_long_diagnostics};
-
-register_long_diagnostics! {
-
-}
-
-register_diagnostics! {
-    E0498  // malformed plugin attribute
+syntax::register_diagnostics! {
+;
+    E0498,  // malformed plugin attribute
 }
diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs
index 952bc9fff6a71..1cf01d481e468 100644
--- a/src/librustc_plugin/lib.rs
+++ b/src/librustc_plugin/lib.rs
@@ -60,9 +60,7 @@
 
 pub use registry::Registry;
 
-mod error_codes;
+pub mod error_codes;
 pub mod registry;
 pub mod load;
 pub mod build;
-
-__build_diagnostic_array! { librustc_plugin, DIAGNOSTICS }
diff --git a/src/librustc_privacy/error_codes.rs b/src/librustc_privacy/error_codes.rs
index 70a799d426a07..67066466f1d22 100644
--- a/src/librustc_privacy/error_codes.rs
+++ b/src/librustc_privacy/error_codes.rs
@@ -1,4 +1,4 @@
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 
 E0445: r##"
 A private trait was used on a public type parameter bound. Erroneous code
@@ -154,8 +154,5 @@ let f = Bar::Foo::new(); // ok!
 ```
 "##,
 
-}
-
-register_diagnostics! {
 //  E0450, moved into resolve
 }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 146058963b69d..28ef3b794babd 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -31,7 +31,7 @@ use syntax_pos::Span;
 use std::{cmp, fmt, mem};
 use std::marker::PhantomData;
 
-mod error_codes;
+pub mod error_codes;
 
 ////////////////////////////////////////////////////////////////////////////////
 /// Generic infrastructure used to implement specific visitors below.
@@ -2035,5 +2035,3 @@ fn check_private_in_public(tcx: TyCtxt<'_>, krate: CrateNum) {
     };
     krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
 }
-
-__build_diagnostic_array! { librustc_privacy, DIAGNOSTICS }
diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs
index 1faaf97e981c1..adbff67cc8dac 100644
--- a/src/librustc_resolve/error_codes.rs
+++ b/src/librustc_resolve/error_codes.rs
@@ -1,9 +1,7 @@
-use syntax::{register_diagnostics, register_long_diagnostics};
-
 // Error messages for EXXXX errors.  Each message should start and end with a
 // new line, and be wrapped to 80 characters.  In vim you can `:set tw=80` and
 // use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 
 E0128: r##"
 Type parameter defaults can only use parameters that occur before them.
@@ -1662,10 +1660,7 @@ fn const_id<T, const N: T>() -> T { // error: const parameter
 }
 ```
 "##,
-
-}
-
-register_diagnostics! {
+;
 //  E0153, unused error code
 //  E0157, unused error code
 //  E0257,
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index e15d02a9f7ec7..4570bbbe33926 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -286,18 +286,18 @@ impl<'a> PathSource<'a> {
     }
 
     fn error_code(self, has_unexpected_resolution: bool) -> &'static str {
-        __diagnostic_used!(E0404);
-        __diagnostic_used!(E0405);
-        __diagnostic_used!(E0412);
-        __diagnostic_used!(E0422);
-        __diagnostic_used!(E0423);
-        __diagnostic_used!(E0425);
-        __diagnostic_used!(E0531);
-        __diagnostic_used!(E0532);
-        __diagnostic_used!(E0573);
-        __diagnostic_used!(E0574);
-        __diagnostic_used!(E0575);
-        __diagnostic_used!(E0576);
+        syntax::diagnostic_used!(E0404);
+        syntax::diagnostic_used!(E0405);
+        syntax::diagnostic_used!(E0412);
+        syntax::diagnostic_used!(E0422);
+        syntax::diagnostic_used!(E0423);
+        syntax::diagnostic_used!(E0425);
+        syntax::diagnostic_used!(E0531);
+        syntax::diagnostic_used!(E0532);
+        syntax::diagnostic_used!(E0573);
+        syntax::diagnostic_used!(E0574);
+        syntax::diagnostic_used!(E0575);
+        syntax::diagnostic_used!(E0576);
         match (self, has_unexpected_resolution) {
             (PathSource::Trait(_), true) => "E0404",
             (PathSource::Trait(_), false) => "E0405",
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index a822fa049ca1c..0c86d8494fde8 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -113,7 +113,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
 
         // Emit special messages for unresolved `Self` and `self`.
         if is_self_type(path, ns) {
-            __diagnostic_used!(E0411);
+            syntax::diagnostic_used!(E0411);
             err.code(DiagnosticId::Error("E0411".into()));
             err.span_label(span, format!("`Self` is only available in impls, traits, \
                                           and type definitions"));
@@ -122,7 +122,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
         if is_self_value(path, ns) {
             debug!("smart_resolve_path_fragment: E0424, source={:?}", source);
 
-            __diagnostic_used!(E0424);
+            syntax::diagnostic_used!(E0424);
             err.code(DiagnosticId::Error("E0424".into()));
             err.span_label(span, match source {
                 PathSource::Pat => {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 875ae449d94e0..6ba08ccef0307 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -67,9 +67,7 @@ use macros::{LegacyBinding, LegacyScope};
 
 type Res = def::Res<NodeId>;
 
-// N.B., this module needs to be declared first so diagnostics are
-// registered before they are used.
-mod error_codes;
+pub mod error_codes;
 mod diagnostics;
 mod late;
 mod macros;
@@ -2817,5 +2815,3 @@ impl CrateLint {
         }
     }
 }
-
-__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index 4d960b416fff0..e11dcfafb8f8b 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-filelength
 
-register_long_diagnostics! {
+syntax::register_diagnostics! {
 
 E0023: r##"
 A pattern used to match against an enum variant must provide a sub-pattern for
@@ -4870,10 +4870,7 @@ fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> {
 The `Box<...>` ensures that the result is of known size,
 and the pin is required to keep it in the same place in memory.
 "##,
-
-}  // (end of detailed error messages)
-
-register_diagnostics! {
+;
 //  E0035, merged into E0087/E0089
 //  E0036, merged into E0087/E0089
 //  E0068,
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 9d9a9d9b559e4..91c7522280af2 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -78,9 +78,7 @@ This API is completely unstable and subject to change.
 
 #[macro_use] extern crate rustc;
 
-// N.B., this module needs to be declared first so diagnostics are
-// registered before they are used.
-mod error_codes;
+pub mod error_codes;
 
 mod astconv;
 mod check;
@@ -389,5 +387,3 @@ pub fn hir_trait_to_predicates<'tcx>(
 
     bounds
 }
-
-__build_diagnostic_array! { librustc_typeck, DIAGNOSTICS }
diff --git a/src/librustc_typeck/structured_errors.rs b/src/librustc_typeck/structured_errors.rs
index 3e3eab8cf4cfb..273a36edc56ff 100644
--- a/src/librustc_typeck/structured_errors.rs
+++ b/src/librustc_typeck/structured_errors.rs
@@ -48,7 +48,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for VariadicError<'tcx> {
     fn session(&self) -> &Session { self.sess }
 
     fn code(&self) -> DiagnosticId {
-        __diagnostic_used!(E0617);
+        syntax::diagnostic_used!(E0617);
         DiagnosticId::Error("E0617".to_owned())
     }
 
@@ -104,7 +104,7 @@ impl<'tcx> StructuredDiagnostic<'tcx> for SizedUnsizedCastError<'tcx> {
     fn session(&self) -> &Session { self.sess }
 
     fn code(&self) -> DiagnosticId {
-        __diagnostic_used!(E0607);
+        syntax::diagnostic_used!(E0607);
         DiagnosticId::Error("E0607".to_owned())
     }
 
diff --git a/src/libsyntax/diagnostics/macros.rs b/src/libsyntax/diagnostics/macros.rs
index b754d0833761e..c95c5bd5d02d4 100644
--- a/src/libsyntax/diagnostics/macros.rs
+++ b/src/libsyntax/diagnostics/macros.rs
@@ -1,13 +1,14 @@
 #[macro_export]
-macro_rules! register_diagnostic {
-    ($code:tt, $description:tt) => (__register_diagnostic! { $code, $description });
-    ($code:tt) => (__register_diagnostic! { $code })
+macro_rules! diagnostic_used {
+    ($code:ident) => (
+        let _ = crate::error_codes::$code;
+    )
 }
 
 #[macro_export]
 macro_rules! span_fatal {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.span_fatal_with_code(
             $span,
             &format!($($message)*),
@@ -19,7 +20,7 @@ macro_rules! span_fatal {
 #[macro_export]
 macro_rules! span_err {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.span_err_with_code(
             $span,
             &format!($($message)*),
@@ -31,7 +32,7 @@ macro_rules! span_err {
 #[macro_export]
 macro_rules! span_warn {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.span_warn_with_code(
             $span,
             &format!($($message)*),
@@ -43,7 +44,7 @@ macro_rules! span_warn {
 #[macro_export]
 macro_rules! struct_err {
     ($session:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.struct_err_with_code(
             &format!($($message)*),
             $crate::errors::DiagnosticId::Error(stringify!($code).to_owned()),
@@ -54,7 +55,7 @@ macro_rules! struct_err {
 #[macro_export]
 macro_rules! span_err_or_warn {
     ($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         if $is_warning {
             $session.span_warn_with_code(
                 $span,
@@ -74,7 +75,7 @@ macro_rules! span_err_or_warn {
 #[macro_export]
 macro_rules! struct_span_fatal {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.struct_span_fatal_with_code(
             $span,
             &format!($($message)*),
@@ -86,7 +87,7 @@ macro_rules! struct_span_fatal {
 #[macro_export]
 macro_rules! struct_span_err {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.struct_span_err_with_code(
             $span,
             &format!($($message)*),
@@ -98,7 +99,7 @@ macro_rules! struct_span_err {
 #[macro_export]
 macro_rules! stringify_error_code {
     ($code:ident) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $crate::errors::DiagnosticId::Error(stringify!($code).to_owned())
     })
 }
@@ -117,7 +118,7 @@ macro_rules! type_error_struct {
 #[macro_export]
 macro_rules! struct_span_warn {
     ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         $session.struct_span_warn_with_code(
             $span,
             &format!($($message)*),
@@ -129,7 +130,7 @@ macro_rules! struct_span_warn {
 #[macro_export]
 macro_rules! struct_span_err_or_warn {
     ($is_warning:expr, $session:expr, $span:expr, $code:ident, $($message:tt)*) => ({
-        __diagnostic_used!($code);
+        $crate::diagnostic_used!($code);
         if $is_warning {
             $session.struct_span_warn_with_code(
                 $span,
@@ -169,20 +170,22 @@ macro_rules! help {
 
 #[macro_export]
 macro_rules! register_diagnostics {
-    ($($code:tt),*) => (
-        $($crate::register_diagnostic! { $code })*
+    ($($ecode:ident: $message:expr,)*) => (
+        $crate::register_diagnostics!{$($ecode:$message,)* ;}
     );
-    ($($code:tt),*,) => (
-        $($crate::register_diagnostic! { $code })*
-    )
-}
 
-#[macro_export]
-macro_rules! register_long_diagnostics {
-    ($($code:tt: $description:tt),*) => (
-        $($crate::register_diagnostic! { $code, $description })*
-    );
-    ($($code:tt: $description:tt),*,) => (
-        $($crate::register_diagnostic! { $code, $description })*
+    ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => (
+        pub static DIAGNOSTICS: &[(&str, &str)] = &[
+            $( (stringify!($ecode), $message), )*
+        ];
+
+        $(
+            #[deny(unused)]
+            pub(crate) const $ecode: &str = $message;
+        )*
+        $(
+            #[deny(unused)]
+            pub(crate) const $code: () = ();
+        )*
     )
 }
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
deleted file mode 100644
index 5de39c8d14d17..0000000000000
--- a/src/libsyntax/diagnostics/plugin.rs
+++ /dev/null
@@ -1,185 +0,0 @@
-use std::collections::BTreeMap;
-
-use crate::ast::{self, Ident, Name};
-use crate::source_map;
-use crate::ext::base::{ExtCtxt, MacEager, MacResult};
-use crate::parse::token::{self, Token};
-use crate::ptr::P;
-use crate::symbol::kw;
-use crate::tokenstream::{TokenTree, TokenStream};
-
-use smallvec::smallvec;
-use syntax_pos::Span;
-
-pub use errors::*;
-
-// Maximum width of any line in an extended error description (inclusive).
-const MAX_DESCRIPTION_WIDTH: usize = 80;
-
-/// Error information type.
-pub struct ErrorInfo {
-    pub description: Option<Name>,
-    pub use_site: Option<Span>
-}
-
-/// Mapping from error codes to metadata.
-pub type ErrorMap = BTreeMap<Name, ErrorInfo>;
-
-pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt<'_>,
-                                   span: Span,
-                                   tts: TokenStream)
-                                   -> Box<dyn MacResult+'cx> {
-    assert_eq!(tts.len(), 1);
-    let code = match tts.into_trees().next() {
-        Some(TokenTree::Token(Token { kind: token::Ident(code, _), .. })) => code,
-        _ => unreachable!()
-    };
-
-    ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
-        match diagnostics.get_mut(&code) {
-            // Previously used errors.
-            Some(&mut ErrorInfo { description: _, use_site: Some(previous_span) }) => {
-                ecx.struct_span_warn(span, &format!(
-                    "diagnostic code {} already used", code
-                )).span_note(previous_span, "previous invocation")
-                  .emit();
-            }
-            // Newly used errors.
-            Some(ref mut info) => {
-                info.use_site = Some(span);
-            }
-            // Unregistered errors.
-            None => {
-                ecx.span_err(span, &format!(
-                    "used diagnostic code {} not registered", code
-                ));
-            }
-        }
-    });
-    MacEager::expr(ecx.expr_tuple(span, Vec::new()))
-}
-
-pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>,
-                                       span: Span,
-                                       tts: TokenStream)
-                                       -> Box<dyn MacResult+'cx> {
-    assert!(tts.len() == 1 || tts.len() == 3);
-    let mut cursor = tts.into_trees();
-    let code = match cursor.next() {
-        Some(TokenTree::Token(Token { kind: token::Ident(code, _), .. })) => code,
-        _ => unreachable!()
-    };
-    let description = match  (cursor.next(), cursor.next()) {
-        (None, None) => None,
-        (
-            Some(TokenTree::Token(Token { kind: token::Comma, .. })),
-            Some(TokenTree::Token(Token { kind: token::Literal(token::Lit { symbol, .. }), ..}))
-        ) => {
-            Some(symbol)
-        },
-        _ => unreachable!()
-    };
-
-    // Check that the description starts and ends with a newline and doesn't
-    // overflow the maximum line width.
-    description.map(|raw_msg| {
-        let msg = raw_msg.as_str();
-        if !msg.starts_with("\n") || !msg.ends_with("\n") {
-            ecx.span_err(span, &format!(
-                "description for error code {} doesn't start and end with a newline",
-                code
-            ));
-        }
-
-        // URLs can be unavoidably longer than the line limit, so we allow them.
-        // Allowed format is: `[name]: https://www.rust-lang.org/`
-        let is_url = |l: &str| l.starts_with("[") && l.contains("]:") && l.contains("http");
-
-        if msg.lines().any(|line| line.len() > MAX_DESCRIPTION_WIDTH && !is_url(line)) {
-            ecx.span_err(span, &format!(
-                "description for error code {} contains a line longer than {} characters.\n\
-                 if you're inserting a long URL use the footnote style to bypass this check.",
-                code, MAX_DESCRIPTION_WIDTH
-            ));
-        }
-    });
-    // Add the error to the map.
-    ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
-        let info = ErrorInfo {
-            description,
-            use_site: None
-        };
-        if diagnostics.insert(code, info).is_some() {
-            ecx.span_err(span, &format!(
-                "diagnostic code {} already registered", code
-            ));
-        }
-    });
-
-    MacEager::items(smallvec![])
-}
-
-pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>,
-                                          span: Span,
-                                          tts: TokenStream)
-                                          -> Box<dyn MacResult+'cx> {
-    assert_eq!(tts.len(), 3);
-    let ident = match tts.into_trees().nth(2) {
-        // DIAGNOSTICS ident.
-        Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }))
-        => Ident::new(name, span),
-        _ => unreachable!()
-    };
-
-    // Construct the output expression.
-    let (count, expr) =
-        ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| {
-            let descriptions: Vec<P<ast::Expr>> =
-                diagnostics.iter().filter_map(|(&code, info)| {
-                    info.description.map(|description| {
-                        ecx.expr_tuple(span, vec![
-                            ecx.expr_str(span, code),
-                            ecx.expr_str(span, description)
-                        ])
-                    })
-                }).collect();
-            (descriptions.len(), ecx.expr_vec(span, descriptions))
-        });
-
-    let static_ = ecx.lifetime(span, Ident::with_dummy_span(kw::StaticLifetime));
-    let ty_str = ecx.ty_rptr(
-        span,
-        ecx.ty_ident(span, ecx.ident_of("str")),
-        Some(static_),
-        ast::Mutability::Immutable,
-    );
-
-    let ty = ecx.ty(
-        span,
-        ast::TyKind::Array(
-            ecx.ty(
-                span,
-                ast::TyKind::Tup(vec![ty_str.clone(), ty_str])
-            ),
-            ast::AnonConst {
-                id: ast::DUMMY_NODE_ID,
-                value: ecx.expr_usize(span, count),
-            },
-        ),
-    );
-
-    MacEager::items(smallvec![
-        P(ast::Item {
-            ident,
-            attrs: Vec::new(),
-            id: ast::DUMMY_NODE_ID,
-            node: ast::ItemKind::Const(
-                ty,
-                expr,
-            ),
-            vis: source_map::respan(span.shrink_to_lo(), ast::VisibilityKind::Public),
-            span,
-            tokens: None,
-        })
-    ])
-}
diff --git a/src/libsyntax/error_codes.rs b/src/libsyntax/error_codes.rs
index 76b2575bfd688..9925dd8ada0d5 100644
--- a/src/libsyntax/error_codes.rs
+++ b/src/libsyntax/error_codes.rs
@@ -421,9 +421,8 @@ Delete the offending feature attribute, or add it to the list of allowed
 features in the `-Z allow_features` flag.
 "##,
 
-}
+;
 
-register_diagnostics! {
     E0539, // incorrect meta item
     E0540, // multiple rustc_deprecated attributes
     E0542, // missing 'since'
@@ -447,7 +446,7 @@ register_diagnostics! {
     // attribute
     E0630,
     E0693, // incorrect `repr(align)` attribute format
-    E0694, // an unknown tool name found in scoped attributes
+//  E0694, // an unknown tool name found in scoped attributes
     E0703, // invalid ABI
     E0717, // rustc_promotable without stability attribute
 }
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 1741932c1b80e..75ce306df800e 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -123,11 +123,8 @@ scoped_tls::scoped_thread_local!(pub static GLOBALS: Globals);
 pub mod diagnostics {
     #[macro_use]
     pub mod macros;
-    pub mod plugin;
 }
 
-// N.B., this module needs to be declared first so diagnostics are
-// registered before they are used.
 pub mod error_codes;
 
 pub mod util {
@@ -182,5 +179,3 @@ pub mod ext {
 }
 
 pub mod early_buffered_lints;
-
-__build_diagnostic_array! { libsyntax, DIAGNOSTICS }
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index b1af4806e2d78..981f5f1f7b004 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -8,7 +8,6 @@ use crate::parse::parser::Parser;
 use crate::parse::parser::emit_unclosed_delims;
 use crate::parse::token::TokenKind;
 use crate::tokenstream::{TokenStream, TokenTree};
-use crate::diagnostics::plugin::ErrorMap;
 use crate::print::pprust;
 use crate::symbol::Symbol;
 
@@ -64,8 +63,6 @@ pub struct ParseSess {
     pub missing_fragment_specifiers: Lock<FxHashSet<Span>>,
     /// Places where raw identifiers were used. This is used for feature-gating raw identifiers.
     pub raw_identifier_spans: Lock<Vec<Span>>,
-    /// The registered diagnostics codes.
-    crate registered_diagnostics: Lock<ErrorMap>,
     /// Used to determine and report recursive module inclusions.
     included_mod_stack: Lock<Vec<PathBuf>>,
     source_map: Lrc<SourceMap>,
@@ -95,7 +92,6 @@ impl ParseSess {
             config: FxHashSet::default(),
             missing_fragment_specifiers: Lock::new(FxHashSet::default()),
             raw_identifier_spans: Lock::new(Vec::new()),
-            registered_diagnostics: Lock::new(ErrorMap::new()),
             included_mod_stack: Lock::new(vec![]),
             source_map,
             buffered_lints: Lock::new(vec![]),
diff --git a/src/libsyntax_ext/error_codes.rs b/src/libsyntax_ext/error_codes.rs
index 49808fc0b60e2..2bc990574f7a8 100644
--- a/src/libsyntax_ext/error_codes.rs
+++ b/src/libsyntax_ext/error_codes.rs
@@ -1,5 +1,3 @@
-use syntax::register_long_diagnostics;
-
 // Error messages for EXXXX errors.
 // Each message should start and end with a new line, and be wrapped to 80
 // characters.  In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use

From 3f1dc326edee5528db80894eedd2036fdc05bca8 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Tue, 3 Sep 2019 21:50:01 -0400
Subject: [PATCH 534/943] Remove codegen dependencies

Not doing this leads to building two copies of e.g. num_cpus in the
sysroot and _llvm deps, leading to conflicts between the two when
compiling librustc_codegen_llvm. It's not entirely clear why this is the
case after the changes in this PR but likely has something to do with a
subtle difference in ordering or similar.
---
 Cargo.lock                           | 4 ----
 src/librustc_codegen_llvm/Cargo.toml | 4 ----
 2 files changed, 8 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 243a326646c38..e0b0640178b03 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3129,11 +3129,7 @@ dependencies = [
 name = "rustc_codegen_llvm"
 version = "0.0.0"
 dependencies = [
- "cc",
- "memmap",
- "num_cpus",
  "rustc_llvm",
- "tempfile",
 ]
 
 [[package]]
diff --git a/src/librustc_codegen_llvm/Cargo.toml b/src/librustc_codegen_llvm/Cargo.toml
index 5e1b0eafdec36..98efa6a5804bd 100644
--- a/src/librustc_codegen_llvm/Cargo.toml
+++ b/src/librustc_codegen_llvm/Cargo.toml
@@ -11,11 +11,7 @@ crate-type = ["dylib"]
 test = false
 
 [dependencies]
-cc = "1.0.1" # Used to locate MSVC
-num_cpus = "1.0"
-tempfile = "3.0"
 rustc_llvm = { path = "../librustc_llvm" }
-memmap = "0.6"
 
 [features]
 # This is used to convince Cargo to separately cache builds of `rustc_codegen_llvm`

From 4de4f303e5cee3e40b8e91a381517a457af7b4cc Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Tue, 3 Sep 2019 22:04:01 -0400
Subject: [PATCH 535/943] Fix error index generator for new
 register_diagnostics API

---
 src/tools/error_index_generator/build.rs | 51 ++++++++++--------------
 1 file changed, 22 insertions(+), 29 deletions(-)

diff --git a/src/tools/error_index_generator/build.rs b/src/tools/error_index_generator/build.rs
index 2ac7351fce469..832aa3b1c8dfd 100644
--- a/src/tools/error_index_generator/build.rs
+++ b/src/tools/error_index_generator/build.rs
@@ -14,9 +14,7 @@ fn main() {
         if entry.file_name() == "error_codes.rs" {
             println!("cargo:rerun-if-changed={}", entry.path().to_str().unwrap());
             let file = fs::read_to_string(entry.path()).unwrap()
-                .replace("use syntax::{register_diagnostics, register_long_diagnostics};", "")
-                .replace("use syntax::register_diagnostics;", "")
-                .replace("use syntax::register_long_diagnostics;", "");
+                .replace("syntax::register_diagnostics!", "register_diagnostics!");
             let contents = format!("(|| {{\n{}\n}})();", file);
 
             fs::write(&out_dir.join(&format!("error_{}.rs", idx)), &contents).unwrap();
@@ -26,36 +24,31 @@ fn main() {
     }
 
     let mut all = String::new();
-    all.push_str("fn register_all() -> Vec<(&'static str, Option<&'static str>)> {\n");
-    all.push_str("let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();\n");
-    all.push_str(r#"
-macro_rules! register_diagnostics {
-    ($($code:tt),*) => {{
-        long_codes.extend([$(
-            stringify!($code),
-        )*].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());
-    }};
-    ($($code:tt),*,) => {{
-        long_codes.extend([$(
-            stringify!($code),
-        )*].iter().cloned().map(|s| (s, None)));
-    }}
-}
+    all.push_str(r###"
+fn register_all() -> Vec<(&'static str, Option<&'static str>)> {
+    let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();
+    macro_rules! register_diagnostics {
+        ($($ecode:ident: $message:expr,)*) => (
+            register_diagnostics!{$($ecode:$message,)* ;}
+        );
 
-macro_rules! register_long_diagnostics {
-    ($($code:tt: $description:tt),*) => {
-        {long_codes.extend([$(
-            (stringify!($code), Some(stringify!($description))),
-        )*].iter());}
-    };
-    ($($code:tt: $description:tt),*,) => {
-        {long_codes.extend([$(
-            (stringify!($code), Some(stringify!($description))),
-        )*].iter());}
+        ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => (
+            $(
+                {long_codes.extend([
+                    (stringify!($ecode), Some(stringify!($message))),
+                ].iter());}
+            )*
+            $(
+                {long_codes.extend([
+                    stringify!($code),
+                ].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>());}
+            )*
+        )
     }
-}"#);
+"###);
     for idx in 0..idx {
         all.push_str(&format!(r#"include!(concat!(env!("OUT_DIR"), "/error_{}.rs"));"#, idx));
+        all.push_str("\n");
     }
     all.push_str("\nlong_codes\n");
     all.push_str("}\n");

From 41b39fce98fc141fef067cc22c1e9e9dc7b88b29 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Tue, 3 Sep 2019 22:10:12 -0400
Subject: [PATCH 536/943] Remove rustc_diagnostic_macros feature

---
 src/librustc/lib.rs                           |  1 -
 src/librustc_codegen_llvm/lib.rs              |  1 -
 src/librustc_codegen_ssa/lib.rs               |  1 -
 src/librustc_codegen_utils/lib.rs             |  1 -
 src/librustc_driver/lib.rs                    |  1 -
 src/librustc_interface/passes.rs              |  4 ----
 src/librustc_lint/lib.rs                      |  1 -
 src/librustc_metadata/lib.rs                  |  1 -
 src/librustc_mir/lib.rs                       |  1 -
 src/librustc_passes/lib.rs                    |  1 -
 src/librustc_plugin/lib.rs                    |  1 -
 src/librustc_privacy/lib.rs                   |  1 -
 src/librustc_resolve/lib.rs                   |  1 -
 src/librustc_typeck/lib.rs                    |  1 -
 src/libsyntax/feature_gate/active.rs          |  6 ------
 src/libsyntax/lib.rs                          |  1 -
 src/libsyntax_ext/lib.rs                      |  1 -
 .../ui/feature-gate/allow-features-empty.rs   |  2 --
 .../feature-gate/allow-features-empty.stderr  | 14 ++++---------
 src/test/ui/feature-gate/allow-features.rs    |  4 +---
 .../ui/feature-gate/allow-features.stderr     |  4 ++--
 .../feature-gate-rustc-diagnostic-macros.rs   | 13 ------------
 ...eature-gate-rustc-diagnostic-macros.stderr | 20 -------------------
 23 files changed, 7 insertions(+), 75 deletions(-)
 delete mode 100644 src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.rs
 delete mode 100644 src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr

diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index c5d2b2d7e7f87..d25b954bbe306 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -45,7 +45,6 @@
 #![feature(non_exhaustive)]
 #![feature(optin_builtin_traits)]
 #![feature(range_is_empty)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(slice_patterns)]
 #![feature(specialization)]
 #![feature(unboxed_closures)]
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index f032d0ff0464c..9f2c303145dc8 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -14,7 +14,6 @@
 #![feature(in_band_lifetimes)]
 #![feature(libc)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(optin_builtin_traits)]
 #![feature(concat_idents)]
 #![feature(link_args)]
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index 0f98310722ee3..90bf964ceaa13 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -4,7 +4,6 @@
 #![feature(box_syntax)]
 #![feature(core_intrinsics)]
 #![feature(libc)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(stmt_expr_attributes)]
 #![feature(try_blocks)]
 #![feature(in_band_lifetimes)]
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index 4ea375b59b2c0..1201446afb531 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -10,7 +10,6 @@
 #![feature(core_intrinsics)]
 #![feature(never_type)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(in_band_lifetimes)]
 
 #![recursion_limit="256"]
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 9a6a12e261c10..a912ea3c35821 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -9,7 +9,6 @@
 #![feature(box_syntax)]
 #![cfg_attr(unix, feature(libc))]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(set_stdio)]
 #![feature(no_debug)]
 #![feature(integer_atomics)]
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index bd9b240e24efa..af769a537a675 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -291,10 +291,6 @@ pub fn register_plugins<'a>(
     let mut registry = Registry::new(sess, krate.span);
 
     time(sess, "plugin registration", || {
-        if sess.features_untracked().rustc_diagnostic_macros {
-            // FIXME: remove feature gate
-        }
-
         for registrar in registrars {
             registry.args_hidden = Some(registrar.args);
             (registrar.fun)(&mut registry);
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 27833161ef23d..4ee6551f78781 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -15,7 +15,6 @@
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 3ab7d372461b8..e6104e629e9fb 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -8,7 +8,6 @@
 #![feature(nll)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(rustc_private)]
 #![feature(slice_patterns)]
 #![feature(specialization)]
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index 7a5db4fc19d02..f27db351b74db 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -14,7 +14,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(const_fn)]
 #![feature(decl_macro)]
 #![feature(exhaustive_patterns)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(never_type)]
 #![feature(specialization)]
 #![feature(try_trait)]
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index 2070f306112a1..cf2da4ffa2af0 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -9,7 +9,6 @@
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
 #![feature(bind_by_move_pattern_guards)]
-#![feature(rustc_diagnostic_macros)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs
index 1cf01d481e468..4e1a47c503e59 100644
--- a/src/librustc_plugin/lib.rs
+++ b/src/librustc_plugin/lib.rs
@@ -54,7 +54,6 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
 
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 28ef3b794babd..1e61f78c357df 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -2,7 +2,6 @@
 
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 6ba08ccef0307..7e93e12601376 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -13,7 +13,6 @@
 #![feature(label_break_value)]
 #![feature(mem_take)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 91c7522280af2..959483e4439ff 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -65,7 +65,6 @@ This API is completely unstable and subject to change.
 #![feature(exhaustive_patterns)]
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(slice_patterns)]
 #![feature(never_type)]
 #![feature(inner_deref)]
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index c947b09fdcb57..86979bdb1fb52 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -120,12 +120,6 @@ declare_features! (
     /// macros disappear).
     (active, allow_internal_unsafe, "1.0.0", None, None),
 
-    /// Allows using the macros:
-    /// + `__diagnostic_used`
-    /// + `__register_diagnostic`
-    /// +`__build_diagnostic_array`
-    (active, rustc_diagnostic_macros, "1.0.0", None, None),
-
     /// Allows using `#[rustc_const_unstable(feature = "foo", ..)]` which
     /// lets a function to be `const` when opted into with `#![feature(foo)]`.
     (active, rustc_const_unstable, "1.0.0", None, None),
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 75ce306df800e..49efbce482fa3 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -18,7 +18,6 @@
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_span)]
-#![feature(rustc_diagnostic_macros)]
 #![feature(try_trait)]
 #![feature(unicode_internals)]
 
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 26ef80b2b06df..5bc6345d8118e 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -9,7 +9,6 @@
 #![feature(nll)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
-#![feature(rustc_diagnostic_macros)]
 
 extern crate proc_macro;
 
diff --git a/src/test/ui/feature-gate/allow-features-empty.rs b/src/test/ui/feature-gate/allow-features-empty.rs
index 784a1d2697d67..641e4b852e79f 100644
--- a/src/test/ui/feature-gate/allow-features-empty.rs
+++ b/src/test/ui/feature-gate/allow-features-empty.rs
@@ -1,8 +1,6 @@
 // compile-flags: -Z allow_features=
 // Note: This test uses rustc internal flags because they will never stabilize.
 
-#![feature(rustc_diagnostic_macros)] //~ ERROR
-
 #![feature(rustc_const_unstable)] //~ ERROR
 
 #![feature(lang_items)] //~ ERROR
diff --git a/src/test/ui/feature-gate/allow-features-empty.stderr b/src/test/ui/feature-gate/allow-features-empty.stderr
index ab41422ed05b8..a87d105850327 100644
--- a/src/test/ui/feature-gate/allow-features-empty.stderr
+++ b/src/test/ui/feature-gate/allow-features-empty.stderr
@@ -1,27 +1,21 @@
-error[E0725]: the feature `rustc_diagnostic_macros` is not in the list of allowed features
-  --> $DIR/allow-features-empty.rs:4:12
-   |
-LL | #![feature(rustc_diagnostic_macros)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
-  --> $DIR/allow-features-empty.rs:6:12
+  --> $DIR/allow-features-empty.rs:4:12
    |
 LL | #![feature(rustc_const_unstable)]
    |            ^^^^^^^^^^^^^^^^^^^^
 
 error[E0725]: the feature `lang_items` is not in the list of allowed features
-  --> $DIR/allow-features-empty.rs:8:12
+  --> $DIR/allow-features-empty.rs:6:12
    |
 LL | #![feature(lang_items)]
    |            ^^^^^^^^^^
 
 error[E0725]: the feature `unknown_stdlib_feature` is not in the list of allowed features
-  --> $DIR/allow-features-empty.rs:10:12
+  --> $DIR/allow-features-empty.rs:8:12
    |
 LL | #![feature(unknown_stdlib_feature)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0725`.
diff --git a/src/test/ui/feature-gate/allow-features.rs b/src/test/ui/feature-gate/allow-features.rs
index de3439a5b628f..de69e48a65fdf 100644
--- a/src/test/ui/feature-gate/allow-features.rs
+++ b/src/test/ui/feature-gate/allow-features.rs
@@ -1,8 +1,6 @@
-// compile-flags: -Z allow_features=rustc_diagnostic_macros,lang_items
+// compile-flags: -Z allow_features=lang_items
 // Note: This test uses rustc internal flags because they will never stabilize.
 
-#![feature(rustc_diagnostic_macros)]
-
 #![feature(rustc_const_unstable)] //~ ERROR
 
 #![feature(lang_items)]
diff --git a/src/test/ui/feature-gate/allow-features.stderr b/src/test/ui/feature-gate/allow-features.stderr
index 5b39a6f053bde..157dddf06ad1d 100644
--- a/src/test/ui/feature-gate/allow-features.stderr
+++ b/src/test/ui/feature-gate/allow-features.stderr
@@ -1,11 +1,11 @@
 error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features
-  --> $DIR/allow-features.rs:6:12
+  --> $DIR/allow-features.rs:4:12
    |
 LL | #![feature(rustc_const_unstable)]
    |            ^^^^^^^^^^^^^^^^^^^^
 
 error[E0725]: the feature `unknown_stdlib_feature` is not in the list of allowed features
-  --> $DIR/allow-features.rs:10:12
+  --> $DIR/allow-features.rs:8:12
    |
 LL | #![feature(unknown_stdlib_feature)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.rs b/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.rs
deleted file mode 100644
index 63c2c31fd30e6..0000000000000
--- a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Test that diagnostic macros are gated by `rustc_diagnostic_macros` feature
-// gate
-
-__register_diagnostic!(E0001);
-//~^ ERROR cannot find macro `__register_diagnostic!` in this scope
-
-fn main() {
-    __diagnostic_used!(E0001);
-    //~^ ERROR cannot find macro `__diagnostic_used!` in this scope
-}
-
-__build_diagnostic_array!(DIAGNOSTICS);
-//~^ ERROR cannot find macro `__build_diagnostic_array!` in this scope
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr b/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr
deleted file mode 100644
index 676b8b9f056c1..0000000000000
--- a/src/test/ui/feature-gates/feature-gate-rustc-diagnostic-macros.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-error: cannot find macro `__build_diagnostic_array!` in this scope
-  --> $DIR/feature-gate-rustc-diagnostic-macros.rs:12:1
-   |
-LL | __build_diagnostic_array!(DIAGNOSTICS);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: cannot find macro `__diagnostic_used!` in this scope
-  --> $DIR/feature-gate-rustc-diagnostic-macros.rs:8:5
-   |
-LL |     __diagnostic_used!(E0001);
-   |     ^^^^^^^^^^^^^^^^^
-
-error: cannot find macro `__register_diagnostic!` in this scope
-  --> $DIR/feature-gate-rustc-diagnostic-macros.rs:4:1
-   |
-LL | __register_diagnostic!(E0001);
-   | ^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
-

From 0b7ba6ec54db24b676d376665692a49d0ecd603a Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Tue, 3 Sep 2019 19:32:44 -0700
Subject: [PATCH 537/943] std: Improve downstream codegen in `Command::env`

This commit rejiggers the generics used in the implementation of
`Command::env` with the purpose of reducing the amount of codegen that
needs to happen in consumer crates, instead preferring to generate code
into libstd.

This was found when profiling the compile times of the `cc` crate where
the binary rlib produced had a lot of `BTreeMap` code compiled into it
but the crate doesn't actually use `BTreeMap`. It turns out that
`Command::env` is generic enough to codegen the entire implementation in
calling crates, but in this case there's no performance concern so it's
fine to compile the code into the standard library.

This change is done by removing the generic on the `CommandEnv` map
which is intended to handle case-insensitive variables on Windows.
Instead now a generic isn't used but rather a `use` statement defined
per-platform is used.

With this commit a debug build of `Command::new("foo").env("a", "b")`
drops from 21k lines of LLVM IR to 10k.
---
 src/libstd/sys/cloudabi/shims/process.rs      |  8 +--
 src/libstd/sys/sgx/process.rs                 |  8 +--
 src/libstd/sys/unix/process/mod.rs            |  1 +
 src/libstd/sys/unix/process/process_common.rs |  8 +--
 .../sys/vxworks/process/process_common.rs     | 10 ++--
 src/libstd/sys/wasi/process.rs                |  8 +--
 src/libstd/sys/wasm/process.rs                |  8 +--
 src/libstd/sys/windows/process.rs             | 24 ++++-----
 src/libstd/sys_common/process.rs              | 51 +++++--------------
 9 files changed, 56 insertions(+), 70 deletions(-)

diff --git a/src/libstd/sys/cloudabi/shims/process.rs b/src/libstd/sys/cloudabi/shims/process.rs
index e719b362cbf55..03a59d6d7c832 100644
--- a/src/libstd/sys/cloudabi/shims/process.rs
+++ b/src/libstd/sys/cloudabi/shims/process.rs
@@ -4,14 +4,16 @@ use crate::io;
 use crate::sys::fs::File;
 use crate::sys::pipe::AnonPipe;
 use crate::sys::{unsupported, Void};
-use crate::sys_common::process::{CommandEnv, DefaultEnvKey};
+use crate::sys_common::process::CommandEnv;
+
+pub use crate::ffi::OsString as EnvKey;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Command
 ////////////////////////////////////////////////////////////////////////////////
 
 pub struct Command {
-    env: CommandEnv<DefaultEnvKey>,
+    env: CommandEnv,
 }
 
 // passed back to std::process with the pipes connected to the child, if any
@@ -37,7 +39,7 @@ impl Command {
 
     pub fn arg(&mut self, _arg: &OsStr) {}
 
-    pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
+    pub fn env_mut(&mut self) -> &mut CommandEnv {
         &mut self.env
     }
 
diff --git a/src/libstd/sys/sgx/process.rs b/src/libstd/sys/sgx/process.rs
index a02e009d95356..edf933d10e074 100644
--- a/src/libstd/sys/sgx/process.rs
+++ b/src/libstd/sys/sgx/process.rs
@@ -4,14 +4,16 @@ use crate::io;
 use crate::sys::fs::File;
 use crate::sys::pipe::AnonPipe;
 use crate::sys::{unsupported, Void};
-use crate::sys_common::process::{CommandEnv, DefaultEnvKey};
+use crate::sys_common::process::CommandEnv;
+
+pub use crate::ffi::OsString as EnvKey;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Command
 ////////////////////////////////////////////////////////////////////////////////
 
 pub struct Command {
-    env: CommandEnv<DefaultEnvKey>
+    env: CommandEnv,
 }
 
 // passed back to std::process with the pipes connected to the child, if any
@@ -38,7 +40,7 @@ impl Command {
     pub fn arg(&mut self, _arg: &OsStr) {
     }
 
-    pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
+    pub fn env_mut(&mut self) -> &mut CommandEnv {
         &mut self.env
     }
 
diff --git a/src/libstd/sys/unix/process/mod.rs b/src/libstd/sys/unix/process/mod.rs
index bba4b21c46232..056a20345f404 100644
--- a/src/libstd/sys/unix/process/mod.rs
+++ b/src/libstd/sys/unix/process/mod.rs
@@ -1,5 +1,6 @@
 pub use self::process_common::{Command, ExitStatus, ExitCode, Stdio, StdioPipes};
 pub use self::process_inner::Process;
+pub use crate::ffi::OsString as EnvKey;
 
 mod process_common;
 #[cfg(not(target_os = "fuchsia"))]
diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index 21fca23a8fe9e..72e66cc8e7240 100644
--- a/src/libstd/sys/unix/process/process_common.rs
+++ b/src/libstd/sys/unix/process/process_common.rs
@@ -7,7 +7,7 @@ use crate::ptr;
 use crate::sys::fd::FileDesc;
 use crate::sys::fs::{File, OpenOptions};
 use crate::sys::pipe::{self, AnonPipe};
-use crate::sys_common::process::{CommandEnv, DefaultEnvKey};
+use crate::sys_common::process::CommandEnv;
 use crate::collections::BTreeMap;
 
 use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
@@ -69,7 +69,7 @@ pub struct Command {
     program: CString,
     args: Vec<CString>,
     argv: Argv,
-    env: CommandEnv<DefaultEnvKey>,
+    env: CommandEnv,
 
     cwd: Option<CString>,
     uid: Option<uid_t>,
@@ -201,7 +201,7 @@ impl Command {
         self.stderr = Some(stderr);
     }
 
-    pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
+    pub fn env_mut(&mut self) -> &mut CommandEnv {
         &mut self.env
     }
 
@@ -271,7 +271,7 @@ impl CStringArray {
     }
 }
 
-fn construct_envp(env: BTreeMap<DefaultEnvKey, OsString>, saw_nul: &mut bool) -> CStringArray {
+fn construct_envp(env: BTreeMap<OsString, OsString>, saw_nul: &mut bool) -> CStringArray {
     let mut result = CStringArray::with_capacity(env.len());
     for (k, v) in env {
         let mut k: OsString = k.into();
diff --git a/src/libstd/sys/vxworks/process/process_common.rs b/src/libstd/sys/vxworks/process/process_common.rs
index ba797354a7380..509140229fd3a 100644
--- a/src/libstd/sys/vxworks/process/process_common.rs
+++ b/src/libstd/sys/vxworks/process/process_common.rs
@@ -7,11 +7,13 @@ use crate::ptr;
 use crate::sys::fd::FileDesc;
 use crate::sys::fs::{File, OpenOptions};
 use crate::sys::pipe::{self, AnonPipe};
-use crate::sys_common::process::{CommandEnv, DefaultEnvKey};
+use crate::sys_common::process::CommandEnv;
 use crate::collections::BTreeMap;
 
 use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
 
+pub use crate::ffi::OsString as EnvKey;
+
 ////////////////////////////////////////////////////////////////////////////////
 // Command
 ////////////////////////////////////////////////////////////////////////////////
@@ -37,7 +39,7 @@ pub struct Command {
     program: CString,
     args: Vec<CString>,
     argv: Argv,
-    env: CommandEnv<DefaultEnvKey>,
+    env: CommandEnv,
 
     cwd: Option<CString>,
     uid: Option<uid_t>,
@@ -170,7 +172,7 @@ impl Command {
         self.stderr = Some(stderr);
     }
 
-    pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
+    pub fn env_mut(&mut self) -> &mut CommandEnv {
         &mut self.env
     }
 
@@ -240,7 +242,7 @@ impl CStringArray {
     }
 }
 
-fn construct_envp(env: BTreeMap<DefaultEnvKey, OsString>, saw_nul: &mut bool) -> CStringArray {
+fn construct_envp(env: BTreeMap<OsString, OsString>, saw_nul: &mut bool) -> CStringArray {
     let mut result = CStringArray::with_capacity(env.len());
     for (k, v) in env {
         let mut k: OsString = k.into();
diff --git a/src/libstd/sys/wasi/process.rs b/src/libstd/sys/wasi/process.rs
index 788b829f4bac9..1c4d028b7618b 100644
--- a/src/libstd/sys/wasi/process.rs
+++ b/src/libstd/sys/wasi/process.rs
@@ -4,14 +4,16 @@ use crate::io;
 use crate::sys::fs::File;
 use crate::sys::pipe::AnonPipe;
 use crate::sys::{unsupported, Void};
-use crate::sys_common::process::{CommandEnv, DefaultEnvKey};
+use crate::sys_common::process::CommandEnv;
+
+pub use crate::ffi::OsString as EnvKey;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Command
 ////////////////////////////////////////////////////////////////////////////////
 
 pub struct Command {
-    env: CommandEnv<DefaultEnvKey>
+    env: CommandEnv
 }
 
 // passed back to std::process with the pipes connected to the child, if any
@@ -38,7 +40,7 @@ impl Command {
     pub fn arg(&mut self, _arg: &OsStr) {
     }
 
-    pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
+    pub fn env_mut(&mut self) -> &mut CommandEnv {
         &mut self.env
     }
 
diff --git a/src/libstd/sys/wasm/process.rs b/src/libstd/sys/wasm/process.rs
index a02e009d95356..edf933d10e074 100644
--- a/src/libstd/sys/wasm/process.rs
+++ b/src/libstd/sys/wasm/process.rs
@@ -4,14 +4,16 @@ use crate::io;
 use crate::sys::fs::File;
 use crate::sys::pipe::AnonPipe;
 use crate::sys::{unsupported, Void};
-use crate::sys_common::process::{CommandEnv, DefaultEnvKey};
+use crate::sys_common::process::CommandEnv;
+
+pub use crate::ffi::OsString as EnvKey;
 
 ////////////////////////////////////////////////////////////////////////////////
 // Command
 ////////////////////////////////////////////////////////////////////////////////
 
 pub struct Command {
-    env: CommandEnv<DefaultEnvKey>
+    env: CommandEnv,
 }
 
 // passed back to std::process with the pipes connected to the child, if any
@@ -38,7 +40,7 @@ impl Command {
     pub fn arg(&mut self, _arg: &OsStr) {
     }
 
-    pub fn env_mut(&mut self) -> &mut CommandEnv<DefaultEnvKey> {
+    pub fn env_mut(&mut self) -> &mut CommandEnv {
         &mut self.env
     }
 
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index 05e0ca6706453..8658deb854635 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -19,7 +19,7 @@ use crate::sys::pipe::{self, AnonPipe};
 use crate::sys::stdio;
 use crate::sys::cvt;
 use crate::sys_common::{AsInner, FromInner, IntoInner};
-use crate::sys_common::process::{CommandEnv, EnvKey};
+use crate::sys_common::process::CommandEnv;
 use crate::borrow::Borrow;
 
 use libc::{c_void, EXIT_SUCCESS, EXIT_FAILURE};
@@ -30,30 +30,28 @@ use libc::{c_void, EXIT_SUCCESS, EXIT_FAILURE};
 
 #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
 #[doc(hidden)]
-pub struct WindowsEnvKey(OsString);
+pub struct EnvKey(OsString);
 
-impl From<OsString> for WindowsEnvKey {
+impl From<OsString> for EnvKey {
     fn from(k: OsString) -> Self {
         let mut buf = k.into_inner().into_inner();
         buf.make_ascii_uppercase();
-        WindowsEnvKey(FromInner::from_inner(FromInner::from_inner(buf)))
+        EnvKey(FromInner::from_inner(FromInner::from_inner(buf)))
     }
 }
 
-impl From<WindowsEnvKey> for OsString {
-    fn from(k: WindowsEnvKey) -> Self { k.0 }
+impl From<EnvKey> for OsString {
+    fn from(k: EnvKey) -> Self { k.0 }
 }
 
-impl Borrow<OsStr> for WindowsEnvKey {
+impl Borrow<OsStr> for EnvKey {
     fn borrow(&self) -> &OsStr { &self.0 }
 }
 
-impl AsRef<OsStr> for WindowsEnvKey {
+impl AsRef<OsStr> for EnvKey {
     fn as_ref(&self) -> &OsStr { &self.0 }
 }
 
-impl EnvKey for WindowsEnvKey {}
-
 
 fn ensure_no_nuls<T: AsRef<OsStr>>(str: T) -> io::Result<T> {
     if str.as_ref().encode_wide().any(|b| b == 0) {
@@ -66,7 +64,7 @@ fn ensure_no_nuls<T: AsRef<OsStr>>(str: T) -> io::Result<T> {
 pub struct Command {
     program: OsString,
     args: Vec<OsString>,
-    env: CommandEnv<WindowsEnvKey>,
+    env: CommandEnv,
     cwd: Option<OsString>,
     flags: u32,
     detach: bool, // not currently exposed in std::process
@@ -110,7 +108,7 @@ impl Command {
     pub fn arg(&mut self, arg: &OsStr) {
         self.args.push(arg.to_os_string())
     }
-    pub fn env_mut(&mut self) -> &mut CommandEnv<WindowsEnvKey> {
+    pub fn env_mut(&mut self) -> &mut CommandEnv {
         &mut self.env
     }
     pub fn cwd(&mut self, dir: &OsStr) {
@@ -498,7 +496,7 @@ fn make_command_line(prog: &OsStr, args: &[OsString]) -> io::Result<Vec<u16>> {
     }
 }
 
-fn make_envp(maybe_env: Option<BTreeMap<WindowsEnvKey, OsString>>)
+fn make_envp(maybe_env: Option<BTreeMap<EnvKey, OsString>>)
              -> io::Result<(*mut c_void, Vec<u16>)> {
     // On Windows we pass an "environment block" which is not a char**, but
     // rather a concatenation of null-terminated k=v\0 sequences, with a final
diff --git a/src/libstd/sys_common/process.rs b/src/libstd/sys_common/process.rs
index 4d40dec97245a..bdf66fca35970 100644
--- a/src/libstd/sys_common/process.rs
+++ b/src/libstd/sys_common/process.rs
@@ -1,47 +1,20 @@
 #![allow(dead_code)]
 #![unstable(feature = "process_internals", issue = "0")]
 
-use crate::ffi::{OsStr, OsString};
-use crate::env;
 use crate::collections::BTreeMap;
-use crate::borrow::Borrow;
-
-pub trait EnvKey:
-    From<OsString> + Into<OsString> +
-    Borrow<OsStr> + Borrow<Self> + AsRef<OsStr> +
-    Ord + Clone {}
-
-// Implement a case-sensitive environment variable key
-#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
-pub struct DefaultEnvKey(OsString);
-
-impl From<OsString> for DefaultEnvKey {
-    fn from(k: OsString) -> Self { DefaultEnvKey(k) }
-}
-
-impl From<DefaultEnvKey> for OsString {
-    fn from(k: DefaultEnvKey) -> Self { k.0 }
-}
-
-impl Borrow<OsStr> for DefaultEnvKey {
-    fn borrow(&self) -> &OsStr { &self.0 }
-}
-
-impl AsRef<OsStr> for DefaultEnvKey {
-    fn as_ref(&self) -> &OsStr { &self.0 }
-}
-
-impl EnvKey for DefaultEnvKey {}
+use crate::env;
+use crate::ffi::{OsStr, OsString};
+use crate::sys::process::EnvKey;
 
 // Stores a set of changes to an environment
 #[derive(Clone, Debug)]
-pub struct CommandEnv<K> {
+pub struct CommandEnv {
     clear: bool,
     saw_path: bool,
-    vars: BTreeMap<K, Option<OsString>>
+    vars: BTreeMap<EnvKey, Option<OsString>>
 }
 
-impl<K: EnvKey> Default for CommandEnv<K> {
+impl Default for CommandEnv {
     fn default() -> Self {
         CommandEnv {
             clear: false,
@@ -51,10 +24,10 @@ impl<K: EnvKey> Default for CommandEnv<K> {
     }
 }
 
-impl<K: EnvKey> CommandEnv<K> {
+impl CommandEnv {
     // Capture the current environment with these changes applied
-    pub fn capture(&self) -> BTreeMap<K, OsString> {
-        let mut result = BTreeMap::<K, OsString>::new();
+    pub fn capture(&self) -> BTreeMap<EnvKey, OsString> {
+        let mut result = BTreeMap::<EnvKey, OsString>::new();
         if !self.clear {
             for (k, v) in env::vars_os() {
                 result.insert(k.into(), v);
@@ -90,7 +63,7 @@ impl<K: EnvKey> CommandEnv<K> {
         !self.clear && self.vars.is_empty()
     }
 
-    pub fn capture_if_changed(&self) -> Option<BTreeMap<K, OsString>> {
+    pub fn capture_if_changed(&self) -> Option<BTreeMap<EnvKey, OsString>> {
         if self.is_unchanged() {
             None
         } else {
@@ -103,6 +76,7 @@ impl<K: EnvKey> CommandEnv<K> {
         self.maybe_saw_path(&key);
         self.vars.insert(key.to_owned().into(), Some(value.to_owned()));
     }
+
     pub fn remove(&mut self, key: &OsStr) {
         self.maybe_saw_path(&key);
         if self.clear {
@@ -111,13 +85,16 @@ impl<K: EnvKey> CommandEnv<K> {
             self.vars.insert(key.to_owned().into(), None);
         }
     }
+
     pub fn clear(&mut self) {
         self.clear = true;
         self.vars.clear();
     }
+
     pub fn have_changed_path(&self) -> bool {
         self.saw_path || self.clear
     }
+
     fn maybe_saw_path(&mut self, key: &OsStr) {
         if !self.saw_path && key == "PATH" {
             self.saw_path = true;

From bb9d3bea30c354fecca5dae735bec62962fc5e4c Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Thu, 5 Sep 2019 11:55:20 -0700
Subject: [PATCH 538/943] rustc: Allow the cdylib crate type with wasm32-wasi

The wasm32-wasi target respects configuration around `crt-static` in
general, but is defaulted to being static. This interacted badly with
code which validated the `cdylib` crate type for `wasm32-wasi`,
erroneously saying that the `cdylib` crate type wasn't supported on
`wasm32-wasi` by default. This commit sets the appropriate flag in
`wasm32_wasi`'s target specification to indicate that the `cdylib` crate
type is supported regardless of `crt-static`

Closes #64187
---
 src/librustc_target/spec/wasm32_wasi.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/librustc_target/spec/wasm32_wasi.rs b/src/librustc_target/spec/wasm32_wasi.rs
index bb33493a77333..86978c05b15d0 100644
--- a/src/librustc_target/spec/wasm32_wasi.rs
+++ b/src/librustc_target/spec/wasm32_wasi.rs
@@ -97,6 +97,10 @@ pub fn target() -> Result<Target, String> {
     options.crt_static_default = true;
     options.crt_static_respected = true;
 
+    // Allow `+crt-static` to create a "cdylib" output which is just a wasm file
+    // without a main function.
+    options.crt_static_allows_dylibs = true;
+
     Ok(Target {
         llvm_target: "wasm32-wasi".to_string(),
         target_endian: "little".to_string(),

From 159d249705659ecb2ef41623105cab1c9f95b802 Mon Sep 17 00:00:00 2001
From: Philipp Hansch <dev@phansch.net>
Date: Thu, 5 Sep 2019 21:31:12 +0200
Subject: [PATCH 539/943] annotate-snippet emitter: Deal with multispans from
 macros, too

This moves the two methods from the `EmitterWriter` impl to trait
default methods in the `Emitter` trait so that they can be re-used by
the `AnnotateSnippetEmitterWriter`.

Closes #61810
---
 .../annotate_snippet_emitter_writer.rs        |  12 +-
 src/librustc_errors/emitter.rs                | 251 +++++++++---------
 2 files changed, 137 insertions(+), 126 deletions(-)

diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs
index 3bed5d81dc514..60ee7507223e9 100644
--- a/src/librustc_errors/annotate_snippet_emitter_writer.rs
+++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs
@@ -30,10 +30,14 @@ pub struct AnnotateSnippetEmitterWriter {
 impl Emitter for AnnotateSnippetEmitterWriter {
     /// The entry point for the diagnostics generation
     fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
-        let children = db.children.clone();
-        let (primary_span, suggestions) = self.primary_span_formatted(&db);
-
-        // FIXME(#59346): Add `fix_multispans_in_std_macros` function from emitter.rs
+        let mut children = db.children.clone();
+        let (mut primary_span, suggestions) = self.primary_span_formatted(&db);
+
+        self.fix_multispans_in_std_macros(&self.source_map,
+                                          &mut primary_span,
+                                          &mut children,
+                                          &db.level,
+                                          db.handler.flags.external_macro_backtrace);
 
         self.emit_messages_default(&db.level,
                                    db.message(),
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index a298f9958f2d1..0ce69eecc6b1e 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -247,6 +247,133 @@ pub trait Emitter {
             (primary_span, &db.suggestions)
         }
     }
+
+    // This does a small "fix" for multispans by looking to see if it can find any that
+    // point directly at <*macros>. Since these are often difficult to read, this
+    // will change the span to point at the use site.
+    fn fix_multispans_in_std_macros(&self,
+                                    source_map: &Option<Lrc<SourceMapperDyn>>,
+                                    span: &mut MultiSpan,
+                                    children: &mut Vec<SubDiagnostic>,
+                                    level: &Level,
+                                    backtrace: bool) {
+        let mut spans_updated = self.fix_multispan_in_std_macros(source_map, span, backtrace);
+        for child in children.iter_mut() {
+            spans_updated |= self.fix_multispan_in_std_macros(
+                                 source_map,
+                                 &mut child.span,
+                                 backtrace
+                             );
+        }
+        let msg = if level == &Error {
+            "this error originates in a macro outside of the current crate \
+             (in Nightly builds, run with -Z external-macro-backtrace \
+              for more info)".to_string()
+        } else {
+            "this warning originates in a macro outside of the current crate \
+             (in Nightly builds, run with -Z external-macro-backtrace \
+              for more info)".to_string()
+        };
+
+        if spans_updated {
+            children.push(SubDiagnostic {
+                level: Level::Note,
+                message: vec![
+                    (msg,
+                     Style::NoStyle),
+                ],
+                span: MultiSpan::new(),
+                render_span: None,
+            });
+        }
+    }
+
+    // This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
+    // <*macros>. Since these locations are often difficult to read, we move these Spans from
+    // <*macros> to their corresponding use site.
+    fn fix_multispan_in_std_macros(&self,
+                                   source_map: &Option<Lrc<SourceMapperDyn>>,
+                                   span: &mut MultiSpan,
+                                   always_backtrace: bool) -> bool {
+        let mut spans_updated = false;
+
+        if let Some(ref sm) = source_map {
+            let mut before_after: Vec<(Span, Span)> = vec![];
+            let mut new_labels: Vec<(Span, String)> = vec![];
+
+            // First, find all the spans in <*macros> and point instead at their use site
+            for sp in span.primary_spans() {
+                if sp.is_dummy() {
+                    continue;
+                }
+                let call_sp = sm.call_span_if_macro(*sp);
+                if call_sp != *sp && !always_backtrace {
+                    before_after.push((*sp, call_sp));
+                }
+                let backtrace_len = sp.macro_backtrace().len();
+                for (i, trace) in sp.macro_backtrace().iter().rev().enumerate() {
+                    // Only show macro locations that are local
+                    // and display them like a span_note
+                    if trace.def_site_span.is_dummy() {
+                        continue;
+                    }
+                    if always_backtrace {
+                        new_labels.push((trace.def_site_span,
+                                            format!("in this expansion of `{}`{}",
+                                                    trace.macro_decl_name,
+                                                    if backtrace_len > 2 {
+                                                        // if backtrace_len == 1 it'll be pointed
+                                                        // at by "in this macro invocation"
+                                                        format!(" (#{})", i + 1)
+                                                    } else {
+                                                        String::new()
+                                                    })));
+                    }
+                    // Check to make sure we're not in any <*macros>
+                    if !sm.span_to_filename(trace.def_site_span).is_macros() &&
+                        !trace.macro_decl_name.starts_with("desugaring of ") &&
+                        !trace.macro_decl_name.starts_with("#[") ||
+                        always_backtrace {
+                        new_labels.push((trace.call_site,
+                                            format!("in this macro invocation{}",
+                                                    if backtrace_len > 2 && always_backtrace {
+                                                        // only specify order when the macro
+                                                        // backtrace is multiple levels deep
+                                                        format!(" (#{})", i + 1)
+                                                    } else {
+                                                        String::new()
+                                                    })));
+                        if !always_backtrace {
+                            break;
+                        }
+                    }
+                }
+            }
+            for (label_span, label_text) in new_labels {
+                span.push_span_label(label_span, label_text);
+            }
+            for sp_label in span.span_labels() {
+                if sp_label.span.is_dummy() {
+                    continue;
+                }
+                if sm.span_to_filename(sp_label.span.clone()).is_macros() &&
+                    !always_backtrace
+                {
+                    let v = sp_label.span.macro_backtrace();
+                    if let Some(use_site) = v.last() {
+                        before_after.push((sp_label.span.clone(), use_site.call_site.clone()));
+                    }
+                }
+            }
+            // After we have them, make sure we replace these 'bad' def sites with their use sites
+            for (before, after) in before_after {
+                span.replace(before, after);
+                spans_updated = true;
+            }
+        }
+
+        spans_updated
+    }
 }
 
 impl Emitter for EmitterWriter {
@@ -254,7 +381,8 @@ impl Emitter for EmitterWriter {
         let mut children = db.children.clone();
         let (mut primary_span, suggestions) = self.primary_span_formatted(&db);
 
-        self.fix_multispans_in_std_macros(&mut primary_span,
+        self.fix_multispans_in_std_macros(&self.sm,
+                                          &mut primary_span,
                                           &mut children,
                                           &db.level,
                                           db.handler.flags.external_macro_backtrace);
@@ -919,127 +1047,6 @@ impl EmitterWriter {
         max
     }
 
-    // This "fixes" MultiSpans that contain Spans that are pointing to locations inside of
-    // <*macros>. Since these locations are often difficult to read, we move these Spans from
-    // <*macros> to their corresponding use site.
-    fn fix_multispan_in_std_macros(&mut self,
-                                   span: &mut MultiSpan,
-                                   always_backtrace: bool) -> bool {
-        let mut spans_updated = false;
-
-        if let Some(ref sm) = self.sm {
-            let mut before_after: Vec<(Span, Span)> = vec![];
-            let mut new_labels: Vec<(Span, String)> = vec![];
-
-            // First, find all the spans in <*macros> and point instead at their use site
-            for sp in span.primary_spans() {
-                if sp.is_dummy() {
-                    continue;
-                }
-                let call_sp = sm.call_span_if_macro(*sp);
-                if call_sp != *sp && !always_backtrace {
-                    before_after.push((*sp, call_sp));
-                }
-                let backtrace_len = sp.macro_backtrace().len();
-                for (i, trace) in sp.macro_backtrace().iter().rev().enumerate() {
-                    // Only show macro locations that are local
-                    // and display them like a span_note
-                    if trace.def_site_span.is_dummy() {
-                        continue;
-                    }
-                    if always_backtrace {
-                        new_labels.push((trace.def_site_span,
-                                            format!("in this expansion of `{}`{}",
-                                                    trace.macro_decl_name,
-                                                    if backtrace_len > 2 {
-                                                        // if backtrace_len == 1 it'll be pointed
-                                                        // at by "in this macro invocation"
-                                                        format!(" (#{})", i + 1)
-                                                    } else {
-                                                        String::new()
-                                                    })));
-                    }
-                    // Check to make sure we're not in any <*macros>
-                    if !sm.span_to_filename(trace.def_site_span).is_macros() &&
-                        !trace.macro_decl_name.starts_with("desugaring of ") &&
-                        !trace.macro_decl_name.starts_with("#[") ||
-                        always_backtrace {
-                        new_labels.push((trace.call_site,
-                                            format!("in this macro invocation{}",
-                                                    if backtrace_len > 2 && always_backtrace {
-                                                        // only specify order when the macro
-                                                        // backtrace is multiple levels deep
-                                                        format!(" (#{})", i + 1)
-                                                    } else {
-                                                        String::new()
-                                                    })));
-                        if !always_backtrace {
-                            break;
-                        }
-                    }
-                }
-            }
-            for (label_span, label_text) in new_labels {
-                span.push_span_label(label_span, label_text);
-            }
-            for sp_label in span.span_labels() {
-                if sp_label.span.is_dummy() {
-                    continue;
-                }
-                if sm.span_to_filename(sp_label.span.clone()).is_macros() &&
-                    !always_backtrace
-                {
-                    let v = sp_label.span.macro_backtrace();
-                    if let Some(use_site) = v.last() {
-                        before_after.push((sp_label.span.clone(), use_site.call_site.clone()));
-                    }
-                }
-            }
-            // After we have them, make sure we replace these 'bad' def sites with their use sites
-            for (before, after) in before_after {
-                span.replace(before, after);
-                spans_updated = true;
-            }
-        }
-
-        spans_updated
-    }
-
-    // This does a small "fix" for multispans by looking to see if it can find any that
-    // point directly at <*macros>. Since these are often difficult to read, this
-    // will change the span to point at the use site.
-    fn fix_multispans_in_std_macros(&mut self,
-                                    span: &mut MultiSpan,
-                                    children: &mut Vec<SubDiagnostic>,
-                                    level: &Level,
-                                    backtrace: bool) {
-        let mut spans_updated = self.fix_multispan_in_std_macros(span, backtrace);
-        for child in children.iter_mut() {
-            spans_updated |= self.fix_multispan_in_std_macros(&mut child.span, backtrace);
-        }
-        let msg = if level == &Error {
-            "this error originates in a macro outside of the current crate \
-             (in Nightly builds, run with -Z external-macro-backtrace \
-              for more info)".to_string()
-        } else {
-            "this warning originates in a macro outside of the current crate \
-             (in Nightly builds, run with -Z external-macro-backtrace \
-              for more info)".to_string()
-        };
-
-        if spans_updated {
-            children.push(SubDiagnostic {
-                level: Level::Note,
-                message: vec![
-                    (msg,
-                     Style::NoStyle),
-                ],
-                span: MultiSpan::new(),
-                render_span: None,
-            });
-        }
-    }
-
     /// Adds a left margin to every line but the first, given a padding length and the label being
     /// displayed, keeping the provided highlighting.
     fn msg_to_buffer(&self,

From 060fe88610ff8bad0e687a819bcb705fe988412a Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Thu, 5 Sep 2019 23:03:50 +0300
Subject: [PATCH 540/943] fill metadata in rustc_lexer's Cargo.toml

We publish this to crates.io, so having non-empty meta is useful
---
 src/librustc_lexer/Cargo.toml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/librustc_lexer/Cargo.toml b/src/librustc_lexer/Cargo.toml
index 675d3065c5b28..950771f0a6927 100644
--- a/src/librustc_lexer/Cargo.toml
+++ b/src/librustc_lexer/Cargo.toml
@@ -2,8 +2,14 @@
 authors = ["The Rust Project Developers"]
 name = "rustc_lexer"
 version = "0.1.0"
+license = "MIT OR Apache-2.0"
 edition = "2018"
 
+repository = "https://github.com/rust-lang/rust/"
+description = """
+Rust lexer used by rustc. No stability guarantees are provided.
+"""
+
 # Note: do not remove this blank `[lib]` section.
 # This will be used when publishing this crate as `rustc-ap-rustc_lexer`.
 [lib]

From afcf9b262d450edd1a7d54754e62f62d50052d8d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 5 Sep 2019 13:15:42 -0700
Subject: [PATCH 541/943] Bail out when encountering likely missing turbofish
 in parser

When encountering a likely intended turbofish without `::`, bubble
up the diagnostic instead of emitting it to allow the parser to recover
more gracefully and avoid uneccessary type errors that are likely to be
wrong.
---
 src/libsyntax/parse/diagnostics.rs            |  5 +-
 src/libsyntax/parse/parser/expr.rs            |  2 +-
 src/test/ui/did_you_mean/issue-40396.rs       | 11 ---
 src/test/ui/did_you_mean/issue-40396.stderr   | 80 +------------------
 .../require-parens-for-chained-comparison.rs  |  3 +-
 ...quire-parens-for-chained-comparison.stderr | 15 +---
 .../ui/parser/trait-object-lifetime-parens.rs |  1 -
 .../trait-object-lifetime-parens.stderr       | 11 +--
 8 files changed, 12 insertions(+), 116 deletions(-)

diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index d4e661d1a38b7..d050d4f4ce705 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -544,7 +544,7 @@ impl<'a> Parser<'a> {
     /// Produce an error if comparison operators are chained (RFC #558).
     /// We only need to check lhs, not rhs, because all comparison ops
     /// have same precedence and are left-associative
-    crate fn check_no_chained_comparison(&self, lhs: &Expr, outer_op: &AssocOp) {
+    crate fn check_no_chained_comparison(&self, lhs: &Expr, outer_op: &AssocOp) -> PResult<'a, ()> {
         debug_assert!(outer_op.is_comparison(),
                       "check_no_chained_comparison: {:?} is not comparison",
                       outer_op);
@@ -563,11 +563,14 @@ impl<'a> Parser<'a> {
                     err.help(
                         "use `::<...>` instead of `<...>` if you meant to specify type arguments");
                     err.help("or use `(...)` if you meant to specify fn arguments");
+                    // These cases cause too many knock-down errors, bail out (#61329).
+                    return Err(err);
                 }
                 err.emit();
             }
             _ => {}
         }
+        Ok(())
     }
 
     crate fn maybe_report_ambiguous_plus(
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 5b9f0f1df6718..aeef216141299 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -231,7 +231,7 @@ impl<'a> Parser<'a> {
 
             self.bump();
             if op.is_comparison() {
-                self.check_no_chained_comparison(&lhs, &op);
+                self.check_no_chained_comparison(&lhs, &op)?;
             }
             // Special cases:
             if op == AssocOp::As {
diff --git a/src/test/ui/did_you_mean/issue-40396.rs b/src/test/ui/did_you_mean/issue-40396.rs
index 63eec50c2d29f..6902779f33d23 100644
--- a/src/test/ui/did_you_mean/issue-40396.rs
+++ b/src/test/ui/did_you_mean/issue-40396.rs
@@ -1,27 +1,16 @@
 fn foo() {
     (0..13).collect<Vec<i32>>();
     //~^ ERROR chained comparison
-    //~| ERROR expected value, found struct `Vec`
-    //~| ERROR expected value, found builtin type `i32`
-    //~| ERROR attempted to take value of method `collect`
 }
 
 fn bar() {
     Vec<i32>::new();
     //~^ ERROR chained comparison
-    //~| ERROR expected value, found struct `Vec`
-    //~| ERROR expected value, found builtin type `i32`
-    //~| ERROR cannot find function `new` in the crate root
 }
 
 fn qux() {
     (0..13).collect<Vec<i32>();
     //~^ ERROR chained comparison
-    //~| ERROR chained comparison
-    //~| ERROR expected value, found struct `Vec`
-    //~| ERROR expected value, found builtin type `i32`
-    //~| ERROR attempted to take value of method `collect`
-    //~| ERROR mismatched types
 }
 
 fn main() {}
diff --git a/src/test/ui/did_you_mean/issue-40396.stderr b/src/test/ui/did_you_mean/issue-40396.stderr
index fe517ee34949d..7a08fda27e355 100644
--- a/src/test/ui/did_you_mean/issue-40396.stderr
+++ b/src/test/ui/did_you_mean/issue-40396.stderr
@@ -8,7 +8,7 @@ LL |     (0..13).collect<Vec<i32>>();
    = help: or use `(...)` if you meant to specify fn arguments
 
 error: chained comparison operators require parentheses
-  --> $DIR/issue-40396.rs:10:8
+  --> $DIR/issue-40396.rs:7:8
    |
 LL |     Vec<i32>::new();
    |        ^^^^^^^
@@ -17,7 +17,7 @@ LL |     Vec<i32>::new();
    = help: or use `(...)` if you meant to specify fn arguments
 
 error: chained comparison operators require parentheses
-  --> $DIR/issue-40396.rs:18:20
+  --> $DIR/issue-40396.rs:12:20
    |
 LL |     (0..13).collect<Vec<i32>();
    |                    ^^^^^^^^
@@ -25,79 +25,5 @@ LL |     (0..13).collect<Vec<i32>();
    = help: use `::<...>` instead of `<...>` if you meant to specify type arguments
    = help: or use `(...)` if you meant to specify fn arguments
 
-error: chained comparison operators require parentheses
-  --> $DIR/issue-40396.rs:18:24
-   |
-LL |     (0..13).collect<Vec<i32>();
-   |                        ^^^^^^
-   |
-   = help: use `::<...>` instead of `<...>` if you meant to specify type arguments
-   = help: or use `(...)` if you meant to specify fn arguments
-
-error[E0423]: expected value, found struct `Vec`
-  --> $DIR/issue-40396.rs:2:21
-   |
-LL |     (0..13).collect<Vec<i32>>();
-   |                     ^^^ did you mean `Vec { /* fields */ }`?
-
-error[E0423]: expected value, found builtin type `i32`
-  --> $DIR/issue-40396.rs:2:25
-   |
-LL |     (0..13).collect<Vec<i32>>();
-   |                         ^^^ not a value
-
-error[E0423]: expected value, found struct `Vec`
-  --> $DIR/issue-40396.rs:10:5
-   |
-LL |     Vec<i32>::new();
-   |     ^^^ did you mean `Vec { /* fields */ }`?
-
-error[E0423]: expected value, found builtin type `i32`
-  --> $DIR/issue-40396.rs:10:9
-   |
-LL |     Vec<i32>::new();
-   |         ^^^ not a value
-
-error[E0425]: cannot find function `new` in the crate root
-  --> $DIR/issue-40396.rs:10:15
-   |
-LL |     Vec<i32>::new();
-   |               ^^^ not found in the crate root
-
-error[E0423]: expected value, found struct `Vec`
-  --> $DIR/issue-40396.rs:18:21
-   |
-LL |     (0..13).collect<Vec<i32>();
-   |                     ^^^ did you mean `Vec { /* fields */ }`?
-
-error[E0423]: expected value, found builtin type `i32`
-  --> $DIR/issue-40396.rs:18:25
-   |
-LL |     (0..13).collect<Vec<i32>();
-   |                         ^^^ not a value
-
-error[E0615]: attempted to take value of method `collect` on type `std::ops::Range<{integer}>`
-  --> $DIR/issue-40396.rs:2:13
-   |
-LL |     (0..13).collect<Vec<i32>>();
-   |             ^^^^^^^ help: use parentheses to call the method: `collect()`
-
-error[E0615]: attempted to take value of method `collect` on type `std::ops::Range<{integer}>`
-  --> $DIR/issue-40396.rs:18:13
-   |
-LL |     (0..13).collect<Vec<i32>();
-   |             ^^^^^^^ help: use parentheses to call the method: `collect()`
-
-error[E0308]: mismatched types
-  --> $DIR/issue-40396.rs:18:29
-   |
-LL |     (0..13).collect<Vec<i32>();
-   |                             ^^ expected bool, found ()
-   |
-   = note: expected type `bool`
-              found type `()`
-
-error: aborting due to 14 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0308, E0423, E0425, E0615.
-For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.rs b/src/test/ui/parser/require-parens-for-chained-comparison.rs
index 525be5d20e27f..3dcc0c8f3d496 100644
--- a/src/test/ui/parser/require-parens-for-chained-comparison.rs
+++ b/src/test/ui/parser/require-parens-for-chained-comparison.rs
@@ -11,8 +11,7 @@ fn main() {
     //~| ERROR: mismatched types
 
     f<X>();
-    //~^ ERROR: chained comparison operators require parentheses
-    //~| ERROR: binary operation `<` cannot be applied to type `fn() {f::<_>}`
+    //~^ ERROR chained comparison operators require parentheses
     //~| HELP: use `::<...>` instead of `<...>`
     //~| HELP: or use `(...)`
 }
diff --git a/src/test/ui/parser/require-parens-for-chained-comparison.stderr b/src/test/ui/parser/require-parens-for-chained-comparison.stderr
index 76e548de045aa..e927f4c32484e 100644
--- a/src/test/ui/parser/require-parens-for-chained-comparison.stderr
+++ b/src/test/ui/parser/require-parens-for-chained-comparison.stderr
@@ -37,17 +37,6 @@ LL |     false == 0 < 2;
    = note: expected type `bool`
               found type `{integer}`
 
-error[E0369]: binary operation `<` cannot be applied to type `fn() {f::<_>}`
-  --> $DIR/require-parens-for-chained-comparison.rs:13:6
-   |
-LL |     f<X>();
-   |     -^- X
-   |     |
-   |     fn() {f::<_>}
-   |
-   = note: an implementation of `std::cmp::PartialOrd` might be missing for `fn() {f::<_>}`
-
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0308, E0369.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/trait-object-lifetime-parens.rs b/src/test/ui/parser/trait-object-lifetime-parens.rs
index 5bbda4296ca7e..c8b0eb684f33d 100644
--- a/src/test/ui/parser/trait-object-lifetime-parens.rs
+++ b/src/test/ui/parser/trait-object-lifetime-parens.rs
@@ -9,7 +9,6 @@ fn check<'a>() {
     let _: Box<('a) + Trait>;
     //~^ ERROR expected type, found `'a`
     //~| ERROR expected `:`, found `)`
-    //~| ERROR chained comparison operators require parentheses
 }
 
 fn main() {}
diff --git a/src/test/ui/parser/trait-object-lifetime-parens.stderr b/src/test/ui/parser/trait-object-lifetime-parens.stderr
index 7ffc26e9edead..319a308c0137c 100644
--- a/src/test/ui/parser/trait-object-lifetime-parens.stderr
+++ b/src/test/ui/parser/trait-object-lifetime-parens.stderr
@@ -16,15 +16,6 @@ error: expected `:`, found `)`
 LL |     let _: Box<('a) + Trait>;
    |                   ^ expected `:`
 
-error: chained comparison operators require parentheses
-  --> $DIR/trait-object-lifetime-parens.rs:9:15
-   |
-LL |     let _: Box<('a) + Trait>;
-   |               ^^^^^^^^^^^^^^^
-   |
-   = help: use `::<...>` instead of `<...>` if you meant to specify type arguments
-   = help: or use `(...)` if you meant to specify fn arguments
-
 error: expected type, found `'a`
   --> $DIR/trait-object-lifetime-parens.rs:9:17
    |
@@ -33,5 +24,5 @@ LL |     let _: Box<('a) + Trait>;
    |         |
    |         while parsing the type for `_`
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 

From bdc6cfc96a181653d6747762027902097e43bd3f Mon Sep 17 00:00:00 2001
From: Baoshan Pang <baoshan.pang@windriver.com>
Date: Thu, 5 Sep 2019 11:26:29 -0700
Subject: [PATCH 542/943] simplify is_vxworks_pure_dynamic

---
 src/tools/compiletest/src/runtest.rs | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 84123cf326535..26fdfe9d1ef1b 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1733,14 +1733,7 @@ impl<'test> TestCx<'test> {
     }
 
     fn is_vxworks_pure_dynamic(&self) -> bool {
-        if self.config.target.contains("vxworks") {
-            match env::var("RUST_VXWORKS_TEST_DYLINK") {
-                Ok(s) => s == "1",
-                _ => false
-            }
-        } else {
-            false
-        }
+        self.config.target.contains("vxworks") && !self.is_vxworks_pure_static()
     }
 
     fn compose_and_run_compiler(&self, mut rustc: Command, input: Option<String>) -> ProcRes {

From 3f3fc52bfa255e68d84ca40a497137f5c6bae4a8 Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Thu, 5 Sep 2019 15:05:58 +0100
Subject: [PATCH 543/943] Simplify std lib injection

---
 src/librustc_interface/passes.rs              |   2 +-
 src/librustc_resolve/diagnostics.rs           |   8 ++
 src/librustc_resolve/macros.rs                |   5 +-
 src/librustc_resolve/resolve_imports.rs       |   7 +-
 src/libsyntax_ext/proc_macro_harness.rs       |  32 +----
 src/libsyntax_ext/standard_library_imports.rs | 124 +++++-------------
 6 files changed, 52 insertions(+), 126 deletions(-)

diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 649cc8a2fb515..48c3ddf39a22b 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -366,8 +366,8 @@ fn configure_and_expand_inner<'a>(
         let (krate, name) = syntax_ext::standard_library_imports::inject(
             krate,
             &mut resolver,
+            &sess.parse_sess,
             alt_std_name,
-            sess.edition(),
         );
         if let Some(name) = name {
             sess.parse_sess.injected_crate_name.set(name);
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index b79e0c2bd3b26..c479912b4ef81 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -604,6 +604,14 @@ impl<'a> Resolver<'a> {
         if lookup_ident.span.rust_2018() {
             let extern_prelude_names = self.extern_prelude.clone();
             for (ident, _) in extern_prelude_names.into_iter() {
+                if ident.span.from_expansion() {
+                    // Idents are adjusted to the root context before being
+                    // resolved in the extern prelude, so reporting this to the
+                    // user is no help. This skips the injected
+                    // `extern crate std` in the 2018 edition, which would
+                    // otherwise cause duplicate suggestions.
+                    continue;
+                }
                 if let Some(crate_id) = self.crate_loader.maybe_process_path_extern(ident.name,
                                                                                     ident.span) {
                     let crate_root = self.get_module(DefId {
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 02022c98c3502..cf99663beaf48 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -128,9 +128,8 @@ impl<'a> base::Resolver for Resolver<'a> {
         }
     }
 
-    // Create a Span with modern hygiene with a definition site of the provided
-    // module, or a fake empty `#[no_implicit_prelude]` module if no module is
-    // provided.
+    // Create a new Expansion with a definition site of the provided module, or
+    // a fake empty `#[no_implicit_prelude]` module if no module is provided.
     fn expansion_for_ast_pass(
         &mut self,
         call_site: Span,
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 4e33ea018a074..ca189e71800b3 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -1307,8 +1307,11 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                 None => continue,
             };
 
-            // Filter away ambiguous imports.
-            let is_good_import = binding.is_import() && !binding.is_ambiguity();
+            // Filter away ambiguous imports and anything that has def-site
+            // hygiene.
+            // FIXME: Implement actual cross-crate hygiene.
+            let is_good_import = binding.is_import() && !binding.is_ambiguity()
+                && !ident.span.modern().from_expansion();
             if is_good_import || binding.is_macro_def() {
                 let res = binding.res();
                 if res != Res::Err {
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index 8a4b78a3efa31..31d32d23a645e 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -392,41 +392,19 @@ fn mk_decls(
         i
     });
 
-    let block = P(ast::Expr {
-        id: ast::DUMMY_NODE_ID,
-        attrs: syntax::ThinVec::new(),
-        node: ast::ExprKind::Block(P(ast::Block {
-            id: ast::DUMMY_NODE_ID,
-            rules: ast::BlockCheckMode::Default,
-            stmts: vec![
-                ast::Stmt {
-                    id: ast::DUMMY_NODE_ID,
-                    node: ast::StmtKind::Item(krate),
-                    span,
-                },
-                ast::Stmt {
-                    id: ast::DUMMY_NODE_ID,
-                    node: ast::StmtKind::Item(decls_static),
-                    span,
-                }
-            ],
-            span,
-        }), None),
+    let block = cx.expr_block(cx.block(
         span,
-    });
+        vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)],
+    ));
 
     let anon_constant = cx.item_const(
         span,
         ast::Ident::new(kw::Underscore, span),
-        P(ast::Ty {
-            id: ast::DUMMY_NODE_ID,
-            node: ast::TyKind::Tup(Vec::new()),
-            span,
-        }),
+        cx.ty(span, ast::TyKind::Tup(Vec::new())),
         block,
     );
 
-    // Integrate the new module into existing module structures.
+    // Integrate the new item into existing module structures.
     let items = AstFragment::Items(smallvec![anon_constant]);
     cx.monotonic_expander().fully_expand_fragment(items).make_items().pop().unwrap()
 }
diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs
index e5dded9ea5319..c577b1e33cfeb 100644
--- a/src/libsyntax_ext/standard_library_imports.rs
+++ b/src/libsyntax_ext/standard_library_imports.rs
@@ -1,19 +1,20 @@
 use syntax::{ast, attr};
 use syntax::edition::Edition;
+use syntax::ext::expand::ExpansionConfig;
 use syntax::ext::hygiene::AstPass;
-use syntax::ext::base::Resolver;
+use syntax::ext::base::{ExtCtxt, Resolver};
+use syntax::parse::ParseSess;
 use syntax::ptr::P;
-use syntax::source_map::respan;
 use syntax::symbol::{Ident, Symbol, kw, sym};
 use syntax_pos::DUMMY_SP;
 
 pub fn inject(
     mut krate: ast::Crate,
     resolver: &mut dyn Resolver,
+    sess: &ParseSess,
     alt_std_name: Option<Symbol>,
-    edition: Edition,
 ) -> (ast::Crate, Option<Symbol>) {
-    let rust_2018 = edition >= Edition::Edition2018;
+    let rust_2018 = sess.edition >= Edition::Edition2018;
 
     // the first name in this list is the crate name of the crate with the prelude
     let names: &[Symbol] = if attr::contains_name(&krate.attrs, sym::no_core) {
@@ -37,112 +38,49 @@ pub fn inject(
     let span = DUMMY_SP.with_def_site_ctxt(expn_id);
     let call_site = DUMMY_SP.with_call_site_ctxt(expn_id);
 
+    let ecfg = ExpansionConfig::default("std_lib_injection".to_string());
+    let cx = ExtCtxt::new(sess, ecfg, resolver);
+
+
     // .rev() to preserve ordering above in combination with insert(0, ...)
-    for &orig_name_sym in names.iter().rev() {
-        let (rename, orig_name) = if rust_2018 {
-            (Ident::new(kw::Underscore, span), Some(orig_name_sym))
+    for &name in names.iter().rev() {
+        let ident = if rust_2018 {
+            Ident::new(name, span)
         } else {
-            (Ident::new(orig_name_sym, call_site), None)
+            Ident::new(name, call_site)
         };
-        krate.module.items.insert(0, P(ast::Item {
-            attrs: vec![attr::mk_attr_outer(
-                attr::mk_word_item(ast::Ident::new(sym::macro_use, span))
-            )],
-            vis: respan(span, ast::VisibilityKind::Inherited),
-            node: ast::ItemKind::ExternCrate(alt_std_name.or(orig_name)),
-            ident: rename,
-            id: ast::DUMMY_NODE_ID,
+        krate.module.items.insert(0, cx.item(
             span,
-            tokens: None,
-        }));
+            ident,
+            vec![cx.attribute(cx.meta_word(span, sym::macro_use))],
+            ast::ItemKind::ExternCrate(alt_std_name),
+        ));
     }
 
-    // the crates have been injected, the assumption is that the first one is the one with
-    // the prelude.
+    // The crates have been injected, the assumption is that the first one is
+    // the one with the prelude.
     let name = names[0];
 
-    let segments = if rust_2018 {
+    let import_path = if rust_2018 {
         [name, sym::prelude, sym::v1].iter()
-            .map(|symbol| ast::PathSegment::from_ident(ast::Ident::new(*symbol, span)))
-            .collect()
+            .map(|symbol| ast::Ident::new(*symbol, span)).collect()
     } else {
         [kw::PathRoot, name, sym::prelude, sym::v1].iter()
-            .map(|symbol| ast::PathSegment::from_ident(ast::Ident::new(*symbol, call_site)))
-            .collect()
+            .map(|symbol| ast::Ident::new(*symbol, span)).collect()
     };
 
-    let use_item = P(ast::Item {
-        attrs: vec![attr::mk_attr_outer(
-            attr::mk_word_item(ast::Ident::new(sym::prelude_import, span)))],
-        vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
-        node: ast::ItemKind::Use(P(ast::UseTree {
-            prefix: ast::Path { segments, span },
+    let use_item = cx.item(
+        span,
+        ast::Ident::invalid(),
+        vec![cx.attribute(cx.meta_word(span, sym::prelude_import))],
+        ast::ItemKind::Use(P(ast::UseTree {
+            prefix: cx.path(span, import_path),
             kind: ast::UseTreeKind::Glob,
             span,
         })),
-        id: ast::DUMMY_NODE_ID,
-        ident: ast::Ident::invalid(),
-        span,
-        tokens: None,
-    });
-
-    let prelude_import_item = if rust_2018 {
-        let hygienic_extern_crate = P(ast::Item {
-            attrs: vec![],
-            vis: respan(span, ast::VisibilityKind::Inherited),
-            node: ast::ItemKind::ExternCrate(alt_std_name),
-            ident: ast::Ident::new(name, span),
-            id: ast::DUMMY_NODE_ID,
-            span,
-            tokens: None,
-        });
-
-        // Use an anonymous const to hide `extern crate std as hygienic_std`
-        // FIXME: Once inter-crate hygiene exists, this can just be `use_item`.
-        P(ast::Item {
-            attrs: Vec::new(),
-            vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
-            node: ast::ItemKind::Const(
-                P(ast::Ty {
-                    id: ast::DUMMY_NODE_ID,
-                    node: ast::TyKind::Tup(Vec::new()),
-                    span,
-                }),
-                P(ast::Expr {
-                    id: ast::DUMMY_NODE_ID,
-                    attrs: syntax::ThinVec::new(),
-                    node: ast::ExprKind::Block(P(ast::Block {
-                        id: ast::DUMMY_NODE_ID,
-                        rules: ast::BlockCheckMode::Default,
-                        stmts: vec![
-                            ast::Stmt {
-                                id: ast::DUMMY_NODE_ID,
-                                node: ast::StmtKind::Item(use_item),
-                                span,
-                            },
-                            ast::Stmt {
-                                id: ast::DUMMY_NODE_ID,
-                                node: ast::StmtKind::Item(hygienic_extern_crate),
-                                span,
-                            }
-                        ],
-                        span,
-                    }), None),
-                    span,
-                })
-            ),
-            id: ast::DUMMY_NODE_ID,
-            ident: ast::Ident::new(kw::Underscore, span),
-            span,
-            tokens: None,
-        })
-    } else {
-        // Have `extern crate std` at the root, so don't need to create a named
-        // extern crate item.
-        use_item
-    };
+    );
 
-    krate.module.items.insert(0, prelude_import_item);
+    krate.module.items.insert(0, use_item);
 
     (krate, Some(name))
 }

From bad8147d01df374e3daa37fe36446781df2eac2d Mon Sep 17 00:00:00 2001
From: Mark Mansi <markm@cs.wisc.edu>
Date: Thu, 5 Sep 2019 16:52:44 -0500
Subject: [PATCH 544/943] fix reviewer comments

---
 src/tools/rustbook/src/main.rs | 66 +++++++++++++++++-----------------
 1 file changed, 33 insertions(+), 33 deletions(-)

diff --git a/src/tools/rustbook/src/main.rs b/src/tools/rustbook/src/main.rs
index b2111442310ef..d5dc9a79b5acb 100644
--- a/src/tools/rustbook/src/main.rs
+++ b/src/tools/rustbook/src/main.rs
@@ -8,6 +8,7 @@ use clap::{App, AppSettings, ArgMatches, SubCommand};
 use mdbook::errors::Result as Result3;
 use mdbook::MDBook;
 
+#[cfg(feature = "linkcheck")]
 use failure::Error;
 #[cfg(feature = "linkcheck")]
 use mdbook::renderer::RenderContext;
@@ -52,36 +53,41 @@ fn main() {
             }
         }
         ("linkcheck", Some(sub_matches)) => {
-            if let Err(err) = linkcheck(sub_matches) {
-                eprintln!("Error: {}", err);
-
-                // HACK: ignore timeouts
-                let actually_broken = {
-                    #[cfg(feature = "linkcheck")]
-                    {
-                        err.downcast::<BrokenLinks>()
-                            .map(|broken_links| {
-                                broken_links
-                                    .links()
-                                    .iter()
-                                    .inspect(|cause| eprintln!("\tCaused By: {}", cause))
-                                    .any(|cause| !format!("{}", cause).contains("timed out"))
-                            })
-                            .unwrap_or(false)
-                    }
-
-                    #[cfg(not(feature = "linkcheck"))]
-                    {
-                        false
+            #[cfg(feature = "linkcheck")]
+            {
+                if let Err(err) = linkcheck(sub_matches) {
+                    eprintln!("Error: {}", err);
+
+                    // HACK: ignore timeouts
+                    let actually_broken = err
+                        .downcast::<BrokenLinks>()
+                        .map(|broken_links| {
+                            broken_links
+                                .links()
+                                .iter()
+                                .inspect(|cause| eprintln!("\tCaused By: {}", cause))
+                                .fold(false, |already_broken, cause| {
+                                    already_broken || !format!("{}", cause).contains("timed out")
+                                })
+                        })
+                        .unwrap_or(false);
+
+                    if actually_broken {
+                        std::process::exit(101);
+                    } else {
+                        std::process::exit(0);
                     }
-                };
-
-                if actually_broken {
-                    std::process::exit(101);
-                } else {
-                    std::process::exit(0);
                 }
             }
+
+            #[cfg(not(feature = "linkcheck"))]
+            {
+                // This avoids the `unused_binding` lint.
+                println!(
+                    "mdbook-linkcheck is disabled, but arguments were passed: {:?}",
+                    sub_matches
+                );
+            }
         }
         (_, _) => unreachable!(),
     };
@@ -97,12 +103,6 @@ pub fn linkcheck(args: &ArgMatches<'_>) -> Result<(), Error> {
     mdbook_linkcheck::check_links(&render_ctx)
 }
 
-#[cfg(not(feature = "linkcheck"))]
-pub fn linkcheck(_args: &ArgMatches<'_>) -> Result<(), Error> {
-    println!("mdbook-linkcheck is disabled.");
-    Ok(())
-}
-
 // Build command implementation
 pub fn build(args: &ArgMatches<'_>) -> Result3<()> {
     let book_dir = get_book_dir(args);

From dc613c6d055c1b45f7e11e6ee03e4a3095d5b8a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 5 Sep 2019 15:29:31 -0700
Subject: [PATCH 545/943] Fix test

---
 src/test/ui-fulldeps/pprust-expr-roundtrip.rs | 47 ++++++++++---------
 1 file changed, 25 insertions(+), 22 deletions(-)

diff --git a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
index 09f58521e5d5c..89c17cf4b3aa3 100644
--- a/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
+++ b/src/test/ui-fulldeps/pprust-expr-roundtrip.rs
@@ -32,13 +32,15 @@ use syntax::print::pprust;
 use syntax::ptr::P;
 
 
-fn parse_expr(ps: &ParseSess, src: &str) -> P<Expr> {
+fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> {
     let src_as_string = src.to_string();
 
-    let mut p = parse::new_parser_from_source_str(ps,
-                                                  FileName::Custom(src_as_string.clone()),
-                                                  src_as_string);
-    p.parse_expr().unwrap()
+    let mut p = parse::new_parser_from_source_str(
+        ps,
+        FileName::Custom(src_as_string.clone()),
+        src_as_string,
+    );
+    p.parse_expr().map_err(|mut e| e.cancel()).ok()
 }
 
 
@@ -209,22 +211,23 @@ fn run() {
         let printed = pprust::expr_to_string(&e);
         println!("printed: {}", printed);
 
-        let mut parsed = parse_expr(&ps, &printed);
-
-        // We want to know if `parsed` is structurally identical to `e`, ignoring trivial
-        // differences like placement of `Paren`s or the exact ranges of node spans.
-        // Unfortunately, there is no easy way to make this comparison. Instead, we add `Paren`s
-        // everywhere we can, then pretty-print. This should give an unambiguous representation of
-        // each `Expr`, and it bypasses nearly all of the parenthesization logic, so we aren't
-        // relying on the correctness of the very thing we're testing.
-        RemoveParens.visit_expr(&mut e);
-        AddParens.visit_expr(&mut e);
-        let text1 = pprust::expr_to_string(&e);
-        RemoveParens.visit_expr(&mut parsed);
-        AddParens.visit_expr(&mut parsed);
-        let text2 = pprust::expr_to_string(&parsed);
-        assert!(text1 == text2,
-                "exprs are not equal:\n  e =      {:?}\n  parsed = {:?}",
-                text1, text2);
+        // Ignore expressions with chained comparisons that fail to parse
+        if let Some(mut parsed) = parse_expr(&ps, &printed) {
+            // We want to know if `parsed` is structurally identical to `e`, ignoring trivial
+            // differences like placement of `Paren`s or the exact ranges of node spans.
+            // Unfortunately, there is no easy way to make this comparison. Instead, we add `Paren`s
+            // everywhere we can, then pretty-print. This should give an unambiguous representation
+            // of each `Expr`, and it bypasses nearly all of the parenthesization logic, so we
+            // aren't relying on the correctness of the very thing we're testing.
+            RemoveParens.visit_expr(&mut e);
+            AddParens.visit_expr(&mut e);
+            let text1 = pprust::expr_to_string(&e);
+            RemoveParens.visit_expr(&mut parsed);
+            AddParens.visit_expr(&mut parsed);
+            let text2 = pprust::expr_to_string(&parsed);
+            assert!(text1 == text2,
+                    "exprs are not equal:\n  e =      {:?}\n  parsed = {:?}",
+                    text1, text2);
+        }
     });
 }

From 5153db136e8419beb217340500a97db553ddabbe Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Thu, 5 Sep 2019 18:40:54 -0400
Subject: [PATCH 546/943] Explicitly create test tempdir

---
 src/bootstrap/test.rs | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 97b28ed9e96c8..00d87f3841cff 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1327,7 +1327,10 @@ impl Step for Compiletest {
             cmd.env("RUSTC_PROFILER_SUPPORT", "1");
         }
 
-        cmd.env("RUST_TEST_TMPDIR", builder.out.join("tmp"));
+        let tmp = builder.out.join("tmp");
+        std::fs::create_dir_all(&tmp).unwrap();
+        cmd.env("RUST_TEST_TMPDIR", tmp);
+
 
         cmd.arg("--adb-path").arg("adb");
         cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR);

From bb1e42599d0062b9a43e83b5486d61eb1fcf0771 Mon Sep 17 00:00:00 2001
From: Taylor Cramer <cramertj@google.com>
Date: Thu, 5 Sep 2019 16:44:22 -0700
Subject: [PATCH 547/943] Add Fuchsia to actually_monotonic

Fuchsia provides a fully monotonic clock.
---
 src/libstd/sys/unix/time.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index 02f377d55c919..fd6796ad22c12 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -311,6 +311,7 @@ mod inner {
         pub fn actually_monotonic() -> bool {
             (cfg!(target_os = "linux") && cfg!(target_arch = "x86_64")) ||
             (cfg!(target_os = "linux") && cfg!(target_arch = "x86")) ||
+            cfg!(target_os = "fuchsia") ||
             false // last clause, used so `||` is always trailing above
         }
 

From 022d9c8eb56144c00980c88d4b68a5a1e487484a Mon Sep 17 00:00:00 2001
From: Alexander Regueiro <alexreg@me.com>
Date: Sun, 1 Sep 2019 18:09:59 +0100
Subject: [PATCH 548/943] Fixed grammar/style in error messages and reblessed
 tests.

---
 src/librustc/mir/interpret/error.rs           | 12 ++---
 src/librustc/session/config.rs                | 20 ++++----
 src/librustc/traits/object_safety.rs          |  7 +--
 .../borrow_check/conflict_errors.rs           |  2 +-
 src/librustc_mir/const_eval.rs                |  4 +-
 src/librustc_mir/error_codes.rs               |  2 +-
 src/librustc_mir/util/borrowck_errors.rs      |  2 +-
 src/libsyntax/parse/parser/expr.rs            |  2 +-
 src/libsyntax/parse/parser/stmt.rs            |  2 +-
 src/test/ui/asm/asm-out-read-uninit.rs        |  2 +-
 src/test/ui/asm/asm-out-read-uninit.stderr    |  4 +-
 .../no-non-guaranteed-initialization.rs       |  2 +-
 .../no-non-guaranteed-initialization.stderr   |  4 +-
 .../partial-initialization-across-await.rs    |  6 +--
 ...partial-initialization-across-await.stderr | 12 ++---
 .../ui/borrowck/assign_mutable_fields.stderr  |  8 ++--
 src/test/ui/borrowck/borrowck-and-init.rs     |  2 +-
 src/test/ui/borrowck/borrowck-and-init.stderr |  4 +-
 src/test/ui/borrowck/borrowck-asm.rs          |  2 +-
 src/test/ui/borrowck/borrowck-asm.stderr      |  4 +-
 src/test/ui/borrowck/borrowck-block-unint.rs  |  2 +-
 .../ui/borrowck/borrowck-block-unint.stderr   |  4 +-
 .../ui/borrowck/borrowck-break-uninit-2.rs    |  2 +-
 .../borrowck/borrowck-break-uninit-2.stderr   |  4 +-
 src/test/ui/borrowck/borrowck-break-uninit.rs |  2 +-
 .../ui/borrowck/borrowck-break-uninit.stderr  |  4 +-
 .../ui/borrowck/borrowck-field-sensitivity.rs |  6 +--
 .../borrowck-field-sensitivity.stderr         | 12 ++---
 src/test/ui/borrowck/borrowck-if-no-else.rs   |  2 +-
 .../ui/borrowck/borrowck-if-no-else.stderr    |  4 +-
 src/test/ui/borrowck/borrowck-if-with-else.rs |  2 +-
 .../ui/borrowck/borrowck-if-with-else.stderr  |  4 +-
 .../borrowck-init-in-called-fn-expr.rs        |  2 +-
 .../borrowck-init-in-called-fn-expr.stderr    |  4 +-
 .../ui/borrowck/borrowck-init-in-fn-expr.rs   |  2 +-
 .../borrowck/borrowck-init-in-fn-expr.stderr  |  4 +-
 src/test/ui/borrowck/borrowck-init-in-fru.rs  |  2 +-
 .../ui/borrowck/borrowck-init-in-fru.stderr   |  4 +-
 .../ui/borrowck/borrowck-init-op-equal.rs     |  2 +-
 .../ui/borrowck/borrowck-init-op-equal.stderr |  4 +-
 .../ui/borrowck/borrowck-init-plus-equal.rs   |  2 +-
 .../borrowck/borrowck-init-plus-equal.stderr  |  4 +-
 src/test/ui/borrowck/borrowck-or-init.rs      |  2 +-
 src/test/ui/borrowck/borrowck-or-init.stderr  |  4 +-
 .../ui/borrowck/borrowck-partial-reinit-4.rs  |  2 +-
 .../borrowck/borrowck-partial-reinit-4.stderr |  4 +-
 src/test/ui/borrowck/borrowck-return.rs       |  2 +-
 src/test/ui/borrowck/borrowck-return.stderr   |  4 +-
 .../ui/borrowck/borrowck-storage-dead.stderr  |  4 +-
 .../ui/borrowck/borrowck-uninit-after-item.rs |  2 +-
 .../borrowck-uninit-after-item.stderr         |  4 +-
 .../borrowck-uninit-field-access.stderr       |  4 +-
 .../borrowck/borrowck-uninit-in-assignop.rs   | 20 ++++----
 .../borrowck-uninit-in-assignop.stderr        | 40 ++++++++--------
 .../ui/borrowck/borrowck-uninit-ref-chain.rs  |  8 ++--
 .../borrowck/borrowck-uninit-ref-chain.stderr | 28 +++++------
 src/test/ui/borrowck/borrowck-uninit.rs       |  2 +-
 src/test/ui/borrowck/borrowck-uninit.stderr   |  4 +-
 .../borrowck/borrowck-union-uninitialized.rs  |  4 +-
 .../borrowck-union-uninitialized.stderr       |  8 ++--
 .../borrowck-use-in-index-lvalue.stderr       |  8 ++--
 ...wck-use-uninitialized-in-cast-trait.stderr |  4 +-
 .../borrowck-use-uninitialized-in-cast.stderr |  4 +-
 src/test/ui/borrowck/borrowck-while-break.rs  |  2 +-
 .../ui/borrowck/borrowck-while-break.stderr   |  4 +-
 src/test/ui/borrowck/borrowck-while-cond.rs   |  2 +-
 .../ui/borrowck/borrowck-while-cond.stderr    |  4 +-
 src/test/ui/borrowck/borrowck-while.rs        |  2 +-
 src/test/ui/borrowck/borrowck-while.stderr    |  4 +-
 .../disallow-possibly-uninitialized.rs        |  8 ++--
 .../disallow-possibly-uninitialized.stderr    | 16 +++----
 ...-54499-field-mutation-marks-mut-as-used.rs |  6 +--
 ...99-field-mutation-marks-mut-as-used.stderr | 12 ++---
 ...ssue-54499-field-mutation-of-never-init.rs |  6 +--
 ...-54499-field-mutation-of-never-init.stderr | 12 ++---
 .../borrowck/issue-62107-match-arm-scopes.rs  |  2 +-
 .../issue-62107-match-arm-scopes.stderr       |  4 +-
 .../reassignment_immutable_fields.stderr      |  8 ++--
 ...gnment_immutable_fields_overlapping.stderr |  4 +-
 ...reassignment_immutable_fields_twice.stderr |  4 +-
 src/test/ui/borrowck/two-phase-across-loop.rs |  2 +-
 src/test/ui/consts/const-err4.stderr          |  2 +-
 ...nst-pointer-values-in-various-types.stderr | 18 +++----
 .../ui/consts/const-eval/double_check2.stderr |  2 +-
 .../consts/const-eval/ref_to_int_match.stderr |  2 +-
 .../consts/const-eval/transmute-const.stderr  |  2 +-
 src/test/ui/consts/const-eval/ub-enum.stderr  | 18 +++----
 .../ui/consts/const-eval/ub-nonnull.stderr    | 12 ++---
 src/test/ui/consts/const-eval/ub-ref.stderr   | 10 ++--
 .../ui/consts/const-eval/ub-uninhabit.stderr  |  6 +--
 .../ui/consts/const-eval/ub-upvars.stderr     |  2 +-
 .../ui/consts/const-eval/ub-wide-ptr.stderr   | 36 +++++++-------
 .../const-eval/union-const-eval-field.stderr  |  2 +-
 .../ui/consts/const-eval/union-ice.stderr     |  6 +--
 src/test/ui/consts/const-eval/union-ub.stderr |  2 +-
 src/test/ui/consts/const_let_refutable.rs     |  4 +-
 src/test/ui/consts/const_let_refutable.stderr |  8 ++--
 src/test/ui/consts/std/alloc.stderr           |  2 +-
 .../ui/consts/validate_never_arrays.stderr    |  2 +-
 src/test/ui/empty/empty-never-array.rs        |  2 +-
 src/test/ui/empty/empty-never-array.stderr    |  4 +-
 .../partial-initialization-across-yield.rs    |  6 +--
 ...partial-initialization-across-yield.stderr | 12 ++---
 src/test/ui/issues/issue-15381.rs             |  2 +-
 src/test/ui/issues/issue-15381.stderr         |  4 +-
 src/test/ui/issues/issue-24267-flow-exit.rs   |  4 +-
 .../ui/issues/issue-24267-flow-exit.stderr    |  8 ++--
 src/test/ui/loops/loop-proper-liveness.rs     |  2 +-
 src/test/ui/loops/loop-proper-liveness.stderr |  4 +-
 .../missing/missing-semicolon-warning.stderr  |  4 +-
 src/test/ui/moves/move-into-dead-array-1.rs   |  2 +-
 .../ui/moves/move-into-dead-array-1.stderr    |  4 +-
 ...ue-21232-partial-init-and-erroneous-use.rs |  8 ++--
 ...1232-partial-init-and-erroneous-use.stderr | 16 +++----
 .../nll/issue-21232-partial-init-and-use.rs   | 24 +++++-----
 .../issue-21232-partial-init-and-use.stderr   | 48 +++++++++----------
 src/test/ui/nll/match-cfg-fake-edges.rs       |  2 +-
 src/test/ui/nll/match-cfg-fake-edges.stderr   |  4 +-
 src/test/ui/nll/match-on-borrowed.stderr      |  4 +-
 src/test/ui/parser/do-catch-suggests-try.rs   |  2 +-
 .../ui/parser/do-catch-suggests-try.stderr    |  2 +-
 .../recursive-types-are-not-uninhabited.rs    |  2 +-
 ...recursive-types-are-not-uninhabited.stderr |  4 +-
 src/test/ui/try-block/try-block-opt-init.rs   |  2 +-
 .../ui/try-block/try-block-opt-init.stderr    |  4 +-
 125 files changed, 381 insertions(+), 380 deletions(-)

diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index ef0e205184871..589a021241d94 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -430,13 +430,13 @@ impl fmt::Debug for UnsupportedOpInfo<'tcx> {
         match self {
             PointerOutOfBounds { ptr, msg, allocation_size } => {
                 write!(f, "{} failed: pointer must be in-bounds at offset {}, \
-                          but is outside bounds of allocation {} which has size {}",
+                           but is outside bounds of allocation {} which has size {}",
                     msg, ptr.offset.bytes(), ptr.alloc_id, allocation_size.bytes())
             },
             ValidationFailure(ref err) => {
                 write!(f, "type validation failed: {}", err)
             }
-            NoMirFor(ref func) => write!(f, "no mir for `{}`", func),
+            NoMirFor(ref func) => write!(f, "no MIR for `{}`", func),
             FunctionAbiMismatch(caller_abi, callee_abi) =>
                 write!(f, "tried to call a function with ABI {:?} using caller ABI {:?}",
                     callee_abi, caller_abi),
@@ -451,9 +451,9 @@ impl fmt::Debug for UnsupportedOpInfo<'tcx> {
             FunctionArgCountMismatch =>
                 write!(f, "tried to call a function with incorrect number of arguments"),
             ReallocatedWrongMemoryKind(ref old, ref new) =>
-                write!(f, "tried to reallocate memory from {} to {}", old, new),
+                write!(f, "tried to reallocate memory from `{}` to `{}`", old, new),
             DeallocatedWrongMemoryKind(ref old, ref new) =>
-                write!(f, "tried to deallocate {} memory but gave {} as the kind", old, new),
+                write!(f, "tried to deallocate `{}` memory but gave `{}` as the kind", old, new),
             InvalidChar(c) =>
                 write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c),
             AlignmentCheckFailed { required, has } =>
@@ -462,7 +462,7 @@ impl fmt::Debug for UnsupportedOpInfo<'tcx> {
             TypeNotPrimitive(ty) =>
                 write!(f, "expected primitive type, got {}", ty),
             PathNotFound(ref path) =>
-                write!(f, "Cannot find path {:?}", path),
+                write!(f, "cannot find path {:?}", path),
             IncorrectAllocationInformation(size, size2, align, align2) =>
                 write!(f, "incorrect alloc info: expected size {} and align {}, \
                            got size {} and align {}",
@@ -525,7 +525,7 @@ impl fmt::Debug for UnsupportedOpInfo<'tcx> {
             InvalidBoolOp(_) =>
                 write!(f, "invalid boolean operation"),
             UnterminatedCString(_) =>
-                write!(f, "attempted to get length of a null terminated string, but no null \
+                write!(f, "attempted to get length of a null-terminated string, but no null \
                     found before end of allocation"),
             ReadUndefBytes(_) =>
                 write!(f, "attempted to read undefined bytes"),
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 740d9db7edcf7..296c6ad19c1cf 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1998,7 +1998,7 @@ pub fn parse_error_format(
             Some(arg) => early_error(
                 ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
                 &format!(
-                    "argument for --error-format must be `human`, `json` or \
+                    "argument for `--error-format` must be `human`, `json` or \
                      `short` (instead was `{}`)",
                     arg
                 ),
@@ -2037,7 +2037,7 @@ pub fn build_session_options_and_crate_config(
             early_error(
                 ErrorOutputType::default(),
                 &format!(
-                    "argument for --edition must be one of: \
+                    "argument for `--edition` must be one of: \
                      {}. (instead was `{}`)",
                     EDITION_NAME_LIST,
                     arg
@@ -2051,7 +2051,7 @@ pub fn build_session_options_and_crate_config(
         early_error(
                 ErrorOutputType::default(),
                 &format!(
-                    "Edition {} is unstable and only \
+                    "edition {} is unstable and only \
                      available for nightly builds of rustc.",
                     edition,
                 )
@@ -2075,14 +2075,14 @@ pub fn build_session_options_and_crate_config(
         if let ErrorOutputType::Json { pretty: true, json_rendered } = error_format {
             early_error(
                 ErrorOutputType::Json { pretty: false, json_rendered },
-                "--error-format=pretty-json is unstable",
+                "`--error-format=pretty-json` is unstable",
             );
         }
         if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(_)) =
             error_format {
             early_error(
                 ErrorOutputType::Json { pretty: false, json_rendered },
-                "--error-format=human-annotate-rs is unstable",
+                "`--error-format=human-annotate-rs` is unstable",
             );
         }
     }
@@ -2132,8 +2132,8 @@ pub fn build_session_options_and_crate_config(
                         early_warn(
                             error_format,
                             &format!(
-                                "--emit={} with -o incompatible with \
-                                 -C codegen-units=N for N > 1",
+                                "`--emit={}` with `-o` incompatible with \
+                                 `-C codegen-units=N` for N > 1",
                                 ot
                             ),
                         );
@@ -2153,21 +2153,21 @@ pub fn build_session_options_and_crate_config(
     if debugging_opts.threads == Some(0) {
         early_error(
             error_format,
-            "Value for threads must be a positive nonzero integer",
+            "value for threads must be a positive non-zero integer",
         );
     }
 
     if debugging_opts.threads.unwrap_or(1) > 1 && debugging_opts.fuel.is_some() {
         early_error(
             error_format,
-            "Optimization fuel is incompatible with multiple threads",
+            "optimization fuel is incompatible with multiple threads",
         );
     }
 
     if codegen_units == Some(0) {
         early_error(
             error_format,
-            "Value for codegen units must be a positive nonzero integer",
+            "value for codegen units must be a positive non-zero integer",
         );
     }
 
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index f7f459cd27f68..c759981b8e8c9 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -368,7 +368,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     match self.layout_of(param_env.and(ty)) {
                         Ok(layout) => &layout.abi,
                         Err(err) => bug!(
-                            "Error: {}\n while computing layout for type {:?}", err, ty
+                            "error: {}\n while computing layout for type {:?}", err, ty
                         )
                     }
                 };
@@ -384,7 +384,7 @@ impl<'tcx> TyCtxt<'tcx> {
                         self.sess.delay_span_bug(
                             self.def_span(method.def_id),
                             &format!(
-                                "Receiver when Self = () should have a Scalar ABI, found {:?}",
+                                "receiver when `Self = ()` should have a Scalar ABI; found {:?}",
                                 abi
                             ),
                         );
@@ -406,7 +406,8 @@ impl<'tcx> TyCtxt<'tcx> {
                         self.sess.delay_span_bug(
                             self.def_span(method.def_id),
                             &format!(
-                                "Receiver when Self = {} should have a ScalarPair ABI, found {:?}",
+                                "receiver when `Self = {}` should have a ScalarPair ABI; \
+                                 found {:?}",
                                 trait_object_ty, abi
                             ),
                         );
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index 247783c420e25..bfc7050ebf71c 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -98,7 +98,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 &self.describe_place_with_options(moved_place, IncludingDowncast(true))
                     .unwrap_or_else(|| "_".to_owned()),
             );
-            err.span_label(span, format!("use of possibly uninitialized {}", item_msg));
+            err.span_label(span, format!("use of possibly-uninitialized {}", item_msg));
 
             use_spans.var_span_label(
                 &mut err,
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 5aa487d901663..db679024dc5a2 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -533,8 +533,8 @@ pub fn error_to_const_error<'mir, 'tcx>(
 
 pub fn note_on_undefined_behavior_error() -> &'static str {
     "The rules on what exactly is undefined behavior aren't clear, \
-    so this check might be overzealous. Please open an issue on the rust compiler \
-    repository if you believe it should not be considered undefined behavior"
+     so this check might be overzealous. Please open an issue on the rustc \
+     repository if you believe it should not be considered undefined behavior."
 }
 
 fn validate_and_turn_into_const<'tcx>(
diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs
index 86c263a447bb6..22432db819020 100644
--- a/src/librustc_mir/error_codes.rs
+++ b/src/librustc_mir/error_codes.rs
@@ -748,7 +748,7 @@ It is not allowed to use or capture an uninitialized variable. For example:
 ```compile_fail,E0381
 fn main() {
     let x: i32;
-    let y = x; // error, use of possibly uninitialized variable
+    let y = x; // error, use of possibly-uninitialized variable
 }
 ```
 
diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs
index 3359d1b3bbfe1..cf9ef55c17b34 100644
--- a/src/librustc_mir/util/borrowck_errors.rs
+++ b/src/librustc_mir/util/borrowck_errors.rs
@@ -50,7 +50,7 @@ impl<'cx, 'tcx> crate::borrow_check::MirBorrowckCtxt<'cx, 'tcx> {
             self,
             span,
             E0381,
-            "{} of possibly uninitialized variable: `{}`",
+            "{} of possibly-uninitialized variable: `{}`",
             verb,
             desc,
         )
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index e502a08f4b253..98c3562b3219f 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -982,7 +982,7 @@ impl<'a> Parser<'a> {
                 }
                 if self.is_do_catch_block() {
                     let mut db = self.fatal("found removed `do catch` syntax");
-                    db.help("Following RFC #2388, the new non-placeholder syntax is `try`");
+                    db.help("following RFC #2388, the new non-placeholder syntax is `try`");
                     return Err(db);
                 }
                 if self.is_try_block() {
diff --git a/src/libsyntax/parse/parser/stmt.rs b/src/libsyntax/parse/parser/stmt.rs
index 651ebf6342e71..748c1a168b0b2 100644
--- a/src/libsyntax/parse/parser/stmt.rs
+++ b/src/libsyntax/parse/parser/stmt.rs
@@ -469,7 +469,7 @@ impl<'a> Parser<'a> {
         self.diagnostic().struct_span_warn(self.token.span, {
             &format!("expected `;`, found {}", self.this_token_descr())
         }).note({
-            "This was erroneously allowed and will become a hard error in a future release"
+            "this was erroneously allowed and will become a hard error in a future release"
         }).emit();
     }
 }
diff --git a/src/test/ui/asm/asm-out-read-uninit.rs b/src/test/ui/asm/asm-out-read-uninit.rs
index 003f1fc5bb62b..78458ff60d4aa 100644
--- a/src/test/ui/asm/asm-out-read-uninit.rs
+++ b/src/test/ui/asm/asm-out-read-uninit.rs
@@ -20,7 +20,7 @@ pub fn main() {
     let x: isize;
     unsafe {
         asm!("mov $1, $0" : "=r"(x) : "r"(x));
-        //~^ ERROR use of possibly uninitialized variable: `x`
+        //~^ ERROR use of possibly-uninitialized variable: `x`
     }
     foo(x);
 }
diff --git a/src/test/ui/asm/asm-out-read-uninit.stderr b/src/test/ui/asm/asm-out-read-uninit.stderr
index 6d0445d4b7a61..71aeda2ad4d2e 100644
--- a/src/test/ui/asm/asm-out-read-uninit.stderr
+++ b/src/test/ui/asm/asm-out-read-uninit.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/asm-out-read-uninit.rs:22:43
    |
 LL |         asm!("mov $1, $0" : "=r"(x) : "r"(x));
-   |                                           ^ use of possibly uninitialized `x`
+   |                                           ^ use of possibly-uninitialized `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.rs b/src/test/ui/async-await/no-non-guaranteed-initialization.rs
index 0afbf4cee1d3c..6a34209d55289 100644
--- a/src/test/ui/async-await/no-non-guaranteed-initialization.rs
+++ b/src/test/ui/async-await/no-non-guaranteed-initialization.rs
@@ -8,7 +8,7 @@ async fn no_non_guaranteed_initialization(x: usize) -> usize {
         y = echo(10).await;
     }
     y
-    //~^ use of possibly uninitialized variable: `y`
+    //~^ use of possibly-uninitialized variable: `y`
 }
 
 async fn echo(x: usize) -> usize { x + 1 }
diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
index 91d7994654f37..b9aa9924bb815 100644
--- a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
+++ b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `y`
+error[E0381]: use of possibly-uninitialized variable: `y`
   --> $DIR/no-non-guaranteed-initialization.rs:10:5
    |
 LL |     y
-   |     ^ use of possibly uninitialized `y`
+   |     ^ use of possibly-uninitialized `y`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/partial-initialization-across-await.rs b/src/test/ui/async-await/partial-initialization-across-await.rs
index 1785fb7f29947..8a98a4b0f6bb4 100644
--- a/src/test/ui/async-await/partial-initialization-across-await.rs
+++ b/src/test/ui/async-await/partial-initialization-across-await.rs
@@ -11,7 +11,7 @@ async fn noop() {}
 async fn test_tuple() {
     let mut t: (i32, i32);
     t.0 = 42;
-    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
     noop().await;
     t.1 = 88;
     let _ = t;
@@ -20,7 +20,7 @@ async fn test_tuple() {
 async fn test_tuple_struct() {
     let mut t: T;
     t.0 = 42;
-    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
     noop().await;
     t.1 = 88;
     let _ = t;
@@ -29,7 +29,7 @@ async fn test_tuple_struct() {
 async fn test_struct() {
     let mut t: S;
     t.x = 42;
-    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
     noop().await;
     t.y = 88;
     let _ = t;
diff --git a/src/test/ui/async-await/partial-initialization-across-await.stderr b/src/test/ui/async-await/partial-initialization-across-await.stderr
index d9a2db985e54d..9a510c22c4b1e 100644
--- a/src/test/ui/async-await/partial-initialization-across-await.stderr
+++ b/src/test/ui/async-await/partial-initialization-across-await.stderr
@@ -1,20 +1,20 @@
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/partial-initialization-across-await.rs:13:5
    |
 LL |     t.0 = 42;
-   |     ^^^^^^^^ use of possibly uninitialized `t`
+   |     ^^^^^^^^ use of possibly-uninitialized `t`
 
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/partial-initialization-across-await.rs:22:5
    |
 LL |     t.0 = 42;
-   |     ^^^^^^^^ use of possibly uninitialized `t`
+   |     ^^^^^^^^ use of possibly-uninitialized `t`
 
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/partial-initialization-across-await.rs:31:5
    |
 LL |     t.x = 42;
-   |     ^^^^^^^^ use of possibly uninitialized `t`
+   |     ^^^^^^^^ use of possibly-uninitialized `t`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/assign_mutable_fields.stderr b/src/test/ui/borrowck/assign_mutable_fields.stderr
index 35101df4e0a6e..40f1aae092dc6 100644
--- a/src/test/ui/borrowck/assign_mutable_fields.stderr
+++ b/src/test/ui/borrowck/assign_mutable_fields.stderr
@@ -1,14 +1,14 @@
-error[E0381]: assign to part of possibly uninitialized variable: `x`
+error[E0381]: assign to part of possibly-uninitialized variable: `x`
   --> $DIR/assign_mutable_fields.rs:9:5
    |
 LL |     x.0 = 1;
-   |     ^^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: assign to part of possibly uninitialized variable: `x`
+error[E0381]: assign to part of possibly-uninitialized variable: `x`
   --> $DIR/assign_mutable_fields.rs:17:5
    |
 LL |     x.0 = 1;
-   |     ^^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^^ use of possibly-uninitialized `x`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-and-init.rs b/src/test/ui/borrowck/borrowck-and-init.rs
index 4427e25186103..f11d44e2217ba 100644
--- a/src/test/ui/borrowck/borrowck-and-init.rs
+++ b/src/test/ui/borrowck/borrowck-and-init.rs
@@ -2,5 +2,5 @@ fn main() {
     let i: isize;
 
     println!("{}", false && { i = 5; true });
-    println!("{}", i); //~ ERROR borrow of possibly uninitialized variable: `i`
+    println!("{}", i); //~ ERROR borrow of possibly-uninitialized variable: `i`
 }
diff --git a/src/test/ui/borrowck/borrowck-and-init.stderr b/src/test/ui/borrowck/borrowck-and-init.stderr
index 2db075194810e..c7e357d4604f7 100644
--- a/src/test/ui/borrowck/borrowck-and-init.stderr
+++ b/src/test/ui/borrowck/borrowck-and-init.stderr
@@ -1,8 +1,8 @@
-error[E0381]: borrow of possibly uninitialized variable: `i`
+error[E0381]: borrow of possibly-uninitialized variable: `i`
   --> $DIR/borrowck-and-init.rs:5:20
    |
 LL |     println!("{}", i);
-   |                    ^ use of possibly uninitialized `i`
+   |                    ^ use of possibly-uninitialized `i`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-asm.rs b/src/test/ui/borrowck/borrowck-asm.rs
index 9c9cc04baafee..c1b0f39f9366c 100644
--- a/src/test/ui/borrowck/borrowck-asm.rs
+++ b/src/test/ui/borrowck/borrowck-asm.rs
@@ -57,7 +57,7 @@ mod test_cases {
     fn indirect_is_not_init() {
         let x: i32;
         unsafe {
-            asm!("nop" : "=*r"(x)); //~ ERROR use of possibly uninitialized variable
+            asm!("nop" : "=*r"(x)); //~ ERROR use of possibly-uninitialized variable
         }
     }
 
diff --git a/src/test/ui/borrowck/borrowck-asm.stderr b/src/test/ui/borrowck/borrowck-asm.stderr
index c771373022ac4..f85b5983acced 100644
--- a/src/test/ui/borrowck/borrowck-asm.stderr
+++ b/src/test/ui/borrowck/borrowck-asm.stderr
@@ -46,11 +46,11 @@ LL |         unsafe {
 LL |             asm!("nop" : "+r"(x));
    |                               ^ cannot assign twice to immutable variable
 
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-asm.rs:60:32
    |
 LL |             asm!("nop" : "=*r"(x));
-   |                                ^ use of possibly uninitialized `x`
+   |                                ^ use of possibly-uninitialized `x`
 
 error[E0506]: cannot assign to `x` because it is borrowed
   --> $DIR/borrowck-asm.rs:68:31
diff --git a/src/test/ui/borrowck/borrowck-block-unint.rs b/src/test/ui/borrowck/borrowck-block-unint.rs
index 1fed2d503bd35..1e7306acaee98 100644
--- a/src/test/ui/borrowck/borrowck-block-unint.rs
+++ b/src/test/ui/borrowck/borrowck-block-unint.rs
@@ -1,7 +1,7 @@
 fn force<F>(f: F) where F: FnOnce() { f(); }
 fn main() {
     let x: isize;
-    force(|| {  //~ ERROR borrow of possibly uninitialized variable: `x`
+    force(|| {  //~ ERROR borrow of possibly-uninitialized variable: `x`
         println!("{}", x);
     });
 }
diff --git a/src/test/ui/borrowck/borrowck-block-unint.stderr b/src/test/ui/borrowck/borrowck-block-unint.stderr
index d2a49962bafca..578f89df46ce1 100644
--- a/src/test/ui/borrowck/borrowck-block-unint.stderr
+++ b/src/test/ui/borrowck/borrowck-block-unint.stderr
@@ -1,8 +1,8 @@
-error[E0381]: borrow of possibly uninitialized variable: `x`
+error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-block-unint.rs:4:11
    |
 LL |     force(|| {
-   |           ^^ use of possibly uninitialized `x`
+   |           ^^ use of possibly-uninitialized `x`
 LL |         println!("{}", x);
    |                        - borrow occurs due to use in closure
 
diff --git a/src/test/ui/borrowck/borrowck-break-uninit-2.rs b/src/test/ui/borrowck/borrowck-break-uninit-2.rs
index dad5325cb8750..126d991a51c6e 100644
--- a/src/test/ui/borrowck/borrowck-break-uninit-2.rs
+++ b/src/test/ui/borrowck/borrowck-break-uninit-2.rs
@@ -6,7 +6,7 @@ fn foo() -> isize {
         x = 0;
     }
 
-    println!("{}", x); //~ ERROR borrow of possibly uninitialized variable: `x`
+    println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x`
 
     return 17;
 }
diff --git a/src/test/ui/borrowck/borrowck-break-uninit-2.stderr b/src/test/ui/borrowck/borrowck-break-uninit-2.stderr
index e40d8d9dfccb9..bc9b25c0221fc 100644
--- a/src/test/ui/borrowck/borrowck-break-uninit-2.stderr
+++ b/src/test/ui/borrowck/borrowck-break-uninit-2.stderr
@@ -1,8 +1,8 @@
-error[E0381]: borrow of possibly uninitialized variable: `x`
+error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-break-uninit-2.rs:9:20
    |
 LL |     println!("{}", x);
-   |                    ^ use of possibly uninitialized `x`
+   |                    ^ use of possibly-uninitialized `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-break-uninit.rs b/src/test/ui/borrowck/borrowck-break-uninit.rs
index 9af02b387d8b0..8ccb21ae8eebf 100644
--- a/src/test/ui/borrowck/borrowck-break-uninit.rs
+++ b/src/test/ui/borrowck/borrowck-break-uninit.rs
@@ -6,7 +6,7 @@ fn foo() -> isize {
         x = 0;
     }
 
-    println!("{}", x); //~ ERROR borrow of possibly uninitialized variable: `x`
+    println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x`
 
     return 17;
 }
diff --git a/src/test/ui/borrowck/borrowck-break-uninit.stderr b/src/test/ui/borrowck/borrowck-break-uninit.stderr
index bbf9b9f1241a2..766d5cfd6348c 100644
--- a/src/test/ui/borrowck/borrowck-break-uninit.stderr
+++ b/src/test/ui/borrowck/borrowck-break-uninit.stderr
@@ -1,8 +1,8 @@
-error[E0381]: borrow of possibly uninitialized variable: `x`
+error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-break-uninit.rs:9:20
    |
 LL |     println!("{}", x);
-   |                    ^ use of possibly uninitialized `x`
+   |                    ^ use of possibly-uninitialized `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-field-sensitivity.rs b/src/test/ui/borrowck/borrowck-field-sensitivity.rs
index 88f74d1ed3300..ab607c2acbd4b 100644
--- a/src/test/ui/borrowck/borrowck-field-sensitivity.rs
+++ b/src/test/ui/borrowck/borrowck-field-sensitivity.rs
@@ -78,20 +78,20 @@ fn fu_move_after_fu_move() {
 
 fn copy_after_field_assign_after_uninit() {
     let mut x: A;
-    x.a = 1; //~ ERROR assign to part of possibly uninitialized variable: `x`
+    x.a = 1; //~ ERROR assign to part of possibly-uninitialized variable: `x`
     drop(x.a);
 }
 
 fn borrow_after_field_assign_after_uninit() {
     let mut x: A;
-    x.a = 1; //~ ERROR assign to part of possibly uninitialized variable: `x`
+    x.a = 1; //~ ERROR assign to part of possibly-uninitialized variable: `x`
     let p = &x.a;
     drop(*p);
 }
 
 fn move_after_field_assign_after_uninit() {
     let mut x: A;
-    x.b = box 1; //~ ERROR assign to part of possibly uninitialized variable: `x`
+    x.b = box 1; //~ ERROR assign to part of possibly-uninitialized variable: `x`
     drop(x.b);
 }
 
diff --git a/src/test/ui/borrowck/borrowck-field-sensitivity.stderr b/src/test/ui/borrowck/borrowck-field-sensitivity.stderr
index 89523235481ad..158b2e42f2ddf 100644
--- a/src/test/ui/borrowck/borrowck-field-sensitivity.stderr
+++ b/src/test/ui/borrowck/borrowck-field-sensitivity.stderr
@@ -108,23 +108,23 @@ LL |     let _z = A { a: 4, .. x };
    |
    = note: move occurs because `x.b` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
 
-error[E0381]: assign to part of possibly uninitialized variable: `x`
+error[E0381]: assign to part of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-field-sensitivity.rs:81:5
    |
 LL |     x.a = 1;
-   |     ^^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: assign to part of possibly uninitialized variable: `x`
+error[E0381]: assign to part of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-field-sensitivity.rs:87:5
    |
 LL |     x.a = 1;
-   |     ^^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: assign to part of possibly uninitialized variable: `x`
+error[E0381]: assign to part of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-field-sensitivity.rs:94:5
    |
 LL |     x.b = box 1;
-   |     ^^^ use of possibly uninitialized `x`
+   |     ^^^ use of possibly-uninitialized `x`
 
 error: aborting due to 14 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-if-no-else.rs b/src/test/ui/borrowck/borrowck-if-no-else.rs
index 044db99d54c1f..f59bcad6f61d7 100644
--- a/src/test/ui/borrowck/borrowck-if-no-else.rs
+++ b/src/test/ui/borrowck/borrowck-if-no-else.rs
@@ -2,5 +2,5 @@ fn foo(x: isize) { println!("{}", x); }
 
 fn main() {
     let x: isize; if 1 > 2 { x = 10; }
-    foo(x); //~ ERROR use of possibly uninitialized variable: `x`
+    foo(x); //~ ERROR use of possibly-uninitialized variable: `x`
 }
diff --git a/src/test/ui/borrowck/borrowck-if-no-else.stderr b/src/test/ui/borrowck/borrowck-if-no-else.stderr
index 1223e409d4df6..3e9d3d4f6d513 100644
--- a/src/test/ui/borrowck/borrowck-if-no-else.stderr
+++ b/src/test/ui/borrowck/borrowck-if-no-else.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-if-no-else.rs:5:9
    |
 LL |     foo(x);
-   |         ^ use of possibly uninitialized `x`
+   |         ^ use of possibly-uninitialized `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-if-with-else.rs b/src/test/ui/borrowck/borrowck-if-with-else.rs
index f632d61a6c3c1..c13318b16c2fa 100644
--- a/src/test/ui/borrowck/borrowck-if-with-else.rs
+++ b/src/test/ui/borrowck/borrowck-if-with-else.rs
@@ -7,5 +7,5 @@ fn main() {
     } else {
         x = 10;
     }
-    foo(x); //~ ERROR use of possibly uninitialized variable: `x`
+    foo(x); //~ ERROR use of possibly-uninitialized variable: `x`
 }
diff --git a/src/test/ui/borrowck/borrowck-if-with-else.stderr b/src/test/ui/borrowck/borrowck-if-with-else.stderr
index d11f29b05f565..53b8a6bba2c76 100644
--- a/src/test/ui/borrowck/borrowck-if-with-else.stderr
+++ b/src/test/ui/borrowck/borrowck-if-with-else.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-if-with-else.rs:10:9
    |
 LL |     foo(x);
-   |         ^ use of possibly uninitialized `x`
+   |         ^ use of possibly-uninitialized `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs
index f7457781adc3e..9905e420f948d 100644
--- a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs
+++ b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs
@@ -1,7 +1,7 @@
 fn main() {
     let j = || -> isize {
         let i: isize;
-        i //~ ERROR use of possibly uninitialized variable: `i`
+        i //~ ERROR use of possibly-uninitialized variable: `i`
     };
     j();
 }
diff --git a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr
index 82a602c6359c1..2d1d9bc8fa41d 100644
--- a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr
+++ b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `i`
+error[E0381]: use of possibly-uninitialized variable: `i`
   --> $DIR/borrowck-init-in-called-fn-expr.rs:4:9
    |
 LL |         i
-   |         ^ use of possibly uninitialized `i`
+   |         ^ use of possibly-uninitialized `i`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs b/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs
index 5055814625539..7dd3396c8c2cb 100644
--- a/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs
+++ b/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs
@@ -1,7 +1,7 @@
 fn main() {
     let f  = || -> isize {
         let i: isize;
-        i //~ ERROR use of possibly uninitialized variable: `i`
+        i //~ ERROR use of possibly-uninitialized variable: `i`
     };
     println!("{}", f());
 }
diff --git a/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr b/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr
index 899739378524c..fd8b90eda6032 100644
--- a/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr
+++ b/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `i`
+error[E0381]: use of possibly-uninitialized variable: `i`
   --> $DIR/borrowck-init-in-fn-expr.rs:4:9
    |
 LL |         i
-   |         ^ use of possibly uninitialized `i`
+   |         ^ use of possibly-uninitialized `i`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-init-in-fru.rs b/src/test/ui/borrowck/borrowck-init-in-fru.rs
index 6da3098dc9336..d7ec2ed75c85c 100644
--- a/src/test/ui/borrowck/borrowck-init-in-fru.rs
+++ b/src/test/ui/borrowck/borrowck-init-in-fru.rs
@@ -7,6 +7,6 @@ struct Point {
 fn main() {
     let mut origin: Point;
     origin = Point { x: 10, ..origin };
-    //~^ ERROR use of possibly uninitialized variable: `origin` [E0381]
+    //~^ ERROR use of possibly-uninitialized variable: `origin` [E0381]
     origin.clone();
 }
diff --git a/src/test/ui/borrowck/borrowck-init-in-fru.stderr b/src/test/ui/borrowck/borrowck-init-in-fru.stderr
index fe55bc2fd95c0..a4c042d1c125f 100644
--- a/src/test/ui/borrowck/borrowck-init-in-fru.stderr
+++ b/src/test/ui/borrowck/borrowck-init-in-fru.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `origin`
+error[E0381]: use of possibly-uninitialized variable: `origin`
   --> $DIR/borrowck-init-in-fru.rs:9:5
    |
 LL |     origin = Point { x: 10, ..origin };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly uninitialized `origin.y`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `origin.y`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-init-op-equal.rs b/src/test/ui/borrowck/borrowck-init-op-equal.rs
index d3fa852ac91ba..784eb8cf85b8a 100644
--- a/src/test/ui/borrowck/borrowck-init-op-equal.rs
+++ b/src/test/ui/borrowck/borrowck-init-op-equal.rs
@@ -1,6 +1,6 @@
 fn test() {
     let v: isize;
-    v += 1; //~ ERROR use of possibly uninitialized variable: `v`
+    v += 1; //~ ERROR use of possibly-uninitialized variable: `v`
     v.clone();
 }
 
diff --git a/src/test/ui/borrowck/borrowck-init-op-equal.stderr b/src/test/ui/borrowck/borrowck-init-op-equal.stderr
index 9863ceb14240f..6c88778ae0e5a 100644
--- a/src/test/ui/borrowck/borrowck-init-op-equal.stderr
+++ b/src/test/ui/borrowck/borrowck-init-op-equal.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `v`
+error[E0381]: use of possibly-uninitialized variable: `v`
   --> $DIR/borrowck-init-op-equal.rs:3:5
    |
 LL |     v += 1;
-   |     ^^^^^^ use of possibly uninitialized `v`
+   |     ^^^^^^ use of possibly-uninitialized `v`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-init-plus-equal.rs b/src/test/ui/borrowck/borrowck-init-plus-equal.rs
index d895a2e16b537..d9d20a2a9c148 100644
--- a/src/test/ui/borrowck/borrowck-init-plus-equal.rs
+++ b/src/test/ui/borrowck/borrowck-init-plus-equal.rs
@@ -1,6 +1,6 @@
 fn test() {
     let mut v: isize;
-    v = v + 1; //~ ERROR use of possibly uninitialized variable: `v`
+    v = v + 1; //~ ERROR use of possibly-uninitialized variable: `v`
     v.clone();
 }
 
diff --git a/src/test/ui/borrowck/borrowck-init-plus-equal.stderr b/src/test/ui/borrowck/borrowck-init-plus-equal.stderr
index 80c4e0c80483d..fe09c8581df0e 100644
--- a/src/test/ui/borrowck/borrowck-init-plus-equal.stderr
+++ b/src/test/ui/borrowck/borrowck-init-plus-equal.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `v`
+error[E0381]: use of possibly-uninitialized variable: `v`
   --> $DIR/borrowck-init-plus-equal.rs:3:9
    |
 LL |     v = v + 1;
-   |         ^ use of possibly uninitialized `v`
+   |         ^ use of possibly-uninitialized `v`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-or-init.rs b/src/test/ui/borrowck/borrowck-or-init.rs
index c0d6c9c2739b2..81b0b80bf11b5 100644
--- a/src/test/ui/borrowck/borrowck-or-init.rs
+++ b/src/test/ui/borrowck/borrowck-or-init.rs
@@ -2,5 +2,5 @@ fn main() {
     let i: isize;
 
     println!("{}", false || { i = 5; true });
-    println!("{}", i); //~ ERROR borrow of possibly uninitialized variable: `i`
+    println!("{}", i); //~ ERROR borrow of possibly-uninitialized variable: `i`
 }
diff --git a/src/test/ui/borrowck/borrowck-or-init.stderr b/src/test/ui/borrowck/borrowck-or-init.stderr
index 122f5192720cc..3fe8d9eededc5 100644
--- a/src/test/ui/borrowck/borrowck-or-init.stderr
+++ b/src/test/ui/borrowck/borrowck-or-init.stderr
@@ -1,8 +1,8 @@
-error[E0381]: borrow of possibly uninitialized variable: `i`
+error[E0381]: borrow of possibly-uninitialized variable: `i`
   --> $DIR/borrowck-or-init.rs:5:20
    |
 LL |     println!("{}", i);
-   |                    ^ use of possibly uninitialized `i`
+   |                    ^ use of possibly-uninitialized `i`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-partial-reinit-4.rs b/src/test/ui/borrowck/borrowck-partial-reinit-4.rs
index 0fb955d201d03..5e5a8cdf4232b 100644
--- a/src/test/ui/borrowck/borrowck-partial-reinit-4.rs
+++ b/src/test/ui/borrowck/borrowck-partial-reinit-4.rs
@@ -15,7 +15,7 @@ impl Drop for Test2 {
 fn stuff() {
     let mut x : (Test2, Test2);
     (x.0).0 = Some(Test);
-    //~^ ERROR assign of possibly uninitialized variable: `x.0`
+    //~^ ERROR assign of possibly-uninitialized variable: `x.0`
 }
 
 fn main() {
diff --git a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr
index f0a9a7dd5e243..218c4f2de5bc7 100644
--- a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr
+++ b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr
@@ -1,8 +1,8 @@
-error[E0381]: assign of possibly uninitialized variable: `x.0`
+error[E0381]: assign of possibly-uninitialized variable: `x.0`
   --> $DIR/borrowck-partial-reinit-4.rs:17:5
    |
 LL |     (x.0).0 = Some(Test);
-   |     ^^^^^^^ use of possibly uninitialized `x.0`
+   |     ^^^^^^^ use of possibly-uninitialized `x.0`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-return.rs b/src/test/ui/borrowck/borrowck-return.rs
index e5bee2ca4bfeb..8c623356f6c6b 100644
--- a/src/test/ui/borrowck/borrowck-return.rs
+++ b/src/test/ui/borrowck/borrowck-return.rs
@@ -1,6 +1,6 @@
 fn f() -> isize {
     let x: isize;
-    return x; //~ ERROR use of possibly uninitialized variable: `x`
+    return x; //~ ERROR use of possibly-uninitialized variable: `x`
 }
 
 fn main() { f(); }
diff --git a/src/test/ui/borrowck/borrowck-return.stderr b/src/test/ui/borrowck/borrowck-return.stderr
index a2b65af5dbfcd..bc74e8e343848 100644
--- a/src/test/ui/borrowck/borrowck-return.stderr
+++ b/src/test/ui/borrowck/borrowck-return.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-return.rs:3:12
    |
 LL |     return x;
-   |            ^ use of possibly uninitialized `x`
+   |            ^ use of possibly-uninitialized `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-storage-dead.stderr b/src/test/ui/borrowck/borrowck-storage-dead.stderr
index 5b9f49c2e7c92..8e4932142f0db 100644
--- a/src/test/ui/borrowck/borrowck-storage-dead.stderr
+++ b/src/test/ui/borrowck/borrowck-storage-dead.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-storage-dead.rs:16:17
    |
 LL |         let _ = x + 1;
-   |                 ^ use of possibly uninitialized `x`
+   |                 ^ use of possibly-uninitialized `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-uninit-after-item.rs b/src/test/ui/borrowck/borrowck-uninit-after-item.rs
index 83f3752a1a850..e9a389657c8fd 100644
--- a/src/test/ui/borrowck/borrowck-uninit-after-item.rs
+++ b/src/test/ui/borrowck/borrowck-uninit-after-item.rs
@@ -1,5 +1,5 @@
 fn main() {
     let bar;
     fn baz(_x: isize) { }
-    baz(bar); //~ ERROR use of possibly uninitialized variable: `bar`
+    baz(bar); //~ ERROR use of possibly-uninitialized variable: `bar`
 }
diff --git a/src/test/ui/borrowck/borrowck-uninit-after-item.stderr b/src/test/ui/borrowck/borrowck-uninit-after-item.stderr
index 2d0b21dd0d6fb..f7f069b81be02 100644
--- a/src/test/ui/borrowck/borrowck-uninit-after-item.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-after-item.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `bar`
+error[E0381]: use of possibly-uninitialized variable: `bar`
   --> $DIR/borrowck-uninit-after-item.rs:4:9
    |
 LL |     baz(bar);
-   |         ^^^ use of possibly uninitialized `bar`
+   |         ^^^ use of possibly-uninitialized `bar`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-uninit-field-access.stderr b/src/test/ui/borrowck/borrowck-uninit-field-access.stderr
index aa214f9c2f590..9f35a4a8d83bd 100644
--- a/src/test/ui/borrowck/borrowck-uninit-field-access.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-field-access.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `a`
+error[E0381]: use of possibly-uninitialized variable: `a`
   --> $DIR/borrowck-uninit-field-access.rs:21:13
    |
 LL |     let _ = a.x + 1;
-   |             ^^^ use of possibly uninitialized `a.x`
+   |             ^^^ use of possibly-uninitialized `a.x`
 
 error[E0382]: use of moved value: `line1.origin`
   --> $DIR/borrowck-uninit-field-access.rs:25:13
diff --git a/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs b/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs
index bfb0dd4301dd1..20350d61d5bb6 100644
--- a/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs
+++ b/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs
@@ -3,32 +3,32 @@
 
 pub fn main() {
     let x: isize;
-    x += 1; //~ ERROR use of possibly uninitialized variable: `x`
+    x += 1; //~ ERROR use of possibly-uninitialized variable: `x`
 
     let x: isize;
-    x -= 1; //~ ERROR use of possibly uninitialized variable: `x`
+    x -= 1; //~ ERROR use of possibly-uninitialized variable: `x`
 
     let x: isize;
-    x *= 1; //~ ERROR use of possibly uninitialized variable: `x`
+    x *= 1; //~ ERROR use of possibly-uninitialized variable: `x`
 
     let x: isize;
-    x /= 1; //~ ERROR use of possibly uninitialized variable: `x`
+    x /= 1; //~ ERROR use of possibly-uninitialized variable: `x`
 
     let x: isize;
-    x %= 1; //~ ERROR use of possibly uninitialized variable: `x`
+    x %= 1; //~ ERROR use of possibly-uninitialized variable: `x`
 
     let x: isize;
-    x ^= 1; //~ ERROR use of possibly uninitialized variable: `x`
+    x ^= 1; //~ ERROR use of possibly-uninitialized variable: `x`
 
     let x: isize;
-    x &= 1; //~ ERROR use of possibly uninitialized variable: `x`
+    x &= 1; //~ ERROR use of possibly-uninitialized variable: `x`
 
     let x: isize;
-    x |= 1; //~ ERROR use of possibly uninitialized variable: `x`
+    x |= 1; //~ ERROR use of possibly-uninitialized variable: `x`
 
     let x: isize;
-    x <<= 1;    //~ ERROR use of possibly uninitialized variable: `x`
+    x <<= 1;    //~ ERROR use of possibly-uninitialized variable: `x`
 
     let x: isize;
-    x >>= 1;    //~ ERROR use of possibly uninitialized variable: `x`
+    x >>= 1;    //~ ERROR use of possibly-uninitialized variable: `x`
 }
diff --git a/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr b/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr
index 163395e42d252..f2036df3ce92a 100644
--- a/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr
@@ -1,62 +1,62 @@
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-in-assignop.rs:6:5
    |
 LL |     x += 1;
-   |     ^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-in-assignop.rs:9:5
    |
 LL |     x -= 1;
-   |     ^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-in-assignop.rs:12:5
    |
 LL |     x *= 1;
-   |     ^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-in-assignop.rs:15:5
    |
 LL |     x /= 1;
-   |     ^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-in-assignop.rs:18:5
    |
 LL |     x %= 1;
-   |     ^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-in-assignop.rs:21:5
    |
 LL |     x ^= 1;
-   |     ^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-in-assignop.rs:24:5
    |
 LL |     x &= 1;
-   |     ^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-in-assignop.rs:27:5
    |
 LL |     x |= 1;
-   |     ^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-in-assignop.rs:30:5
    |
 LL |     x <<= 1;
-   |     ^^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-in-assignop.rs:33:5
    |
 LL |     x >>= 1;
-   |     ^^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^^ use of possibly-uninitialized `x`
 
 error: aborting due to 10 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs b/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs
index fa9148f984077..0ccea49f329bb 100644
--- a/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs
+++ b/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs
@@ -15,19 +15,19 @@ fn main() {
 
 
     let mut a: S<i32, i32>;
-    a.x = 0;            //~ ERROR assign to part of possibly uninitialized variable: `a` [E0381]
+    a.x = 0;            //~ ERROR assign to part of possibly-uninitialized variable: `a` [E0381]
     let _b = &a.x;
 
     let mut a: S<&&i32, &&i32>;
-    a.x = &&0;          //~ ERROR assign to part of possibly uninitialized variable: `a` [E0381]
+    a.x = &&0;          //~ ERROR assign to part of possibly-uninitialized variable: `a` [E0381]
     let _b = &**a.x;
 
 
     let mut a: S<i32, i32>;
-    a.x = 0;            //~ ERROR assign to part of possibly uninitialized variable: `a` [E0381]
+    a.x = 0;            //~ ERROR assign to part of possibly-uninitialized variable: `a` [E0381]
     let _b = &a.y;
 
     let mut a: S<&&i32, &&i32>;
-    a.x = &&0;          //~ assign to part of possibly uninitialized variable: `a` [E0381]
+    a.x = &&0;          //~ assign to part of possibly-uninitialized variable: `a` [E0381]
     let _b = &**a.y;
 }
diff --git a/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr b/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr
index d87621f04d653..d99a50df75b8c 100644
--- a/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr
@@ -1,44 +1,44 @@
-error[E0381]: borrow of possibly uninitialized variable: `x`
+error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-ref-chain.rs:8:14
    |
 LL |     let _y = &**x;
-   |              ^^^^ use of possibly uninitialized `**x`
+   |              ^^^^ use of possibly-uninitialized `**x`
 
-error[E0381]: borrow of possibly uninitialized variable: `x`
+error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-ref-chain.rs:11:14
    |
 LL |     let _y = &**x;
-   |              ^^^^ use of possibly uninitialized `**x`
+   |              ^^^^ use of possibly-uninitialized `**x`
 
-error[E0381]: borrow of possibly uninitialized variable: `x`
+error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit-ref-chain.rs:14:14
    |
 LL |     let _y = &**x;
-   |              ^^^^ use of possibly uninitialized `**x`
+   |              ^^^^ use of possibly-uninitialized `**x`
 
-error[E0381]: assign to part of possibly uninitialized variable: `a`
+error[E0381]: assign to part of possibly-uninitialized variable: `a`
   --> $DIR/borrowck-uninit-ref-chain.rs:18:5
    |
 LL |     a.x = 0;
-   |     ^^^^^^^ use of possibly uninitialized `a`
+   |     ^^^^^^^ use of possibly-uninitialized `a`
 
-error[E0381]: assign to part of possibly uninitialized variable: `a`
+error[E0381]: assign to part of possibly-uninitialized variable: `a`
   --> $DIR/borrowck-uninit-ref-chain.rs:22:5
    |
 LL |     a.x = &&0;
-   |     ^^^^^^^^^ use of possibly uninitialized `a`
+   |     ^^^^^^^^^ use of possibly-uninitialized `a`
 
-error[E0381]: assign to part of possibly uninitialized variable: `a`
+error[E0381]: assign to part of possibly-uninitialized variable: `a`
   --> $DIR/borrowck-uninit-ref-chain.rs:27:5
    |
 LL |     a.x = 0;
-   |     ^^^^^^^ use of possibly uninitialized `a`
+   |     ^^^^^^^ use of possibly-uninitialized `a`
 
-error[E0381]: assign to part of possibly uninitialized variable: `a`
+error[E0381]: assign to part of possibly-uninitialized variable: `a`
   --> $DIR/borrowck-uninit-ref-chain.rs:31:5
    |
 LL |     a.x = &&0;
-   |     ^^^^^^^^^ use of possibly uninitialized `a`
+   |     ^^^^^^^^^ use of possibly-uninitialized `a`
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-uninit.rs b/src/test/ui/borrowck/borrowck-uninit.rs
index 71c1f596fa21b..017b955a39535 100644
--- a/src/test/ui/borrowck/borrowck-uninit.rs
+++ b/src/test/ui/borrowck/borrowck-uninit.rs
@@ -2,5 +2,5 @@ fn foo(x: isize) { println!("{}", x); }
 
 fn main() {
     let x: isize;
-    foo(x); //~ ERROR use of possibly uninitialized variable: `x`
+    foo(x); //~ ERROR use of possibly-uninitialized variable: `x`
 }
diff --git a/src/test/ui/borrowck/borrowck-uninit.stderr b/src/test/ui/borrowck/borrowck-uninit.stderr
index 5db9c1b250cc2..effc209e81659 100644
--- a/src/test/ui/borrowck/borrowck-uninit.stderr
+++ b/src/test/ui/borrowck/borrowck-uninit.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-uninit.rs:5:9
    |
 LL |     foo(x);
-   |         ^ use of possibly uninitialized `x`
+   |         ^ use of possibly-uninitialized `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-union-uninitialized.rs b/src/test/ui/borrowck/borrowck-union-uninitialized.rs
index 9cab0b19202a0..3cc71e7cece0e 100644
--- a/src/test/ui/borrowck/borrowck-union-uninitialized.rs
+++ b/src/test/ui/borrowck/borrowck-union-uninitialized.rs
@@ -10,8 +10,8 @@ fn main() {
     unsafe {
         let mut s: S;
         let mut u: U;
-        s.a = 0; //~ ERROR assign to part of possibly uninitialized variable: `s`
-        u.a = 0; //~ ERROR assign to part of possibly uninitialized variable: `u`
+        s.a = 0; //~ ERROR assign to part of possibly-uninitialized variable: `s`
+        u.a = 0; //~ ERROR assign to part of possibly-uninitialized variable: `u`
         let sa = s.a;
         let ua = u.a;
     }
diff --git a/src/test/ui/borrowck/borrowck-union-uninitialized.stderr b/src/test/ui/borrowck/borrowck-union-uninitialized.stderr
index 06c884e244667..bd9ec5e579ca9 100644
--- a/src/test/ui/borrowck/borrowck-union-uninitialized.stderr
+++ b/src/test/ui/borrowck/borrowck-union-uninitialized.stderr
@@ -1,14 +1,14 @@
-error[E0381]: assign to part of possibly uninitialized variable: `s`
+error[E0381]: assign to part of possibly-uninitialized variable: `s`
   --> $DIR/borrowck-union-uninitialized.rs:13:9
    |
 LL |         s.a = 0;
-   |         ^^^^^^^ use of possibly uninitialized `s`
+   |         ^^^^^^^ use of possibly-uninitialized `s`
 
-error[E0381]: assign to part of possibly uninitialized variable: `u`
+error[E0381]: assign to part of possibly-uninitialized variable: `u`
   --> $DIR/borrowck-union-uninitialized.rs:14:9
    |
 LL |         u.a = 0;
-   |         ^^^^^^^ use of possibly uninitialized `u`
+   |         ^^^^^^^ use of possibly-uninitialized `u`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr
index c03ef759f570a..d1b396aba8257 100644
--- a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr
+++ b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr
@@ -1,14 +1,14 @@
-error[E0381]: use of possibly uninitialized variable: `w`
+error[E0381]: use of possibly-uninitialized variable: `w`
   --> $DIR/borrowck-use-in-index-lvalue.rs:3:5
    |
 LL |     w[5] = 0;
-   |     ^^^^ use of possibly uninitialized `*w`
+   |     ^^^^ use of possibly-uninitialized `*w`
 
-error[E0381]: use of possibly uninitialized variable: `w`
+error[E0381]: use of possibly-uninitialized variable: `w`
   --> $DIR/borrowck-use-in-index-lvalue.rs:6:5
    |
 LL |     w[5] = 0;
-   |     ^^^^ use of possibly uninitialized `*w`
+   |     ^^^^ use of possibly-uninitialized `*w`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr
index 2b80140c6b376..ca5227c98c862 100644
--- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr
+++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr
@@ -1,8 +1,8 @@
-error[E0381]: borrow of possibly uninitialized variable: `x`
+error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:9:13
    |
 LL |     let y = x as *const dyn Foo;
-   |             ^ use of possibly uninitialized `*x`
+   |             ^ use of possibly-uninitialized `*x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr
index 84e717a4639cd..24897a0f2dc9c 100644
--- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr
+++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr
@@ -1,8 +1,8 @@
-error[E0381]: borrow of possibly uninitialized variable: `x`
+error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-use-uninitialized-in-cast.rs:7:13
    |
 LL |     let y = x as *const i32;
-   |             ^ use of possibly uninitialized `*x`
+   |             ^ use of possibly-uninitialized `*x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-while-break.rs b/src/test/ui/borrowck/borrowck-while-break.rs
index e16bc58656d81..48e4221470221 100644
--- a/src/test/ui/borrowck/borrowck-while-break.rs
+++ b/src/test/ui/borrowck/borrowck-while-break.rs
@@ -4,7 +4,7 @@ fn test(cond: bool) {
         v = 3;
         break;
     }
-    println!("{}", v); //~ ERROR borrow of possibly uninitialized variable: `v`
+    println!("{}", v); //~ ERROR borrow of possibly-uninitialized variable: `v`
 }
 
 fn main() {
diff --git a/src/test/ui/borrowck/borrowck-while-break.stderr b/src/test/ui/borrowck/borrowck-while-break.stderr
index 0fe3cdc96a874..3eaaf8d7df08d 100644
--- a/src/test/ui/borrowck/borrowck-while-break.stderr
+++ b/src/test/ui/borrowck/borrowck-while-break.stderr
@@ -1,8 +1,8 @@
-error[E0381]: borrow of possibly uninitialized variable: `v`
+error[E0381]: borrow of possibly-uninitialized variable: `v`
   --> $DIR/borrowck-while-break.rs:7:20
    |
 LL |     println!("{}", v);
-   |                    ^ use of possibly uninitialized `v`
+   |                    ^ use of possibly-uninitialized `v`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-while-cond.rs b/src/test/ui/borrowck/borrowck-while-cond.rs
index 28a5fb18a7f1d..b3ec20711c12b 100644
--- a/src/test/ui/borrowck/borrowck-while-cond.rs
+++ b/src/test/ui/borrowck/borrowck-while-cond.rs
@@ -1,4 +1,4 @@
 fn main() {
     let x: bool;
-    while x { } //~ ERROR use of possibly uninitialized variable: `x`
+    while x { } //~ ERROR use of possibly-uninitialized variable: `x`
 }
diff --git a/src/test/ui/borrowck/borrowck-while-cond.stderr b/src/test/ui/borrowck/borrowck-while-cond.stderr
index 06deae345ab60..92937a9c5730e 100644
--- a/src/test/ui/borrowck/borrowck-while-cond.stderr
+++ b/src/test/ui/borrowck/borrowck-while-cond.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-while-cond.rs:3:11
    |
 LL |     while x { }
-   |           ^ use of possibly uninitialized `x`
+   |           ^ use of possibly-uninitialized `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-while.rs b/src/test/ui/borrowck/borrowck-while.rs
index 4274fa997a0ab..6b3220c7d8591 100644
--- a/src/test/ui/borrowck/borrowck-while.rs
+++ b/src/test/ui/borrowck/borrowck-while.rs
@@ -1,7 +1,7 @@
 fn f() -> isize {
     let mut x: isize;
     while 1 == 1 { x = 10; }
-    return x; //~ ERROR use of possibly uninitialized variable: `x`
+    return x; //~ ERROR use of possibly-uninitialized variable: `x`
 }
 
 fn main() { f(); }
diff --git a/src/test/ui/borrowck/borrowck-while.stderr b/src/test/ui/borrowck/borrowck-while.stderr
index 60622d648dd23..a1f8f64725dcd 100644
--- a/src/test/ui/borrowck/borrowck-while.stderr
+++ b/src/test/ui/borrowck/borrowck-while.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/borrowck-while.rs:4:12
    |
 LL |     return x;
-   |            ^ use of possibly uninitialized `x`
+   |            ^ use of possibly-uninitialized `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.rs b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs
index a987c00b09191..7043cb3a164e7 100644
--- a/src/test/ui/borrowck/disallow-possibly-uninitialized.rs
+++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs
@@ -4,19 +4,19 @@
 fn main() {
     let mut t: (u64, u64);
     t.0 = 1;
-    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
     t.1 = 1;
 
     let mut t: (u64, u64);
     t.1 = 1;
-    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
     t.0 = 1;
 
     let mut t: (u64, u64);
     t.0 = 1;
-    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
 
     let mut t: (u64,);
     t.0 = 1;
-    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
 }
diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
index a32b17b165934..8d5b39341c109 100644
--- a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
+++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr
@@ -1,26 +1,26 @@
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/disallow-possibly-uninitialized.rs:6:5
    |
 LL |     t.0 = 1;
-   |     ^^^^^^^ use of possibly uninitialized `t`
+   |     ^^^^^^^ use of possibly-uninitialized `t`
 
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/disallow-possibly-uninitialized.rs:11:5
    |
 LL |     t.1 = 1;
-   |     ^^^^^^^ use of possibly uninitialized `t`
+   |     ^^^^^^^ use of possibly-uninitialized `t`
 
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/disallow-possibly-uninitialized.rs:16:5
    |
 LL |     t.0 = 1;
-   |     ^^^^^^^ use of possibly uninitialized `t`
+   |     ^^^^^^^ use of possibly-uninitialized `t`
 
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/disallow-possibly-uninitialized.rs:20:5
    |
 LL |     t.0 = 1;
-   |     ^^^^^^^ use of possibly uninitialized `t`
+   |     ^^^^^^^ use of possibly-uninitialized `t`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs
index 8d8ac279b23a8..f031a144443b3 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs
@@ -10,7 +10,7 @@ fn main() {
     {
         let mut t: Tuple;
         t.0 = S(1);
-        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
         t.1 = 2;
         println!("{:?} {:?}", t.0, t.1);
     }
@@ -18,7 +18,7 @@ fn main() {
     {
         let mut u: Tpair;
         u.0 = S(1);
-        //~^ ERROR assign to part of possibly uninitialized variable: `u` [E0381]
+        //~^ ERROR assign to part of possibly-uninitialized variable: `u` [E0381]
         u.1 = 2;
         println!("{:?} {:?}", u.0, u.1);
     }
@@ -26,7 +26,7 @@ fn main() {
     {
         let mut v: Spair;
         v.x = S(1);
-        //~^ ERROR assign to part of possibly uninitialized variable: `v` [E0381]
+        //~^ ERROR assign to part of possibly-uninitialized variable: `v` [E0381]
         v.y = 2;
         println!("{:?} {:?}", v.x, v.y);
     }
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr
index 6f18ff161372a..22c6c3964edc1 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr
@@ -1,20 +1,20 @@
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:12:9
    |
 LL |         t.0 = S(1);
-   |         ^^^^^^^^^^ use of possibly uninitialized `t`
+   |         ^^^^^^^^^^ use of possibly-uninitialized `t`
 
-error[E0381]: assign to part of possibly uninitialized variable: `u`
+error[E0381]: assign to part of possibly-uninitialized variable: `u`
   --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:20:9
    |
 LL |         u.0 = S(1);
-   |         ^^^^^^^^^^ use of possibly uninitialized `u`
+   |         ^^^^^^^^^^ use of possibly-uninitialized `u`
 
-error[E0381]: assign to part of possibly uninitialized variable: `v`
+error[E0381]: assign to part of possibly-uninitialized variable: `v`
   --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:28:9
    |
 LL |         v.x = S(1);
-   |         ^^^^^^^^^^ use of possibly uninitialized `v`
+   |         ^^^^^^^^^^ use of possibly-uninitialized `v`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs
index 1a1b376bf9bcf..660d9e85ef54e 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs
@@ -10,7 +10,7 @@ fn main() {
     {
         let t: Tuple;
         t.0 = S(1);
-        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
         t.1 = 2;
         println!("{:?} {:?}", t.0, t.1);
     }
@@ -18,7 +18,7 @@ fn main() {
     {
         let u: Tpair;
         u.0 = S(1);
-        //~^ ERROR assign to part of possibly uninitialized variable: `u` [E0381]
+        //~^ ERROR assign to part of possibly-uninitialized variable: `u` [E0381]
         u.1 = 2;
         println!("{:?} {:?}", u.0, u.1);
     }
@@ -26,7 +26,7 @@ fn main() {
     {
         let v: Spair;
         v.x = S(1);
-        //~^ ERROR assign to part of possibly uninitialized variable: `v` [E0381]
+        //~^ ERROR assign to part of possibly-uninitialized variable: `v` [E0381]
         v.y = 2;
         println!("{:?} {:?}", v.x, v.y);
     }
diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr
index 68873ac5c02e2..5f9c978c342f6 100644
--- a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr
+++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr
@@ -1,20 +1,20 @@
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/issue-54499-field-mutation-of-never-init.rs:12:9
    |
 LL |         t.0 = S(1);
-   |         ^^^^^^^^^^ use of possibly uninitialized `t`
+   |         ^^^^^^^^^^ use of possibly-uninitialized `t`
 
-error[E0381]: assign to part of possibly uninitialized variable: `u`
+error[E0381]: assign to part of possibly-uninitialized variable: `u`
   --> $DIR/issue-54499-field-mutation-of-never-init.rs:20:9
    |
 LL |         u.0 = S(1);
-   |         ^^^^^^^^^^ use of possibly uninitialized `u`
+   |         ^^^^^^^^^^ use of possibly-uninitialized `u`
 
-error[E0381]: assign to part of possibly uninitialized variable: `v`
+error[E0381]: assign to part of possibly-uninitialized variable: `v`
   --> $DIR/issue-54499-field-mutation-of-never-init.rs:28:9
    |
 LL |         v.x = S(1);
-   |         ^^^^^^^^^^ use of possibly uninitialized `v`
+   |         ^^^^^^^^^^ use of possibly-uninitialized `v`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs b/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs
index 220b2ecf04d38..f8efa8c891eb3 100644
--- a/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs
+++ b/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs
@@ -1,7 +1,7 @@
 fn main() {
     let e: i32;
     match e {
-        //~^ ERROR use of possibly uninitialized variable
+        //~^ ERROR use of possibly-uninitialized variable
         ref u if true => {}
         ref v if true => {
             let tx = 0;
diff --git a/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr
index 9701343d2b1dd..0eca447b55159 100644
--- a/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr
+++ b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `e`
+error[E0381]: use of possibly-uninitialized variable: `e`
   --> $DIR/issue-62107-match-arm-scopes.rs:3:11
    |
 LL |     match e {
-   |           ^ use of possibly uninitialized `e`
+   |           ^ use of possibly-uninitialized `e`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/reassignment_immutable_fields.stderr b/src/test/ui/borrowck/reassignment_immutable_fields.stderr
index d455a8f078743..f09db378a75b4 100644
--- a/src/test/ui/borrowck/reassignment_immutable_fields.stderr
+++ b/src/test/ui/borrowck/reassignment_immutable_fields.stderr
@@ -1,14 +1,14 @@
-error[E0381]: assign to part of possibly uninitialized variable: `x`
+error[E0381]: assign to part of possibly-uninitialized variable: `x`
   --> $DIR/reassignment_immutable_fields.rs:7:5
    |
 LL |     x.0 = 1;
-   |     ^^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^^ use of possibly-uninitialized `x`
 
-error[E0381]: assign to part of possibly uninitialized variable: `x`
+error[E0381]: assign to part of possibly-uninitialized variable: `x`
   --> $DIR/reassignment_immutable_fields.rs:15:5
    |
 LL |     x.0 = 1;
-   |     ^^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^^ use of possibly-uninitialized `x`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr
index 649c127dcc9d4..5f346708eb610 100644
--- a/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr
+++ b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr
@@ -1,8 +1,8 @@
-error[E0381]: assign to part of possibly uninitialized variable: `x`
+error[E0381]: assign to part of possibly-uninitialized variable: `x`
   --> $DIR/reassignment_immutable_fields_overlapping.rs:12:5
    |
 LL |     x.a = 1;
-   |     ^^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^^ use of possibly-uninitialized `x`
 
 error[E0594]: cannot assign to `x.b`, as `x` is not declared as mutable
   --> $DIR/reassignment_immutable_fields_overlapping.rs:13:5
diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr
index 9a2824ccb3cd2..14f0fee84c9aa 100644
--- a/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr
+++ b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr
@@ -7,11 +7,11 @@ LL |     x = (22, 44);
 LL |     x.0 = 1;
    |     ^^^^^^^ cannot assign
 
-error[E0381]: assign to part of possibly uninitialized variable: `x`
+error[E0381]: assign to part of possibly-uninitialized variable: `x`
   --> $DIR/reassignment_immutable_fields_twice.rs:12:5
    |
 LL |     x.0 = 1;
-   |     ^^^^^^^ use of possibly uninitialized `x`
+   |     ^^^^^^^ use of possibly-uninitialized `x`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/borrowck/two-phase-across-loop.rs b/src/test/ui/borrowck/two-phase-across-loop.rs
index 12222342c95a1..3fcea7d171349 100644
--- a/src/test/ui/borrowck/two-phase-across-loop.rs
+++ b/src/test/ui/borrowck/two-phase-across-loop.rs
@@ -1,4 +1,4 @@
-// Test that a borrow which starts as a 2-phase borrow and gets
+// Test that a borrow which starts as a two-phase borrow and gets
 // carried around a loop winds up conflicting with itself.
 
 struct Foo { x: String }
diff --git a/src/test/ui/consts/const-err4.stderr b/src/test/ui/consts/const-err4.stderr
index 1feec3c21c0a5..081b09e33006f 100644
--- a/src/test/ui/consts/const-err4.stderr
+++ b/src/test/ui/consts/const-err4.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL |     Boo = [unsafe { Foo { b: () }.a }; 4][3],
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr
index 3333ffac4c9b0..e0df787f80a44 100644
--- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr
+++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL |     const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: any use of this value will cause an error
   --> $DIR/const-pointer-values-in-various-types.rs:28:43
@@ -38,7 +38,7 @@ error[E0080]: it is undefined behavior to use this value
 LL |     const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/const-pointer-values-in-various-types.rs:40:5
@@ -46,7 +46,7 @@ error[E0080]: it is undefined behavior to use this value
 LL |     const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: any use of this value will cause an error
   --> $DIR/const-pointer-values-in-various-types.rs:43:43
@@ -78,7 +78,7 @@ error[E0080]: it is undefined behavior to use this value
 LL |     const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/const-pointer-values-in-various-types.rs:55:5
@@ -86,7 +86,7 @@ error[E0080]: it is undefined behavior to use this value
 LL |     const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: any use of this value will cause an error
   --> $DIR/const-pointer-values-in-various-types.rs:58:45
@@ -102,7 +102,7 @@ error[E0080]: it is undefined behavior to use this value
 LL |     const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: any use of this value will cause an error
   --> $DIR/const-pointer-values-in-various-types.rs:64:47
@@ -150,7 +150,7 @@ error[E0080]: it is undefined behavior to use this value
 LL |     const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: any use of this value will cause an error
   --> $DIR/const-pointer-values-in-various-types.rs:82:43
@@ -190,7 +190,7 @@ error[E0080]: it is undefined behavior to use this value
 LL |     const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: any use of this value will cause an error
   --> $DIR/const-pointer-values-in-various-types.rs:97:43
@@ -214,7 +214,7 @@ error[E0080]: it is undefined behavior to use this value
 LL |     const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: any use of this value will cause an error
   --> $DIR/const-pointer-values-in-various-types.rs:106:43
diff --git a/src/test/ui/consts/const-eval/double_check2.stderr b/src/test/ui/consts/const-eval/double_check2.stderr
index 9c56f1995208f..28e0922ecafa6 100644
--- a/src/test/ui/consts/const-eval/double_check2.stderr
+++ b/src/test/ui/consts/const-eval/double_check2.stderr
@@ -7,7 +7,7 @@ LL | |     Union { u8: &BAR }.bar,
 LL | | )};
    | |___^ type validation failed: encountered 5 at .1.<deref>, but expected a valid enum discriminant
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.stderr
index 0be82e3434142..b72a5b80afa8d 100644
--- a/src/test/ui/consts/const-eval/ref_to_int_match.stderr
+++ b/src/test/ui/consts/const-eval/ref_to_int_match.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: could not evaluate constant pattern
   --> $DIR/ref_to_int_match.rs:7:14
diff --git a/src/test/ui/consts/const-eval/transmute-const.stderr b/src/test/ui/consts/const-eval/transmute-const.stderr
index cacf86364796f..47f89fccf7a81 100644
--- a/src/test/ui/consts/const-eval/transmute-const.stderr
+++ b/src/test/ui/consts/const-eval/transmute-const.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | static FOO: bool = unsafe { mem::transmute(3u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3, but expected something less or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-eval/ub-enum.stderr b/src/test/ui/consts/const-eval/ub-enum.stderr
index 30dd86592d469..8ebc9dbec8ab2 100644
--- a/src/test/ui/consts/const-eval/ub-enum.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_ENUM: Enum = unsafe { TransmuteEnum { in2: 1 }.out1 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 1, but expected a valid enum discriminant
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-enum.rs:26:1
@@ -12,7 +12,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_ENUM_PTR: Enum = unsafe { TransmuteEnum { in1: &1 }.out1 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-enum.rs:29:1
@@ -20,7 +20,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { TransmuteEnum { in1: &1 }.out2 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be equal to 0
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-enum.rs:48:1
@@ -28,7 +28,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_ENUM2: Enum2 = unsafe { TransmuteEnum2 { in1: 0 }.out1 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected a valid enum discriminant
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-enum.rs:50:1
@@ -36,7 +36,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_ENUM2_PTR: Enum2 = unsafe { TransmuteEnum2 { in2: &0 }.out1 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-enum.rs:52:1
@@ -44,7 +44,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out2 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected something that cannot possibly fail to be equal to 2
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-enum.rs:56:1
@@ -52,7 +52,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { TransmuteEnum2 { in3: () }.out1 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected a valid enum discriminant
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-enum.rs:60:1
@@ -60,7 +60,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { TransmuteEnum2 { in2: &0 }.out3 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected a valid enum discriminant
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-enum.rs:71:1
@@ -68,7 +68,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .<downcast-variant(Some)>.0.1, but expected something less or equal to 1114111
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/consts/const-eval/ub-nonnull.stderr b/src/test/ui/consts/const-eval/ub-nonnull.stderr
index de20c3d0b8cfe..80d80a986751e 100644
--- a/src/test/ui/consts/const-eval/ub-nonnull.stderr
+++ b/src/test/ui/consts/const-eval/ub-nonnull.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: any use of this value will cause an error
   --> $DIR/ub-nonnull.rs:18:29
@@ -30,7 +30,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-nonnull.rs:24:1
@@ -38,7 +38,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-nonnull.rs:32:1
@@ -46,7 +46,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const UNINIT: NonZeroU8 = unsafe { Transmute { uninit: () }.out };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected something greater or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-nonnull.rs:40:1
@@ -54,7 +54,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something in the range 10..=30
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-nonnull.rs:46:1
@@ -62,7 +62,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 20, but expected something less or equal to 10, or greater or equal to 30
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/consts/const-eval/ub-ref.stderr b/src/test/ui/consts/const-eval/ub-ref.stderr
index cd3cc38467c36..01bde413c0d9c 100644
--- a/src/test/ui/consts/const-eval/ub-ref.stderr
+++ b/src/test/ui/consts/const-eval/ub-ref.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered unaligned reference (required 2 byte alignment but found 1)
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-ref.rs:11:1
@@ -12,7 +12,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0, but expected something greater or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-ref.rs:17:1
@@ -20,7 +20,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-ref.rs:20:1
@@ -28,7 +28,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer at .<deref>, but expected plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-ref.rs:23:1
@@ -36,7 +36,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (created from integer)
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/consts/const-eval/ub-uninhabit.stderr b/src/test/ui/consts/const-eval/ub-uninhabit.stderr
index 43d91483797bf..3877f3cab6d44 100644
--- a/src/test/ui/consts/const-eval/ub-uninhabit.stderr
+++ b/src/test/ui/consts/const-eval/ub-uninhabit.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_BAD_BAD: Bar = unsafe { (TransmuteUnion::<(), Bar> { a: () }).b };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-uninhabit.rs:18:1
@@ -12,7 +12,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at .<deref>
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-uninhabit.rs:21:1
@@ -20,7 +20,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { (TransmuteUnion::<(), [Bar; 1]> { a: () }).b };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/consts/const-eval/ub-upvars.stderr b/src/test/ui/consts/const-eval/ub-upvars.stderr
index f8273ba902a88..ea6ab3ae5b5ba 100644
--- a/src/test/ui/consts/const-eval/ub-upvars.stderr
+++ b/src/test/ui/consts/const-eval/ub-upvars.stderr
@@ -8,7 +8,7 @@ LL | |     move || { let _ = bad_ref; let _ = another_var; }
 LL | | };
    | |__^ type validation failed: encountered 0 at .<deref>.<dyn-downcast>.<closure-var(bad_ref)>, but expected something greater or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
index aadabc323fbd4..9134ef5a31ad9 100644
--- a/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
+++ b/src/test/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const STR_TOO_LONG: &str = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.str};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (not entirely in bounds)
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:90:1
@@ -12,7 +12,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const STR_LENGTH_PTR: &str = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.str};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:93:1
@@ -20,7 +20,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.my_str};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:97:1
@@ -28,7 +28,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const STR_NO_UTF8: &str = unsafe { SliceTransmute { slice: &[0xFF] }.str };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:100:1
@@ -36,7 +36,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const MYSTR_NO_UTF8: &MyStr = unsafe { SliceTransmute { slice: &[0xFF] }.my_str };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized or non-UTF-8 data in str at .<deref>.0
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:107:1
@@ -44,7 +44,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe { SliceTransmute { addr: 42 }.slice};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:110:1
@@ -52,7 +52,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const SLICE_TOO_LONG: &[u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.slice};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling reference (not entirely in bounds)
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:113:1
@@ -60,7 +60,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:117:1
@@ -68,7 +68,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { BoolTransmute { val: 3 }.bl }];
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>[0], but expected something less or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:123:1
@@ -76,7 +76,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { BoolTransmute { val: 3 }.bl }, [false]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.0, but expected something less or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:126:1
@@ -84,7 +84,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.1[0], but expected something less or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:133:1
@@ -92,7 +92,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:138:1
@@ -100,7 +100,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const TRAIT_OBJ_SHORT_VTABLE_1: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:141:1
@@ -108,7 +108,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const TRAIT_OBJ_SHORT_VTABLE_2: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:144:1
@@ -116,7 +116,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const TRAIT_OBJ_INT_VTABLE: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:148:1
@@ -124,7 +124,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.<dyn-downcast>, but expected something less or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:152:1
@@ -132,7 +132,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 0 } }.rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/ub-wide-ptr.rs:154:1
@@ -140,7 +140,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.raw_rust};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to 18 previous errors
 
diff --git a/src/test/ui/consts/const-eval/union-const-eval-field.stderr b/src/test/ui/consts/const-eval/union-const-eval-field.stderr
index 4d008a0e02ad7..9193bd9dea189 100644
--- a/src/test/ui/consts/const-eval/union-const-eval-field.stderr
+++ b/src/test/ui/consts/const-eval/union-const-eval-field.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL |     const FIELD3: Field3 = unsafe { UNION.field3 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-eval/union-ice.stderr b/src/test/ui/consts/const-eval/union-ice.stderr
index 8d950e86d27fc..476f3651740ab 100644
--- a/src/test/ui/consts/const-eval/union-ice.stderr
+++ b/src/test/ui/consts/const-eval/union-ice.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const FIELD3: Field3 = unsafe { UNION.field3 };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized bytes, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ice.rs:16:1
@@ -15,7 +15,7 @@ LL | |     b: unsafe { UNION.field3 },
 LL | | };
    | |__^ type validation failed: encountered uninitialized bytes at .b, but expected initialized plain (non-pointer) bytes
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error[E0080]: it is undefined behavior to use this value
   --> $DIR/union-ice.rs:26:1
@@ -29,7 +29,7 @@ LL | |     a: 42,
 LL | | };
    | |__^ type validation failed: encountered undefined bytes at .b[1]
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/consts/const-eval/union-ub.stderr b/src/test/ui/consts/const-eval/union-ub.stderr
index 6a3a397585c89..fa67bc0d8e7b5 100644
--- a/src/test/ui/consts/const-eval/union-ub.stderr
+++ b/src/test/ui/consts/const-eval/union-ub.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 42, but expected something less or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const_let_refutable.rs b/src/test/ui/consts/const_let_refutable.rs
index 7b3a591223025..d48d5945e7da9 100644
--- a/src/test/ui/consts/const_let_refutable.rs
+++ b/src/test/ui/consts/const_let_refutable.rs
@@ -2,6 +2,6 @@ fn main() {}
 
 const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument
     a + b //~ ERROR can only call other `const fn` within a `const fn`
-    //~^ ERROR use of possibly uninitialized variable: `a`
-    //~| ERROR use of possibly uninitialized variable: `b`
+    //~^ ERROR use of possibly-uninitialized variable: `a`
+    //~| ERROR use of possibly-uninitialized variable: `b`
 }
diff --git a/src/test/ui/consts/const_let_refutable.stderr b/src/test/ui/consts/const_let_refutable.stderr
index a61c9b0c9fef9..31a3098a26376 100644
--- a/src/test/ui/consts/const_let_refutable.stderr
+++ b/src/test/ui/consts/const_let_refutable.stderr
@@ -13,17 +13,17 @@ LL |     a + b
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add `#![feature(const_fn)]` to the crate attributes to enable
 
-error[E0381]: use of possibly uninitialized variable: `a`
+error[E0381]: use of possibly-uninitialized variable: `a`
   --> $DIR/const_let_refutable.rs:4:5
    |
 LL |     a + b
-   |     ^ use of possibly uninitialized `a`
+   |     ^ use of possibly-uninitialized `a`
 
-error[E0381]: use of possibly uninitialized variable: `b`
+error[E0381]: use of possibly-uninitialized variable: `b`
   --> $DIR/const_let_refutable.rs:4:9
    |
 LL |     a + b
-   |         ^ use of possibly uninitialized `b`
+   |         ^ use of possibly-uninitialized `b`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/consts/std/alloc.stderr b/src/test/ui/consts/std/alloc.stderr
index 74a8f3daf6aaa..26b7a24ebfa6f 100644
--- a/src/test/ui/consts/std/alloc.stderr
+++ b/src/test/ui/consts/std/alloc.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0 at .align_, but expected something greater or equal to 1
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/validate_never_arrays.stderr b/src/test/ui/consts/validate_never_arrays.stderr
index 7a7d816873350..c4c7a33718279 100644
--- a/src/test/ui/consts/validate_never_arrays.stderr
+++ b/src/test/ui/consts/validate_never_arrays.stderr
@@ -4,7 +4,7 @@ error[E0080]: it is undefined behavior to use this value
 LL | const FOO: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at .<deref>
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/empty/empty-never-array.rs b/src/test/ui/empty/empty-never-array.rs
index ffd2545b291e2..f0ecea42f39c8 100644
--- a/src/test/ui/empty/empty-never-array.rs
+++ b/src/test/ui/empty/empty-never-array.rs
@@ -10,7 +10,7 @@ fn transmute<T, U>(t: T) -> U {
     let Helper::U(u) = Helper::T(t, []);
     //~^ ERROR refutable pattern in local binding: `T(_, _)` not covered
     u
-    //~^ ERROR use of possibly uninitialized variable: `u`
+    //~^ ERROR use of possibly-uninitialized variable: `u`
 }
 
 fn main() {
diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr
index 01ee1c3a4d7fa..a7f7cfa289e00 100644
--- a/src/test/ui/empty/empty-never-array.stderr
+++ b/src/test/ui/empty/empty-never-array.stderr
@@ -11,11 +11,11 @@ LL | | }
 LL |       let Helper::U(u) = Helper::T(t, []);
    |           ^^^^^^^^^^^^ pattern `T(_, _)` not covered
 
-error[E0381]: use of possibly uninitialized variable: `u`
+error[E0381]: use of possibly-uninitialized variable: `u`
   --> $DIR/empty-never-array.rs:12:5
    |
 LL |     u
-   |     ^ use of possibly uninitialized `u`
+   |     ^ use of possibly-uninitialized `u`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/generator/partial-initialization-across-yield.rs b/src/test/ui/generator/partial-initialization-across-yield.rs
index 1e4593002cb9a..8b75721420351 100644
--- a/src/test/ui/generator/partial-initialization-across-yield.rs
+++ b/src/test/ui/generator/partial-initialization-across-yield.rs
@@ -10,7 +10,7 @@ fn test_tuple() {
     let _ = || {
         let mut t: (i32, i32);
         t.0 = 42;
-        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
         yield;
         t.1 = 88;
         let _ = t;
@@ -21,7 +21,7 @@ fn test_tuple_struct() {
     let _ = || {
         let mut t: T;
         t.0 = 42;
-        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
         yield;
         t.1 = 88;
         let _ = t;
@@ -32,7 +32,7 @@ fn test_struct() {
     let _ = || {
         let mut t: S;
         t.x = 42;
-        //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+        //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
         yield;
         t.y = 88;
         let _ = t;
diff --git a/src/test/ui/generator/partial-initialization-across-yield.stderr b/src/test/ui/generator/partial-initialization-across-yield.stderr
index 8bf0037e07009..66b86488eaec7 100644
--- a/src/test/ui/generator/partial-initialization-across-yield.stderr
+++ b/src/test/ui/generator/partial-initialization-across-yield.stderr
@@ -1,20 +1,20 @@
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/partial-initialization-across-yield.rs:12:9
    |
 LL |         t.0 = 42;
-   |         ^^^^^^^^ use of possibly uninitialized `t`
+   |         ^^^^^^^^ use of possibly-uninitialized `t`
 
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/partial-initialization-across-yield.rs:23:9
    |
 LL |         t.0 = 42;
-   |         ^^^^^^^^ use of possibly uninitialized `t`
+   |         ^^^^^^^^ use of possibly-uninitialized `t`
 
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/partial-initialization-across-yield.rs:34:9
    |
 LL |         t.x = 42;
-   |         ^^^^^^^^ use of possibly uninitialized `t`
+   |         ^^^^^^^^ use of possibly-uninitialized `t`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-15381.rs b/src/test/ui/issues/issue-15381.rs
index d21c321b09399..4c8e1b41beefc 100644
--- a/src/test/ui/issues/issue-15381.rs
+++ b/src/test/ui/issues/issue-15381.rs
@@ -4,6 +4,6 @@ fn main() {
     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
         //~^ ERROR refutable pattern in `for` loop binding: `&[]` not covered
         println!("y={}", y);
-        //~^ ERROR borrow of possibly uninitialized variable: `y`
+        //~^ ERROR borrow of possibly-uninitialized variable: `y`
     }
 }
diff --git a/src/test/ui/issues/issue-15381.stderr b/src/test/ui/issues/issue-15381.stderr
index a8495846b3610..e8106059052da 100644
--- a/src/test/ui/issues/issue-15381.stderr
+++ b/src/test/ui/issues/issue-15381.stderr
@@ -4,11 +4,11 @@ error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered
 LL |     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
    |         ^^^^^^^^ pattern `&[]` not covered
 
-error[E0381]: borrow of possibly uninitialized variable: `y`
+error[E0381]: borrow of possibly-uninitialized variable: `y`
   --> $DIR/issue-15381.rs:6:26
    |
 LL |         println!("y={}", y);
-   |                          ^ use of possibly uninitialized `y`
+   |                          ^ use of possibly-uninitialized `y`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-24267-flow-exit.rs b/src/test/ui/issues/issue-24267-flow-exit.rs
index a1b4d75d4048f..d6809ee4143b0 100644
--- a/src/test/ui/issues/issue-24267-flow-exit.rs
+++ b/src/test/ui/issues/issue-24267-flow-exit.rs
@@ -9,11 +9,11 @@ pub fn main() {
 pub fn foo1() {
     let x: i32;
     loop { x = break; }
-    println!("{}", x); //~ ERROR borrow of possibly uninitialized variable: `x`
+    println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x`
 }
 
 pub fn foo2() {
     let x: i32;
     for _ in 0..10 { x = continue; }
-    println!("{}", x); //~ ERROR borrow of possibly uninitialized variable: `x`
+    println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x`
 }
diff --git a/src/test/ui/issues/issue-24267-flow-exit.stderr b/src/test/ui/issues/issue-24267-flow-exit.stderr
index 3b4f27621f696..4eb41ca24ddfe 100644
--- a/src/test/ui/issues/issue-24267-flow-exit.stderr
+++ b/src/test/ui/issues/issue-24267-flow-exit.stderr
@@ -1,14 +1,14 @@
-error[E0381]: borrow of possibly uninitialized variable: `x`
+error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/issue-24267-flow-exit.rs:12:20
    |
 LL |     println!("{}", x);
-   |                    ^ use of possibly uninitialized `x`
+   |                    ^ use of possibly-uninitialized `x`
 
-error[E0381]: borrow of possibly uninitialized variable: `x`
+error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/issue-24267-flow-exit.rs:18:20
    |
 LL |     println!("{}", x);
-   |                    ^ use of possibly uninitialized `x`
+   |                    ^ use of possibly-uninitialized `x`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/loops/loop-proper-liveness.rs b/src/test/ui/loops/loop-proper-liveness.rs
index b8f76fbe57ba3..b242ec4296d66 100644
--- a/src/test/ui/loops/loop-proper-liveness.rs
+++ b/src/test/ui/loops/loop-proper-liveness.rs
@@ -6,7 +6,7 @@ fn test1() {
     'a: loop {
         x = loop { break 'a };
     }
-    println!("{:?}", x); //~ ERROR borrow of possibly uninitialized variable
+    println!("{:?}", x); //~ ERROR borrow of possibly-uninitialized variable
 }
 
 // test2 and test3 should not fail.
diff --git a/src/test/ui/loops/loop-proper-liveness.stderr b/src/test/ui/loops/loop-proper-liveness.stderr
index c87720659fd78..d55f9ff31e3ee 100644
--- a/src/test/ui/loops/loop-proper-liveness.stderr
+++ b/src/test/ui/loops/loop-proper-liveness.stderr
@@ -1,8 +1,8 @@
-error[E0381]: borrow of possibly uninitialized variable: `x`
+error[E0381]: borrow of possibly-uninitialized variable: `x`
   --> $DIR/loop-proper-liveness.rs:9:22
    |
 LL |     println!("{:?}", x);
-   |                      ^ use of possibly uninitialized `x`
+   |                      ^ use of possibly-uninitialized `x`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/missing/missing-semicolon-warning.stderr b/src/test/ui/missing/missing-semicolon-warning.stderr
index b3f3ebc855daa..b4001aba2882c 100644
--- a/src/test/ui/missing/missing-semicolon-warning.stderr
+++ b/src/test/ui/missing/missing-semicolon-warning.stderr
@@ -7,7 +7,7 @@ LL |         $( let x = $e1 )*;
 LL | fn main() { m!(0, 0; 0, 0); }
    |             --------------- in this macro invocation
    |
-   = note: This was erroneously allowed and will become a hard error in a future release
+   = note: this was erroneously allowed and will become a hard error in a future release
 
 warning: expected `;`, found `println`
   --> $DIR/missing-semicolon-warning.rs:7:12
@@ -18,5 +18,5 @@ LL |         $( println!("{}", $e2) )*;
 LL | fn main() { m!(0, 0; 0, 0); }
    |             --------------- in this macro invocation
    |
-   = note: This was erroneously allowed and will become a hard error in a future release
+   = note: this was erroneously allowed and will become a hard error in a future release
 
diff --git a/src/test/ui/moves/move-into-dead-array-1.rs b/src/test/ui/moves/move-into-dead-array-1.rs
index 16a18da4a44a3..2d0ff58526393 100644
--- a/src/test/ui/moves/move-into-dead-array-1.rs
+++ b/src/test/ui/moves/move-into-dead-array-1.rs
@@ -11,5 +11,5 @@ fn main() {
 
 fn foo(i: usize) {
     let mut a: [D; 4];
-    a[i] = d();        //~ ERROR use of possibly uninitialized variable: `a`
+    a[i] = d();        //~ ERROR use of possibly-uninitialized variable: `a`
 }
diff --git a/src/test/ui/moves/move-into-dead-array-1.stderr b/src/test/ui/moves/move-into-dead-array-1.stderr
index 33da0e54a1e4c..5f20ccfeddf48 100644
--- a/src/test/ui/moves/move-into-dead-array-1.stderr
+++ b/src/test/ui/moves/move-into-dead-array-1.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `a`
+error[E0381]: use of possibly-uninitialized variable: `a`
   --> $DIR/move-into-dead-array-1.rs:14:5
    |
 LL |     a[i] = d();
-   |     ^^^^ use of possibly uninitialized `a`
+   |     ^^^^ use of possibly-uninitialized `a`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs
index 906ea32b9c42d..1983e13db0afd 100644
--- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs
+++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs
@@ -26,13 +26,13 @@ impl Drop for D {
 fn cannot_partially_init_adt_with_drop() {
     let d: D;
     d.x = 10;
-    //~^ ERROR assign of possibly uninitialized variable: `d` [E0381]
+    //~^ ERROR assign of possibly-uninitialized variable: `d` [E0381]
 }
 
 fn cannot_partially_init_mutable_adt_with_drop() {
     let mut d: D;
     d.x = 10;
-    //~^ ERROR assign of possibly uninitialized variable: `d` [E0381]
+    //~^ ERROR assign of possibly-uninitialized variable: `d` [E0381]
 }
 
 fn cannot_partially_reinit_adt_with_drop() {
@@ -45,13 +45,13 @@ fn cannot_partially_reinit_adt_with_drop() {
 fn cannot_partially_init_inner_adt_via_outer_with_drop() {
     let d: D;
     d.s.y = 20;
-    //~^ ERROR assign to part of possibly uninitialized variable: `d` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `d` [E0381]
 }
 
 fn cannot_partially_init_inner_adt_via_mutable_outer_with_drop() {
     let mut d: D;
     d.s.y = 20;
-    //~^ ERROR assign to part of possibly uninitialized variable: `d` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `d` [E0381]
 }
 
 fn cannot_partially_reinit_inner_adt_via_outer_with_drop() {
diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr
index 153d9bdf3215d..1b66e034d3785 100644
--- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr
+++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr
@@ -1,14 +1,14 @@
-error[E0381]: assign of possibly uninitialized variable: `d`
+error[E0381]: assign of possibly-uninitialized variable: `d`
   --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:28:5
    |
 LL |     d.x = 10;
-   |     ^^^^^^^^ use of possibly uninitialized `d`
+   |     ^^^^^^^^ use of possibly-uninitialized `d`
 
-error[E0381]: assign of possibly uninitialized variable: `d`
+error[E0381]: assign of possibly-uninitialized variable: `d`
   --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:34:5
    |
 LL |     d.x = 10;
-   |     ^^^^^^^^ use of possibly uninitialized `d`
+   |     ^^^^^^^^ use of possibly-uninitialized `d`
 
 error[E0382]: assign of moved value: `d`
   --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:41:5
@@ -20,17 +20,17 @@ LL |     drop(d);
 LL |     d.x = 10;
    |     ^^^^^^^^ value assigned here after move
 
-error[E0381]: assign to part of possibly uninitialized variable: `d`
+error[E0381]: assign to part of possibly-uninitialized variable: `d`
   --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:47:5
    |
 LL |     d.s.y = 20;
-   |     ^^^^^^^^^^ use of possibly uninitialized `d.s`
+   |     ^^^^^^^^^^ use of possibly-uninitialized `d.s`
 
-error[E0381]: assign to part of possibly uninitialized variable: `d`
+error[E0381]: assign to part of possibly-uninitialized variable: `d`
   --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:53:5
    |
 LL |     d.s.y = 20;
-   |     ^^^^^^^^^^ use of possibly uninitialized `d.s`
+   |     ^^^^^^^^^^ use of possibly-uninitialized `d.s`
 
 error[E0382]: assign to part of moved value: `d`
   --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:60:5
diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-use.rs
index 633cbdba2d40e..7da47c85f5450 100644
--- a/src/test/ui/nll/issue-21232-partial-init-and-use.rs
+++ b/src/test/ui/nll/issue-21232-partial-init-and-use.rs
@@ -97,14 +97,14 @@ macro_rules! use_part {
 fn test_0000_local_fully_init_and_use_struct() {
     let s: S<B>;
     s.x = 10; s.y = Box::new(20);
-    //~^ ERROR assign to part of possibly uninitialized variable: `s` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `s` [E0381]
     use_fully!(struct s);
 }
 
 fn test_0001_local_fully_init_and_use_tuple() {
     let t: T;
     t.0 = 10; t.1 = Box::new(20);
-    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
     use_fully!(tuple t);
 }
 
@@ -125,14 +125,14 @@ fn test_0011_local_fully_reinit_and_use_tuple() {
 fn test_0100_local_partial_init_and_use_struct() {
     let s: S<B>;
     s.x = 10;
-    //~^ ERROR assign to part of possibly uninitialized variable: `s` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `s` [E0381]
     use_part!(struct s);
 }
 
 fn test_0101_local_partial_init_and_use_tuple() {
     let t: T;
     t.0 = 10;
-    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
     use_part!(tuple t);
 }
 
@@ -153,14 +153,14 @@ fn test_0111_local_partial_reinit_and_use_tuple() {
 fn test_0200_local_void_init_and_use_struct() {
     let s: S<Void>;
     s.x = 10;
-    //~^ ERROR assign to part of possibly uninitialized variable: `s` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `s` [E0381]
     use_part!(struct s);
 }
 
 fn test_0201_local_void_init_and_use_tuple() {
     let t: Tvoid;
     t.0 = 10;
-    //~^ ERROR assign to part of possibly uninitialized variable: `t` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381]
     use_part!(tuple t);
 }
 
@@ -176,14 +176,14 @@ fn test_0201_local_void_init_and_use_tuple() {
 fn test_1000_field_fully_init_and_use_struct() {
     let q: Q<S<B>>;
     q.r.f.x = 10; q.r.f.y = Box::new(20);
-    //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
     use_fully!(struct q.r.f);
 }
 
 fn test_1001_field_fully_init_and_use_tuple() {
     let q: Q<T>;
     q.r.f.0 = 10; q.r.f.1 = Box::new(20);
-    //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
     use_fully!(tuple q.r.f);
 }
 
@@ -204,14 +204,14 @@ fn test_1011_field_fully_reinit_and_use_tuple() {
 fn test_1100_field_partial_init_and_use_struct() {
     let q: Q<S<B>>;
     q.r.f.x = 10;
-    //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
     use_part!(struct q.r.f);
 }
 
 fn test_1101_field_partial_init_and_use_tuple() {
     let q: Q<T>;
     q.r.f.0 = 10;
-    //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
     use_part!(tuple q.r.f);
 }
 
@@ -232,14 +232,14 @@ fn test_1111_field_partial_reinit_and_use_tuple() {
 fn test_1200_field_void_init_and_use_struct() {
     let mut q: Q<S<Void>>;
     q.r.f.x = 10;
-    //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
     use_part!(struct q.r.f);
 }
 
 fn test_1201_field_void_init_and_use_tuple() {
     let mut q: Q<Tvoid>;
     q.r.f.0 = 10;
-    //~^ ERROR assign to part of possibly uninitialized variable: `q` [E0381]
+    //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381]
     use_part!(tuple q.r.f);
 }
 
diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr
index 1cdf728a5e604..32147898320c0 100644
--- a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr
+++ b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr
@@ -1,14 +1,14 @@
-error[E0381]: assign to part of possibly uninitialized variable: `s`
+error[E0381]: assign to part of possibly-uninitialized variable: `s`
   --> $DIR/issue-21232-partial-init-and-use.rs:99:5
    |
 LL |     s.x = 10; s.y = Box::new(20);
-   |     ^^^^^^^^ use of possibly uninitialized `s`
+   |     ^^^^^^^^ use of possibly-uninitialized `s`
 
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/issue-21232-partial-init-and-use.rs:106:5
    |
 LL |     t.0 = 10; t.1 = Box::new(20);
-   |     ^^^^^^^^ use of possibly uninitialized `t`
+   |     ^^^^^^^^ use of possibly-uninitialized `t`
 
 error[E0382]: assign to part of moved value: `s`
   --> $DIR/issue-21232-partial-init-and-use.rs:113:5
@@ -30,17 +30,17 @@ LL |     let mut t: T = (0, Box::new(0)); drop(t);
 LL |     t.0 = 10; t.1 = Box::new(20);
    |     ^^^^^^^^ value partially assigned here after move
 
-error[E0381]: assign to part of possibly uninitialized variable: `s`
+error[E0381]: assign to part of possibly-uninitialized variable: `s`
   --> $DIR/issue-21232-partial-init-and-use.rs:127:5
    |
 LL |     s.x = 10;
-   |     ^^^^^^^^ use of possibly uninitialized `s`
+   |     ^^^^^^^^ use of possibly-uninitialized `s`
 
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/issue-21232-partial-init-and-use.rs:134:5
    |
 LL |     t.0 = 10;
-   |     ^^^^^^^^ use of possibly uninitialized `t`
+   |     ^^^^^^^^ use of possibly-uninitialized `t`
 
 error[E0382]: assign to part of moved value: `s`
   --> $DIR/issue-21232-partial-init-and-use.rs:141:5
@@ -62,29 +62,29 @@ LL |     let mut t: T = (0, Box::new(0)); drop(t);
 LL |     t.0 = 10;
    |     ^^^^^^^^ value partially assigned here after move
 
-error[E0381]: assign to part of possibly uninitialized variable: `s`
+error[E0381]: assign to part of possibly-uninitialized variable: `s`
   --> $DIR/issue-21232-partial-init-and-use.rs:155:5
    |
 LL |     s.x = 10;
-   |     ^^^^^^^^ use of possibly uninitialized `s`
+   |     ^^^^^^^^ use of possibly-uninitialized `s`
 
-error[E0381]: assign to part of possibly uninitialized variable: `t`
+error[E0381]: assign to part of possibly-uninitialized variable: `t`
   --> $DIR/issue-21232-partial-init-and-use.rs:162:5
    |
 LL |     t.0 = 10;
-   |     ^^^^^^^^ use of possibly uninitialized `t`
+   |     ^^^^^^^^ use of possibly-uninitialized `t`
 
-error[E0381]: assign to part of possibly uninitialized variable: `q`
+error[E0381]: assign to part of possibly-uninitialized variable: `q`
   --> $DIR/issue-21232-partial-init-and-use.rs:178:5
    |
 LL |     q.r.f.x = 10; q.r.f.y = Box::new(20);
-   |     ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
 
-error[E0381]: assign to part of possibly uninitialized variable: `q`
+error[E0381]: assign to part of possibly-uninitialized variable: `q`
   --> $DIR/issue-21232-partial-init-and-use.rs:185:5
    |
 LL |     q.r.f.0 = 10; q.r.f.1 = Box::new(20);
-   |     ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
 
 error[E0382]: assign to part of moved value: `q.r`
   --> $DIR/issue-21232-partial-init-and-use.rs:192:5
@@ -106,17 +106,17 @@ LL |     q.r.f.0 = 10; q.r.f.1 = Box::new(20);
    |
    = note: move occurs because `q.r` has type `R<(u32, std::boxed::Box<u32>)>`, which does not implement the `Copy` trait
 
-error[E0381]: assign to part of possibly uninitialized variable: `q`
+error[E0381]: assign to part of possibly-uninitialized variable: `q`
   --> $DIR/issue-21232-partial-init-and-use.rs:206:5
    |
 LL |     q.r.f.x = 10;
-   |     ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
 
-error[E0381]: assign to part of possibly uninitialized variable: `q`
+error[E0381]: assign to part of possibly-uninitialized variable: `q`
   --> $DIR/issue-21232-partial-init-and-use.rs:213:5
    |
 LL |     q.r.f.0 = 10;
-   |     ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
 
 error[E0382]: assign to part of moved value: `q.r`
   --> $DIR/issue-21232-partial-init-and-use.rs:220:5
@@ -138,17 +138,17 @@ LL |     q.r.f.0 = 10;
    |
    = note: move occurs because `q.r` has type `R<(u32, std::boxed::Box<u32>)>`, which does not implement the `Copy` trait
 
-error[E0381]: assign to part of possibly uninitialized variable: `q`
+error[E0381]: assign to part of possibly-uninitialized variable: `q`
   --> $DIR/issue-21232-partial-init-and-use.rs:234:5
    |
 LL |     q.r.f.x = 10;
-   |     ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
 
-error[E0381]: assign to part of possibly uninitialized variable: `q`
+error[E0381]: assign to part of possibly-uninitialized variable: `q`
   --> $DIR/issue-21232-partial-init-and-use.rs:241:5
    |
 LL |     q.r.f.0 = 10;
-   |     ^^^^^^^^^^^^ use of possibly uninitialized `q.r.f`
+   |     ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f`
 
 error[E0382]: assign to part of moved value: `c`
   --> $DIR/issue-21232-partial-init-and-use.rs:259:13
diff --git a/src/test/ui/nll/match-cfg-fake-edges.rs b/src/test/ui/nll/match-cfg-fake-edges.rs
index 94e4a763866f6..5fc9966cdf807 100644
--- a/src/test/ui/nll/match-cfg-fake-edges.rs
+++ b/src/test/ui/nll/match-cfg-fake-edges.rs
@@ -20,7 +20,7 @@ fn guard_may_be_skipped(y: i32) {
     match y {
         _ if { x = 2; true } => 1,
         _ if {
-            x; //~ ERROR use of possibly uninitialized variable: `x`
+            x; //~ ERROR use of possibly-uninitialized variable: `x`
             false
         } => 2,
         _ => 3,
diff --git a/src/test/ui/nll/match-cfg-fake-edges.stderr b/src/test/ui/nll/match-cfg-fake-edges.stderr
index b1e0fa739769a..3d9037bbe7bf8 100644
--- a/src/test/ui/nll/match-cfg-fake-edges.stderr
+++ b/src/test/ui/nll/match-cfg-fake-edges.stderr
@@ -1,8 +1,8 @@
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/match-cfg-fake-edges.rs:23:13
    |
 LL |             x;
-   |             ^ use of possibly uninitialized `x`
+   |             ^ use of possibly-uninitialized `x`
 
 error[E0382]: use of moved value: `x`
   --> $DIR/match-cfg-fake-edges.rs:37:13
diff --git a/src/test/ui/nll/match-on-borrowed.stderr b/src/test/ui/nll/match-on-borrowed.stderr
index 9f804dfb3d7be..284a910a01b8a 100644
--- a/src/test/ui/nll/match-on-borrowed.stderr
+++ b/src/test/ui/nll/match-on-borrowed.stderr
@@ -34,11 +34,11 @@ LL |         true => (),
 LL |     x;
    |     - borrow later used here
 
-error[E0381]: use of possibly uninitialized variable: `n`
+error[E0381]: use of possibly-uninitialized variable: `n`
   --> $DIR/match-on-borrowed.rs:92:11
    |
 LL |     match n {}
-   |           ^ use of possibly uninitialized `n`
+   |           ^ use of possibly-uninitialized `n`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/parser/do-catch-suggests-try.rs b/src/test/ui/parser/do-catch-suggests-try.rs
index 61fae721ffbde..d805ab75882dd 100644
--- a/src/test/ui/parser/do-catch-suggests-try.rs
+++ b/src/test/ui/parser/do-catch-suggests-try.rs
@@ -1,5 +1,5 @@
 fn main() {
     let _: Option<()> = do catch {};
     //~^ ERROR found removed `do catch` syntax
-    //~^^ HELP Following RFC #2388, the new non-placeholder syntax is `try`
+    //~^^ HELP following RFC #2388, the new non-placeholder syntax is `try`
 }
diff --git a/src/test/ui/parser/do-catch-suggests-try.stderr b/src/test/ui/parser/do-catch-suggests-try.stderr
index 6d13b0f1cc872..e151d4cf8a6aa 100644
--- a/src/test/ui/parser/do-catch-suggests-try.stderr
+++ b/src/test/ui/parser/do-catch-suggests-try.stderr
@@ -4,7 +4,7 @@ error: found removed `do catch` syntax
 LL |     let _: Option<()> = do catch {};
    |                         ^^
    |
-   = help: Following RFC #2388, the new non-placeholder syntax is `try`
+   = help: following RFC #2388, the new non-placeholder syntax is `try`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
index 45910c3c3a8c6..f6b317886bfad 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.rs
@@ -6,7 +6,7 @@ fn foo(res: Result<u32, &R>) -> u32 {
     let Ok(x) = res;
     //~^ ERROR refutable pattern
     x
-    //~^ ERROR use of possibly uninitialized variable: `x`
+    //~^ ERROR use of possibly-uninitialized variable: `x`
 }
 
 fn main() {
diff --git a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
index eee331d95b9bc..b9385952fafa3 100644
--- a/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
+++ b/src/test/ui/recursion/recursive-types-are-not-uninhabited.stderr
@@ -4,11 +4,11 @@ error[E0005]: refutable pattern in local binding: `Err(_)` not covered
 LL |     let Ok(x) = res;
    |         ^^^^^ pattern `Err(_)` not covered
 
-error[E0381]: use of possibly uninitialized variable: `x`
+error[E0381]: use of possibly-uninitialized variable: `x`
   --> $DIR/recursive-types-are-not-uninhabited.rs:8:5
    |
 LL |     x
-   |     ^ use of possibly uninitialized `x`
+   |     ^ use of possibly-uninitialized `x`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/try-block/try-block-opt-init.rs b/src/test/ui/try-block/try-block-opt-init.rs
index 2387db8de4d6a..ef10b47fd1305 100644
--- a/src/test/ui/try-block/try-block-opt-init.rs
+++ b/src/test/ui/try-block/try-block-opt-init.rs
@@ -12,5 +12,5 @@ pub fn main() {
         Ok::<(), ()>(())?;
         use_val(cfg_res);
     };
-    assert_eq!(cfg_res, 5); //~ ERROR borrow of possibly uninitialized variable: `cfg_res`
+    assert_eq!(cfg_res, 5); //~ ERROR borrow of possibly-uninitialized variable: `cfg_res`
 }
diff --git a/src/test/ui/try-block/try-block-opt-init.stderr b/src/test/ui/try-block/try-block-opt-init.stderr
index ec0128dbdf0fc..308906477d914 100644
--- a/src/test/ui/try-block/try-block-opt-init.stderr
+++ b/src/test/ui/try-block/try-block-opt-init.stderr
@@ -1,8 +1,8 @@
-error[E0381]: borrow of possibly uninitialized variable: `cfg_res`
+error[E0381]: borrow of possibly-uninitialized variable: `cfg_res`
   --> $DIR/try-block-opt-init.rs:15:5
    |
 LL |     assert_eq!(cfg_res, 5);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ use of possibly uninitialized `cfg_res`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `cfg_res`
    |
    = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 

From 867ce769b6a27c8f359eb6573f5da8b34677d055 Mon Sep 17 00:00:00 2001
From: Shotaro Yamada <sinkuu@sinkuu.xyz>
Date: Fri, 6 Sep 2019 14:31:09 +0900
Subject: [PATCH 549/943] Make rustc_mir::dataflow module pub

---
 src/librustc_mir/dataflow/mod.rs | 18 +++++++++---------
 src/librustc_mir/lib.rs          |  2 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 7fe2a890a5371..c349cf4a47ba1 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -56,7 +56,7 @@ where
 /// string (as well as that of rendering up-front); in exchange, you
 /// don't have to hand over ownership of your value or deal with
 /// borrowing it.
-pub(crate) struct DebugFormatted(String);
+pub struct DebugFormatted(String);
 
 impl DebugFormatted {
     pub fn new(input: &dyn fmt::Debug) -> DebugFormatted {
@@ -70,7 +70,7 @@ impl fmt::Debug for DebugFormatted {
     }
 }
 
-pub(crate) trait Dataflow<'tcx, BD: BitDenotation<'tcx>> {
+pub trait Dataflow<'tcx, BD: BitDenotation<'tcx>> {
     /// Sets up and runs the dataflow problem, using `p` to render results if
     /// implementation so chooses.
     fn dataflow<P>(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted {
@@ -121,7 +121,7 @@ pub struct MoveDataParamEnv<'tcx> {
     pub(crate) param_env: ty::ParamEnv<'tcx>,
 }
 
-pub(crate) fn do_dataflow<'a, 'tcx, BD, P>(
+pub fn do_dataflow<'a, 'tcx, BD, P>(
     tcx: TyCtxt<'tcx>,
     body: &'a Body<'tcx>,
     def_id: DefId,
@@ -565,7 +565,7 @@ pub struct GenKill<T> {
     pub(crate) kill_set: T,
 }
 
-type GenKillSet<T> = GenKill<HybridBitSet<T>>;
+pub type GenKillSet<T> = GenKill<HybridBitSet<T>>;
 
 impl<T> GenKill<T> {
     /// Creates a new tuple where `gen_set == kill_set == elem`.
@@ -580,28 +580,28 @@ impl<T> GenKill<T> {
 }
 
 impl<E:Idx> GenKillSet<E> {
-    pub(crate) fn clear(&mut self) {
+    pub fn clear(&mut self) {
         self.gen_set.clear();
         self.kill_set.clear();
     }
 
-    fn gen(&mut self, e: E) {
+    pub fn gen(&mut self, e: E) {
         self.gen_set.insert(e);
         self.kill_set.remove(e);
     }
 
-    fn gen_all(&mut self, i: impl IntoIterator<Item: Borrow<E>>) {
+    pub fn gen_all(&mut self, i: impl IntoIterator<Item: Borrow<E>>) {
         for j in i {
             self.gen(*j.borrow());
         }
     }
 
-    fn kill(&mut self, e: E) {
+    pub fn kill(&mut self, e: E) {
         self.gen_set.remove(e);
         self.kill_set.insert(e);
     }
 
-    fn kill_all(&mut self, i: impl IntoIterator<Item: Borrow<E>>) {
+    pub fn kill_all(&mut self, i: impl IntoIterator<Item: Borrow<E>>) {
         for j in i {
             self.kill(*j.borrow());
         }
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index cccf7b9545bdb..2b6e42b33a2de 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -36,7 +36,7 @@ mod error_codes;
 
 mod borrow_check;
 mod build;
-mod dataflow;
+pub mod dataflow;
 mod hair;
 mod lints;
 mod shim;

From 0ca645ac5f88fcaed9c7b8246af1462a90fea5a1 Mon Sep 17 00:00:00 2001
From: Philipp Hansch <dev@phansch.net>
Date: Fri, 6 Sep 2019 07:34:55 +0200
Subject: [PATCH 550/943] annotate-snippet emitter: Update issue number

The tracking issue has been replaced by one with mentoring instructions.
---
 src/librustc_errors/annotate_snippet_emitter_writer.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs
index 3bed5d81dc514..50841236bb498 100644
--- a/src/librustc_errors/annotate_snippet_emitter_writer.rs
+++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs
@@ -105,7 +105,7 @@ impl<'a>  DiagnosticConverter<'a> {
         annotated_files: Vec<FileWithAnnotatedLines>,
         primary_lo: Loc
     ) -> Vec<Slice> {
-        // FIXME(#59346): Provide a test case where `annotated_files` is > 1
+        // FIXME(#64205): Provide a test case where `annotated_files` is > 1
         annotated_files.iter().flat_map(|annotated_file| {
             annotated_file.lines.iter().map(|line| {
                 let line_source = Self::source_string(annotated_file.file.clone(), &line);

From ba7d1b80d051f8004fa6a294e8331dcb33b85f6d Mon Sep 17 00:00:00 2001
From: Guanqun Lu <guanqun.lu@gmail.com>
Date: Fri, 6 Sep 2019 15:14:25 +0800
Subject: [PATCH 551/943] it's more pythonic to use 'is not None' in python
 files

---
 src/bootstrap/bootstrap.py       | 2 +-
 src/libcore/unicode/printable.py | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 4162fe1df5086..179cd488be732 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -668,7 +668,7 @@ def check_submodule(self, module, slow_submodules):
     def update_submodule(self, module, checked_out, recorded_submodules):
         module_path = os.path.join(self.rust_root, module)
 
-        if checked_out != None:
+        if checked_out is not None:
             default_encoding = sys.getdefaultencoding()
             checked_out = checked_out.communicate()[0].decode(default_encoding).strip()
             if recorded_submodules[module] == checked_out:
diff --git a/src/libcore/unicode/printable.py b/src/libcore/unicode/printable.py
index 748917f1d3420..4e8b4ecad0200 100644
--- a/src/libcore/unicode/printable.py
+++ b/src/libcore/unicode/printable.py
@@ -60,7 +60,7 @@ def get_codepoints(f):
         yield Codepoint(codepoint, class_)
         prev_codepoint = codepoint
 
-    if class_first != None:
+    if class_first is not None:
         raise ValueError("Missing Last after First")
 
     for c in range(prev_codepoint + 1, NUM_CODEPOINTS):

From 2d168fa74174b6dd02b718b90289bd79c6edf3ff Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Fri, 6 Sep 2019 10:35:14 +0200
Subject: [PATCH 552/943] mir borrowck: drive-by cleanup.

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

diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 8ded539e7205a..5c397ff3019db 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -164,8 +164,8 @@ fn do_mir_borrowck<'a, 'tcx>(
         };
 
     let mdpe = MoveDataParamEnv {
-        move_data: move_data,
-        param_env: param_env,
+        move_data,
+        param_env,
     };
 
     let dead_unwinds = BitSet::new_empty(body.basic_blocks().len());

From 055409538d601e905d72a08dd6c28256587fba3d Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Fri, 6 Sep 2019 10:39:38 +0200
Subject: [PATCH 553/943] Refuse to downgrade NLL errors on Rust >= 2018.

---
 src/librustc_mir/borrow_check/mod.rs                |  5 ++++-
 .../borrowck/borrowck-migrate-to-nll.edition.stderr | 13 ++++++-------
 src/test/ui/borrowck/borrowck-migrate-to-nll.rs     |  4 +++-
 .../borrowck/borrowck-migrate-to-nll.zflag.stderr   |  4 ++--
 4 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 5c397ff3019db..9ad7cbc478bb0 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -259,7 +259,10 @@ fn do_mir_borrowck<'a, 'tcx>(
         move_error_reported: BTreeMap::new(),
         uninitialized_error_reported: Default::default(),
         errors_buffer,
-        disable_error_downgrading: false,
+        // Only downgrade errors on Rust 2015 and refuse to do so on Rust 2018.
+        // FIXME(Centril): In Rust 1.40.0, refuse doing so on 2015 as well and
+        // proceed to throwing out the migration infrastructure.
+        disable_error_downgrading: body.span.rust_2018(),
         nonlexical_regioncx: regioncx,
         used_mut: Default::default(),
         used_mut_upvars: SmallVec::new(),
diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr
index a33a1d00a5786..58f2cadcc6573 100644
--- a/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr
+++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr
@@ -1,15 +1,14 @@
-warning[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-migrate-to-nll.rs:28:21
+error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-migrate-to-nll.rs:29:21
    |
 LL |     let x = &mut block;
    |             ---------- mutable borrow occurs here
 LL |     let p: &'a u8 = &*block.current;
    |                     ^^^^^^^^^^^^^^^ immutable borrow occurs here
-LL |     // (use `x` and `p` so enabling NLL doesn't assign overly short lifetimes)
+...
 LL |     drop(x);
    |          - mutable borrow later used here
-   |
-   = warning: this error has been downgraded to a warning for backwards compatibility with previous releases
-   = warning: this represents potential undefined behavior in your code and this warning will become a hard error in the future
-   = note: for more information, try `rustc --explain E0729`
 
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0502`.
diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs
index 6dda317e57efe..98fd5682277b3 100644
--- a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs
+++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs
@@ -4,6 +4,8 @@
 //
 // Therefore, for backwards-compatiblity, under borrowck=migrate the
 // NLL checks will be emitted as *warnings*.
+//
+// In Rust 2018, no errors will be downgraded to warnings.
 
 // NLL mode makes this compile-fail; we cannot currently encode a
 // test that is run-pass or compile-fail based on compare-mode. So
@@ -16,7 +18,6 @@
 //[zflag]compile-flags: -Z borrowck=migrate
 //[edition]edition:2018
 //[zflag] run-pass
-//[edition] run-pass
 
 pub struct Block<'a> {
     current: &'a u8,
@@ -26,6 +27,7 @@ pub struct Block<'a> {
 fn bump<'a>(mut block: &mut Block<'a>) {
     let x = &mut block;
     let p: &'a u8 = &*block.current;
+    //[edition]~^ ERROR cannot borrow `*block.current` as immutable
     // (use `x` and `p` so enabling NLL doesn't assign overly short lifetimes)
     drop(x);
     drop(p);
diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr
index a33a1d00a5786..ace336a3bf32a 100644
--- a/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr
+++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr
@@ -1,11 +1,11 @@
 warning[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-migrate-to-nll.rs:28:21
+  --> $DIR/borrowck-migrate-to-nll.rs:29:21
    |
 LL |     let x = &mut block;
    |             ---------- mutable borrow occurs here
 LL |     let p: &'a u8 = &*block.current;
    |                     ^^^^^^^^^^^^^^^ immutable borrow occurs here
-LL |     // (use `x` and `p` so enabling NLL doesn't assign overly short lifetimes)
+...
 LL |     drop(x);
    |          - mutable borrow later used here
    |

From 39bfb3626c04fe03d50864e13a6baeed1c0378f4 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Fri, 6 Sep 2019 11:10:53 +0200
Subject: [PATCH 554/943] Fix miri

---
 src/librustc/mir/interpret/allocation.rs | 28 ++++++++++++++++++++++++
 src/tools/miri                           |  2 +-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index df1d9a987011d..13552a61acb0e 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -130,6 +130,34 @@ impl<Tag> Allocation<Tag> {
     }
 }
 
+impl Allocation<()> {
+    /// Add Tag and Extra fields
+    pub fn retag<T, E>(
+        self,
+        mut tagger: impl FnMut(AllocId) -> T,
+        extra: E,
+    ) -> Allocation<T, E> {
+        Allocation {
+            bytes: self.bytes,
+            size: self.size,
+            relocations: Relocations::from_presorted(
+                self.relocations.iter()
+                    // The allocations in the relocations (pointers stored *inside* this allocation)
+                    // all get the base pointer tag.
+                    .map(|&(offset, ((), alloc))| {
+                        let tag = tagger(alloc);
+                        (offset, (tag, alloc))
+                    })
+                    .collect()
+            ),
+            undef_mask: self.undef_mask,
+            align: self.align,
+            mutability: self.mutability,
+            extra,
+        }
+    }
+}
+
 /// Raw accessors. Provide access to otherwise private bytes.
 impl<Tag, Extra> Allocation<Tag, Extra> {
     pub fn len(&self) -> usize {
diff --git a/src/tools/miri b/src/tools/miri
index 69268fb75fdb4..e479ab26406ed 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 69268fb75fdb452296caa9bc4aaeff1674279de2
+Subproject commit e479ab26406ed8a473987e5f4a1f3be3e978e5d2

From 32101ad3b38d29291a5150840e88aeef2fb911a1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= <matti@marinelayer.io>
Date: Thu, 22 Aug 2019 12:28:03 +0200
Subject: [PATCH 555/943] Upgrade rand to 0.7

---
 Cargo.lock                          | 13 +++++++------
 src/librustc_incremental/Cargo.toml |  2 +-
 src/libstd/Cargo.toml               |  2 +-
 src/libstd/fs.rs                    |  2 +-
 src/libstd/tests/env.rs             |  2 +-
 5 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 313fef1c086a8..43eb28168086a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1151,12 +1151,13 @@ dependencies = [
 
 [[package]]
 name = "getrandom"
-version = "0.1.8"
+version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34f33de6f0ae7c9cb5e574502a562e2b512799e32abb801cd1e79ad952b62b49"
+checksum = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571"
 dependencies = [
  "cfg-if",
  "libc",
+ "wasi",
 ]
 
 [[package]]
@@ -1583,9 +1584,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 
 [[package]]
 name = "libc"
-version = "0.2.61"
+version = "0.2.62"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c665266eb592905e8503ba3403020f4b8794d26263f412ca33171600eca9a6fa"
+checksum = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -3248,7 +3249,7 @@ version = "0.0.0"
 dependencies = [
  "graphviz",
  "log",
- "rand 0.6.1",
+ "rand 0.7.0",
  "rustc",
  "rustc_data_structures",
  "rustc_fs_util",
@@ -3864,7 +3865,7 @@ dependencies = [
  "panic_abort",
  "panic_unwind",
  "profiler_builtins",
- "rand 0.6.1",
+ "rand 0.7.0",
  "rustc_asan",
  "rustc_lsan",
  "rustc_msan",
diff --git a/src/librustc_incremental/Cargo.toml b/src/librustc_incremental/Cargo.toml
index a931ad3b66e21..659c4c89fe33c 100644
--- a/src/librustc_incremental/Cargo.toml
+++ b/src/librustc_incremental/Cargo.toml
@@ -12,7 +12,7 @@ doctest = false
 [dependencies]
 graphviz = { path = "../libgraphviz" }
 log = "0.4"
-rand = "0.6"
+rand = "0.7"
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 18a46cf0b5257..a34ab598aed94 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -38,7 +38,7 @@ features = [
 optional = true
 
 [dev-dependencies]
-rand = "0.6.1"
+rand = "0.7"
 
 [target.x86_64-apple-darwin.dependencies]
 rustc_asan = { path = "../librustc_asan" }
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 5f76875bd66c4..b14e02a2cb478 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -2144,7 +2144,7 @@ mod tests {
     use crate::sys_common::io::test::{TempDir, tmpdir};
     use crate::thread;
 
-    use rand::{rngs::StdRng, FromEntropy, RngCore};
+    use rand::{rngs::StdRng, RngCore, SeedableRng};
 
     #[cfg(windows)]
     use crate::os::windows::fs::{symlink_dir, symlink_file};
diff --git a/src/libstd/tests/env.rs b/src/libstd/tests/env.rs
index 06fb5533afdd8..f8014cb2ad9af 100644
--- a/src/libstd/tests/env.rs
+++ b/src/libstd/tests/env.rs
@@ -5,7 +5,7 @@ use rand::{thread_rng, Rng};
 use rand::distributions::Alphanumeric;
 
 fn make_rand_name() -> OsString {
-    let mut rng = thread_rng();
+    let rng = thread_rng();
     let n = format!("TEST{}", rng.sample_iter(&Alphanumeric).take(10)
                                  .collect::<String>());
     let n = OsString::from(n);

From 58ba1f51efab249411a932880e3c10d36355b166 Mon Sep 17 00:00:00 2001
From: Tim Vermeulen <tvermeulen@me.com>
Date: Fri, 28 Jun 2019 14:43:32 +0200
Subject: [PATCH 556/943] Add Iterator comparison methods that take a
 comparison function

---
 src/libcore/iter/traits/iterator.rs | 109 ++++++++++++++++++++++++++--
 src/libcore/tests/iter.rs           |  56 ++++++++++++++
 src/libcore/tests/lib.rs            |   1 +
 3 files changed, 160 insertions(+), 6 deletions(-)

diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs
index 8fd5fe0653eed..c09df3f7f22cb 100644
--- a/src/libcore/iter/traits/iterator.rs
+++ b/src/libcore/iter/traits/iterator.rs
@@ -2557,10 +2557,40 @@ pub trait Iterator {
     /// assert_eq!([1, 2].iter().cmp([1].iter()), Ordering::Greater);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
-    fn cmp<I>(mut self, other: I) -> Ordering where
+    fn cmp<I>(self, other: I) -> Ordering
+    where
         I: IntoIterator<Item = Self::Item>,
         Self::Item: Ord,
         Self: Sized,
+    {
+        self.cmp_by(other, |x, y| x.cmp(&y))
+    }
+
+    /// Lexicographically compares the elements of this `Iterator` with those
+    /// of another with respect to the specified comparison function.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(iter_order_by)]
+    ///
+    /// use std::cmp::Ordering;
+    ///
+    /// let xs = [1, 2, 3, 4];
+    /// let ys = [1, 4, 9, 16];
+    ///
+    /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| x.cmp(&y)), Ordering::Less);
+    /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (x * x).cmp(&y)), Ordering::Equal);
+    /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater);
+    /// ```
+    #[unstable(feature = "iter_order_by", issue = "0")]
+    fn cmp_by<I, F>(mut self, other: I, mut cmp: F) -> Ordering
+    where
+        Self: Sized,
+        I: IntoIterator,
+        F: FnMut(Self::Item, I::Item) -> Ordering,
     {
         let mut other = other.into_iter();
 
@@ -2579,7 +2609,7 @@ pub trait Iterator {
                 Some(val) => val,
             };
 
-            match x.cmp(&y) {
+            match cmp(x, y) {
                 Ordering::Equal => (),
                 non_eq => return non_eq,
             }
@@ -2601,10 +2631,49 @@ pub trait Iterator {
     /// assert_eq!([std::f64::NAN].iter().partial_cmp([1.].iter()), None);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
-    fn partial_cmp<I>(mut self, other: I) -> Option<Ordering> where
+    fn partial_cmp<I>(self, other: I) -> Option<Ordering>
+    where
         I: IntoIterator,
         Self::Item: PartialOrd<I::Item>,
         Self: Sized,
+    {
+        self.partial_cmp_by(other, |x, y| x.partial_cmp(&y))
+    }
+
+    /// Lexicographically compares the elements of this `Iterator` with those
+    /// of another with respect to the specified comparison function.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(iter_order_by)]
+    ///
+    /// use std::cmp::Ordering;
+    ///
+    /// let xs = [1.0, 2.0, 3.0, 4.0];
+    /// let ys = [1.0, 4.0, 9.0, 16.0];
+    ///
+    /// assert_eq!(
+    ///     xs.iter().partial_cmp_by(&ys, |&x, &y| x.partial_cmp(&y)),
+    ///     Some(Ordering::Less)
+    /// );
+    /// assert_eq!(
+    ///     xs.iter().partial_cmp_by(&ys, |&x, &y| (x * x).partial_cmp(&y)),
+    ///     Some(Ordering::Equal)
+    /// );
+    /// assert_eq!(
+    ///     xs.iter().partial_cmp_by(&ys, |&x, &y| (2.0 * x).partial_cmp(&y)),
+    ///     Some(Ordering::Greater)
+    /// );
+    /// ```
+    #[unstable(feature = "iter_order_by", issue = "0")]
+    fn partial_cmp_by<I, F>(mut self, other: I, mut partial_cmp: F) -> Option<Ordering>
+    where
+        Self: Sized,
+        I: IntoIterator,
+        F: FnMut(Self::Item, I::Item) -> Option<Ordering>,
     {
         let mut other = other.into_iter();
 
@@ -2623,7 +2692,7 @@ pub trait Iterator {
                 Some(val) => val,
             };
 
-            match x.partial_cmp(&y) {
+            match partial_cmp(x, y) {
                 Some(Ordering::Equal) => (),
                 non_eq => return non_eq,
             }
@@ -2640,10 +2709,36 @@ pub trait Iterator {
     /// assert_eq!([1].iter().eq([1, 2].iter()), false);
     /// ```
     #[stable(feature = "iter_order", since = "1.5.0")]
-    fn eq<I>(mut self, other: I) -> bool where
+    fn eq<I>(self, other: I) -> bool
+    where
         I: IntoIterator,
         Self::Item: PartialEq<I::Item>,
         Self: Sized,
+    {
+        self.eq_by(other, |x, y| x == y)
+    }
+
+    /// Determines if the elements of this `Iterator` are equal to those of
+    /// another with respect to the specified equality function.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// #![feature(iter_order_by)]
+    ///
+    /// let xs = [1, 2, 3, 4];
+    /// let ys = [1, 4, 9, 16];
+    ///
+    /// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y));
+    /// ```
+    #[unstable(feature = "iter_order_by", issue = "0")]
+    fn eq_by<I, F>(mut self, other: I, mut eq: F) -> bool
+    where
+        Self: Sized,
+        I: IntoIterator,
+        F: FnMut(Self::Item, I::Item) -> bool,
     {
         let mut other = other.into_iter();
 
@@ -2658,7 +2753,9 @@ pub trait Iterator {
                 Some(val) => val,
             };
 
-            if x != y { return false }
+            if !eq(x, y) {
+                return false;
+            }
         }
     }
 
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 8e0658d87c1fb..d7088cf891f77 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -57,6 +57,62 @@ fn test_multi_iter() {
     assert!(xs.iter().lt(xs.iter().skip(2)));
 }
 
+#[test]
+fn test_cmp_by() {
+    use core::cmp::Ordering;
+
+    let f = |x: i32, y: i32| (x * x).cmp(&y);
+    let xs = || [1, 2, 3, 4].iter().copied();
+    let ys = || [1, 4, 16].iter().copied();
+
+    assert_eq!(xs().cmp_by(ys(), f), Ordering::Less);
+    assert_eq!(ys().cmp_by(xs(), f), Ordering::Greater);
+    assert_eq!(xs().cmp_by(xs().map(|x| x * x), f), Ordering::Equal);
+    assert_eq!(xs().rev().cmp_by(ys().rev(), f), Ordering::Greater);
+    assert_eq!(xs().cmp_by(ys().rev(), f), Ordering::Less);
+    assert_eq!(xs().cmp_by(ys().take(2), f), Ordering::Greater);
+}
+
+#[test]
+fn test_partial_cmp_by() {
+    use core::cmp::Ordering;
+    use core::f64;
+
+    let f = |x: i32, y: i32| (x * x).partial_cmp(&y);
+    let xs = || [1, 2, 3, 4].iter().copied();
+    let ys = || [1, 4, 16].iter().copied();
+
+    assert_eq!(xs().partial_cmp_by(ys(), f), Some(Ordering::Less));
+    assert_eq!(ys().partial_cmp_by(xs(), f), Some(Ordering::Greater));
+    assert_eq!(xs().partial_cmp_by(xs().map(|x| x * x), f), Some(Ordering::Equal));
+    assert_eq!(xs().rev().partial_cmp_by(ys().rev(), f), Some(Ordering::Greater));
+    assert_eq!(xs().partial_cmp_by(xs().rev(), f), Some(Ordering::Less));
+    assert_eq!(xs().partial_cmp_by(ys().take(2), f), Some(Ordering::Greater));
+
+    let f = |x: f64, y: f64| (x * x).partial_cmp(&y);
+    let xs = || [1.0, 2.0, 3.0, 4.0].iter().copied();
+    let ys = || [1.0, 4.0, f64::NAN, 16.0].iter().copied();
+
+    assert_eq!(xs().partial_cmp_by(ys(), f), None);
+    assert_eq!(ys().partial_cmp_by(xs(), f), Some(Ordering::Greater));
+}
+
+#[test]
+fn test_eq_by() {
+    let f = |x: i32, y: i32| x * x == y;
+    let xs = || [1, 2, 3, 4].iter().copied();
+    let ys = || [1, 4, 9, 16].iter().copied();
+
+    assert!(xs().eq_by(ys(), f));
+    assert!(!ys().eq_by(xs(), f));
+    assert!(!xs().eq_by(xs(), f));
+    assert!(!ys().eq_by(ys(), f));
+
+    assert!(!xs().take(3).eq_by(ys(), f));
+    assert!(!xs().eq_by(ys().take(3), f));
+    assert!(xs().take(3).eq_by(ys().take(3), f));
+}
+
 #[test]
 fn test_counter_from_iter() {
     let it = (0..).step_by(5).take(10);
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index a3b108b2e9cea..3b4e47438e10a 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -32,6 +32,7 @@
 #![feature(const_fn)]
 #![feature(iter_partition_in_place)]
 #![feature(iter_is_partitioned)]
+#![feature(iter_order_by)]
 
 extern crate test;
 

From eedf555d0c041caa0a9e7c8cd4394716e637feaf Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Wed, 4 Sep 2019 15:21:46 +0300
Subject: [PATCH 557/943] rustc_codegen_llvm: give names to non-alloca variable
 values.

---
 src/librustc_codegen_llvm/debuginfo/mod.rs   | 35 ++++++++++++++++++--
 src/librustc_codegen_llvm/llvm/ffi.rs        |  2 ++
 src/librustc_codegen_ssa/mir/mod.rs          | 16 ++++-----
 src/librustc_codegen_ssa/mir/statement.rs    | 16 ++++++++-
 src/librustc_codegen_ssa/traits/debuginfo.rs |  2 +-
 src/test/codegen/var-names.rs                | 15 +++++++++
 6 files changed, 73 insertions(+), 13 deletions(-)
 create mode 100644 src/test/codegen/var-names.rs

diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index cad2bcdc05fc9..6dedf10f0ab83 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -32,7 +32,7 @@ use rustc_codegen_ssa::debuginfo::{FunctionDebugContext, MirDebugScope, Variable
 
 use libc::c_uint;
 use std::cell::RefCell;
-use std::ffi::CString;
+use std::ffi::{CStr, CString};
 
 use syntax_pos::{self, Span, Pos};
 use syntax::ast;
@@ -224,8 +224,37 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         gdb::insert_reference_to_gdb_debug_scripts_section_global(self)
     }
 
-    fn set_value_name(&mut self, value: &'ll Value, name: &str) {
-        let cname = SmallCStr::new(name);
+    fn set_var_name(&mut self, value: &'ll Value, name: impl ToString) {
+        // Avoid wasting time if LLVM value names aren't even enabled.
+        if self.sess().fewer_names() {
+            return;
+        }
+
+        // Only function parameters and instructions are local to a function,
+        // don't change the name of anything else (e.g. globals).
+        let param_or_inst = unsafe {
+            llvm::LLVMIsAArgument(value).is_some() ||
+            llvm::LLVMIsAInstruction(value).is_some()
+        };
+        if !param_or_inst {
+            return;
+        }
+
+        let old_name = unsafe {
+            CStr::from_ptr(llvm::LLVMGetValueName(value))
+        };
+        match old_name.to_str() {
+            Ok("") => {}
+            Ok(_) => {
+                // Avoid replacing the name if it already exists.
+                // While we could combine the names somehow, it'd
+                // get noisy quick, and the usefulness is dubious.
+                return;
+            }
+            Err(_) => return,
+        }
+
+        let cname = CString::new(name.to_string()).unwrap();
         unsafe {
             llvm::LLVMSetValueName(value, cname.as_ptr());
         }
diff --git a/src/librustc_codegen_llvm/llvm/ffi.rs b/src/librustc_codegen_llvm/llvm/ffi.rs
index 9f9410560e373..b07214fdc03f3 100644
--- a/src/librustc_codegen_llvm/llvm/ffi.rs
+++ b/src/librustc_codegen_llvm/llvm/ffi.rs
@@ -806,6 +806,7 @@ extern "C" {
     pub fn LLVMRustRemoveFunctionAttributes(Fn: &Value, index: c_uint, attr: Attribute);
 
     // Operations on parameters
+    pub fn LLVMIsAArgument(Val: &Value) -> Option<&Value>;
     pub fn LLVMCountParams(Fn: &Value) -> c_uint;
     pub fn LLVMGetParam(Fn: &Value, Index: c_uint) -> &Value;
 
@@ -818,6 +819,7 @@ extern "C" {
     pub fn LLVMDeleteBasicBlock(BB: &BasicBlock);
 
     // Operations on instructions
+    pub fn LLVMIsAInstruction(Val: &Value) -> Option<&Value>;
     pub fn LLVMGetFirstBasicBlock(Fn: &Value) -> &BasicBlock;
 
     // Operations on call sites
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index 8acb3ba06267e..00e9ca01f4dd2 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -518,19 +518,19 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 PassMode::Ignore(IgnoreMode::CVarArgs) => {}
                 PassMode::Direct(_) => {
                     let llarg = bx.get_param(llarg_idx);
-                    bx.set_value_name(llarg, &name);
+                    bx.set_var_name(llarg, &name);
                     llarg_idx += 1;
                     return local(
                         OperandRef::from_immediate_or_packed_pair(bx, llarg, arg.layout));
                 }
                 PassMode::Pair(..) => {
-                    let a = bx.get_param(llarg_idx);
-                    bx.set_value_name(a, &(name.clone() + ".0"));
-                    llarg_idx += 1;
+                    let (a, b) = (bx.get_param(llarg_idx), bx.get_param(llarg_idx + 1));
+                    llarg_idx += 2;
 
-                    let b = bx.get_param(llarg_idx);
-                    bx.set_value_name(b, &(name + ".1"));
-                    llarg_idx += 1;
+                    // FIXME(eddyb) these are scalar components,
+                    // maybe extract the high-level fields?
+                    bx.set_var_name(a, format_args!("{}.0", name));
+                    bx.set_var_name(b, format_args!("{}.1", name));
 
                     return local(OperandRef {
                         val: OperandValue::Pair(a, b),
@@ -546,7 +546,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             // already put it in a temporary alloca and gave it up.
             // FIXME: lifetimes
             let llarg = bx.get_param(llarg_idx);
-            bx.set_value_name(llarg, &name);
+            bx.set_var_name(llarg, &name);
             llarg_idx += 1;
             PlaceRef::new_sized(llarg, arg.layout)
         } else if arg.is_unsized_indirect() {
diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs
index 3617f3afaae41..594f45c833758 100644
--- a/src/librustc_codegen_ssa/mir/statement.rs
+++ b/src/librustc_codegen_ssa/mir/statement.rs
@@ -29,7 +29,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             self.codegen_rvalue_unsized(bx, cg_indirect_dest, rvalue)
                         }
                         LocalRef::Operand(None) => {
-                            let (bx, operand) = self.codegen_rvalue_operand(bx, rvalue);
+                            let (mut bx, operand) = self.codegen_rvalue_operand(bx, rvalue);
+                            if let Some(name) = self.mir.local_decls[index].name {
+                                match operand.val {
+                                    OperandValue::Ref(x, ..) |
+                                    OperandValue::Immediate(x) => {
+                                        bx.set_var_name(x, name);
+                                    }
+                                    OperandValue::Pair(a, b) => {
+                                        // FIXME(eddyb) these are scalar components,
+                                        // maybe extract the high-level fields?
+                                        bx.set_var_name(a, format_args!("{}.0", name));
+                                        bx.set_var_name(b, format_args!("{}.1", name));
+                                    }
+                                }
+                            }
                             self.locals[index] = LocalRef::Operand(Some(operand));
                             bx
                         }
diff --git a/src/librustc_codegen_ssa/traits/debuginfo.rs b/src/librustc_codegen_ssa/traits/debuginfo.rs
index be2fa7279aa7c..9c16b864ef21d 100644
--- a/src/librustc_codegen_ssa/traits/debuginfo.rs
+++ b/src/librustc_codegen_ssa/traits/debuginfo.rs
@@ -57,5 +57,5 @@ pub trait DebugInfoBuilderMethods<'tcx>: BackendTypes {
         span: Span,
     );
     fn insert_reference_to_gdb_debug_scripts_section_global(&mut self);
-    fn set_value_name(&mut self, value: Self::Value, name: &str);
+    fn set_var_name(&mut self, value: Self::Value, name: impl ToString);
 }
diff --git a/src/test/codegen/var-names.rs b/src/test/codegen/var-names.rs
new file mode 100644
index 0000000000000..3140a7c6b6cc2
--- /dev/null
+++ b/src/test/codegen/var-names.rs
@@ -0,0 +1,15 @@
+// compile-flags: -O -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: define i32 @test(i32 %a, i32 %b)
+#[no_mangle]
+pub fn test(a: u32, b: u32) -> u32 {
+    let c = a + b;
+    // CHECK: %c = add i32 %a, %b
+    let d = c;
+    let e = d * a;
+    // CHECK-NEXT: %e = mul i32 %c, %a
+    e
+    // CHECK-NEXT: ret i32 %e
+}

From b0006dff1041f0eea718ca29607cd6ec372e4e30 Mon Sep 17 00:00:00 2001
From: Alexander Regueiro <alexreg@me.com>
Date: Thu, 5 Sep 2019 17:15:28 +0100
Subject: [PATCH 558/943] A few cosmetic improvements to code & comments in
 liballoc and libcore

---
 src/liballoc/collections/linked_list/tests.rs |   4 +-
 src/liballoc/raw_vec.rs                       | 150 +++++++++---------
 src/liballoc/raw_vec/tests.rs                 |   6 +-
 src/liballoc/rc.rs                            |   2 +-
 src/liballoc/sync.rs                          |   2 +-
 src/libcore/any.rs                            |   6 +-
 src/libcore/marker.rs                         |   4 +-
 src/libcore/ptr/mod.rs                        |   4 +-
 src/libcore/ptr/non_null.rs                   |   2 +-
 src/libstd/env.rs                             |   2 +-
 src/libstd/error.rs                           |  34 ++--
 src/libstd/ffi/c_str.rs                       |   2 +-
 src/libstd/process.rs                         |   2 +-
 13 files changed, 109 insertions(+), 111 deletions(-)

diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs
index 9a6c57d286970..ecb5948f11b36 100644
--- a/src/liballoc/collections/linked_list/tests.rs
+++ b/src/liballoc/collections/linked_list/tests.rs
@@ -102,8 +102,8 @@ fn test_append() {
         assert_eq!(m.pop_front(), Some(elt))
     }
     assert_eq!(n.len(), 0);
-    // let's make sure it's working properly, since we
-    // did some direct changes to private members
+    // Let's make sure it's working properly, since we
+    // did some direct changes to private members.
     n.push_back(3);
     assert_eq!(n.len(), 1);
     assert_eq!(n.pop_front(), Some(3));
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index bc8a38f6b3aad..f1c5904afe6fc 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -19,26 +19,26 @@ mod tests;
 /// involved. This type is excellent for building your own data structures like Vec and VecDeque.
 /// In particular:
 ///
-/// * Produces Unique::empty() on zero-sized types
-/// * Produces Unique::empty() on zero-length allocations
-/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics)
-/// * Guards against 32-bit systems allocating more than isize::MAX bytes
-/// * Guards against overflowing your length
-/// * Aborts on OOM or calls handle_alloc_error as applicable
-/// * Avoids freeing Unique::empty()
-/// * Contains a ptr::Unique and thus endows the user with all related benefits
+/// * Produces `Unique::empty()` on zero-sized types.
+/// * Produces `Unique::empty()` on zero-length allocations.
+/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics).
+/// * Guards against 32-bit systems allocating more than isize::MAX bytes.
+/// * Guards against overflowing your length.
+/// * Aborts on OOM or calls `handle_alloc_error` as applicable.
+/// * Avoids freeing `Unique::empty()`.
+/// * Contains a `ptr::Unique` and thus endows the user with all related benefits.
 ///
 /// This type does not in anyway inspect the memory that it manages. When dropped it *will*
-/// free its memory, but it *won't* try to Drop its contents. It is up to the user of RawVec
-/// to handle the actual things *stored* inside of a RawVec.
+/// free its memory, but it *won't* try to drop its contents. It is up to the user of `RawVec`
+/// to handle the actual things *stored* inside of a `RawVec`.
 ///
-/// Note that a RawVec always forces its capacity to be usize::MAX for zero-sized types.
-/// This enables you to use capacity growing logic catch the overflows in your length
+/// Note that a `RawVec` always forces its capacity to be `usize::MAX` for zero-sized types.
+/// This enables you to use capacity-growing logic catch the overflows in your length
 /// that might occur with zero-sized types.
 ///
-/// However this means that you need to be careful when round-tripping this type
-/// with a `Box<[T]>`: `capacity()` won't yield the len. However `with_capacity`,
-/// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity
+/// The above means that you need to be careful when round-tripping this type with a
+/// `Box<[T]>`, since `capacity()` won't yield the length. However, `with_capacity`,
+/// `shrink_to_fit`, and `from_box` will actually set `RawVec`'s private capacity
 /// field. This allows zero-sized types to not be special-cased by consumers of
 /// this type.
 #[allow(missing_debug_implementations)]
@@ -49,14 +49,14 @@ pub struct RawVec<T, A: Alloc = Global> {
 }
 
 impl<T, A: Alloc> RawVec<T, A> {
-    /// Like `new` but parameterized over the choice of allocator for
-    /// the returned RawVec.
+    /// Like `new`, but parameterized over the choice of allocator for
+    /// the returned `RawVec`.
     pub const fn new_in(a: A) -> Self {
-        // !0 is usize::MAX. This branch should be stripped at compile time.
-        // FIXME(mark-i-m): use this line when `if`s are allowed in `const`
+        // `!0` is `usize::MAX`. This branch should be stripped at compile time.
+        // FIXME(mark-i-m): use this line when `if`s are allowed in `const`:
         //let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
 
-        // Unique::empty() doubles as "unallocated" and "zero-sized allocation"
+        // `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
         RawVec {
             ptr: Unique::empty(),
             // FIXME(mark-i-m): use `cap` when ifs are allowed in const
@@ -65,15 +65,15 @@ impl<T, A: Alloc> RawVec<T, A> {
         }
     }
 
-    /// Like `with_capacity` but parameterized over the choice of
-    /// allocator for the returned RawVec.
+    /// Like `with_capacity`, but parameterized over the choice of
+    /// allocator for the returned `RawVec`.
     #[inline]
     pub fn with_capacity_in(capacity: usize, a: A) -> Self {
         RawVec::allocate_in(capacity, false, a)
     }
 
-    /// Like `with_capacity_zeroed` but parameterized over the choice
-    /// of allocator for the returned RawVec.
+    /// Like `with_capacity_zeroed`, but parameterized over the choice
+    /// of allocator for the returned `RawVec`.
     #[inline]
     pub fn with_capacity_zeroed_in(capacity: usize, a: A) -> Self {
         RawVec::allocate_in(capacity, true, a)
@@ -86,7 +86,7 @@ impl<T, A: Alloc> RawVec<T, A> {
             let alloc_size = capacity.checked_mul(elem_size).unwrap_or_else(|| capacity_overflow());
             alloc_guard(alloc_size).unwrap_or_else(|_| capacity_overflow());
 
-            // handles ZSTs and `capacity = 0` alike
+            // Handles ZSTs and `capacity == 0` alike.
             let ptr = if alloc_size == 0 {
                 NonNull::<T>::dangling()
             } else {
@@ -113,20 +113,20 @@ impl<T, A: Alloc> RawVec<T, A> {
 }
 
 impl<T> RawVec<T, Global> {
-    /// Creates the biggest possible RawVec (on the system heap)
-    /// without allocating. If T has positive size, then this makes a
-    /// RawVec with capacity 0. If T has 0 size, then it makes a
-    /// RawVec with capacity `usize::MAX`. Useful for implementing
+    /// Creates the biggest possible `RawVec` (on the system heap)
+    /// without allocating. If `T` has positive size, then this makes a
+    /// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a
+    /// `RawVec` with capacity `usize::MAX`. Useful for implementing
     /// delayed allocation.
     pub const fn new() -> Self {
         Self::new_in(Global)
     }
 
-    /// Creates a RawVec (on the system heap) with exactly the
+    /// Creates a `RawVec` (on the system heap) with exactly the
     /// capacity and alignment requirements for a `[T; capacity]`. This is
-    /// equivalent to calling RawVec::new when `capacity` is 0 or T is
+    /// equivalent to calling `RawVec::new` when `capacity` is `0` or `T` is
     /// zero-sized. Note that if `T` is zero-sized this means you will
-    /// *not* get a RawVec with the requested capacity!
+    /// *not* get a `RawVec` with the requested capacity.
     ///
     /// # Panics
     ///
@@ -136,13 +136,13 @@ impl<T> RawVec<T, Global> {
     ///
     /// # Aborts
     ///
-    /// Aborts on OOM
+    /// Aborts on OOM.
     #[inline]
     pub fn with_capacity(capacity: usize) -> Self {
         RawVec::allocate_in(capacity, false, Global)
     }
 
-    /// Like `with_capacity` but guarantees the buffer is zeroed.
+    /// Like `with_capacity`, but guarantees the buffer is zeroed.
     #[inline]
     pub fn with_capacity_zeroed(capacity: usize) -> Self {
         RawVec::allocate_in(capacity, true, Global)
@@ -150,13 +150,13 @@ impl<T> RawVec<T, Global> {
 }
 
 impl<T, A: Alloc> RawVec<T, A> {
-    /// Reconstitutes a RawVec from a pointer, capacity, and allocator.
+    /// Reconstitutes a `RawVec` from a pointer, capacity, and allocator.
     ///
     /// # Undefined Behavior
     ///
-    /// The ptr must be allocated (via the given allocator `a`), and with the given capacity. The
-    /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems).
-    /// If the ptr and capacity come from a RawVec created via `a`, then this is guaranteed.
+    /// The `ptr` must be allocated (via the given allocator `a`), and with the given `capacity`.
+    /// The `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems).
+    /// If the `ptr` and `capacity` come from a `RawVec` created via `a`, then this is guaranteed.
     pub unsafe fn from_raw_parts_in(ptr: *mut T, capacity: usize, a: A) -> Self {
         RawVec {
             ptr: Unique::new_unchecked(ptr),
@@ -167,13 +167,13 @@ impl<T, A: Alloc> RawVec<T, A> {
 }
 
 impl<T> RawVec<T, Global> {
-    /// Reconstitutes a RawVec from a pointer, capacity.
+    /// Reconstitutes a `RawVec` from a pointer and capacity.
     ///
     /// # Undefined Behavior
     ///
-    /// The ptr must be allocated (on the system heap), and with the given capacity. The
-    /// capacity cannot exceed `isize::MAX` (only a concern on 32-bit systems).
-    /// If the ptr and capacity come from a RawVec, then this is guaranteed.
+    /// The `ptr` must be allocated (on the system heap), and with the given `capacity`.
+    /// Th `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems).
+    /// If the `ptr` and `capacity` come from a `RawVec`, then this is guaranteed.
     pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self {
         RawVec {
             ptr: Unique::new_unchecked(ptr),
@@ -194,7 +194,7 @@ impl<T> RawVec<T, Global> {
 
 impl<T, A: Alloc> RawVec<T, A> {
     /// Gets a raw pointer to the start of the allocation. Note that this is
-    /// Unique::empty() if `capacity = 0` or T is zero-sized. In the former case, you must
+    /// `Unique::empty()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
     /// be careful.
     pub fn ptr(&self) -> *mut T {
         self.ptr.as_ptr()
@@ -212,12 +212,12 @@ impl<T, A: Alloc> RawVec<T, A> {
         }
     }
 
-    /// Returns a shared reference to the allocator backing this RawVec.
+    /// Returns a shared reference to the allocator backing this `RawVec`.
     pub fn alloc(&self) -> &A {
         &self.a
     }
 
-    /// Returns a mutable reference to the allocator backing this RawVec.
+    /// Returns a mutable reference to the allocator backing this `RawVec`.
     pub fn alloc_mut(&mut self) -> &mut A {
         &mut self.a
     }
@@ -247,7 +247,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     ///
     /// # Panics
     ///
-    /// * Panics if T is zero-sized on the assumption that you managed to exhaust
+    /// * Panics if `T` is zero-sized on the assumption that you managed to exhaust
     ///   all `usize::MAX` slots in your imaginary buffer.
     /// * Panics on 32-bit platforms if the requested capacity exceeds
     ///   `isize::MAX` bytes.
@@ -290,20 +290,20 @@ impl<T, A: Alloc> RawVec<T, A> {
         unsafe {
             let elem_size = mem::size_of::<T>();
 
-            // since we set the capacity to usize::MAX when elem_size is
-            // 0, getting to here necessarily means the RawVec is overfull.
+            // Since we set the capacity to `usize::MAX` when `elem_size` is
+            // 0, getting to here necessarily means the `RawVec` is overfull.
             assert!(elem_size != 0, "capacity overflow");
 
             let (new_cap, uniq) = match self.current_layout() {
                 Some(cur) => {
                     // Since we guarantee that we never allocate more than
-                    // isize::MAX bytes, `elem_size * self.cap <= isize::MAX` as
+                    // `isize::MAX` bytes, `elem_size * self.cap <= isize::MAX` as
                     // a precondition, so this can't overflow. Additionally the
                     // alignment will never be too large as to "not be
                     // satisfiable", so `Layout::from_size_align` will always
                     // return `Some`.
                     //
-                    // tl;dr; we bypass runtime checks due to dynamic assertions
+                    // TL;DR, we bypass runtime checks due to dynamic assertions
                     // in this module, allowing us to use
                     // `from_size_align_unchecked`.
                     let new_cap = 2 * self.cap;
@@ -320,8 +320,8 @@ impl<T, A: Alloc> RawVec<T, A> {
                     }
                 }
                 None => {
-                    // skip to 4 because tiny Vec's are dumb; but not if that
-                    // would cause overflow
+                    // Skip to 4 because tiny `Vec`'s are dumb; but not if that
+                    // would cause overflow.
                     let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 };
                     match self.a.alloc_array::<T>(new_cap) {
                         Ok(ptr) => (new_cap, ptr.into()),
@@ -342,7 +342,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     ///
     /// # Panics
     ///
-    /// * Panics if T is zero-sized on the assumption that you managed to exhaust
+    /// * Panics if `T` is zero-sized on the assumption that you managed to exhaust
     ///   all `usize::MAX` slots in your imaginary buffer.
     /// * Panics on 32-bit platforms if the requested capacity exceeds
     ///   `isize::MAX` bytes.
@@ -356,15 +356,15 @@ impl<T, A: Alloc> RawVec<T, A> {
                 None => return false, // nothing to double
             };
 
-            // since we set the capacity to usize::MAX when elem_size is
-            // 0, getting to here necessarily means the RawVec is overfull.
+            // Since we set the capacity to `usize::MAX` when `elem_size` is
+            // 0, getting to here necessarily means the `RawVec` is overfull.
             assert!(elem_size != 0, "capacity overflow");
 
-            // Since we guarantee that we never allocate more than isize::MAX
+            // Since we guarantee that we never allocate more than `isize::MAX`
             // bytes, `elem_size * self.cap <= isize::MAX` as a precondition, so
             // this can't overflow.
             //
-            // Similarly like with `double` above we can go straight to
+            // Similarly to with `double` above, we can go straight to
             // `Layout::from_size_align_unchecked` as we know this won't
             // overflow and the alignment is sufficiently small.
             let new_cap = 2 * self.cap;
@@ -409,7 +409,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     ///
     /// # Aborts
     ///
-    /// Aborts on OOM
+    /// Aborts on OOM.
     pub fn reserve_exact(&mut self, used_capacity: usize, needed_extra_capacity: usize) {
         match self.reserve_internal(used_capacity, needed_extra_capacity, Infallible, Exact) {
             Err(CapacityOverflow) => capacity_overflow(),
@@ -424,7 +424,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     fn amortized_new_size(&self, used_capacity: usize, needed_extra_capacity: usize)
         -> Result<usize, TryReserveError> {
 
-        // Nothing we can really do about these checks :(
+        // Nothing we can really do about these checks, sadly.
         let required_cap = used_capacity.checked_add(needed_extra_capacity)
             .ok_or(CapacityOverflow)?;
         // Cannot overflow, because `cap <= isize::MAX`, and type of `cap` is `usize`.
@@ -459,7 +459,7 @@ impl<T, A: Alloc> RawVec<T, A> {
     ///
     /// # Aborts
     ///
-    /// Aborts on OOM
+    /// Aborts on OOM.
     ///
     /// # Examples
     ///
@@ -538,7 +538,7 @@ impl<T, A: Alloc> RawVec<T, A> {
 
             // Here, `cap < used_capacity + needed_extra_capacity <= new_cap`
             // (regardless of whether `self.cap - used_capacity` wrapped).
-            // Therefore we can safely call grow_in_place.
+            // Therefore, we can safely call `grow_in_place`.
 
             let new_layout = Layout::new::<T>().repeat(new_cap).unwrap().0;
             // FIXME: may crash and burn on over-reserve
@@ -576,14 +576,14 @@ impl<T, A: Alloc> RawVec<T, A> {
             return;
         }
 
-        // This check is my waterloo; it's the only thing Vec wouldn't have to do.
+        // This check is my waterloo; it's the only thing `Vec` wouldn't have to do.
         assert!(self.cap >= amount, "Tried to shrink to a larger capacity");
 
         if amount == 0 {
             // We want to create a new zero-length vector within the
-            // same allocator.  We use ptr::write to avoid an
+            // same allocator. We use `ptr::write` to avoid an
             // erroneous attempt to drop the contents, and we use
-            // ptr::read to sidestep condition against destructuring
+            // `ptr::read` to sidestep condition against destructuring
             // types that implement Drop.
 
             unsafe {
@@ -600,7 +600,7 @@ impl<T, A: Alloc> RawVec<T, A> {
                 //
                 // We also know that `self.cap` is greater than `amount`, and
                 // consequently we don't need runtime checks for creating either
-                // layout
+                // layout.
                 let old_size = elem_size * self.cap;
                 let new_size = elem_size * amount;
                 let align = mem::align_of::<T>();
@@ -653,7 +653,7 @@ impl<T, A: Alloc> RawVec<T, A> {
                 return Ok(());
             }
 
-            // Nothing we can really do about these checks :(
+            // Nothing we can really do about these checks, sadly.
             let new_cap = match strategy {
                 Exact => used_capacity.checked_add(needed_extra_capacity).ok_or(CapacityOverflow)?,
                 Amortized => self.amortized_new_size(used_capacity, needed_extra_capacity)?,
@@ -692,7 +692,7 @@ impl<T> RawVec<T, Global> {
     /// Converts the entire buffer into `Box<[T]>`.
     ///
     /// Note that this will correctly reconstitute any `cap` changes
-    /// that may have been performed. (see description of type for details)
+    /// that may have been performed. (See description of type for details.)
     ///
     /// # Undefined Behavior
     ///
@@ -700,7 +700,7 @@ impl<T> RawVec<T, Global> {
     /// the rules around uninitialized boxed values are not finalized yet,
     /// but until they are, it is advisable to avoid them.
     pub unsafe fn into_box(self) -> Box<[T]> {
-        // NOTE: not calling `capacity()` here, actually using the real `cap` field!
+        // NOTE: not calling `capacity()` here; actually using the real `cap` field!
         let slice = slice::from_raw_parts_mut(self.ptr(), self.cap);
         let output: Box<[T]> = Box::from_raw(slice);
         mem::forget(self);
@@ -709,7 +709,7 @@ impl<T> RawVec<T, Global> {
 }
 
 impl<T, A: Alloc> RawVec<T, A> {
-    /// Frees the memory owned by the RawVec *without* trying to Drop its contents.
+    /// Frees the memory owned by the `RawVec` *without* trying to drop its contents.
     pub unsafe fn dealloc_buffer(&mut self) {
         let elem_size = mem::size_of::<T>();
         if elem_size != 0 {
@@ -721,22 +721,20 @@ impl<T, A: Alloc> RawVec<T, A> {
 }
 
 unsafe impl<#[may_dangle] T, A: Alloc> Drop for RawVec<T, A> {
-    /// Frees the memory owned by the RawVec *without* trying to Drop its contents.
+    /// Frees the memory owned by the `RawVec` *without* trying to drop its contents.
     fn drop(&mut self) {
         unsafe { self.dealloc_buffer(); }
     }
 }
 
-
-
 // We need to guarantee the following:
-// * We don't ever allocate `> isize::MAX` byte-size objects
-// * We don't overflow `usize::MAX` and actually allocate too little
+// * We don't ever allocate `> isize::MAX` byte-size objects.
+// * We don't overflow `usize::MAX` and actually allocate too little.
 //
 // On 64-bit we just need to check for overflow since trying to allocate
 // `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add
 // an extra guard for this in case we're running on a platform which can use
-// all 4GB in user-space. e.g., PAE or x32
+// all 4GB in user-space, e.g., PAE or x32.
 
 #[inline]
 fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
@@ -751,5 +749,5 @@ fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
 // ensure that the code generation related to these panics is minimal as there's
 // only one location which panics rather than a bunch throughout the module.
 fn capacity_overflow() -> ! {
-    panic!("capacity overflow")
+    panic!("capacity overflow");
 }
diff --git a/src/liballoc/raw_vec/tests.rs b/src/liballoc/raw_vec/tests.rs
index c389898d1ef04..d35b62fc1ef15 100644
--- a/src/liballoc/raw_vec/tests.rs
+++ b/src/liballoc/raw_vec/tests.rs
@@ -5,12 +5,12 @@ fn allocator_param() {
     use crate::alloc::AllocErr;
 
     // Writing a test of integration between third-party
-    // allocators and RawVec is a little tricky because the RawVec
+    // allocators and `RawVec` is a little tricky because the `RawVec`
     // API does not expose fallible allocation methods, so we
     // cannot check what happens when allocator is exhausted
     // (beyond detecting a panic).
     //
-    // Instead, this just checks that the RawVec methods do at
+    // Instead, this just checks that the `RawVec` methods do at
     // least go through the Allocator API when it reserves
     // storage.
 
@@ -44,7 +44,7 @@ fn allocator_param() {
 fn reserve_does_not_overallocate() {
     {
         let mut v: RawVec<u32> = RawVec::new();
-        // First `reserve` allocates like `reserve_exact`
+        // First, `reserve` allocates like `reserve_exact`.
         v.reserve(0, 9);
         assert_eq!(9, v.capacity());
     }
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 2b222caf13f3d..439f24e95ca0d 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -567,7 +567,7 @@ impl<T: ?Sized> Rc<T> {
     ///     let x = Rc::from_raw(x_ptr);
     ///     assert_eq!(&*x, "hello");
     ///
-    ///     // Further calls to `Rc::from_raw(x_ptr)` would be memory unsafe.
+    ///     // Further calls to `Rc::from_raw(x_ptr)` would be memory-unsafe.
     /// }
     ///
     /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs
index 9ffc1673e5ab8..3bf22a87feaa7 100644
--- a/src/liballoc/sync.rs
+++ b/src/liballoc/sync.rs
@@ -547,7 +547,7 @@ impl<T: ?Sized> Arc<T> {
     ///     let x = Arc::from_raw(x_ptr);
     ///     assert_eq!(&*x, "hello");
     ///
-    ///     // Further calls to `Arc::from_raw(x_ptr)` would be memory unsafe.
+    ///     // Further calls to `Arc::from_raw(x_ptr)` would be memory-unsafe.
     /// }
     ///
     /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index e8a0a88f12a7e..0afbf4f134679 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -153,13 +153,13 @@ impl dyn Any {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is<T: Any>(&self) -> bool {
-        // Get TypeId of the type this function is instantiated with
+        // Get `TypeId` of the type this function is instantiated with.
         let t = TypeId::of::<T>();
 
-        // Get TypeId of the type in the trait object
+        // Get `TypeId` of the type in the trait object.
         let concrete = self.type_id();
 
-        // Compare both TypeIds on equality
+        // Compare both `TypeId`s on equality.
         t == concrete
     }
 
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index 89af2528c052a..347e7dce6e67d 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -602,10 +602,10 @@ unsafe impl<T: ?Sized> Freeze for *mut T {}
 unsafe impl<T: ?Sized> Freeze for &T {}
 unsafe impl<T: ?Sized> Freeze for &mut T {}
 
-/// Types which can be safely moved after being pinned.
+/// Types that can be safely moved after being pinned.
 ///
 /// Since Rust itself has no notion of immovable types, and considers moves
-/// (e.g. through assignment or [`mem::replace`]) to always be safe,
+/// (e.g., through assignment or [`mem::replace`]) to always be safe,
 /// this trait cannot prevent types from moving by itself.
 ///
 /// Instead it is used to prevent moves through the type system,
diff --git a/src/libcore/ptr/mod.rs b/src/libcore/ptr/mod.rs
index f5fbd1a6b1325..13ccc9b252a77 100644
--- a/src/libcore/ptr/mod.rs
+++ b/src/libcore/ptr/mod.rs
@@ -1042,7 +1042,7 @@ impl<T: ?Sized> *const T {
         (self as *const u8) == null()
     }
 
-    /// Cast to a pointer to a different type
+    /// Casts to a pointer of another type.
     #[stable(feature = "ptr_cast", since = "1.38.0")]
     #[inline]
     pub const fn cast<U>(self) -> *const U {
@@ -1726,7 +1726,7 @@ impl<T: ?Sized> *mut T {
         (self as *mut u8) == null_mut()
     }
 
-    /// Cast to a pointer to a different type
+    /// Casts to a pointer of another type.
     #[stable(feature = "ptr_cast", since = "1.38.0")]
     #[inline]
     pub const fn cast<U>(self) -> *mut U {
diff --git a/src/libcore/ptr/non_null.rs b/src/libcore/ptr/non_null.rs
index ad3d1ce396ab7..7dcd57f1f9858 100644
--- a/src/libcore/ptr/non_null.rs
+++ b/src/libcore/ptr/non_null.rs
@@ -125,7 +125,7 @@ impl<T: ?Sized> NonNull<T> {
         &mut *self.as_ptr()
     }
 
-    /// Cast to a pointer of another type
+    /// Casts to a pointer of another type.
     #[stable(feature = "nonnull_cast", since = "1.27.0")]
     #[inline]
     pub const fn cast<U>(self) -> NonNull<U> {
diff --git a/src/libstd/env.rs b/src/libstd/env.rs
index eca93399e5807..b89893692698c 100644
--- a/src/libstd/env.rs
+++ b/src/libstd/env.rs
@@ -290,7 +290,7 @@ impl Error for VarError {
 ///
 /// Note that while concurrent access to environment variables is safe in Rust,
 /// some platforms only expose inherently unsafe non-threadsafe APIs for
-/// inspecting the environment. As a result extra care needs to be taken when
+/// inspecting the environment. As a result, extra care needs to be taken when
 /// auditing calls to unsafe external FFI functions to ensure that any external
 /// environment accesses are properly synchronized with accesses in Rust.
 ///
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 117a430eec6b9..19a77a48d9a48 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -196,10 +196,10 @@ pub trait Error: Debug + Display {
     #[stable(feature = "error_source", since = "1.30.0")]
     fn source(&self) -> Option<&(dyn Error + 'static)> { None }
 
-    /// Gets the `TypeId` of `self`
+    /// Gets the `TypeId` of `self`.
     #[doc(hidden)]
     #[unstable(feature = "error_type_id",
-               reason = "this is memory unsafe to override in user code",
+               reason = "this is memory-unsafe to override in user code",
                issue = "60784")]
     fn type_id(&self, _: private::Internal) -> TypeId where Self: 'static {
         TypeId::of::<Self>()
@@ -601,19 +601,19 @@ impl Error for char::ParseCharError {
     }
 }
 
-// copied from any.rs
+// Copied from `any.rs`.
 impl dyn Error + 'static {
     /// Returns `true` if the boxed type is the same as `T`
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn is<T: Error + 'static>(&self) -> bool {
-        // Get TypeId of the type this function is instantiated with
+        // Get `TypeId` of the type this function is instantiated with.
         let t = TypeId::of::<T>();
 
-        // Get TypeId of the type in the trait object
+        // Get `TypeId` of the type in the trait object.
         let boxed = self.type_id(private::Internal);
 
-        // Compare both TypeIds on equality
+        // Compare both `TypeId`s on equality.
         t == boxed
     }
 
@@ -647,21 +647,21 @@ impl dyn Error + 'static {
 }
 
 impl dyn Error + 'static + Send {
-    /// Forwards to the method defined on the type `Any`.
+    /// Forwards to the method defined on the type `dyn Error`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn is<T: Error + 'static>(&self) -> bool {
         <dyn Error + 'static>::is::<T>(self)
     }
 
-    /// Forwards to the method defined on the type `Any`.
+    /// Forwards to the method defined on the type `dyn Error`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
         <dyn Error + 'static>::downcast_ref::<T>(self)
     }
 
-    /// Forwards to the method defined on the type `Any`.
+    /// Forwards to the method defined on the type `dyn Error`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
@@ -670,21 +670,21 @@ impl dyn Error + 'static + Send {
 }
 
 impl dyn Error + 'static + Send + Sync {
-    /// Forwards to the method defined on the type `Any`.
+    /// Forwards to the method defined on the type `dyn Error`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn is<T: Error + 'static>(&self) -> bool {
         <dyn Error + 'static>::is::<T>(self)
     }
 
-    /// Forwards to the method defined on the type `Any`.
+    /// Forwards to the method defined on the type `dyn Error`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
         <dyn Error + 'static>::downcast_ref::<T>(self)
     }
 
-    /// Forwards to the method defined on the type `Any`.
+    /// Forwards to the method defined on the type `dyn Error`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
@@ -695,7 +695,7 @@ impl dyn Error + 'static + Send + Sync {
 impl dyn Error {
     #[inline]
     #[stable(feature = "error_downcast", since = "1.3.0")]
-    /// Attempt to downcast the box to a concrete type.
+    /// Attempts to downcast the box to a concrete type.
     pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {
         if self.is::<T>() {
             unsafe {
@@ -863,12 +863,12 @@ impl<'a> Iterator for ErrorIter<'a> {
 impl dyn Error + Send {
     #[inline]
     #[stable(feature = "error_downcast", since = "1.3.0")]
-    /// Attempt to downcast the box to a concrete type.
+    /// Attempts to downcast the box to a concrete type.
     pub fn downcast<T: Error + 'static>(self: Box<Self>)
                                         -> Result<Box<T>, Box<dyn Error + Send>> {
         let err: Box<dyn Error> = self;
         <dyn Error>::downcast(err).map_err(|s| unsafe {
-            // reapply the Send marker
+            // Reapply the `Send` marker.
             transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
         })
     }
@@ -877,12 +877,12 @@ impl dyn Error + Send {
 impl dyn Error + Send + Sync {
     #[inline]
     #[stable(feature = "error_downcast", since = "1.3.0")]
-    /// Attempt to downcast the box to a concrete type.
+    /// Attempts to downcast the box to a concrete type.
     pub fn downcast<T: Error + 'static>(self: Box<Self>)
                                         -> Result<Box<T>, Box<Self>> {
         let err: Box<dyn Error> = self;
         <dyn Error>::downcast(err).map_err(|s| unsafe {
-            // reapply the Send+Sync marker
+            // Reapply the `Send + Sync` marker.
             transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
         })
     }
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 65f4e0cafe09e..3ce2b68d858eb 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -615,7 +615,7 @@ impl CString {
 }
 
 // Turns this `CString` into an empty string to prevent
-// memory unsafe code from working by accident. Inline
+// memory-unsafe code from working by accident. Inline
 // to prevent LLVM from optimizing it away in debug builds.
 #[stable(feature = "cstring_drop", since = "1.13.0")]
 impl Drop for CString {
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 000f80f99e7a9..c50025ab7d1de 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -1595,7 +1595,7 @@ pub fn id() -> u32 {
 
 /// A trait for implementing arbitrary return types in the `main` function.
 ///
-/// The c-main function only supports to return integers as return type.
+/// The C-main function only supports to return integers as return type.
 /// So, every type implementing the `Termination` trait has to be converted
 /// to an integer.
 ///

From e1d27eb73cc2f318157f744d8175e1ef0340ff52 Mon Sep 17 00:00:00 2001
From: Shiqing <shiqing-thu18@yandex.com>
Date: Sat, 7 Sep 2019 00:16:11 +0800
Subject: [PATCH 559/943] Reduce span to function name in unreachable calls

---
 src/librustc_typeck/check/expr.rs                  | 4 ++++
 src/test/ui/never-assign-dead-code.stderr          | 4 ++--
 src/test/ui/reachable/expr_call.stderr             | 4 ++--
 src/test/ui/reachable/expr_method.stderr           | 6 +++---
 src/test/ui/unreachable/unreachable-in-call.rs     | 2 +-
 src/test/ui/unreachable/unreachable-in-call.stderr | 8 +++-----
 6 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 9644815f805d9..da72dfd155182 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -161,6 +161,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Warn for non-block expressions with diverging children.
         match expr.node {
             ExprKind::Block(..) | ExprKind::Loop(..) | ExprKind::Match(..) => {},
+            ExprKind::Call(ref callee, _) =>
+                self.warn_if_unreachable(expr.hir_id, callee.span, "call"),
+            ExprKind::MethodCall(_, ref span, _) =>
+                self.warn_if_unreachable(expr.hir_id, *span, "call"),
             _ => self.warn_if_unreachable(expr.hir_id, expr.span, "expression"),
         }
 
diff --git a/src/test/ui/never-assign-dead-code.stderr b/src/test/ui/never-assign-dead-code.stderr
index 779780a90a81d..b1b5bf03fe52a 100644
--- a/src/test/ui/never-assign-dead-code.stderr
+++ b/src/test/ui/never-assign-dead-code.stderr
@@ -11,11 +11,11 @@ LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]`
 
-warning: unreachable expression
+warning: unreachable call
   --> $DIR/never-assign-dead-code.rs:10:5
    |
 LL |     drop(x);
-   |     ^^^^^^^
+   |     ^^^^
 
 warning: unused variable: `x`
   --> $DIR/never-assign-dead-code.rs:9:9
diff --git a/src/test/ui/reachable/expr_call.stderr b/src/test/ui/reachable/expr_call.stderr
index df5cff16f9a46..f2db17e4dfe8e 100644
--- a/src/test/ui/reachable/expr_call.stderr
+++ b/src/test/ui/reachable/expr_call.stderr
@@ -10,11 +10,11 @@ note: lint level defined here
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: unreachable expression
+error: unreachable call
   --> $DIR/expr_call.rs:18:5
    |
 LL |     bar(return);
-   |     ^^^^^^^^^^^
+   |     ^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/reachable/expr_method.stderr b/src/test/ui/reachable/expr_method.stderr
index bbfa2ef529add..947ea0fee889c 100644
--- a/src/test/ui/reachable/expr_method.stderr
+++ b/src/test/ui/reachable/expr_method.stderr
@@ -10,11 +10,11 @@ note: lint level defined here
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: unreachable expression
-  --> $DIR/expr_method.rs:21:5
+error: unreachable call
+  --> $DIR/expr_method.rs:21:9
    |
 LL |     Foo.bar(return);
-   |     ^^^^^^^^^^^^^^^
+   |         ^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unreachable/unreachable-in-call.rs b/src/test/ui/unreachable/unreachable-in-call.rs
index 25f849d7a0a91..dd94e79f4d84c 100644
--- a/src/test/ui/unreachable/unreachable-in-call.rs
+++ b/src/test/ui/unreachable/unreachable-in-call.rs
@@ -14,7 +14,7 @@ fn diverge_first() {
          get_u8()); //~ ERROR unreachable expression
 }
 fn diverge_second() {
-    call( //~ ERROR unreachable expression
+    call( //~ ERROR unreachable call
         get_u8(),
         diverge());
 }
diff --git a/src/test/ui/unreachable/unreachable-in-call.stderr b/src/test/ui/unreachable/unreachable-in-call.stderr
index f8dd54590f6ae..c740011c4a125 100644
--- a/src/test/ui/unreachable/unreachable-in-call.stderr
+++ b/src/test/ui/unreachable/unreachable-in-call.stderr
@@ -10,13 +10,11 @@ note: lint level defined here
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
 
-error: unreachable expression
+error: unreachable call
   --> $DIR/unreachable-in-call.rs:17:5
    |
-LL | /     call(
-LL | |         get_u8(),
-LL | |         diverge());
-   | |__________________^
+LL |     call(
+   |     ^^^^
 
 error: aborting due to 2 previous errors
 

From 10f46b69bc32bd1cb5f013ce904957aeb28603bb Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Fri, 6 Sep 2019 18:02:12 +0100
Subject: [PATCH 560/943] Move the HIR cfg to `rustc_ast_borrowck`

No new code should be using it.
---
 src/librustc/lib.rs                           |  1 -
 src/librustc_ast_borrowck/borrowck/mod.rs     |  2 +-
 .../borrowck/move_data.rs                     |  2 +-
 .../cfg/construct.rs                          | 12 +++----
 .../cfg/graphviz.rs                           | 11 +++----
 .../cfg/mod.rs                                | 31 ++++++++-----------
 src/librustc_ast_borrowck/dataflow.rs         |  5 ++-
 src/librustc_ast_borrowck/graphviz.rs         |  7 ++---
 src/librustc_ast_borrowck/lib.rs              |  1 +
 src/librustc_driver/pretty.rs                 |  3 +-
 10 files changed, 32 insertions(+), 43 deletions(-)
 rename src/{librustc => librustc_ast_borrowck}/cfg/construct.rs (98%)
 rename src/{librustc => librustc_ast_borrowck}/cfg/graphviz.rs (94%)
 rename src/{librustc => librustc_ast_borrowck}/cfg/mod.rs (51%)

diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 368f5bb64fe6c..bf4330a29a7df 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -97,7 +97,6 @@ pub mod query;
 
 #[macro_use]
 pub mod arena;
-pub mod cfg;
 pub mod dep_graph;
 pub mod hir;
 pub mod ich;
diff --git a/src/librustc_ast_borrowck/borrowck/mod.rs b/src/librustc_ast_borrowck/borrowck/mod.rs
index 3bbd7ae5c352f..23d5480c60562 100644
--- a/src/librustc_ast_borrowck/borrowck/mod.rs
+++ b/src/librustc_ast_borrowck/borrowck/mod.rs
@@ -9,7 +9,6 @@ use InteriorKind::*;
 
 use rustc::hir::HirId;
 use rustc::hir::Node;
-use rustc::cfg;
 use rustc::middle::borrowck::{BorrowCheckResult, SignalledError};
 use rustc::hir::def_id::{DefId, LocalDefId};
 use rustc::middle::mem_categorization as mc;
@@ -28,6 +27,7 @@ use log::debug;
 
 use rustc::hir;
 
+use crate::cfg;
 use crate::dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom};
 
 pub mod check_loans;
diff --git a/src/librustc_ast_borrowck/borrowck/move_data.rs b/src/librustc_ast_borrowck/borrowck/move_data.rs
index 887a0e2f20e16..67d818161b1b5 100644
--- a/src/librustc_ast_borrowck/borrowck/move_data.rs
+++ b/src/librustc_ast_borrowck/borrowck/move_data.rs
@@ -4,7 +4,7 @@
 use crate::dataflow::{DataFlowContext, BitwiseOperator, DataFlowOperator, KillFrom};
 
 use crate::borrowck::*;
-use rustc::cfg;
+use crate::cfg;
 use rustc::ty::{self, TyCtxt};
 use rustc::util::nodemap::FxHashMap;
 
diff --git a/src/librustc/cfg/construct.rs b/src/librustc_ast_borrowck/cfg/construct.rs
similarity index 98%
rename from src/librustc/cfg/construct.rs
rename to src/librustc_ast_borrowck/cfg/construct.rs
index 0dad2dda837b5..339d92145c64f 100644
--- a/src/librustc/cfg/construct.rs
+++ b/src/librustc_ast_borrowck/cfg/construct.rs
@@ -1,11 +1,11 @@
 use crate::cfg::*;
-use crate::middle::region;
 use rustc_data_structures::graph::implementation as graph;
-use crate::ty::{self, TyCtxt};
+use rustc::middle::region;
+use rustc::ty::{self, TyCtxt};
 
-use crate::hir::{self, PatKind};
-use crate::hir::def_id::DefId;
-use crate::hir::ptr::P;
+use rustc::hir::{self, PatKind};
+use rustc::hir::def_id::DefId;
+use rustc::hir::ptr::P;
 
 struct CFGBuilder<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -30,7 +30,7 @@ struct LoopScope {
     break_index: CFGIndex,    // where to go on a `break`
 }
 
-pub fn construct(tcx: TyCtxt<'_>, body: &hir::Body) -> CFG {
+pub(super) fn construct(tcx: TyCtxt<'_>, body: &hir::Body) -> CFG {
     let mut graph = graph::Graph::new();
     let entry = graph.add_node(CFGNodeData::Entry);
 
diff --git a/src/librustc/cfg/graphviz.rs b/src/librustc_ast_borrowck/cfg/graphviz.rs
similarity index 94%
rename from src/librustc/cfg/graphviz.rs
rename to src/librustc_ast_borrowck/cfg/graphviz.rs
index 918120057d4d3..46409f1a1cebf 100644
--- a/src/librustc/cfg/graphviz.rs
+++ b/src/librustc_ast_borrowck/cfg/graphviz.rs
@@ -1,15 +1,12 @@
 /// This module provides linkage between rustc::middle::graph and
 /// libgraphviz traits.
 
-// For clarity, rename the graphviz crate locally to dot.
-use graphviz as dot;
-
 use crate::cfg;
-use crate::hir;
-use crate::ty::TyCtxt;
+use rustc::hir;
+use rustc::ty::TyCtxt;
 
-pub type Node<'a> = (cfg::CFGIndex, &'a cfg::CFGNode);
-pub type Edge<'a> = &'a cfg::CFGEdge;
+pub(crate) type Node<'a> = (cfg::CFGIndex, &'a cfg::CFGNode);
+pub(crate) type Edge<'a> = &'a cfg::CFGEdge;
 
 pub struct LabelledCFG<'a, 'tcx> {
     pub tcx: TyCtxt<'tcx>,
diff --git a/src/librustc/cfg/mod.rs b/src/librustc_ast_borrowck/cfg/mod.rs
similarity index 51%
rename from src/librustc/cfg/mod.rs
rename to src/librustc_ast_borrowck/cfg/mod.rs
index 88fc7fbfad51f..981199c91d513 100644
--- a/src/librustc/cfg/mod.rs
+++ b/src/librustc_ast_borrowck/cfg/mod.rs
@@ -2,18 +2,18 @@
 //! Uses `Graph` as the underlying representation.
 
 use rustc_data_structures::graph::implementation as graph;
-use crate::ty::TyCtxt;
-use crate::hir;
-use crate::hir::def_id::DefId;
+use rustc::ty::TyCtxt;
+use rustc::hir;
+use rustc::hir::def_id::DefId;
 
 mod construct;
 pub mod graphviz;
 
 pub struct CFG {
-    pub owner_def_id: DefId,
-    pub graph: CFGGraph,
-    pub entry: CFGIndex,
-    pub exit: CFGIndex,
+    owner_def_id: DefId,
+    pub(crate) graph: CFGGraph,
+    pub(crate) entry: CFGIndex,
+    exit: CFGIndex,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq)]
@@ -26,7 +26,7 @@ pub enum CFGNodeData {
 }
 
 impl CFGNodeData {
-    pub fn id(&self) -> hir::ItemLocalId {
+    pub(crate) fn id(&self) -> hir::ItemLocalId {
         if let CFGNodeData::AST(id) = *self {
             id
         } else {
@@ -37,24 +37,19 @@ impl CFGNodeData {
 
 #[derive(Debug)]
 pub struct CFGEdgeData {
-    pub exiting_scopes: Vec<hir::ItemLocalId>
+    pub(crate) exiting_scopes: Vec<hir::ItemLocalId>
 }
 
-pub type CFGIndex = graph::NodeIndex;
+pub(crate) type CFGIndex = graph::NodeIndex;
 
-pub type CFGGraph = graph::Graph<CFGNodeData, CFGEdgeData>;
+pub(crate) type CFGGraph = graph::Graph<CFGNodeData, CFGEdgeData>;
 
-pub type CFGNode = graph::Node<CFGNodeData>;
+pub(crate) type CFGNode = graph::Node<CFGNodeData>;
 
-pub type CFGEdge = graph::Edge<CFGEdgeData>;
+pub(crate) type CFGEdge = graph::Edge<CFGEdgeData>;
 
 impl CFG {
     pub fn new(tcx: TyCtxt<'_>, body: &hir::Body) -> CFG {
         construct::construct(tcx, body)
     }
-
-    pub fn node_is_reachable(&self, id: hir::ItemLocalId) -> bool {
-        self.graph.depth_traverse(self.entry, graph::OUTGOING)
-                  .any(|idx| self.graph.node_data(idx).id() == id)
-    }
 }
diff --git a/src/librustc_ast_borrowck/dataflow.rs b/src/librustc_ast_borrowck/dataflow.rs
index 3a4c8c924764e..a8562901d99c5 100644
--- a/src/librustc_ast_borrowck/dataflow.rs
+++ b/src/librustc_ast_borrowck/dataflow.rs
@@ -3,9 +3,7 @@
 //! and thus uses bitvectors. Your job is simply to specify the so-called
 //! GEN and KILL bits for each expression.
 
-use rustc::cfg;
-use rustc::cfg::CFGIndex;
-use rustc::ty::TyCtxt;
+use crate::cfg::{self, CFGIndex};
 use std::mem;
 use std::usize;
 use log::debug;
@@ -16,6 +14,7 @@ use rustc::util::nodemap::FxHashMap;
 use rustc::hir;
 use rustc::hir::intravisit;
 use rustc::hir::print as pprust;
+use rustc::ty::TyCtxt;
 
 #[derive(Copy, Clone, Debug)]
 pub enum EntryOrExit {
diff --git a/src/librustc_ast_borrowck/graphviz.rs b/src/librustc_ast_borrowck/graphviz.rs
index 7a8a23ca76afc..c077dc828aba2 100644
--- a/src/librustc_ast_borrowck/graphviz.rs
+++ b/src/librustc_ast_borrowck/graphviz.rs
@@ -4,13 +4,12 @@
 
 pub use Variant::*;
 
-pub use rustc::cfg::graphviz::{Node, Edge};
-use rustc::cfg::graphviz as cfg_dot;
-
+pub(crate) use crate::cfg::graphviz::{Node, Edge};
+use crate::cfg::graphviz as cfg_dot;
+use crate::cfg::CFGIndex;
 use crate::borrowck::{self, BorrowckCtxt, LoanPath};
 use crate::dataflow::{DataFlowOperator, DataFlowContext, EntryOrExit};
 use log::debug;
-use rustc::cfg::CFGIndex;
 use std::rc::Rc;
 
 #[derive(Debug, Copy, Clone)]
diff --git a/src/librustc_ast_borrowck/lib.rs b/src/librustc_ast_borrowck/lib.rs
index dc818278a4b74..aea97fea1a9fd 100644
--- a/src/librustc_ast_borrowck/lib.rs
+++ b/src/librustc_ast_borrowck/lib.rs
@@ -18,5 +18,6 @@ mod borrowck;
 pub mod graphviz;
 
 mod dataflow;
+pub mod cfg;
 
 pub use borrowck::provide;
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index cb17401f6247b..c4d3ad946f9f6 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -1,7 +1,5 @@
 //! The various pretty-printing routines.
 
-use rustc::cfg;
-use rustc::cfg::graphviz::LabelledCFG;
 use rustc::hir;
 use rustc::hir::map as hir_map;
 use rustc::hir::map::blocks;
@@ -14,6 +12,7 @@ use rustc::util::common::ErrorReported;
 use rustc_interface::util::ReplaceBodyWithLoop;
 use rustc_ast_borrowck as borrowck;
 use rustc_ast_borrowck::graphviz as borrowck_dot;
+use rustc_ast_borrowck::cfg::{self, graphviz::LabelledCFG};
 use rustc_mir::util::{write_mir_pretty, write_mir_graphviz};
 
 use syntax::ast;

From 8ddbe7660fa6297193fe81e50f5d342a16cb06b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= <matti@marinelayer.io>
Date: Thu, 29 Aug 2019 13:22:21 +0200
Subject: [PATCH 561/943] Upgrade env_logger to 0.6

---
 Cargo.lock                       | 36 +++++++++++---------------------
 src/librustc_driver/Cargo.toml   |  2 +-
 src/tools/compiletest/Cargo.toml |  2 +-
 3 files changed, 14 insertions(+), 26 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 313fef1c086a8..c9f2092eb5236 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -277,7 +277,7 @@ dependencies = [
  "crypto-hash",
  "curl",
  "curl-sys",
- "env_logger 0.6.0",
+ "env_logger",
  "failure",
  "filetime",
  "flate2",
@@ -507,7 +507,7 @@ name = "compiletest"
 version = "0.0.0"
 dependencies = [
  "diff",
- "env_logger 0.5.13",
+ "env_logger",
  "getopts",
  "lazy_static 1.3.0",
  "libc",
@@ -909,21 +909,9 @@ dependencies = [
 
 [[package]]
 name = "env_logger"
-version = "0.5.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "15b0a4d2e39f8420210be8b27eeda28029729e2fd4291019455016c348240c38"
-dependencies = [
- "atty",
- "humantime",
- "log",
- "termcolor",
-]
-
-[[package]]
-name = "env_logger"
-version = "0.6.0"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e"
+checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
 dependencies = [
  "atty",
  "humantime",
@@ -1774,7 +1762,7 @@ dependencies = [
  "chrono",
  "clap",
  "elasticlunr-rs",
- "env_logger 0.6.0",
+ "env_logger",
  "error-chain",
  "handlebars",
  "itertools 0.8.0",
@@ -1799,7 +1787,7 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "77d1f0ba4d1e6b86fa18e8853d026d7d76a97eb7eb5eb052ed80901e43b7fc10"
 dependencies = [
- "env_logger 0.6.0",
+ "env_logger",
  "failure",
  "log",
  "mdbook",
@@ -1992,7 +1980,7 @@ dependencies = [
  "colored",
  "compiletest_rs",
  "directories",
- "env_logger 0.6.0",
+ "env_logger",
  "getrandom",
  "hex",
  "log",
@@ -2363,7 +2351,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"
 dependencies = [
  "chrono",
- "env_logger 0.6.0",
+ "env_logger",
  "log",
 ]
 
@@ -2440,7 +2428,7 @@ dependencies = [
  "bitflags",
  "clap",
  "derive_more",
- "env_logger 0.6.0",
+ "env_logger",
  "humantime",
  "lazy_static 1.3.0",
  "log",
@@ -2734,7 +2722,7 @@ dependencies = [
  "clippy_lints",
  "crossbeam-channel",
  "difference",
- "env_logger 0.6.0",
+ "env_logger",
  "failure",
  "futures",
  "heck",
@@ -3203,7 +3191,7 @@ dependencies = [
 name = "rustc_driver"
 version = "0.0.0"
 dependencies = [
- "env_logger 0.5.13",
+ "env_logger",
  "graphviz",
  "log",
  "rustc",
@@ -3590,7 +3578,7 @@ dependencies = [
  "derive-new",
  "diff",
  "dirs",
- "env_logger 0.6.0",
+ "env_logger",
  "failure",
  "getopts",
  "ignore",
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index b030517e28ec2..a839ee56b2b6e 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -12,7 +12,7 @@ crate-type = ["dylib"]
 [dependencies]
 graphviz = { path = "../libgraphviz" }
 log = "0.4"
-env_logger = { version = "0.5", default-features = false }
+env_logger = { version = "0.6", default-features = false }
 rustc = { path = "../librustc" }
 rustc_target = { path = "../librustc_target" }
 rustc_ast_borrowck = { path = "../librustc_ast_borrowck" }
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index e759ad1f35dde..745233c151cd6 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2018"
 
 [dependencies]
 diff = "0.1.10"
-env_logger = { version = "0.5", default-features = false }
+env_logger = { version = "0.6", default-features = false }
 getopts = "0.2"
 log = "0.4"
 regex = "1.0"

From f6481ed1c31d2a3c43fab73e58901f7c25360fcb Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Fri, 6 Sep 2019 19:21:20 +0100
Subject: [PATCH 562/943] Correct pluralisation of various diagnostic messages

---
 src/librustc/ty/error.rs           |  4 +++-
 src/librustc_typeck/check/pat.rs   | 33 +++++++++++++++++++++---------
 src/libsyntax/ext/tt/transcribe.rs |  9 ++++++--
 src/libsyntax_ext/format.rs        |  2 +-
 4 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index fe8f94ab1d314..f67526ea4a1d9 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -200,7 +200,9 @@ impl<'tcx> ty::TyS<'tcx> {
             ty::Array(_, n) => {
                 let n = tcx.lift_to_global(&n).unwrap();
                 match n.try_eval_usize(tcx, ty::ParamEnv::empty()) {
-                    Some(n) => format!("array of {} elements", n).into(),
+                    Some(n) => {
+                        format!("array of {} element{}", n, if n != 1 { "s" } else { "" }).into()
+                    }
                     None => "array".into(),
                 }
             }
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 24d0659391b04..8502b89de1469 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -1098,22 +1098,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
         struct_span_err!(
-            self.tcx.sess, span, E0527,
-            "pattern requires {} elements but array has {}",
-            min_len, size
+            self.tcx.sess,
+            span,
+            E0527,
+            "pattern requires {} element{} but array has {}",
+            min_len,
+            if min_len != 1 { "s" } else { "" },
+            size,
         )
-        .span_label(span, format!("expected {} elements", size))
+        .span_label(span, format!("expected {} element{}", size, if size != 1 { "s" } else { "" }))
         .emit();
     }
 
     fn error_scrutinee_with_rest_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {
         struct_span_err!(
-            self.tcx.sess, span, E0528,
-            "pattern requires at least {} elements but array has {}",
-            min_len, size
-        )
-        .span_label(span, format!("pattern cannot match array of {} elements", size))
-        .emit();
+            self.tcx.sess,
+            span,
+            E0528,
+            "pattern requires at least {} element{} but array has {}",
+            min_len,
+            if min_len != 1 { "s" } else { "" },
+            size,
+        ).span_label(
+            span,
+            format!(
+                "pattern cannot match array of {} element{}",
+                size,
+                if size != 1 { "s" } else { "" },
+            ),
+        ).emit();
     }
 
     fn error_scrutinee_unfixed_length(&self, span: Span) {
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 30d5df13dcedb..23735727fe8cf 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -345,8 +345,13 @@ impl LockstepIterSize {
                 LockstepIterSize::Constraint(r_len, _) if l_len == r_len => self,
                 LockstepIterSize::Constraint(r_len, r_id) => {
                     let msg = format!(
-                        "meta-variable `{}` repeats {} times, but `{}` repeats {} times",
-                        l_id, l_len, r_id, r_len
+                        "meta-variable `{}` repeats {} time{}, but `{}` repeats {} time{}",
+                        l_id,
+                        l_len,
+                        if l_len != 1 { "s" } else { "" },
+                        r_id,
+                        r_len,
+                        if r_len != 1 { "s" } else { "" },
                     );
                     LockstepIterSize::Contradiction(msg)
                 }
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index e29f12c50c526..dec84c8286292 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -291,7 +291,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 &format!(
                     "{} positional argument{} in format string, but {}",
                     count,
-                    if count > 1 { "s" } else { "" },
+                    if count != 1 { "s" } else { "" },
                     self.describe_num_args(),
                 ),
             );

From 0b97726e6c524d2cc0de4c2f5b1284eca010a7b2 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Fri, 6 Sep 2019 19:21:26 +0100
Subject: [PATCH 563/943] Update ui tests

---
 src/test/ui/coercion/coercion-slice.rs      | 2 +-
 src/test/ui/coercion/coercion-slice.stderr  | 2 +-
 src/test/ui/issues/issue-15783.rs           | 8 ++++----
 src/test/ui/issues/issue-15783.stderr       | 2 +-
 src/test/ui/match/match-vec-mismatch.stderr | 2 +-
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/test/ui/coercion/coercion-slice.rs b/src/test/ui/coercion/coercion-slice.rs
index 312b634c9fd0b..b69edcf260637 100644
--- a/src/test/ui/coercion/coercion-slice.rs
+++ b/src/test/ui/coercion/coercion-slice.rs
@@ -4,5 +4,5 @@ fn main() {
     let _: &[i32] = [0];
     //~^ ERROR mismatched types
     //~| expected type `&[i32]`
-    //~| expected &[i32], found array of 1 elements
+    //~| expected &[i32], found array of 1 element
 }
diff --git a/src/test/ui/coercion/coercion-slice.stderr b/src/test/ui/coercion/coercion-slice.stderr
index 6fa712371178b..ccd776e987938 100644
--- a/src/test/ui/coercion/coercion-slice.stderr
+++ b/src/test/ui/coercion/coercion-slice.stderr
@@ -4,7 +4,7 @@ error[E0308]: mismatched types
 LL |     let _: &[i32] = [0];
    |                     ^^^
    |                     |
-   |                     expected &[i32], found array of 1 elements
+   |                     expected &[i32], found array of 1 element
    |                     help: consider borrowing here: `&[0]`
    |
    = note: expected type `&[i32]`
diff --git a/src/test/ui/issues/issue-15783.rs b/src/test/ui/issues/issue-15783.rs
index 77eae914fa1ca..5189f550cfbd6 100644
--- a/src/test/ui/issues/issue-15783.rs
+++ b/src/test/ui/issues/issue-15783.rs
@@ -6,9 +6,9 @@ fn main() {
     let name = "Foo";
     let x = Some(&[name]);
     let msg = foo(x);
-//~^ ERROR mismatched types
-//~| expected type `std::option::Option<&[&str]>`
-//~| found type `std::option::Option<&[&str; 1]>`
-//~| expected slice, found array of 1 elements
+    //~^ ERROR mismatched types
+    //~| expected type `std::option::Option<&[&str]>`
+    //~| found type `std::option::Option<&[&str; 1]>`
+    //~| expected slice, found array of 1 element
     assert_eq!(msg, 3);
 }
diff --git a/src/test/ui/issues/issue-15783.stderr b/src/test/ui/issues/issue-15783.stderr
index 595fe4025ad48..1d54b2830d6c5 100644
--- a/src/test/ui/issues/issue-15783.stderr
+++ b/src/test/ui/issues/issue-15783.stderr
@@ -2,7 +2,7 @@ error[E0308]: mismatched types
   --> $DIR/issue-15783.rs:8:19
    |
 LL |     let msg = foo(x);
-   |                   ^ expected slice, found array of 1 elements
+   |                   ^ expected slice, found array of 1 element
    |
    = note: expected type `std::option::Option<&[&str]>`
               found type `std::option::Option<&[&str; 1]>`
diff --git a/src/test/ui/match/match-vec-mismatch.stderr b/src/test/ui/match/match-vec-mismatch.stderr
index 2f1bbb7621659..a3523bb689e6b 100644
--- a/src/test/ui/match/match-vec-mismatch.stderr
+++ b/src/test/ui/match/match-vec-mismatch.stderr
@@ -10,7 +10,7 @@ error[E0529]: expected an array or slice, found `std::string::String`
 LL |         ['f', 'o', ..] => {}
    |         ^^^^^^^^^^^^^^ pattern cannot match with input type `std::string::String`
 
-error[E0527]: pattern requires 1 elements but array has 3
+error[E0527]: pattern requires 1 element but array has 3
   --> $DIR/match-vec-mismatch.rs:20:9
    |
 LL |         [0] => {},

From 055d3798d40ca0eefa52fa152bf3c913240281af Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Sat, 31 Aug 2019 16:03:54 +0300
Subject: [PATCH 564/943] reduce visibility

---
 src/libsyntax/parse/parser.rs | 22 +++++++++++-----------
 src/libsyntax/util/parser.rs  |  2 +-
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 49b05551bae86..ab5462baaf721 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -132,7 +132,7 @@ pub struct Parser<'a> {
     /// into modules, and sub-parsers have new values for this name.
     pub root_module_name: Option<String>,
     crate expected_tokens: Vec<TokenType>,
-    crate token_cursor: TokenCursor,
+    token_cursor: TokenCursor,
     desugar_doc_comments: bool,
     /// `true` we should configure out of line modules as we parse.
     pub cfg_mods: bool,
@@ -161,19 +161,19 @@ impl<'a> Drop for Parser<'a> {
 }
 
 #[derive(Clone)]
-crate struct TokenCursor {
-    crate frame: TokenCursorFrame,
-    crate stack: Vec<TokenCursorFrame>,
+struct TokenCursor {
+    frame: TokenCursorFrame,
+    stack: Vec<TokenCursorFrame>,
 }
 
 #[derive(Clone)]
-crate struct TokenCursorFrame {
-    crate delim: token::DelimToken,
-    crate span: DelimSpan,
-    crate open_delim: bool,
-    crate tree_cursor: tokenstream::Cursor,
-    crate close_delim: bool,
-    crate last_token: LastToken,
+struct TokenCursorFrame {
+    delim: token::DelimToken,
+    span: DelimSpan,
+    open_delim: bool,
+    tree_cursor: tokenstream::Cursor,
+    close_delim: bool,
+    last_token: LastToken,
 }
 
 /// This is used in `TokenCursorFrame` above to track tokens that are consumed
diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs
index a501541c95909..fceaed360cdb4 100644
--- a/src/libsyntax/util/parser.rs
+++ b/src/libsyntax/util/parser.rs
@@ -69,7 +69,7 @@ pub enum Fixity {
 
 impl AssocOp {
     /// Creates a new AssocOP from a token
-    pub fn from_token(t: &Token) -> Option<AssocOp> {
+    crate fn from_token(t: &Token) -> Option<AssocOp> {
         use AssocOp::*;
         match t.kind {
             token::BinOpEq(k) => Some(AssignOp(k)),

From a26ee8586c150e786ffaa47fba06ebcc671373d1 Mon Sep 17 00:00:00 2001
From: Matthew Maurer <mmaurer@google.com>
Date: Fri, 6 Sep 2019 12:41:54 -0700
Subject: [PATCH 565/943] Include compiler-rt in the source tarball

In #60981 we switched to using src/llvm-project/compiler-rt inside
compiler-builtins rather than a separate copy of it.
In order to have the "c" feature turn on in builds from the source
tarball, we need to include that path in its creation.

fixes #64239
---
 src/bootstrap/dist.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 0f4ac63651ca9..500d5766a899e 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -808,6 +808,7 @@ fn copy_src_dirs(builder: &Builder<'_>, src_dirs: &[&str], exclude_dirs: &[&str]
             "llvm-project/lld", "llvm-project\\lld",
             "llvm-project/lldb", "llvm-project\\lldb",
             "llvm-project/llvm", "llvm-project\\llvm",
+            "llvm-project/compiler-rt", "llvm-project\\compiler-rt",
         ];
         if spath.contains("llvm-project") && !spath.ends_with("llvm-project")
             && !LLVM_PROJECTS.iter().any(|path| spath.contains(path))

From 7dd5c661081b12de72e5a869b9c80131f7a6b464 Mon Sep 17 00:00:00 2001
From: Aditya Atluri <adityaatluri@users.noreply.github.com>
Date: Fri, 6 Sep 2019 12:54:42 -0700
Subject: [PATCH 566/943] Added more prereqs and note about default directory

---
 README.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/README.md b/README.md
index 724bc36ecc6fb..4c2e4eef6552f 100644
--- a/README.md
+++ b/README.md
@@ -32,6 +32,7 @@ or reading the [rustc guide][rustcguidebuild].
    * `cmake` 3.4.3 or later
    * `curl`
    * `git`
+   * `ssl` which comes in `libssl-dev` or `openssl-devel`
 
 2. Clone the [source] with `git`:
 
@@ -56,6 +57,8 @@ or reading the [rustc guide][rustcguidebuild].
     an installation (using `./x.py install`) that you set the `prefix` value
     in the `[install]` section to a directory that you have write permissions.
 
+    Create install directory if you are not installing in default directory
+
 4. Build and install:
 
     ```sh

From 3dde650efa3a8910cccaef38e89fe74272d67c91 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Fri, 6 Sep 2019 23:41:54 +0300
Subject: [PATCH 567/943] Move injection of attributes from command line to
 `libsyntax_ext`

---
 src/librustc_interface/passes.rs   |  4 +-
 src/libsyntax/attr/mod.rs          | 59 +++++++-----------------------
 src/libsyntax/parse/attr.rs        |  2 +-
 src/libsyntax_ext/cmdline_attrs.rs | 30 +++++++++++++++
 src/libsyntax_ext/lib.rs           |  1 +
 5 files changed, 48 insertions(+), 48 deletions(-)
 create mode 100644 src/libsyntax_ext/cmdline_attrs.rs

diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 24b44964e4fd2..08ae3360eb94f 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -230,7 +230,9 @@ pub fn register_plugins<'a>(
     crate_name: &str,
 ) -> Result<(ast::Crate, PluginInfo)> {
     krate = time(sess, "attributes injection", || {
-        syntax::attr::inject(krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr)
+        syntax_ext::cmdline_attrs::inject(
+            krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr
+        )
     });
 
     let (mut krate, features) = syntax::config::features(
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 0e5cfa73a9e3a..69de3150354e7 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -16,7 +16,7 @@ use crate::mut_visit::visit_clobber;
 use crate::source_map::{BytePos, Spanned, DUMMY_SP};
 use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
 use crate::parse::parser::Parser;
-use crate::parse::{self, ParseSess, PResult};
+use crate::parse::{ParseSess, PResult};
 use crate::parse::token::{self, Token};
 use crate::ptr::P;
 use crate::symbol::{sym, Symbol};
@@ -25,7 +25,7 @@ use crate::tokenstream::{TokenStream, TokenTree, DelimSpan};
 use crate::GLOBALS;
 
 use log::debug;
-use syntax_pos::{FileName, Span};
+use syntax_pos::Span;
 
 use std::iter;
 use std::ops::DerefMut;
@@ -381,28 +381,25 @@ crate fn mk_attr_id() -> AttrId {
     AttrId(id)
 }
 
-/// Returns an inner attribute with the given value and span.
-pub fn mk_attr_inner(item: MetaItem) -> Attribute {
+pub fn mk_attr(style: AttrStyle, path: Path, tokens: TokenStream, span: Span) -> Attribute {
     Attribute {
         id: mk_attr_id(),
-        style: ast::AttrStyle::Inner,
-        path: item.path,
-        tokens: item.node.tokens(item.span),
+        style,
+        path,
+        tokens,
         is_sugared_doc: false,
-        span: item.span,
+        span,
     }
 }
 
+/// Returns an inner attribute with the given value and span.
+pub fn mk_attr_inner(item: MetaItem) -> Attribute {
+    mk_attr(AttrStyle::Inner, item.path, item.node.tokens(item.span), item.span)
+}
+
 /// Returns an outer attribute with the given value and span.
 pub fn mk_attr_outer(item: MetaItem) -> Attribute {
-    Attribute {
-        id: mk_attr_id(),
-        style: ast::AttrStyle::Outer,
-        path: item.path,
-        tokens: item.node.tokens(item.span),
-        is_sugared_doc: false,
-        span: item.span,
-    }
+    mk_attr(AttrStyle::Outer, item.path, item.node.tokens(item.span), item.span)
 }
 
 pub fn mk_sugared_doc_attr(text: Symbol, span: Span) -> Attribute {
@@ -716,33 +713,3 @@ derive_has_attrs! {
     Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm,
     ast::Field, ast::FieldPat, ast::Variant, ast::Param
 }
-
-pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate {
-    for raw_attr in attrs {
-        let mut parser = parse::new_parser_from_source_str(
-            parse_sess,
-            FileName::cli_crate_attr_source_code(&raw_attr),
-            raw_attr.clone(),
-        );
-
-        let start_span = parser.token.span;
-        let (path, tokens) = panictry!(parser.parse_meta_item_unrestricted());
-        let end_span = parser.token.span;
-        if parser.token != token::Eof {
-            parse_sess.span_diagnostic
-                .span_err(start_span.to(end_span), "invalid crate attribute");
-            continue;
-        }
-
-        krate.attrs.push(Attribute {
-            id: mk_attr_id(),
-            style: AttrStyle::Inner,
-            path,
-            tokens,
-            is_sugared_doc: false,
-            span: start_span.to(end_span),
-        });
-    }
-
-    krate
-}
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 671178223f503..d9c4baad49ded 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -176,7 +176,7 @@ impl<'a> Parser<'a> {
     /// PATH
     /// PATH `=` TOKEN_TREE
     /// The delimiters or `=` are still put into the resulting token stream.
-    crate fn parse_meta_item_unrestricted(&mut self) -> PResult<'a, (ast::Path, TokenStream)> {
+    pub fn parse_meta_item_unrestricted(&mut self) -> PResult<'a, (ast::Path, TokenStream)> {
         let meta = match self.token.kind {
             token::Interpolated(ref nt) => match **nt {
                 Nonterminal::NtMeta(ref meta) => Some(meta.clone()),
diff --git a/src/libsyntax_ext/cmdline_attrs.rs b/src/libsyntax_ext/cmdline_attrs.rs
new file mode 100644
index 0000000000000..bb8e3df3db921
--- /dev/null
+++ b/src/libsyntax_ext/cmdline_attrs.rs
@@ -0,0 +1,30 @@
+//! Attributes injected into the crate root from command line using `-Z crate-attr`.
+
+use syntax::ast::{self, AttrStyle};
+use syntax::attr::mk_attr;
+use syntax::panictry;
+use syntax::parse::{self, token, ParseSess};
+use syntax_pos::FileName;
+
+pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate {
+    for raw_attr in attrs {
+        let mut parser = parse::new_parser_from_source_str(
+            parse_sess,
+            FileName::cli_crate_attr_source_code(&raw_attr),
+            raw_attr.clone(),
+        );
+
+        let start_span = parser.token.span;
+        let (path, tokens) = panictry!(parser.parse_meta_item_unrestricted());
+        let end_span = parser.token.span;
+        if parser.token != token::Eof {
+            parse_sess.span_diagnostic
+                .span_err(start_span.to(end_span), "invalid crate attribute");
+            continue;
+        }
+
+        krate.attrs.push(mk_attr(AttrStyle::Inner, path, tokens, start_span.to(end_span)));
+    }
+
+    krate
+}
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 26ef80b2b06df..5c0a63ebbe7cb 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -40,6 +40,7 @@ mod source_util;
 mod test;
 mod trace_macros;
 
+pub mod cmdline_attrs;
 pub mod plugin_macro_defs;
 pub mod proc_macro_harness;
 pub mod standard_library_imports;

From f0386a10e0112acef6ea0447e6e5a3ac1c7cb118 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Sat, 7 Sep 2019 13:16:18 +0100
Subject: [PATCH 568/943] Add "bool" lang item

---
 src/libcore/bool/mod.rs                          | 7 +++++++
 src/libcore/lib.rs                               | 1 +
 src/librustc/middle/lang_items.rs                | 1 +
 src/librustc_typeck/check/method/probe.rs        | 4 ++++
 src/librustc_typeck/coherence/inherent_impls.rs  | 8 ++++++++
 src/librustdoc/clean/mod.rs                      | 2 +-
 src/librustdoc/passes/collect_intra_doc_links.rs | 1 +
 src/librustdoc/passes/collect_trait_impls.rs     | 1 +
 8 files changed, 24 insertions(+), 1 deletion(-)
 create mode 100644 src/libcore/bool/mod.rs

diff --git a/src/libcore/bool/mod.rs b/src/libcore/bool/mod.rs
new file mode 100644
index 0000000000000..ddca07b27a53f
--- /dev/null
+++ b/src/libcore/bool/mod.rs
@@ -0,0 +1,7 @@
+//! impl bool {}
+
+#![stable(feature = "core_bool", since = "1.39.0")]
+
+#[cfg(not(boostrap_stdarch_ignore_this))]
+#[lang = "bool"]
+impl bool {}
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index c168d5c8a2eac..03b6aa68d3c27 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -198,6 +198,7 @@ pub mod borrow;
 pub mod any;
 pub mod array;
 pub mod ascii;
+pub mod bool;
 pub mod sync;
 pub mod cell;
 pub mod char;
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 6b04600eb75f8..0aa708033c1a7 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -246,6 +246,7 @@ pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> LanguageItems {
 
 language_item_table! {
 //  Variant name,                Name,                 Method name,             Target;
+    BoolImplItem,                "bool",               bool_impl,               Target::Impl;
     CharImplItem,                "char",               char_impl,               Target::Impl;
     StrImplItem,                 "str",                str_impl,                Target::Impl;
     SliceImplItem,               "slice",              slice_impl,              Target::Impl;
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 1c01c8408be6c..c8838311e8dbf 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -578,6 +578,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             ty::Param(p) => {
                 self.assemble_inherent_candidates_from_param(p);
             }
+            ty::Bool => {
+                let lang_def_id = lang_items.bool_impl();
+                self.assemble_inherent_impl_for_primitive(lang_def_id);
+            }
             ty::Char => {
                 let lang_def_id = lang_items.char_impl();
                 self.assemble_inherent_impl_for_primitive(lang_def_id);
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index fb79a85ea25bf..e7c2126cfd727 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -67,6 +67,14 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
             ty::Dynamic(ref data, ..) if data.principal_def_id().is_some() => {
                 self.check_def_id(item, data.principal_def_id().unwrap());
             }
+            ty::Bool => {
+                self.check_primitive_impl(def_id,
+                                          lang_items.bool_impl(),
+                                          None,
+                                          "bool",
+                                          "bool",
+                                          item.span);
+            }
             ty::Char => {
                 self.check_primitive_impl(def_id,
                                           lang_items.char_impl(),
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 4971155113263..38eff43bad2be 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -3977,7 +3977,7 @@ fn build_deref_target_impls(cx: &DocContext<'_>,
             F32 => tcx.lang_items().f32_impl(),
             F64 => tcx.lang_items().f64_impl(),
             Char => tcx.lang_items().char_impl(),
-            Bool => None,
+            Bool => tcx.lang_items().bool_impl(),
             Str => tcx.lang_items().str_impl(),
             Slice => tcx.lang_items().slice_impl(),
             Array => tcx.lang_items().slice_impl(),
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 2951b2ccb2af9..d6073cdc1e11d 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -679,6 +679,7 @@ fn primitive_impl(cx: &DocContext<'_>, path_str: &str) -> Option<DefId> {
         "f32" => tcx.lang_items().f32_impl(),
         "f64" => tcx.lang_items().f64_impl(),
         "str" => tcx.lang_items().str_impl(),
+        "bool" => tcx.lang_items().bool_impl(),
         "char" => tcx.lang_items().char_impl(),
         _ => None,
     }
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 86e4e9fd95637..28c64d0b9638e 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -53,6 +53,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
         lang_items.f64_impl(),
         lang_items.f32_runtime_impl(),
         lang_items.f64_runtime_impl(),
+        lang_items.bool_impl(),
         lang_items.char_impl(),
         lang_items.str_impl(),
         lang_items.slice_impl(),

From 0d084670d726d17505c03f71a258a42229680e7e Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Thu, 5 Sep 2019 18:04:58 +0300
Subject: [PATCH 569/943] resolve: Do not afraid to set current module to enums
 and traits

---
 src/librustc_resolve/build_reduced_graph.rs | 11 ++++-------
 src/librustc_resolve/lib.rs                 |  6 +++++-
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 81bd687e26321..333509e18504d 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -728,9 +728,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                                              expansion,
                                              item.span);
                 self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
+                self.parent_scope.module = module;
 
                 for variant in &(*enum_definition).variants {
-                    self.build_reduced_graph_for_variant(variant, module, vis);
+                    self.build_reduced_graph_for_variant(variant, vis);
                 }
             }
 
@@ -818,10 +819,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
 
     // Constructs the reduced graph for one variant. Variants exist in the
     // type and value namespaces.
-    fn build_reduced_graph_for_variant(&mut self,
-                                       variant: &Variant,
-                                       parent: Module<'a>,
-                                       vis: ty::Visibility) {
+    fn build_reduced_graph_for_variant(&mut self, variant: &Variant, vis: ty::Visibility) {
+        let parent = self.parent_scope.module;
         let expn_id = self.parent_scope.expansion;
         let ident = variant.ident;
 
@@ -1253,9 +1252,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
         let expansion = self.parent_scope.expansion;
         self.r.define(parent, item.ident, ns, (res, vis, item.span, expansion));
 
-        self.parent_scope.module = parent.parent.unwrap(); // nearest normal ancestor
         visit::walk_trait_item(self, item);
-        self.parent_scope.module = parent;
     }
 
     fn visit_token(&mut self, t: Token) {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 7f65e5dfaa2bf..29676f96ce7a8 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -538,7 +538,11 @@ impl<'a> ModuleData<'a> {
     }
 
     fn nearest_item_scope(&'a self) -> Module<'a> {
-        if self.is_trait() { self.parent.unwrap() } else { self }
+        match self.kind {
+            ModuleKind::Def(DefKind::Enum, ..) | ModuleKind::Def(DefKind::Trait, ..) =>
+                self.parent.expect("enum or trait module without a parent"),
+            _ => self,
+        }
     }
 
     fn is_ancestor_of(&self, mut other: &Self) -> bool {

From 691f645ecd38d346fb047bbcb148694bd82c6a92 Mon Sep 17 00:00:00 2001
From: Aleksi Juvani <aleksi@aleksijuvani.com>
Date: Sat, 7 Sep 2019 17:18:10 +0300
Subject: [PATCH 570/943] Fix sysroot on macOS when cross-compiling and SDKROOT
 is set

Fixes rust-lang/cargo#7283
Closes rust-lang/cargo#7284

r? @alexcrichton
---
 src/librustc_target/spec/apple_base.rs        | 45 ++++++++++++++++++-
 src/librustc_target/spec/apple_ios_base.rs    | 42 +----------------
 src/librustc_target/spec/i686_apple_darwin.rs | 12 ++++-
 .../spec/x86_64_apple_darwin.rs               | 12 ++++-
 4 files changed, 67 insertions(+), 44 deletions(-)

diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs
index 53364e72bfe3a..aa5080aaaf6e6 100644
--- a/src/librustc_target/spec/apple_base.rs
+++ b/src/librustc_target/spec/apple_base.rs
@@ -1,4 +1,4 @@
-use std::env;
+use std::{env, io, path::Path, process::Command};
 
 use crate::spec::{LinkArgs, TargetOptions};
 
@@ -51,3 +51,46 @@ pub fn macos_llvm_target(arch: &str) -> String {
     let (major, minor) = macos_deployment_target();
     format!("{}-apple-macosx{}.{}.0", arch, major, minor)
 }
+
+pub fn sysroot(sdk: &str) -> Result<String, String> {
+    let actual_sdk_path = sdk_path(sdk)?;
+    // Like Clang, allow the SDKROOT environment variable used by Xcode to define the sysroot
+    if let Some(sdk_root) = env::var("SDKROOT").ok() {
+        let sdk_root_p = Path::new(&sdk_root);
+        // Ignore SDKROOT if it's not a valid path
+        if !sdk_root_p.is_absolute() || sdk_root_p == Path::new("/") || !sdk_root_p.exists() {
+            return Ok(actual_sdk_path);
+        }
+        // Ignore SDKROOT if it's clearly set for the wrong platform, which may occur when we're
+        // compiling a custom build script while targeting iOS for example
+        match sdk {
+            "iphoneos" if sdk_root.contains("iPhoneSimulator.platform")
+                || sdk_root.contains("MacOSX.platform") => return Ok(actual_sdk_path),
+            "iphonesimulator" if sdk_root.contains("iPhoneOS.platform")
+                || sdk_root.contains("MacOSX.platform") => return Ok(actual_sdk_path),
+            "macosx" | "macosx10.15" if sdk_root.contains("iPhoneOS.platform")
+                || sdk_root.contains("iPhoneSimulator.platform") => return Ok(actual_sdk_path),
+            _ => return Ok(sdk_root),
+        }
+    }
+    Ok(actual_sdk_path)
+}
+
+fn sdk_path(sdk_name: &str) -> Result<String, String> {
+    let res =
+        Command::new("xcrun").arg("--show-sdk-path").arg("-sdk").arg(sdk_name).output().and_then(
+            |output| {
+                if output.status.success() {
+                    Ok(String::from_utf8(output.stdout).unwrap())
+                } else {
+                    let error = String::from_utf8(output.stderr);
+                    let error = format!("process exit with error: {}", error.unwrap());
+                    Err(io::Error::new(io::ErrorKind::Other, &error[..]))
+                }
+            },
+        );
+    match res {
+        Ok(output) => Ok(output.trim().to_string()),
+        Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
+    }
+}
diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs
index 6d3900c0b203f..db4a818083183 100644
--- a/src/librustc_target/spec/apple_ios_base.rs
+++ b/src/librustc_target/spec/apple_ios_base.rs
@@ -1,7 +1,3 @@
-use std::env;
-use std::io;
-use std::path::Path;
-use std::process::Command;
 use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
 
 use Arch::*;
@@ -30,42 +26,6 @@ impl Arch {
     }
 }
 
-pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> {
-    // Following what clang does
-    // (https://github.com/llvm/llvm-project/blob/
-    // 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678)
-    // to allow the SDK path to be set. (For clang, xcrun sets
-    // SDKROOT; for rustc, the user or build system can set it, or we
-    // can fall back to checking for xcrun on PATH.)
-    if let Some(sdkroot) = env::var("SDKROOT").ok() {
-        let sdkroot_path = Path::new(&sdkroot);
-        if sdkroot_path.is_absolute() && sdkroot_path != Path::new("/") && sdkroot_path.exists() {
-            return Ok(sdkroot);
-        }
-    }
-    let res = Command::new("xcrun")
-                      .arg("--show-sdk-path")
-                      .arg("-sdk")
-                      .arg(sdk_name)
-                      .output()
-                      .and_then(|output| {
-                          if output.status.success() {
-                              Ok(String::from_utf8(output.stdout).unwrap())
-                          } else {
-                              let error = String::from_utf8(output.stderr);
-                              let error = format!("process exit with error: {}",
-                                                  error.unwrap());
-                              Err(io::Error::new(io::ErrorKind::Other,
-                                                 &error[..]))
-                          }
-                      });
-
-    match res {
-        Ok(output) => Ok(output.trim().to_string()),
-        Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e))
-    }
-}
-
 fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> {
     let sdk_name = match arch {
         Armv7 | Armv7s | Arm64 => "iphoneos",
@@ -75,7 +35,7 @@ fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> {
 
     let arch_name = arch.to_string();
 
-    let sdk_root = get_sdk_root(sdk_name)?;
+    let sdk_root = super::apple_base::sysroot(sdk_name)?;
 
     let mut args = LinkArgs::new();
     args.insert(LinkerFlavor::Gcc,
diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs
index 7d804ea53fb31..a60c007212474 100644
--- a/src/librustc_target/spec/i686_apple_darwin.rs
+++ b/src/librustc_target/spec/i686_apple_darwin.rs
@@ -1,10 +1,20 @@
 use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
+    let sysroot = super::apple_base::sysroot("macosx")?;
     let mut base = super::apple_base::opts();
     base.cpu = "yonah".to_string();
     base.max_atomic_width = Some(64);
-    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
+    base.pre_link_args.insert(
+        LinkerFlavor::Gcc,
+        vec![
+            "-m32".to_string(),
+            "-isysroot".to_string(),
+            sysroot.clone(),
+            "-Wl,-syslibroot".to_string(),
+            sysroot,
+        ],
+    );
     base.stack_probes = true;
     base.eliminate_frame_pointer = false;
 
diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs
index 182103440f035..b72d037565b5b 100644
--- a/src/librustc_target/spec/x86_64_apple_darwin.rs
+++ b/src/librustc_target/spec/x86_64_apple_darwin.rs
@@ -1,11 +1,21 @@
 use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
+    let sysroot = super::apple_base::sysroot("macosx")?;
     let mut base = super::apple_base::opts();
     base.cpu = "core2".to_string();
     base.max_atomic_width = Some(128); // core2 support cmpxchg16b
     base.eliminate_frame_pointer = false;
-    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
+    base.pre_link_args.insert(
+        LinkerFlavor::Gcc,
+        vec![
+            "-m64".to_string(),
+            "-isysroot".to_string(),
+            sysroot.clone(),
+            "-Wl,-syslibroot".to_string(),
+            sysroot,
+        ],
+    );
     base.stack_probes = true;
 
     // Clang automatically chooses a more specific target based on

From 56f635304b7a2689cfe5e98577428d67f059b413 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sat, 7 Sep 2019 17:33:50 +0300
Subject: [PATCH 571/943] resolve: Adjust `hygienic_lexical_parent` to account
 for enum and trait modules

---
 src/librustc_resolve/lib.rs                    |  2 +-
 src/test/ui/resolve/block-with-trait-parent.rs | 14 ++++++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/resolve/block-with-trait-parent.rs

diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 29676f96ce7a8..efb64c9341f13 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -1644,7 +1644,7 @@ impl<'a> Resolver<'a> {
         }
 
         if let ModuleKind::Block(..) = module.kind {
-            return Some(module.parent.unwrap());
+            return Some(module.parent.unwrap().nearest_item_scope());
         }
 
         None
diff --git a/src/test/ui/resolve/block-with-trait-parent.rs b/src/test/ui/resolve/block-with-trait-parent.rs
new file mode 100644
index 0000000000000..bc86f94e921cb
--- /dev/null
+++ b/src/test/ui/resolve/block-with-trait-parent.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+trait Trait {
+    fn method(&self) {
+        // Items inside a block turn it into a module internally.
+        struct S;
+        impl Trait for S {}
+
+        // OK, `Trait` is in scope here from method resolution point of view.
+        S.method();
+    }
+}
+
+fn main() {}

From b73e32c795ec438a4b2e1901abc4e2a281e1a18a Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Sat, 7 Sep 2019 15:49:27 +0100
Subject: [PATCH 572/943] Add `bool::then` and `bool::then_with`

---
 src/libcore/bool/mod.rs   | 42 ++++++++++++++++++++++++++++++++++++++-
 src/libcore/tests/bool.rs |  7 +++++++
 src/libcore/tests/lib.rs  |  2 ++
 3 files changed, 50 insertions(+), 1 deletion(-)
 create mode 100644 src/libcore/tests/bool.rs

diff --git a/src/libcore/bool/mod.rs b/src/libcore/bool/mod.rs
index ddca07b27a53f..0fbd3b8c2bbce 100644
--- a/src/libcore/bool/mod.rs
+++ b/src/libcore/bool/mod.rs
@@ -4,4 +4,44 @@
 
 #[cfg(not(boostrap_stdarch_ignore_this))]
 #[lang = "bool"]
-impl bool {}
+impl bool {
+    /// Returns `Some(t)` if the `bool` is `true`, or `None` otherwise.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(bool_to_option)]
+    ///
+    /// assert_eq!(false.then(0), None);
+    /// assert_eq!(true.then(0), Some(0));
+    /// ```
+    #[unstable(feature = "bool_to_option", issue = "0")]
+    #[inline]
+    pub fn then<T>(self, t: T) -> Option<T> {
+        if self {
+            Some(t)
+        } else {
+            None
+        }
+    }
+
+    /// Returns `Some(f())` if the `bool` is `true`, or `None` otherwise.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(bool_to_option)]
+    ///
+    /// assert_eq!(false.then_with(|| 0), None);
+    /// assert_eq!(true.then_with(|| 0), Some(0));
+    /// ```
+    #[unstable(feature = "bool_to_option", issue = "0")]
+    #[inline]
+    pub fn then_with<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
+        if self {
+            Some(f())
+        } else {
+            None
+        }
+    }
+}
diff --git a/src/libcore/tests/bool.rs b/src/libcore/tests/bool.rs
new file mode 100644
index 0000000000000..0f1e6e89451e9
--- /dev/null
+++ b/src/libcore/tests/bool.rs
@@ -0,0 +1,7 @@
+#[test]
+fn test_bool_to_option() {
+    assert_eq!(false.then(0), None);
+    assert_eq!(true.then(0), Some(0));
+    assert_eq!(false.then_with(|| 0), None);
+    assert_eq!(true.then_with(|| 0), Some(0));
+}
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index a3b108b2e9cea..b2c29aa269265 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -1,3 +1,4 @@
+#![feature(bool_to_option)]
 #![feature(bound_cloned)]
 #![feature(box_syntax)]
 #![feature(cell_update)]
@@ -40,6 +41,7 @@ mod any;
 mod array;
 mod ascii;
 mod atomic;
+mod bool;
 mod cell;
 mod char;
 mod clone;

From c1d29ee3c754c63fc6c8c3a522b7a71a5a19616a Mon Sep 17 00:00:00 2001
From: Alexander Regueiro <alexreg@me.com>
Date: Fri, 6 Sep 2019 03:57:44 +0100
Subject: [PATCH 573/943] Aggregation of cosmetic changes made during work on
 REPL PRs: librustc

---
 src/librustc/arena.rs                         |   2 +-
 src/librustc/hir/check_attr.rs                |   7 +-
 src/librustc/hir/def.rs                       |  22 +-
 src/librustc/hir/def_id.rs                    |   7 +-
 src/librustc/hir/intravisit.rs                |  20 +-
 src/librustc/hir/itemlikevisit.rs             |  21 +-
 src/librustc/hir/lowering.rs                  |  18 +-
 src/librustc/hir/lowering/item.rs             |   4 +-
 src/librustc/hir/map/collector.rs             |   2 +-
 src/librustc/hir/map/definitions.rs           |  77 +++---
 src/librustc/hir/map/mod.rs                   |  41 ++--
 src/librustc/hir/mod.rs                       |  53 +++--
 src/librustc/hir/print.rs                     |  25 +-
 src/librustc/ich/hcx.rs                       |  54 ++---
 src/librustc/ich/impls_hir.rs                 |  18 +-
 src/librustc/ich/impls_ty.rs                  |   6 +-
 src/librustc/infer/mod.rs                     |   8 +-
 src/librustc/lint/context.rs                  |  20 +-
 src/librustc/lint/mod.rs                      |   6 +-
 src/librustc/middle/entry.rs                  |  18 +-
 src/librustc/middle/expr_use_visitor.rs       |   2 +-
 src/librustc/middle/lang_items.rs             |  18 +-
 src/librustc/middle/region.rs                 |  82 ++++---
 src/librustc/mir/cache.rs                     |   2 +-
 src/librustc/mir/interpret/allocation.rs      | 109 +++++----
 src/librustc/mir/interpret/error.rs           |  16 +-
 src/librustc/mir/interpret/mod.rs             | 110 ++++-----
 src/librustc/mir/interpret/pointer.rs         |   9 +-
 src/librustc/mir/interpret/value.rs           |  10 +-
 src/librustc/mir/mod.rs                       | 170 +++++++-------
 src/librustc/query/mod.rs                     |   5 +-
 src/librustc/session/config.rs                | 137 ++++++-----
 src/librustc/session/mod.rs                   |  61 ++---
 src/librustc/traits/object_safety.rs          |  22 +-
 .../traits/query/evaluate_obligation.rs       |   5 +-
 src/librustc/traits/query/method_autoderef.rs |  10 +-
 src/librustc/traits/util.rs                   |   6 +-
 src/librustc/ty/codec.rs                      |  21 +-
 src/librustc/ty/context.rs                    | 165 +++++++------
 src/librustc/ty/fold.rs                       |   4 +-
 .../ty/inhabitedness/def_id_forest.rs         |  18 +-
 src/librustc/ty/inhabitedness/mod.rs          |  35 +--
 src/librustc/ty/mod.rs                        |   2 +-
 src/librustc/ty/print/mod.rs                  |   7 +-
 src/librustc/ty/print/pretty.rs               |  79 ++++---
 src/librustc/ty/query/on_disk_cache.rs        | 219 +++++++++---------
 src/librustc/ty/query/plumbing.rs             | 106 +++++----
 src/librustc/ty/sty.rs                        |   8 +-
 src/librustc_ast_borrowck/cfg/construct.rs    | 146 ++++++------
 src/librustc_ast_borrowck/cfg/graphviz.rs     |  11 +-
 50 files changed, 1028 insertions(+), 996 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index b3a561ef74be7..d4fc1b12830a1 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -187,7 +187,7 @@ impl<T: Copy> ArenaAllocatable for T {}
 
 unsafe trait ArenaField<'tcx>: Sized {
     /// Returns a specific arena to allocate from.
-    /// If None is returned, the DropArena will be used.
+    /// If `None` is returned, the `DropArena` will be used.
     fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>>;
 }
 
diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs
index eae956c978a8e..1df09429e519f 100644
--- a/src/librustc/hir/check_attr.rs
+++ b/src/librustc/hir/check_attr.rs
@@ -4,13 +4,12 @@
 //! conflicts between multiple such attributes attached to the same
 //! item.
 
-
-use crate::ty::TyCtxt;
-use crate::ty::query::Providers;
-
 use crate::hir;
 use crate::hir::def_id::DefId;
 use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
+use crate::ty::TyCtxt;
+use crate::ty::query::Providers;
+
 use std::fmt::{self, Display};
 use syntax::symbol::sym;
 use syntax_pos::Span;
diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs
index f83fbcdc263b0..f7d31ca06ee56 100644
--- a/src/librustc/hir/def.rs
+++ b/src/librustc/hir/def.rs
@@ -1,15 +1,17 @@
+use self::Namespace::*;
+
 use crate::hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use crate::hir;
+use crate::ty;
 use crate::util::nodemap::DefIdMap;
+
 use syntax::ast;
 use syntax::ext::base::MacroKind;
 use syntax::ast::NodeId;
 use syntax_pos::Span;
 use rustc_macros::HashStable;
-use crate::hir;
-use crate::ty;
-use std::fmt::Debug;
 
-use self::Namespace::*;
+use std::fmt::Debug;
 
 /// Encodes if a `DefKind::Ctor` is the constructor of an enum variant or a struct.
 #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
@@ -115,7 +117,7 @@ impl DefKind {
         }
     }
 
-    /// An English article for the def.
+    /// Gets an English article for the definition.
     pub fn article(&self) -> &'static str {
         match *self {
             DefKind::AssocTy
@@ -134,18 +136,22 @@ pub enum Res<Id = hir::HirId> {
     Def(DefKind, DefId),
 
     // Type namespace
+
     PrimTy(hir::PrimTy),
     SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
     ToolMod, // e.g., `rustfmt` in `#[rustfmt::skip]`
 
     // Value namespace
+
     SelfCtor(DefId /* impl */),  // `DefId` refers to the impl
     Local(Id),
 
     // Macro namespace
+
     NonMacroAttr(NonMacroAttrKind), // e.g., `#[inline]` or `#[rustfmt::skip]`
 
     // All namespaces
+
     Err,
 }
 
@@ -330,7 +336,7 @@ impl NonMacroAttrKind {
 }
 
 impl<Id> Res<Id> {
-    /// Return the `DefId` of this `Def` if it has an id, else panic.
+    /// Return the `DefId` of this `Def` if it has an ID, else panic.
     pub fn def_id(&self) -> DefId
     where
         Id: Debug,
@@ -340,7 +346,7 @@ impl<Id> Res<Id> {
         })
     }
 
-    /// Return `Some(..)` with the `DefId` of this `Res` if it has a id, else `None`.
+    /// Return `Some(..)` with the `DefId` of this `Res` if it has a ID, else `None`.
     pub fn opt_def_id(&self) -> Option<DefId> {
         match *self {
             Res::Def(_, id) => Some(id),
@@ -379,7 +385,7 @@ impl<Id> Res<Id> {
         }
     }
 
-    /// An English article for the res.
+    /// Gets an English article for the `Res`.
     pub fn article(&self) -> &'static str {
         match *self {
             Res::Def(kind, _) => kind.article(),
diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs
index c91ad7858d0bb..d0bdc14913183 100644
--- a/src/librustc/hir/def_id.rs
+++ b/src/librustc/hir/def_id.rs
@@ -11,7 +11,7 @@ newtype_index! {
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum CrateNum {
-    /// A special CrateNum that we use for the tcx.rcache when decoding from
+    /// A special `CrateNum` that we use for the `tcx.rcache` when decoding from
     /// the incr. comp. cache.
     ReservedForIncrCompCache,
     Index(CrateId),
@@ -26,11 +26,10 @@ impl ::std::fmt::Debug for CrateNum {
     }
 }
 
-/// Item definitions in the currently-compiled crate would have the CrateNum
-/// LOCAL_CRATE in their DefId.
+/// Item definitions in the currently-compiled crate would have the `CrateNum`
+/// `LOCAL_CRATE` in their `DefId`.
 pub const LOCAL_CRATE: CrateNum = CrateNum::Index(CrateId::from_u32_const(0));
 
-
 impl Idx for CrateNum {
     #[inline]
     fn new(value: usize) -> Self {
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index bbde3510e29f9..1f125de967216 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -31,11 +31,13 @@
 //! This order consistency is required in a few places in rustc, for
 //! example generator inference, and possibly also HIR borrowck.
 
-use syntax::ast::{Ident, Name, Attribute};
-use syntax_pos::Span;
+use super::itemlikevisit::DeepVisitor;
+
 use crate::hir::*;
 use crate::hir::map::Map;
-use super::itemlikevisit::DeepVisitor;
+
+use syntax::ast::{Ident, Name, Attribute};
+use syntax_pos::Span;
 
 #[derive(Copy, Clone)]
 pub enum FnKind<'a> {
@@ -139,7 +141,7 @@ impl<'this, 'tcx> NestedVisitorMap<'this, 'tcx> {
 /// explicitly, you need to override each method. (And you also need
 /// to monitor future changes to `Visitor` in case a new method with a
 /// new default implementation gets introduced.)
-pub trait Visitor<'v> : Sized {
+pub trait Visitor<'v>: Sized {
     ///////////////////////////////////////////////////////////////////////////
     // Nested items.
 
@@ -162,8 +164,8 @@ pub trait Visitor<'v> : Sized {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v>;
 
     /// Invoked when a nested item is encountered. By default does
-    /// nothing unless you override `nested_visit_map` to return
-    /// `Some(_)`, in which case it will walk the item. **You probably
+    /// nothing unless you override `nested_visit_map` to return other than
+    /// `None`, in which case it will walk the item. **You probably
     /// don't want to override this method** -- instead, override
     /// `nested_visit_map` or use the "shallow" or "deep" visit
     /// patterns described on `itemlikevisit::ItemLikeVisitor`. The only
@@ -201,8 +203,8 @@ pub trait Visitor<'v> : Sized {
 
     /// Invoked to visit the body of a function, method or closure. Like
     /// visit_nested_item, does nothing by default unless you override
-    /// `nested_visit_map` to return `Some(_)`, in which case it will walk the
-    /// body.
+    /// `nested_visit_map` to return other htan `None`, in which case it will walk
+    /// the body.
     fn visit_nested_body(&mut self, id: BodyId) {
         let opt_body = self.nested_visit_map().intra().map(|map| map.body(id));
         if let Some(body) = opt_body {
@@ -603,7 +605,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
             visitor.visit_lifetime(lifetime);
             visitor.visit_ty(&mutable_type.ty)
         }
-        TyKind::Never => {},
+        TyKind::Never => {}
         TyKind::Tup(ref tuple_element_types) => {
             walk_list!(visitor, visit_ty, tuple_element_types);
         }
diff --git a/src/librustc/hir/itemlikevisit.rs b/src/librustc/hir/itemlikevisit.rs
index 35b181245837f..39dd46c2d2903 100644
--- a/src/librustc/hir/itemlikevisit.rs
+++ b/src/librustc/hir/itemlikevisit.rs
@@ -1,7 +1,7 @@
 use super::{Item, ImplItem, TraitItem};
 use super::intravisit::Visitor;
 
-/// The "item-like visitor" visitor defines only the top-level methods
+/// The "item-like visitor" defines only the top-level methods
 /// that can be invoked by `Crate::visit_all_item_likes()`. Whether
 /// this trait is the right one to implement will depend on the
 /// overall pattern you need. Here are the three available patterns,
@@ -18,11 +18,11 @@ use super::intravisit::Visitor;
 ///    an item, but don't care about how item-like things are nested
 ///    within one another.
 ///    - Example: Examine each expression to look for its type and do some check or other.
-///    - How: Implement `intravisit::Visitor` and use
-///      `tcx.hir().krate().visit_all_item_likes(visitor.as_deep_visitor())`. Within
-///      your `intravisit::Visitor` impl, implement methods like
-///      `visit_expr()`; don't forget to invoke
-///      `intravisit::walk_visit_expr()` to keep walking the subparts.
+///    - How: Implement `intravisit::Visitor` and override the `nested_visit_map()` method
+///      to return `NestedVisitorMap::OnlyBodies` and use
+///      `tcx.hir().krate().visit_all_item_likes(&mut visitor.as_deep_visitor())`. Within
+///      your `intravisit::Visitor` impl, implement methods like `visit_expr()` (don't forget
+///      to invoke `intravisit::walk_expr()` to keep walking the subparts).
 ///    - Pro: Visitor methods for any kind of HIR node, not just item-like things.
 ///    - Pro: Integrates well into dependency tracking.
 ///    - Con: Don't get information about nesting between items
@@ -30,10 +30,9 @@ use super::intravisit::Visitor;
 ///    item-like things.
 ///    - Example: Lifetime resolution, which wants to bring lifetimes declared on the
 ///      impl into scope while visiting the impl-items, and then back out again.
-///    - How: Implement `intravisit::Visitor` and override the
-///      `nested_visit_map()` methods to return
-///      `NestedVisitorMap::All`. Walk your crate with
-///      `intravisit::walk_crate()` invoked on `tcx.hir().krate()`.
+///    - How: Implement `intravisit::Visitor` and override the `nested_visit_map()` method
+///      to return `NestedVisitorMap::All`. Walk your crate with `intravisit::walk_crate()`
+///      invoked on `tcx.hir().krate()`.
 ///    - Pro: Visitor methods for any kind of HIR node, not just item-like things.
 ///    - Pro: Preserves nesting information
 ///    - Con: Does not integrate well into dependency tracking.
@@ -79,7 +78,7 @@ impl<'v, 'hir, V> ItemLikeVisitor<'hir> for DeepVisitor<'v, V>
     }
 }
 
-/// A parallel variant of ItemLikeVisitor
+/// A parallel variant of `ItemLikeVisitor`.
 pub trait ParItemLikeVisitor<'hir> {
     fn visit_item(&self, item: &'hir Item);
     fn visit_trait_item(&self, trait_item: &'hir TraitItem);
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 190b50b10b281..fd6445ea3c4d4 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -79,7 +79,7 @@ const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
 pub struct LoweringContext<'a> {
     crate_root: Option<Symbol>,
 
-    /// Used to assign ids to HIR nodes that do not directly correspond to an AST node.
+    /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
     sess: &'a Session,
 
     cstore: &'a dyn CrateStore,
@@ -126,7 +126,7 @@ pub struct LoweringContext<'a> {
     /// lifetime definitions in the corresponding impl or function generics.
     lifetimes_to_define: Vec<(Span, ParamName)>,
 
-    /// Whether or not in-band lifetimes are being collected. This is used to
+    /// `true` ifs in-band lifetimes are being collected. This is used to
     /// indicate whether or not we're in a place where new lifetimes will result
     /// in in-band lifetime definitions, such a function or an impl header,
     /// including implicit lifetimes from `impl_header_lifetime_elision`.
@@ -154,13 +154,13 @@ pub struct LoweringContext<'a> {
 }
 
 pub trait Resolver {
-    /// Obtain resolution for a `NodeId` with a single resolution.
+    /// Obtains resolution for a `NodeId` with a single resolution.
     fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
 
-    /// Obtain per-namespace resolutions for `use` statement with the given `NoedId`.
+    /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
     fn get_import_res(&mut self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;
 
-    /// Obtain resolution for a label with the given `NodeId`.
+    /// Obtains resolution for a label with the given `NodeId`.
     fn get_label_res(&mut self, id: NodeId) -> Option<NodeId>;
 
     /// We must keep the set of definitions up to date as we add nodes that weren't in the AST.
@@ -699,7 +699,7 @@ impl<'a> LoweringContext<'a> {
     fn lower_res(&mut self, res: Res<NodeId>) -> Res {
         res.map_id(|id| {
             self.lower_node_id_generic(id, |_| {
-                panic!("expected node_id to be lowered already for res {:#?}", res)
+                panic!("expected `NodeId` to be lowered already for res {:#?}", res);
             })
         })
     }
@@ -1364,7 +1364,7 @@ impl<'a> LoweringContext<'a> {
                     }
                 }
             }
-            TyKind::Mac(_) => bug!("`TyMac` should have been expanded by now."),
+            TyKind::Mac(_) => bug!("`TyMac` should have been expanded by now"),
             TyKind::CVarArgs => {
                 // Create the implicit lifetime of the "spoofed" `VaListImpl`.
                 let span = self.sess.source_map().next_point(t.span.shrink_to_lo());
@@ -2999,7 +2999,7 @@ impl<'a> LoweringContext<'a> {
             }
             StmtKind::Expr(ref e) => hir::StmtKind::Expr(P(self.lower_expr(e))),
             StmtKind::Semi(ref e) => hir::StmtKind::Semi(P(self.lower_expr(e))),
-            StmtKind::Mac(..) => panic!("Shouldn't exist here"),
+            StmtKind::Mac(..) => panic!("shouldn't exist here"),
         };
         smallvec![hir::Stmt {
             hir_id: self.lower_node_id(s.id),
@@ -3187,7 +3187,7 @@ impl<'a> LoweringContext<'a> {
 
         hir::Path {
             span,
-            res: res.map_id(|_| panic!("unexpected node_id")),
+            res: res.map_id(|_| panic!("unexpected `NodeId`")),
             segments: segments.into(),
         }
     }
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 4e432f4981d23..5f82e42abb308 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -718,7 +718,7 @@ impl LoweringContext<'_> {
                         AnonymousLifetimeMode::PassThrough,
                         |this, _| {
                             (
-                                // Disallow impl Trait in foreign items
+                                // Disallow `impl Trait` in foreign items.
                                 this.lower_fn_decl(fdec, None, false, None),
                                 this.lower_fn_params_to_names(fdec),
                             )
@@ -732,7 +732,7 @@ impl LoweringContext<'_> {
                         self.lower_ty(t, ImplTraitContext::disallowed()), self.lower_mutability(m))
                 }
                 ForeignItemKind::Ty => hir::ForeignItemKind::Type,
-                ForeignItemKind::Macro(_) => panic!("shouldn't exist here"),
+                ForeignItemKind::Macro(_) => panic!("macro shouldn't exist here"),
             },
             vis: self.lower_visibility(&i.vis, None),
             span: i.span,
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index b8bd1d73fc28b..4179cf2ff807f 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -340,7 +340,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     /// their outer items.
 
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> {
-        panic!("visit_nested_xxx must be manually implemented in this visitor")
+        panic!("`visit_nested_xxx` must be manually implemented in this visitor");
     }
 
     fn visit_nested_item(&mut self, item: ItemId) {
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index 6dc3c7038f569..651fe8449ac93 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -7,10 +7,12 @@
 use crate::hir;
 use crate::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, CRATE_DEF_INDEX};
 use crate::ich::Fingerprint;
+use crate::session::CrateDisambiguator;
+use crate::util::nodemap::NodeMap;
+
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::{IndexVec};
 use rustc_data_structures::stable_hasher::StableHasher;
-use crate::session::CrateDisambiguator;
 use std::borrow::Borrow;
 use std::fmt::Write;
 use std::hash::Hash;
@@ -18,12 +20,11 @@ use syntax::ast;
 use syntax::ext::hygiene::ExpnId;
 use syntax::symbol::{Symbol, sym, InternedString};
 use syntax_pos::{Span, DUMMY_SP};
-use crate::util::nodemap::NodeMap;
 
-/// The DefPathTable maps DefIndexes to DefKeys and vice versa.
-/// Internally the DefPathTable holds a tree of DefKeys, where each DefKey
-/// stores the DefIndex of its parent.
-/// There is one DefPathTable for each crate.
+/// The `DefPathTable` maps `DefIndex`es to `DefKey`s and vice versa.
+/// Internally the `DefPathTable` holds a tree of `DefKey`s, where each `DefKey`
+/// stores the `DefIndex` of its parent.
+/// There is one `DefPathTable` for each crate.
 #[derive(Clone, Default, RustcDecodable, RustcEncodable)]
 pub struct DefPathTable {
     index_to_key: Vec<DefKey>,
@@ -121,7 +122,7 @@ impl DefKey {
     fn compute_stable_hash(&self, parent_hash: DefPathHash) -> DefPathHash {
         let mut hasher = StableHasher::new();
 
-        // We hash a 0u8 here to disambiguate between regular DefPath hashes,
+        // We hash a `0u8` here to disambiguate between regular `DefPath` hashes,
         // and the special "root_parent" below.
         0u8.hash(&mut hasher);
         parent_hash.hash(&mut hasher);
@@ -145,8 +146,7 @@ impl DefKey {
                                crate_disambiguator: CrateDisambiguator)
                                -> DefPathHash {
         let mut hasher = StableHasher::new();
-        // Disambiguate this from a regular DefPath hash,
-        // see compute_stable_hash() above.
+        // Disambiguate this from a regular `DefPath` hash; see `compute_stable_hash()` above.
         1u8.hash(&mut hasher);
         crate_name.hash(&mut hasher);
         crate_disambiguator.hash(&mut hasher);
@@ -155,10 +155,10 @@ impl DefKey {
 }
 
 /// A pair of `DefPathData` and an integer disambiguator. The integer is
-/// normally 0, but in the event that there are multiple defs with the
+/// normally `0`, but in the event that there are multiple defs with the
 /// same `parent` and `data`, we use this field to disambiguate
 /// between them. This introduces some artificial ordering dependency
-/// but means that if you have (e.g.) two impls for the same type in
+/// but means that if you have, e.g., two impls for the same type in
 /// the same module, they do get distinct `DefId`s.
 #[derive(Clone, PartialEq, Debug, Hash, RustcEncodable, RustcDecodable)]
 pub struct DisambiguatedDefPathData {
@@ -277,29 +277,34 @@ impl DefPath {
 pub enum DefPathData {
     // Root: these should only be used for the root nodes, because
     // they are treated specially by the `def_path` function.
-    /// The crate root (marker)
+
+    /// The crate root (marker).
     CrateRoot,
-    // Catch-all for random DefId things like `DUMMY_NODE_ID`
+    // Catch-all for random `DefId` things like `DUMMY_NODE_ID`.
     Misc,
+
     // Different kinds of items and item-like things:
-    /// An impl
+
+    /// An impl.
     Impl,
-    /// Something in the type NS
+    /// Something in the type namespace.
     TypeNs(InternedString),
-    /// Something in the value NS
+    /// Something in the value namespace.
     ValueNs(InternedString),
-    /// Something in the macro NS
+    /// Something in the macro namespace.
     MacroNs(InternedString),
-    /// Something in the lifetime NS
+    /// Something in the lifetime namespace.
     LifetimeNs(InternedString),
-    /// A closure expression
+    /// A closure expression.
     ClosureExpr,
-    // Subportions of items
-    /// Implicit ctor for a unit or tuple-like struct or enum variant.
+
+    // Subportions of items:
+
+    /// Implicit constructor for a unit or tuple-like struct or enum variant.
     Ctor,
-    /// A constant expression (see {ast,hir}::AnonConst).
+    /// A constant expression (see `{ast,hir}::AnonConst`).
     AnonConst,
-    /// An `impl Trait` type node
+    /// An `impl Trait` type node.
     ImplTrait,
     /// Identifies a piece of crate metadata that is global to a whole crate
     /// (as opposed to just one item). `GlobalMetaData` components are only
@@ -435,7 +440,7 @@ impl Definitions {
         self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index);
         self.set_invocation_parent(ExpnId::root(), root_index);
 
-        // Allocate some other DefIndices that always must exist.
+        // Allocate some other `DefIndex`es that always must exist.
         GlobalMetaDataKind::allocate_def_indices(self);
 
         root_index
@@ -458,7 +463,7 @@ impl Definitions {
                 data,
                 self.table.def_key(self.node_to_def_index[&node_id]));
 
-        // The root node must be created with create_root_def()
+        // The root node must be created with `create_root_def()`.
         assert!(data != DefPathData::CrateRoot);
 
         // Find the next free disambiguator for this key.
@@ -486,9 +491,9 @@ impl Definitions {
         assert_eq!(index.index(), self.def_index_to_node.len());
         self.def_index_to_node.push(node_id);
 
-        // Some things for which we allocate DefIndices don't correspond to
-        // anything in the AST, so they don't have a NodeId. For these cases
-        // we don't need a mapping from NodeId to DefIndex.
+        // Some things for which we allocate `DefIndex`es don't correspond to
+        // anything in the AST, so they don't have a `NodeId`. For these cases
+        // we don't need a mapping from `NodeId` to `DefIndex`.
         if node_id != ast::DUMMY_NODE_ID {
             debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
             self.node_to_def_index.insert(node_id, index);
@@ -498,7 +503,7 @@ impl Definitions {
             self.expansions_that_defined.insert(index, expn_id);
         }
 
-        // The span is added if it isn't dummy
+        // The span is added if it isn't dummy.
         if !span.is_dummy() {
             self.def_index_to_span.insert(index, span);
         }
@@ -506,12 +511,12 @@ impl Definitions {
         index
     }
 
-    /// Initialize the `ast::NodeId` to `HirId` mapping once it has been generated during
+    /// Initializes the `ast::NodeId` to `HirId` mapping once it has been generated during
     /// AST to HIR lowering.
     pub fn init_node_id_to_hir_id_mapping(&mut self,
                                           mapping: IndexVec<ast::NodeId, hir::HirId>) {
         assert!(self.node_to_hir_id.is_empty(),
-                "Trying initialize NodeId -> HirId mapping twice");
+                "trying to initialize `NodeId` -> `HirId` mapping twice");
         self.node_to_hir_id = mapping;
     }
 
@@ -533,7 +538,7 @@ impl Definitions {
 
     pub fn set_invocation_parent(&mut self, invoc_id: ExpnId, parent: DefIndex) {
         let old_parent = self.invocation_parents.insert(invoc_id, parent);
-        assert!(old_parent.is_none(), "parent def-index is reset for an invocation");
+        assert!(old_parent.is_none(), "parent `DefIndex` is reset for an invocation");
     }
 }
 
@@ -585,9 +590,9 @@ impl DefPathData {
     }
 }
 
-// We define the GlobalMetaDataKind enum with this macro because we want to
+// We define the `GlobalMetaDataKind` enum with this macro because we want to
 // make sure that we exhaustively iterate over all variants when registering
-// the corresponding DefIndices in the DefTable.
+// the corresponding `DefIndex`es in the `DefTable`.
 macro_rules! define_global_metadata_kind {
     (pub enum GlobalMetaDataKind {
         $($variant:ident),*
@@ -609,7 +614,7 @@ macro_rules! define_global_metadata_kind {
                         DUMMY_SP
                     );
 
-                    // Make sure calling def_index does not crash.
+                    // Make sure calling `def_index` does not crash.
                     instance.def_index(&definitions.table);
                 })*
             }
@@ -623,7 +628,7 @@ macro_rules! define_global_metadata_kind {
                     }
                 };
 
-                // These DefKeys are all right after the root,
+                // These `DefKey`s are all right after the root,
                 // so a linear search is fine.
                 let index = def_path_table.index_to_key
                                           .iter()
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index eb8be6e6e3cbc..5cec8a593f12a 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -5,10 +5,15 @@ pub use self::definitions::{
 };
 
 use crate::dep_graph::{DepGraph, DepNode, DepKind, DepNodeIndex};
-
+use crate::hir::*;
+use crate::hir::DefKind;
 use crate::hir::def_id::{CRATE_DEF_INDEX, DefId, LocalDefId};
-
+use crate::hir::itemlikevisit::ItemLikeVisitor;
+use crate::hir::print::Nested;
 use crate::middle::cstore::CrateStoreDyn;
+use crate::ty::query::Providers;
+use crate::util::nodemap::FxHashMap;
+use crate::util::common::time;
 
 use rustc_target::spec::abi::Abi;
 use rustc_data_structures::svh::Svh;
@@ -18,15 +23,7 @@ use syntax::source_map::Spanned;
 use syntax::ext::base::MacroKind;
 use syntax_pos::{Span, DUMMY_SP};
 
-use crate::hir::*;
-use crate::hir::DefKind;
-use crate::hir::itemlikevisit::ItemLikeVisitor;
-use crate::hir::print::Nested;
-use crate::util::nodemap::FxHashMap;
-use crate::util::common::time;
-
 use std::result::Result::Err;
-use crate::ty::query::Providers;
 
 pub mod blocks;
 mod collector;
@@ -627,7 +624,7 @@ impl<'hir> Map<'hir> {
             .unwrap_or(hir_id)
     }
 
-    /// Check if the node is an argument. An argument is a local variable whose
+    /// Checks if the node is an argument. An argument is a local variable whose
     /// immediate parent is an item or a closure.
     pub fn is_argument(&self, id: HirId) -> bool {
         match self.find(id) {
@@ -733,7 +730,7 @@ impl<'hir> Map<'hir> {
     /// ```
     /// fn foo(x: usize) -> bool {
     ///     if x == 1 {
-    ///         true  // `get_return_block` gets passed the `id` corresponding
+    ///         true  // If `get_return_block` gets passed the `id` corresponding
     ///     } else {  // to this, it will return `foo`'s `HirId`.
     ///         false
     ///     }
@@ -743,7 +740,7 @@ impl<'hir> Map<'hir> {
     /// ```
     /// fn foo(x: usize) -> bool {
     ///     loop {
-    ///         true  // `get_return_block` gets passed the `id` corresponding
+    ///         true  // If `get_return_block` gets passed the `id` corresponding
     ///     }         // to this, it will return `None`.
     ///     false
     /// }
@@ -994,9 +991,9 @@ impl<'hir> Map<'hir> {
         self.map.iter().enumerate().filter_map(|(i, local_map)| {
             local_map.as_ref().map(|m| (i, m))
         }).flat_map(move |(array_index, local_map)| {
-            // Iterate over each valid entry in the local map
+            // Iterate over each valid entry in the local map.
             local_map.iter_enumerated().filter_map(move |(i, entry)| entry.map(move |_| {
-                // Reconstruct the HirId based on the 3 indices we used to find it
+                // Reconstruct the `HirId` based on the 3 indices we used to find it.
                 HirId {
                     owner: DefIndex::from(array_index),
                     local_id: i,
@@ -1207,7 +1204,7 @@ pub fn map_crate<'hir>(sess: &crate::session::Session,
         definitions,
     };
 
-    time(sess, "validate hir map", || {
+    time(sess, "validate HIR map", || {
         hir_id_validator::check_crate(&map);
     });
 
@@ -1247,9 +1244,9 @@ impl<'a> print::State<'a> {
             Node::Pat(a)          => self.print_pat(&a),
             Node::Arm(a)          => self.print_arm(&a),
             Node::Block(a)        => {
-                // containing cbox, will be closed by print-block at }
+                // Containing cbox, will be closed by print-block at `}`.
                 self.cbox(print::INDENT_UNIT);
-                // head-ibox, will be closed by print-block after {
+                // Head-ibox, will be closed by print-block after `{`.
                 self.ibox(0);
                 self.print_block(&a)
             }
@@ -1257,8 +1254,8 @@ impl<'a> print::State<'a> {
             Node::Visibility(a)   => self.print_visibility(&a),
             Node::GenericParam(_) => bug!("cannot print Node::GenericParam"),
             Node::Field(_)        => bug!("cannot print StructField"),
-            // these cases do not carry enough information in the
-            // hir_map to reconstruct their full structure for pretty
+            // These cases do not carry enough information in the
+            // `hir_map` to reconstruct their full structure for pretty
             // printing.
             Node::Ctor(..)        => bug!("cannot print isolated Ctor"),
             Node::Local(a)        => self.print_local_decl(&a),
@@ -1273,8 +1270,8 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String {
     let id_str = if include_id { &id_str[..] } else { "" };
 
     let path_str = || {
-        // This functionality is used for debugging, try to use TyCtxt to get
-        // the user-friendly path, otherwise fall back to stringifying DefPath.
+        // This functionality is used for debugging, try to use `TyCtxt` to get
+        // the user-friendly path, otherwise fall back to stringifying `DefPath`.
         crate::ty::tls::with_opt(|tcx| {
             if let Some(tcx) = tcx {
                 let def_id = map.local_def_id(id);
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index d2c45a5af8598..f5e644625729b 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -13,26 +13,24 @@ pub use self::UnsafeSource::*;
 use crate::hir::def::{Res, DefKind};
 use crate::hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
 use crate::hir::ptr::P;
-use crate::util::nodemap::{NodeMap, FxHashSet};
 use crate::mir::mono::Linkage;
+use crate::ty::AdtKind;
+use crate::ty::query::Providers;
+use crate::util::nodemap::{NodeMap, FxHashSet};
 
 use errors::FatalError;
 use syntax_pos::{Span, DUMMY_SP, symbol::InternedString, MultiSpan};
 use syntax::source_map::Spanned;
-use rustc_target::spec::abi::Abi;
 use syntax::ast::{self, CrateSugar, Ident, Name, NodeId, AsmDialect};
 use syntax::ast::{Attribute, Label, LitKind, StrStyle, FloatTy, IntTy, UintTy};
 use syntax::attr::{InlineAttr, OptimizeAttr};
 use syntax::symbol::{Symbol, kw};
 use syntax::tokenstream::TokenStream;
 use syntax::util::parser::ExprPrecedence;
-use crate::ty::AdtKind;
-use crate::ty::query::Providers;
-
+use rustc_target::spec::abi::Abi;
 use rustc_data_structures::sync::{par_for_each_in, Send, Sync};
 use rustc_data_structures::thin_vec::ThinVec;
 use rustc_macros::HashStable;
-
 use rustc_serialize::{self, Encoder, Encodable, Decoder, Decodable};
 use std::collections::{BTreeSet, BTreeMap};
 use std::fmt;
@@ -99,7 +97,8 @@ impl rustc_serialize::UseSpecializedEncodable for HirId {
         } = *self;
 
         owner.encode(s)?;
-        local_id.encode(s)
+        local_id.encode(s)?;
+        Ok(())
     }
 }
 
@@ -121,7 +120,7 @@ impl fmt::Display for HirId {
     }
 }
 
-// Hack to ensure that we don't try to access the private parts of `ItemLocalId` in this module
+// Hack to ensure that we don't try to access the private parts of `ItemLocalId` in this module.
 mod item_local_id_inner {
     use rustc_data_structures::indexed_vec::Idx;
     use rustc_macros::HashStable;
@@ -746,7 +745,7 @@ pub struct Crate {
     // Attributes from non-exported macros, kept only for collecting the library feature list.
     pub non_exported_macro_attrs: HirVec<Attribute>,
 
-    // N.B., we use a BTreeMap here so that `visit_all_items` iterates
+    // N.B., we use a `BTreeMap` here so that `visit_all_items` iterates
     // over the ids in increasing order. In principle it should not
     // matter what order we visit things in, but in *practice* it
     // does, because it can affect the order in which errors are
@@ -1403,13 +1402,13 @@ pub struct AnonConst {
     pub body: BodyId,
 }
 
-/// An expression
+/// An expression.
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct Expr {
-    pub span: Span,
+    pub hir_id: HirId,
     pub node: ExprKind,
     pub attrs: ThinVec<Attribute>,
-    pub hir_id: HirId,
+    pub span: Span,
 }
 
 // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
@@ -2422,37 +2421,37 @@ pub enum ItemKind {
     ///
     /// or just
     ///
-    /// `use foo::bar::baz;` (with `as baz` implicitly on the right)
+    /// `use foo::bar::baz;` (with `as baz` implicitly on the right).
     Use(P<Path>, UseKind),
 
-    /// A `static` item
+    /// A `static` item.
     Static(P<Ty>, Mutability, BodyId),
-    /// A `const` item
+    /// A `const` item.
     Const(P<Ty>, BodyId),
-    /// A function declaration
+    /// A function declaration.
     Fn(P<FnDecl>, FnHeader, Generics, BodyId),
-    /// A module
+    /// A module.
     Mod(Mod),
-    /// An external module
+    /// An external module.
     ForeignMod(ForeignMod),
-    /// Module-level inline assembly (from global_asm!)
+    /// Module-level inline assembly (from `global_asm!`).
     GlobalAsm(P<GlobalAsm>),
-    /// A type alias, e.g., `type Foo = Bar<u8>`
+    /// A type alias, e.g., `type Foo = Bar<u8>`.
     TyAlias(P<Ty>, Generics),
-    /// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`
+    /// An opaque `impl Trait` type alias, e.g., `type Foo = impl Bar;`.
     OpaqueTy(OpaqueTy),
-    /// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`
+    /// An enum definition, e.g., `enum Foo<A, B> {C<A>, D<B>}`.
     Enum(EnumDef, Generics),
-    /// A struct definition, e.g., `struct Foo<A> {x: A}`
+    /// A struct definition, e.g., `struct Foo<A> {x: A}`.
     Struct(VariantData, Generics),
-    /// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`
+    /// A union definition, e.g., `union Foo<A, B> {x: A, y: B}`.
     Union(VariantData, Generics),
-    /// A trait definition
+    /// A trait definition.
     Trait(IsAuto, Unsafety, Generics, GenericBounds, HirVec<TraitItemRef>),
-    /// A trait alias
+    /// A trait alias.
     TraitAlias(Generics, GenericBounds),
 
-    /// An implementation, eg `impl<A> Trait for Foo { .. }`
+    /// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
     Impl(Unsafety,
          ImplPolarity,
          Defaultness,
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 21cc72efee4a3..cfbfb5eceb550 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1293,11 +1293,11 @@ impl<'a> State<'a> {
                 self.print_closure_params(&decl, body);
                 self.s.space();
 
-                // this is a bare expression
+                // This is a bare expression.
                 self.ann.nested(self, Nested::Body(body));
                 self.end(); // need to close a box
 
-                // a box will be closed by print_expr, but we didn't want an overall
+                // A box will be closed by `print_expr`, but we didn't want an overall
                 // wrapper so we closed the corresponding opening. so create an
                 // empty box to satisfy the close.
                 self.ibox(0);
@@ -1307,9 +1307,9 @@ impl<'a> State<'a> {
                     self.print_ident(label.ident);
                     self.word_space(":");
                 }
-                // containing cbox, will be closed by print-block at }
+                // containing cbox, will be closed by print-block at `}`
                 self.cbox(INDENT_UNIT);
-                // head-box, will be closed by print-block after {
+                // head-box, will be closed by print-block after `{`
                 self.ibox(0);
                 self.print_block(&blk);
             }
@@ -1759,7 +1759,7 @@ impl<'a> State<'a> {
                         self.word_space(",");
                     }
                     if let PatKind::Wild = p.node {
-                        // Print nothing
+                        // Print nothing.
                     } else {
                         self.print_pat(&p);
                     }
@@ -1891,7 +1891,7 @@ impl<'a> State<'a> {
             i += 1;
 
             if let hir::TyKind::Infer = ty.node {
-                // Print nothing
+                // Print nothing.
             } else {
                 s.s.word(":");
                 s.s.space();
@@ -2221,7 +2221,6 @@ impl<'a> State<'a> {
     }
 }
 
-// Dup'ed from parse::classify, but adapted for the HIR.
 /// Does this expression require a semicolon to be treated
 /// as a statement? The negation of this: 'can this expression
 /// be used as a statement without a semicolon' -- is used
@@ -2229,6 +2228,8 @@ impl<'a> State<'a> {
 ///     if true {...} else {...}
 ///      |x| 5
 /// isn't parsed as (if true {...} else {...} | x) | 5
+//
+// Duplicated from `parse::classify`, but adapted for the HIR.
 fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool {
     match e.node {
         hir::ExprKind::Match(..) |
@@ -2238,7 +2239,7 @@ fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool {
     }
 }
 
-/// this statement requires a semicolon after it.
+/// This statement requires a semicolon after it.
 /// note that in one case (stmt_semi), we've already
 /// seen the semicolon, and thus don't need another.
 fn stmt_ends_with_semi(stmt: &hir::StmtKind) -> bool {
@@ -2277,7 +2278,7 @@ fn bin_op_to_assoc_op(op: hir::BinOpKind) -> AssocOp {
     }
 }
 
-/// Expressions that syntactically contain an "exterior" struct literal i.e., not surrounded by any
+/// Expressions that syntactically contain an "exterior" struct literal, i.e., not surrounded by any
 /// parens or other delimiters, e.g., `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
 /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
 fn contains_exterior_struct_lit(value: &hir::Expr) -> bool {
@@ -2287,7 +2288,7 @@ fn contains_exterior_struct_lit(value: &hir::Expr) -> bool {
         hir::ExprKind::Assign(ref lhs, ref rhs) |
         hir::ExprKind::AssignOp(_, ref lhs, ref rhs) |
         hir::ExprKind::Binary(_, ref lhs, ref rhs) => {
-            // X { y: 1 } + X { y: 2 }
+            // `X { y: 1 } + X { y: 2 }`
             contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs)
         }
         hir::ExprKind::Unary(_, ref x) |
@@ -2295,12 +2296,12 @@ fn contains_exterior_struct_lit(value: &hir::Expr) -> bool {
         hir::ExprKind::Type(ref x, _) |
         hir::ExprKind::Field(ref x, _) |
         hir::ExprKind::Index(ref x, _) => {
-            // &X { y: 1 }, X { y: 1 }.y
+            // `&X { y: 1 }, X { y: 1 }.y`
             contains_exterior_struct_lit(&x)
         }
 
         hir::ExprKind::MethodCall(.., ref exprs) => {
-            // X { y: 1 }.bar(...)
+            // `X { y: 1 }.bar(...)`
             contains_exterior_struct_lit(&exprs[0])
         }
 
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index e77faea1e4c58..182a9ade8c36e 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -12,7 +12,6 @@ use std::hash as std_hash;
 use std::cell::RefCell;
 
 use syntax::ast;
-
 use syntax::source_map::SourceMap;
 use syntax::ext::hygiene::SyntaxContext;
 use syntax::symbol::Symbol;
@@ -20,9 +19,9 @@ use syntax::tokenstream::DelimSpan;
 use syntax_pos::{Span, DUMMY_SP};
 use syntax_pos::hygiene;
 
-use rustc_data_structures::stable_hasher::{HashStable,
-                                           StableHasher, StableHasherResult,
-                                           ToStableHashKey};
+use rustc_data_structures::stable_hasher::{
+    HashStable, StableHasher, StableHasherResult, ToStableHashKey,
+};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use smallvec::SmallVec;
 
@@ -32,9 +31,9 @@ fn compute_ignored_attr_names() -> FxHashSet<Symbol> {
 }
 
 /// This is the context state available during incr. comp. hashing. It contains
-/// enough information to transform DefIds and HirIds into stable DefPaths (i.e.
-/// a reference to the TyCtxt) and it holds a few caches for speeding up various
-/// things (e.g., each DefId/DefPath is only hashed once).
+/// enough information to transform `DefId`s and `HirId`s into stable `DefPath`s (i.e.,
+/// a reference to the `TyCtxt`) and it holds a few caches for speeding up various
+/// things (e.g., each `DefId`/`DefPath` is only hashed once).
 #[derive(Clone)]
 pub struct StableHashingContext<'a> {
     sess: &'a Session,
@@ -46,7 +45,7 @@ pub struct StableHashingContext<'a> {
     node_id_hashing_mode: NodeIdHashingMode,
 
     // Very often, we are hashing something that does not need the
-    // CachingSourceMapView, so we initialize it lazily.
+    // `CachingSourceMapView`, so we initialize it lazily.
     raw_source_map: &'a SourceMap,
     caching_source_map: Option<CachingSourceMapView<'a>>,
 }
@@ -57,24 +56,24 @@ pub enum NodeIdHashingMode {
     HashDefPath,
 }
 
-/// The BodyResolver allows to map a BodyId to the corresponding hir::Body.
-/// We could also just store a plain reference to the hir::Crate but we want
+/// The `BodyResolver` allows mapping a `BodyId` to the corresponding `hir::Body`.
+/// We could also just store a plain reference to the `hir::Crate` but we want
 /// to avoid that the crate is used to get untracked access to all of the HIR.
 #[derive(Clone, Copy)]
 struct BodyResolver<'tcx>(&'tcx hir::Crate);
 
 impl<'tcx> BodyResolver<'tcx> {
-    // Return a reference to the hir::Body with the given BodyId.
-    // DOES NOT DO ANY TRACKING, use carefully.
+    /// Returns a reference to the `hir::Body` with the given `BodyId`.
+    /// **Does not do any tracking**; use carefully.
     fn body(self, id: hir::BodyId) -> &'tcx hir::Body {
         self.0.body(id)
     }
 }
 
 impl<'a> StableHashingContext<'a> {
-    // The `krate` here is only used for mapping BodyIds to Bodies.
-    // Don't use it for anything else or you'll run the risk of
-    // leaking data out of the tracking system.
+    /// The `krate` here is only used for mapping `BodyId`s to `Body`s.
+    /// Don't use it for anything else or you'll run the risk of
+    /// leaking data out of the tracking system.
     #[inline]
     pub fn new(sess: &'a Session,
                krate: &'a hir::Crate,
@@ -217,9 +216,7 @@ impl<'a> StableHashingContextProvider<'a> for StableHashingContext<'a> {
     }
 }
 
-impl<'a> crate::dep_graph::DepGraphSafe for StableHashingContext<'a> {
-}
-
+impl<'a> crate::dep_graph::DepGraphSafe for StableHashingContext<'a> {}
 
 impl<'a> HashStable<StableHashingContext<'a>> for hir::BodyId {
     fn hash_stable<W: StableHasherResult>(&self,
@@ -292,16 +289,15 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for ast::NodeId {
 }
 
 impl<'a> HashStable<StableHashingContext<'a>> for Span {
-
-    // Hash a span in a stable way. We can't directly hash the span's BytePos
-    // fields (that would be similar to hashing pointers, since those are just
-    // offsets into the SourceMap). Instead, we hash the (file name, line, column)
-    // triple, which stays the same even if the containing SourceFile has moved
-    // within the SourceMap.
-    // Also note that we are hashing byte offsets for the column, not unicode
-    // codepoint offsets. For the purpose of the hash that's sufficient.
-    // Also, hashing filenames is expensive so we avoid doing it twice when the
-    // span starts and ends in the same file, which is almost always the case.
+    /// Hashes a span in a stable way. We can't directly hash the span's `BytePos`
+    /// fields (that would be similar to hashing pointers, since those are just
+    /// offsets into the `SourceMap`). Instead, we hash the (file name, line, column)
+    /// triple, which stays the same even if the containing `SourceFile` has moved
+    /// within the `SourceMap`.
+    /// Also note that we are hashing byte offsets for the column, not unicode
+    /// codepoint offsets. For the purpose of the hash that's sufficient.
+    /// Also, hashing filenames is expensive so we avoid doing it twice when the
+    /// span starts and ends in the same file, which is almost always the case.
     fn hash_stable<W: StableHasherResult>(&self,
                                           hcx: &mut StableHashingContext<'a>,
                                           hasher: &mut StableHasher<W>) {
@@ -340,7 +336,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for Span {
         }
 
         std_hash::Hash::hash(&TAG_VALID_SPAN, hasher);
-        // We truncate the stable_id hash and line and col numbers. The chances
+        // We truncate the stable ID hash and line and column numbers. The chances
         // of causing a collision this way should be minimal.
         std_hash::Hash::hash(&(file_lo.name_hash as u64), hasher);
 
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index fb981d961129f..6e6492d0426f2 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -5,8 +5,10 @@ use crate::hir;
 use crate::hir::map::DefPathHash;
 use crate::hir::def_id::{DefId, LocalDefId, CrateNum, CRATE_DEF_INDEX};
 use crate::ich::{StableHashingContext, NodeIdHashingMode, Fingerprint};
-use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
-                                           StableHasher, StableHasherResult};
+
+use rustc_data_structures::stable_hasher::{
+    HashStable, ToStableHashKey, StableHasher, StableHasherResult,
+};
 use smallvec::SmallVec;
 use std::mem;
 use syntax::ast;
@@ -82,9 +84,9 @@ for hir::ItemLocalId {
     }
 }
 
-// The following implementations of HashStable for ItemId, TraitItemId, and
-// ImplItemId deserve special attention. Normally we do not hash NodeIds within
-// the HIR, since they just signify a HIR nodes own path. But ItemId et al
+// The following implementations of HashStable for `ItemId`, `TraitItemId`, and
+// `ImplItemId` deserve special attention. Normally we do not hash `NodeId`s within
+// the HIR, since they just signify a HIR nodes own path. But `ItemId` et al
 // are used when another item in the HIR is *referenced* and we certainly
 // want to pick up on a reference changing its target, so we hash the NodeIds
 // in "DefPath Mode".
@@ -131,7 +133,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItemId {
     }
 }
 
-
 impl_stable_hash_for!(struct ast::Label {
     ident
 });
@@ -241,7 +242,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::ImplItem {
     }
 }
 
-impl_stable_hash_for!(enum ::syntax::ast::CrateSugar {
+impl_stable_hash_for!(enum ast::CrateSugar {
     JustCrate,
     PubCrate,
 });
@@ -365,8 +366,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::def_id::DefIndex {
     }
 }
 
-impl<'a> ToStableHashKey<StableHashingContext<'a>>
-for hir::def_id::DefIndex {
+impl<'a> ToStableHashKey<StableHashingContext<'a>> for hir::def_id::DefIndex {
     type KeyType = DefPathHash;
 
     #[inline]
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index be7669fcad875..f230c53728748 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -204,7 +204,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::TyVid {
     fn hash_stable<W: StableHasherResult>(&self,
                                           _hcx: &mut StableHashingContext<'a>,
                                           _hasher: &mut StableHasher<W>) {
-        // TyVid values are confined to an inference context and hence
+        // `TyVid` values are confined to an inference context and hence
         // should not be hashed.
         bug!("ty::TyKind::hash_stable() - can't hash a TyVid {:?}.", *self)
     }
@@ -214,7 +214,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::IntVid {
     fn hash_stable<W: StableHasherResult>(&self,
                                           _hcx: &mut StableHashingContext<'a>,
                                           _hasher: &mut StableHasher<W>) {
-        // IntVid values are confined to an inference context and hence
+        // `IntVid` values are confined to an inference context and hence
         // should not be hashed.
         bug!("ty::TyKind::hash_stable() - can't hash an IntVid {:?}.", *self)
     }
@@ -224,7 +224,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::FloatVid {
     fn hash_stable<W: StableHasherResult>(&self,
                                           _hcx: &mut StableHashingContext<'a>,
                                           _hasher: &mut StableHasher<W>) {
-        // FloatVid values are confined to an inference context and hence
+        // `FloatVid` values are confined to an inference context and hence
         // should not be hashed.
         bug!("ty::TyKind::hash_stable() - can't hash a FloatVid {:?}.", *self)
     }
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index cc28567e2fc9e..8638f42976f04 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -1321,13 +1321,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         T: TypeFoldable<'tcx>,
     {
         if !value.needs_infer() {
-            return value.clone(); // avoid duplicated subst-folding
+            return value.clone(); // Avoid duplicated subst-folding.
         }
         let mut r = resolve::OpportunisticVarResolver::new(self);
         value.fold_with(&mut r)
     }
 
-    /// Returns first unresolved variable contained in `T`. In the
+    /// Returns the first unresolved variable contained in `T`. In the
     /// process of visiting `T`, this will resolve (where possible)
     /// type variables in `T`, but it never constructs the final,
     /// resolved type, so it's more efficient than
@@ -1462,7 +1462,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
         let copy_def_id = self.tcx.require_lang_item(lang_items::CopyTraitLangItem, None);
 
-        // this can get called from typeck (by euv), and moves_by_default
+        // This can get called from typeck (by euv), and `moves_by_default`
         // rightly refuses to work with inference variables, but
         // moves_by_default has a cache, which we want to use in other
         // cases.
@@ -1482,7 +1482,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         closure_kind_ty.to_opt_closure_kind()
     }
 
-    /// Obtain the signature of a closure. For closures, unlike
+    /// Obtains the signature of a closure. For closures, unlike
     /// `tcx.fn_sig(def_id)`, this method will work during the
     /// type-checking of the enclosing function and return the closure
     /// signature in its partially inferred state.
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 77df93080cd16..c658120b95df3 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -16,32 +16,32 @@
 
 use self::TargetLint::*;
 
-use std::slice;
-use rustc_data_structures::sync::{ReadGuard, Lock, ParallelIterator, join, par_iter};
+use crate::hir;
+use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use crate::hir::intravisit as hir_visit;
+use crate::hir::intravisit::Visitor;
+use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData};
 use crate::lint::{EarlyLintPass, LateLintPass, EarlyLintPassObject, LateLintPassObject};
 use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer};
 use crate::lint::builtin::BuiltinLintDiagnostics;
 use crate::lint::levels::{LintLevelSets, LintLevelsBuilder};
 use crate::middle::privacy::AccessLevels;
-use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
 use crate::session::{config, early_error, Session};
 use crate::ty::{self, print::Printer, subst::Kind, TyCtxt, Ty};
 use crate::ty::layout::{LayoutError, LayoutOf, TyLayout};
 use crate::util::nodemap::FxHashMap;
 use crate::util::common::time;
 
+use errors::DiagnosticBuilder;
+use std::slice;
 use std::default::Default as StdDefault;
+use rustc_data_structures::sync::{ReadGuard, Lock, ParallelIterator, join, par_iter};
+use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
 use syntax::ast;
 use syntax::edition;
-use syntax_pos::{MultiSpan, Span, symbol::Symbol};
-use errors::DiagnosticBuilder;
-use crate::hir;
-use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use crate::hir::intravisit as hir_visit;
-use crate::hir::intravisit::Visitor;
-use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData};
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax::visit as ast_visit;
+use syntax_pos::{MultiSpan, Span, symbol::Symbol};
 
 /// Information about the registered lints.
 ///
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index e33f8e27871b2..5b490b701267d 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -875,12 +875,12 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
         ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external"
         ExpnKind::Macro(MacroKind::Bang, _) => {
             if expn_data.def_site.is_dummy() {
-                // dummy span for the def_site means it's an external macro
+                // Dummy span for the `def_site` means it's an external macro.
                 return true;
             }
             match sess.source_map().span_to_snippet(expn_data.def_site) {
                 Ok(code) => !code.starts_with("macro_rules"),
-                // no snippet = external macro or compiler-builtin expansion
+                // No snippet means external macro or compiler-builtin expansion.
                 Err(_) => true,
             }
         }
@@ -888,7 +888,7 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
     }
 }
 
-/// Returns whether `span` originates in a derive macro's expansion
+/// Returns `true` if `span` originates in a derive-macro's expansion.
 pub fn in_derive_expansion(span: Span) -> bool {
     if let ExpnKind::Macro(MacroKind::Derive, _) = span.ctxt().outer_expn_data().kind {
         return true;
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index 53c099c0b4339..93bb301f0951a 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -16,17 +16,17 @@ struct EntryContext<'a, 'tcx> {
 
     map: &'a hir_map::Map<'tcx>,
 
-    // The top-level function called 'main'
+    /// The top-level function called 'main'.
     main_fn: Option<(HirId, Span)>,
 
-    // The function that has attribute named 'main'
+    /// The function that has attribute named 'main'.
     attr_main_fn: Option<(HirId, Span)>,
 
-    // The function that has the attribute 'start' on it
+    /// The function that has the attribute 'start' on it.
     start_fn: Option<(HirId, Span)>,
 
-    // The functions that one might think are 'main' but aren't, e.g.
-    // main functions not defined at the top level. For diagnostics.
+    /// The functions that one might think are 'main' but aren't, e.g.
+    /// main functions not defined at the top level. For diagnostics.
     non_main_fns: Vec<(HirId, Span)> ,
 }
 
@@ -39,11 +39,11 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
     }
 
     fn visit_trait_item(&mut self, _trait_item: &'tcx TraitItem) {
-        // entry fn is never a trait item
+        // Entry fn is never a trait item.
     }
 
     fn visit_impl_item(&mut self, _impl_item: &'tcx ImplItem) {
-        // entry fn is never an impl item
+        // Entry fn is never a trait item.
     }
 }
 
@@ -54,7 +54,7 @@ fn entry_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<(DefId, EntryFnType)> {
         *ty == config::CrateType::Executable
     });
     if !any_exe {
-        // No need to find a main function
+        // No need to find a main function.
         return None;
     }
 
@@ -148,7 +148,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De
     } else if let Some((hir_id, _)) = visitor.main_fn {
         Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main))
     } else {
-        // No main function
+        // There is no main function.
         let mut err = struct_err!(tcx.sess, E0601,
             "`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE));
         if !visitor.non_main_fns.is_empty() {
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 222c2a405d65b..de6dadabcbf56 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -596,7 +596,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
             }
 
             hir::StmtKind::Item(_) => {
-                // we don't visit nested items in this visitor,
+                // We don't visit nested items in this visitor,
                 // only the fn body we were given.
             }
 
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 6b04600eb75f8..6dfd7a7f94378 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -3,10 +3,8 @@
 //! Language items are items that represent concepts intrinsic to the language
 //! itself. Examples are:
 //!
-//! * Traits that specify "kinds"; e.g., "Sync", "Send".
-//!
-//! * Traits that represent operators; e.g., "Add", "Sub", "Index".
-//!
+//! * Traits that specify "kinds"; e.g., `Sync`, `Send`.
+//! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`.
 //! * Functions called by the compiler itself.
 
 pub use self::LangItem::*;
@@ -151,11 +149,11 @@ impl ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> {
     }
 
     fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
-        // at present, lang items are always items, not trait items
+        // At present, lang items are always items, not trait items.
     }
 
     fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
-        // at present, lang items are always items, not impl items
+        // At present, lang items are always items, not impl items.
     }
 }
 
@@ -204,7 +202,7 @@ impl LanguageItemCollector<'tcx> {
     }
 }
 
-/// Extract the first `lang = "$name"` out of a list of attributes.
+/// Extracts the first `lang = "$name"` out of a list of attributes.
 /// The attributes `#[panic_handler]` and `#[alloc_error_handler]`
 /// are also extracted out when found.
 pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
@@ -216,7 +214,7 @@ pub fn extract(attrs: &[ast::Attribute]) -> Option<(Symbol, Span)> {
     }))
 }
 
-/// Traverse and collect all the lang items in all crates.
+/// Traverses and collects all the lang items in all crates.
 pub fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> LanguageItems {
     // Initialize the collector.
     let mut collector = LanguageItemCollector::new(tcx);
@@ -367,7 +365,7 @@ language_item_table! {
 
     MaybeUninitLangItem,         "maybe_uninit",       maybe_uninit,            Target::Union;
 
-    // Align offset for stride != 1, must not panic.
+    // Align offset for stride != 1; must not panic.
     AlignOffsetLangItem,         "align_offset",       align_offset_fn,         Target::Fn;
 
     TerminationTraitLangItem,    "termination",        termination,             Target::Trait;
@@ -378,7 +376,7 @@ language_item_table! {
 
 impl<'tcx> TyCtxt<'tcx> {
     /// Returns the `DefId` for a given `LangItem`.
-    /// If not found, fatally abort compilation.
+    /// If not found, fatally aborts compilation.
     pub fn require_lang_item(&self, lang_item: LangItem, span: Option<Span>) -> DefId {
         self.lang_items().require(lang_item).unwrap_or_else(|msg| {
             if let Some(span) = span {
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 28aa86ef9afb2..b9d8a4ec68fad 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -6,29 +6,27 @@
 //!
 //! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
 
+use crate::hir;
+use crate::hir::Node;
+use crate::hir::def_id::DefId;
+use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
+use crate::hir::{Block, Arm, Pat, PatKind, Stmt, Expr, Local};
 use crate::ich::{StableHashingContext, NodeIdHashingMode};
 use crate::util::nodemap::{FxHashMap, FxHashSet};
-use crate::ty;
+use crate::ty::{self, DefIdTree, TyCtxt};
+use crate::ty::query::Providers;
 
-use std::mem;
-use std::fmt;
+use rustc_data_structures::indexed_vec::Idx;
+use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult};
 use rustc_macros::HashStable;
 use syntax::source_map;
 use syntax_pos::{Span, DUMMY_SP};
-use crate::ty::{DefIdTree, TyCtxt};
-use crate::ty::query::Providers;
 
-use crate::hir;
-use crate::hir::Node;
-use crate::hir::def_id::DefId;
-use crate::hir::intravisit::{self, Visitor, NestedVisitorMap};
-use crate::hir::{Block, Arm, Pat, PatKind, Stmt, Expr, Local};
-use rustc_data_structures::indexed_vec::Idx;
-use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
-                                           StableHasherResult};
+use std::fmt;
+use std::mem;
 
-/// Scope represents a statically-describable scope that can be
-/// used to bound the lifetime/region for values.
+/// Represents a statically-describable scope that can be used to
+/// bound the lifetime/region for values.
 ///
 /// `Node(node_id)`: Any AST node that has any scope at all has the
 /// `Node(node_id)` scope. Other variants represent special cases not
@@ -225,7 +223,7 @@ pub struct ScopeTree {
     /// have lifetime parameters free in this body.
     root_parent: Option<hir::HirId>,
 
-    /// `parent_map` maps from a scope ID to the enclosing scope id;
+    /// Maps from a scope ID to the enclosing scope id;
     /// this is usually corresponding to the lexical nesting, though
     /// in the case of closures the parent scope is the innermost
     /// conditional expression or repeating block. (Note that the
@@ -233,17 +231,17 @@ pub struct ScopeTree {
     /// the closure itself.)
     parent_map: FxHashMap<Scope, (Scope, ScopeDepth)>,
 
-    /// `var_map` maps from a variable or binding ID to the block in
-    /// which that variable is declared.
+    /// Maps from a variable or binding ID to the block in which that
+    /// variable is declared.
     var_map: FxHashMap<hir::ItemLocalId, Scope>,
 
-    /// maps from a `NodeId` to the associated destruction scope (if any)
+    /// Maps from a `NodeId` to the associated destruction scope (if any).
     destruction_scopes: FxHashMap<hir::ItemLocalId, Scope>,
 
-    /// `rvalue_scopes` includes entries for those expressions whose cleanup scope is
-    /// larger than the default. The map goes from the expression id
-    /// to the cleanup scope id. For rvalues not present in this
-    /// table, the appropriate cleanup scope is the innermost
+    /// `rvalue_scopes` includes entries for those expressions whose
+    /// cleanup scope is larger than the default. The map goes from the
+    /// expression ID to the cleanup scope id. For rvalues not present in
+    /// this table, the appropriate cleanup scope is the innermost
     /// enclosing statement, conditional expression, or repeating
     /// block (see `terminating_scopes`).
     /// In constants, None is used to indicate that certain expressions
@@ -318,7 +316,7 @@ pub struct ScopeTree {
     ///     4. By `2.` and `3.`, `D` is *statically* storage-dead at `U`,
     ///     QED.
     ///
-    /// I don't think this property relies on `3.` in an essential way - it
+    /// This property ought to not on (3) in an essential way -- it
     /// is probably still correct even if we have "unrestricted" terminating
     /// scopes. However, why use the complicated proof when a simple one
     /// works?
@@ -341,20 +339,20 @@ pub struct ScopeTree {
 
 #[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub struct YieldData {
-    /// `Span` of the yield.
+    /// The `Span` of the yield.
     pub span: Span,
-    /// The number of expressions and patterns appearing before the `yield` in the body + 1.
+    /// The number of expressions and patterns appearing before the `yield` in the body plus one.
     pub expr_and_pat_count: usize,
     pub source: hir::YieldSource,
 }
 
 #[derive(Debug, Copy, Clone)]
 pub struct Context {
-    /// the root of the current region tree. This is typically the id
+    /// The root of the current region tree. This is typically the id
     /// of the innermost fn body. Each fn forms its own disjoint tree
     /// in the region hierarchy. These fn bodies are themselves
     /// arranged into a tree. See the "Modeling closures" section of
-    /// the README in infer::region_constraints for more
+    /// the README in `infer::region_constraints` for more
     /// details.
     root_id: Option<hir::ItemLocalId>,
 
@@ -369,15 +367,15 @@ pub struct Context {
 struct RegionResolutionVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
 
-    // The number of expressions and patterns visited in the current body
+    // The number of expressions and patterns visited in the current body.
     expr_and_pat_count: usize,
     // When this is `true`, we record the `Scopes` we encounter
     // when processing a Yield expression. This allows us to fix
     // up their indices.
     pessimistic_yield: bool,
-    // Stores scopes when pessimistic_yield is true.
+    // Stores scopes when `pessimistic_yield` is `true`.
     fixup_scopes: Vec<Scope>,
-    // Generated scope tree:
+    // The generated scope tree.
     scope_tree: ScopeTree,
 
     cx: Context,
@@ -411,7 +409,7 @@ struct ExprLocatorVisitor {
     expr_and_pat_count: usize,
 }
 
-// This visitor has to have the same visit_expr calls as RegionResolutionVisitor
+// This visitor has to have the same `visit_expr` calls as `RegionResolutionVisitor`
 // since `expr_count` is compared against the results there.
 impl<'tcx> Visitor<'tcx> for ExprLocatorVisitor {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
@@ -456,7 +454,7 @@ impl<'tcx> ScopeTree {
             assert!(prev.is_none());
         }
 
-        // record the destruction scopes for later so we can query them
+        // Record the destruction scopes for later so we can query them.
         if let ScopeData::Destruction = child.data {
             self.destruction_scopes.insert(child.item_local_id(), child);
         }
@@ -478,7 +476,7 @@ impl<'tcx> ScopeTree {
         self.destruction_scopes.get(&n).cloned()
     }
 
-    /// Records that `sub_closure` is defined within `sup_closure`. These ids
+    /// Records that `sub_closure` is defined within `sup_closure`. These IDs
     /// should be the ID of the block that is the fn body, which is
     /// also the root of the region hierarchy for that fn.
     fn record_closure_parent(&mut self,
@@ -505,14 +503,14 @@ impl<'tcx> ScopeTree {
         self.rvalue_scopes.insert(var, lifetime);
     }
 
+    /// Returns the narrowest scope that encloses `id`, if any.
     pub fn opt_encl_scope(&self, id: Scope) -> Option<Scope> {
-        //! Returns the narrowest scope that encloses `id`, if any.
         self.parent_map.get(&id).cloned().map(|(p, _)| p)
     }
 
+    /// Returns the narrowest scope that encloses `id`, if any.
     #[allow(dead_code)] // used in cfg
     pub fn encl_scope(&self, id: Scope) -> Scope {
-        //! Returns the narrowest scope that encloses `id`, if any.
         self.opt_encl_scope(id).unwrap()
     }
 
@@ -522,16 +520,15 @@ impl<'tcx> ScopeTree {
             bug!("no enclosing scope for id {:?}", var_id))
     }
 
+    /// Returns the scope when the temp created by `expr_id` will be cleaned up.
     pub fn temporary_scope(&self, expr_id: hir::ItemLocalId) -> Option<Scope> {
-        //! Returns the scope when temp created by expr_id will be cleaned up
-
-        // check for a designated rvalue scope
+        // Check for a designated rvalue scope.
         if let Some(&s) = self.rvalue_scopes.get(&expr_id) {
             debug!("temporary_scope({:?}) = {:?} [custom]", expr_id, s);
             return s;
         }
 
-        // else, locate the innermost terminating scope
+        // Otherwise, locate the innermost terminating scope
         // if there's one. Static items, for instance, won't
         // have an enclosing scope, hence no scope will be
         // returned.
@@ -552,9 +549,8 @@ impl<'tcx> ScopeTree {
         return None;
     }
 
+    /// Returns the lifetime of the variable `id`.
     pub fn var_region(&self, id: hir::ItemLocalId) -> ty::RegionKind {
-        //! Returns the lifetime of the variable `id`.
-
         let scope = ty::ReScope(self.var_scope(id));
         debug!("var_region({:?}) = {:?}", id, scope);
         scope
@@ -589,7 +585,7 @@ impl<'tcx> ScopeTree {
         return true;
     }
 
-    /// Returns the ID of the innermost containing body
+    /// Returns the ID of the innermost containing body.
     pub fn containing_body(&self, mut scope: Scope) -> Option<hir::ItemLocalId> {
         loop {
             if let ScopeData::CallSite = scope.data {
diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs
index 3d33e249536c7..1f604877841a7 100644
--- a/src/librustc/mir/cache.rs
+++ b/src/librustc/mir/cache.rs
@@ -27,7 +27,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for Cache {
     fn hash_stable<W: StableHasherResult>(&self,
                                           _: &mut StableHashingContext<'a>,
                                           _: &mut StableHasher<W>) {
-        // do nothing
+        // Do nothing.
     }
 }
 
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index 13552a61acb0e..e81096c3066f1 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -13,7 +13,7 @@ use rustc_data_structures::sorted_map::SortedMap;
 use rustc_target::abi::HasDataLayout;
 use std::borrow::Cow;
 
-// NOTE: When adding new fields, make sure to adjust the Snapshot impl in
+// NOTE: When adding new fields, make sure to adjust the `Snapshot` impl in
 // `src/librustc_mir/interpret/snapshot.rs`.
 #[derive(
     Clone,
@@ -27,7 +27,7 @@ use std::borrow::Cow;
     RustcDecodable,
     HashStable,
 )]
-pub struct Allocation<Tag=(),Extra=()> {
+pub struct Allocation<Tag = (),Extra = ()> {
     /// The actual bytes of the allocation.
     /// Note that the bytes of a pointer represent the offset of the pointer.
     bytes: Vec<u8>,
@@ -42,7 +42,7 @@ pub struct Allocation<Tag=(),Extra=()> {
     pub size: Size,
     /// The alignment of the allocation to detect unaligned reads.
     pub align: Align,
-    /// Whether the allocation is mutable.
+    /// `true` if the allocation is mutable.
     /// Also used by codegen to determine if a static should be put into mutable memory,
     /// which happens for `static mut` and `static` with interior mutability.
     pub mutability: Mutability,
@@ -50,7 +50,6 @@ pub struct Allocation<Tag=(),Extra=()> {
     pub extra: Extra,
 }
 
-
 pub trait AllocationExtra<Tag>: ::std::fmt::Debug + Clone {
     // There is no constructor in here because the constructor's type depends
     // on `MemoryKind`, and making things sufficiently generic leads to painful
@@ -92,7 +91,7 @@ pub trait AllocationExtra<Tag>: ::std::fmt::Debug + Clone {
     }
 }
 
-// For Tag=() and no extra state, we have is a trivial implementation.
+// For `Tag = ()` and no extra state, we have a trivial implementation.
 impl AllocationExtra<()> for () { }
 
 // The constructors are all without extra; the extra gets added by a machine hook later.
@@ -185,7 +184,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
 
 impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx Allocation {}
 
-/// Byte accessors
+/// Byte accessors.
 impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
     /// Just a small local helper function to avoid a bit of code repetition.
     /// Returns the range of this allocation that was meant.
@@ -195,7 +194,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         offset: Size,
         size: Size
     ) -> Range<usize> {
-        let end = offset + size; // this does overflow checking
+        let end = offset + size; // This does overflow checking.
         assert_eq!(
             end.bytes() as usize as u64, end.bytes(),
             "cannot handle this access on this host architecture"
@@ -232,7 +231,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
             self.check_defined(ptr, size)?;
             self.check_relocations(cx, ptr, size)?;
         } else {
-            // We still don't want relocations on the *edges*
+            // We still don't want relocations on the *edges*.
             self.check_relocation_edges(cx, ptr, size)?;
         }
 
@@ -241,7 +240,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         Ok(&self.bytes[range])
     }
 
-    /// Check that these bytes are initialized and not pointer bytes, and then return them
+    /// Checks that these bytes are initialized and not pointer bytes, and then return them
     /// as a slice.
     ///
     /// It is the caller's responsibility to check bounds and alignment beforehand.
@@ -293,7 +292,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
     }
 }
 
-/// Reading and writing
+/// Reading and writing.
 impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
     /// Reads bytes until a `0` is encountered. Will error if the end of the allocation is reached
     /// before a `0` is found.
@@ -329,9 +328,9 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         allow_ptr_and_undef: bool,
     ) -> InterpResult<'tcx>
     {
-        // Check bounds and relocations on the edges
+        // Check bounds and relocations on the edges.
         self.get_bytes_with_undef_and_ptr(cx, ptr, size)?;
-        // Check undef and ptr
+        // Check undef and ptr.
         if !allow_ptr_and_undef {
             self.check_defined(ptr, size)?;
             self.check_relocations(cx, ptr, size)?;
@@ -372,12 +371,12 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         Ok(())
     }
 
-    /// Read a *non-ZST* scalar
+    /// Reads a *non-ZST* scalar.
     ///
-    /// zsts can't be read out of two reasons:
-    /// * byteorder cannot work with zero element buffers
-    /// * in order to obtain a `Pointer` we need to check for ZSTness anyway due to integer pointers
-    ///   being valid for ZSTs
+    /// ZSTs can't be read for two reasons:
+    /// * byte-order cannot work with zero-element buffers;
+    /// * in order to obtain a `Pointer`, we need to check for ZSTness anyway due to integer
+    ///   pointers being valid for ZSTs.
     ///
     /// It is the caller's responsibility to check bounds and alignment beforehand.
     pub fn read_scalar(
@@ -387,20 +386,20 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         size: Size
     ) -> InterpResult<'tcx, ScalarMaybeUndef<Tag>>
     {
-        // get_bytes_unchecked tests relocation edges
+        // `get_bytes_unchecked` tests relocation edges.
         let bytes = self.get_bytes_with_undef_and_ptr(cx, ptr, size)?;
         // Undef check happens *after* we established that the alignment is correct.
-        // We must not return Ok() for unaligned pointers!
+        // We must not return `Ok()` for unaligned pointers!
         if self.check_defined(ptr, size).is_err() {
-            // this inflates undefined bytes to the entire scalar, even if only a few
-            // bytes are undefined
+            // This inflates undefined bytes to the entire scalar, even if only a few
+            // bytes are undefined.
             return Ok(ScalarMaybeUndef::Undef);
         }
-        // Now we do the actual reading
+        // Now we do the actual reading.
         let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
-        // See if we got a pointer
+        // See if we got a pointer.
         if size != cx.data_layout().pointer_size {
-            // *Now* better make sure that the inside also is free of relocations.
+            // *Now*, we better make sure that the inside is free of relocations too.
             self.check_relocations(cx, ptr, size)?;
         } else {
             match self.relocations.get(&ptr.offset) {
@@ -415,7 +414,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         Ok(ScalarMaybeUndef::Scalar(Scalar::from_uint(bits, size)))
     }
 
-    /// Read a pointer-sized scalar.
+    /// Reads a pointer-sized scalar.
     ///
     /// It is the caller's responsibility to check bounds and alignment beforehand.
     pub fn read_ptr_sized(
@@ -427,12 +426,12 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         self.read_scalar(cx, ptr, cx.data_layout().pointer_size)
     }
 
-    /// Write a *non-ZST* scalar
+    /// Writes a *non-ZST* scalar.
     ///
-    /// zsts can't be read out of two reasons:
-    /// * byteorder cannot work with zero element buffers
-    /// * in oder to obtain a `Pointer` we need to check for ZSTness anyway due to integer pointers
-    ///   being valid for ZSTs
+    /// ZSTs can't be read for two reasons:
+    /// * byte-order cannot work with zero-element buffers;
+    /// * in order to obtain a `Pointer`, we need to check for ZSTness anyway due to integer
+    ///   pointers being valid for ZSTs.
     ///
     /// It is the caller's responsibility to check bounds and alignment beforehand.
     pub fn write_scalar(
@@ -460,7 +459,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         let dst = self.get_bytes_mut(cx, ptr, type_size)?;
         write_target_uint(endian, dst, bytes).unwrap();
 
-        // See if we have to also write a relocation
+        // See if we have to also write a relocation.
         match val {
             Scalar::Ptr(val) => {
                 self.relocations.insert(
@@ -474,7 +473,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
         Ok(())
     }
 
-    /// Write a pointer-sized scalar.
+    /// Writes a pointer-sized scalar.
     ///
     /// It is the caller's responsibility to check bounds and alignment beforehand.
     pub fn write_ptr_sized(
@@ -489,9 +488,9 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
     }
 }
 
-/// Relocations
+/// Relocations.
 impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
-    /// Returns all relocations overlapping with the given ptr-offset pair.
+    /// Returns all relocations overlapping with the given pointer-offset pair.
     pub fn get_relocations(
         &self,
         cx: &impl HasDataLayout,
@@ -501,7 +500,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
         // We have to go back `pointer_size - 1` bytes, as that one would still overlap with
         // the beginning of this range.
         let start = ptr.offset.bytes().saturating_sub(cx.data_layout().pointer_size.bytes() - 1);
-        let end = ptr.offset + size; // this does overflow checking
+        let end = ptr.offset + size; // This does overflow checking.
         self.relocations.range(Size::from_bytes(start)..end)
     }
 
@@ -561,7 +560,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
         Ok(())
     }
 
-    /// Error if there are relocations overlapping with the edges of the
+    /// Errors if there are relocations overlapping with the edges of the
     /// given memory range.
     #[inline]
     fn check_relocation_edges(
@@ -577,7 +576,7 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
 }
 
 
-/// Undefined bytes
+/// Undefined bytes.
 impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
     /// Checks that a range of bytes is defined. If not, returns the `ReadUndefBytes`
     /// error which will report the first byte which is undefined.
@@ -618,7 +617,7 @@ pub struct AllocationDefinedness {
 
 /// Transferring the definedness mask to other allocations.
 impl<Tag, Extra> Allocation<Tag, Extra> {
-    /// Creates a run-length encoding of the undef_mask.
+    /// Creates a run-length encoding of the undef mask.
     pub fn compress_undef_range(
         &self,
         src: Pointer<Tag>,
@@ -631,10 +630,10 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
         // Therefor we precompute a compressed version of the undef mask of the source value and
         // then write it back `repeat` times without computing any more information from the source.
 
-        // a precomputed cache for ranges of defined/undefined bits
+        // A precomputed cache for ranges of defined/undefined bits
         // 0000010010001110 will become
-        // [5, 1, 2, 1, 3, 3, 1]
-        // where each element toggles the state
+        // `[5, 1, 2, 1, 3, 3, 1]`,
+        // where each element toggles the state.
 
         let mut ranges = smallvec::SmallVec::<[u64; 1]>::new();
         let initial = self.undef_mask.get(src.offset);
@@ -642,7 +641,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
         let mut cur = initial;
 
         for i in 1..size.bytes() {
-            // FIXME: optimize to bitshift the current undef block's bits and read the top bit
+            // FIXME: optimize to bitshift the current undef block's bits and read the top bit.
             if self.undef_mask.get(src.offset + Size::from_bytes(i)) == cur {
                 cur_len += 1;
             } else {
@@ -657,7 +656,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
         AllocationDefinedness { ranges, initial, }
     }
 
-    /// Apply multiple instances of the run-length encoding to the undef_mask.
+    /// Applies multiple instances of the run-length encoding to the undef mask.
     pub fn mark_compressed_undef_range(
         &mut self,
         defined: &AllocationDefinedness,
@@ -665,7 +664,7 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
         size: Size,
         repeat: u64,
     ) {
-        // an optimization where we can just overwrite an entire range of definedness bits if
+        // An optimization where we can just overwrite an entire range of definedness bits if
         // they are going to be uniformly `1` or `0`.
         if defined.ranges.len() <= 1 {
             self.undef_mask.set_range_inbounds(
@@ -694,9 +693,9 @@ impl<Tag, Extra> Allocation<Tag, Extra> {
     }
 }
 
-/// Relocations
+/// Relocations.
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)]
-pub struct Relocations<Tag=(), Id=AllocId>(SortedMap<Size, (Tag, Id)>);
+pub struct Relocations<Tag = (), Id = AllocId>(SortedMap<Size, (Tag, Id)>);
 
 impl<Tag, Id> Relocations<Tag, Id> {
     pub fn new() -> Self {
@@ -838,8 +837,8 @@ impl UndefMask {
         let (blocka, bita) = bit_index(start);
         let (blockb, bitb) = bit_index(end);
         if blocka == blockb {
-            // first set all bits but the first `bita`
-            // then unset the last `64 - bitb` bits
+            // First set all bits except the first `bita`,
+            // then unset the last `64 - bitb` bits.
             let range = if bitb == 0 {
                 u64::max_value() << bita
             } else {
@@ -854,24 +853,24 @@ impl UndefMask {
         }
         // across block boundaries
         if new_state {
-            // set bita..64 to 1
+            // Set `bita..64` to `1`.
             self.blocks[blocka] |= u64::max_value() << bita;
-            // set 0..bitb to 1
+            // Set `0..bitb` to `1`.
             if bitb != 0 {
                 self.blocks[blockb] |= u64::max_value() >> (64 - bitb);
             }
-            // fill in all the other blocks (much faster than one bit at a time)
+            // Fill in all the other blocks (much faster than one bit at a time).
             for block in (blocka + 1) .. blockb {
                 self.blocks[block] = u64::max_value();
             }
         } else {
-            // set bita..64 to 0
+            // Set `bita..64` to `0`.
             self.blocks[blocka] &= !(u64::max_value() << bita);
-            // set 0..bitb to 0
+            // Set `0..bitb` to `0`.
             if bitb != 0 {
                 self.blocks[blockb] &= !(u64::max_value() >> (64 - bitb));
             }
-            // fill in all the other blocks (much faster than one bit at a time)
+            // Fill in all the other blocks (much faster than one bit at a time).
             for block in (blocka + 1) .. blockb {
                 self.blocks[block] = 0;
             }
@@ -908,7 +907,7 @@ impl UndefMask {
             let additional_blocks = amount.bytes() / Self::BLOCK_SIZE + 1;
             assert_eq!(additional_blocks as usize as u64, additional_blocks);
             self.blocks.extend(
-                // FIXME(oli-obk): optimize this by repeating `new_state as Block`
+                // FIXME(oli-obk): optimize this by repeating `new_state as Block`.
                 iter::repeat(0).take(additional_blocks as usize),
             );
         }
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 589a021241d94..09c822f7508a0 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -1,23 +1,21 @@
-use std::{fmt, env};
+use super::{RawConst, Pointer, CheckInAllocMsg, ScalarMaybeUndef};
 
 use crate::hir;
 use crate::hir::map::definitions::DefPathData;
 use crate::mir;
 use crate::ty::{self, Ty, layout};
 use crate::ty::layout::{Size, Align, LayoutError};
-use rustc_target::spec::abi::Abi;
-use rustc_macros::HashStable;
-
-use super::{RawConst, Pointer, CheckInAllocMsg, ScalarMaybeUndef};
+use crate::ty::query::TyCtxtAt;
 
 use backtrace::Backtrace;
-
-use crate::ty::query::TyCtxtAt;
 use errors::DiagnosticBuilder;
-
+use rustc_macros::HashStable;
+use rustc_target::spec::abi::Abi;
 use syntax_pos::{Pos, Span};
 use syntax::symbol::Symbol;
 
+use std::{fmt, env};
+
 #[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)]
 pub enum ErrorHandled {
     /// Already reported a lint or an error for this evaluation.
@@ -582,7 +580,7 @@ pub type InterpResult<'tcx, T = ()> = Result<T, InterpErrorInfo<'tcx>>;
 
 impl fmt::Display for InterpError<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // Forward `Display` to `Debug`
+        // Forward `Display` to `Debug`.
         write!(f, "{:?}", self)
     }
 }
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index 1ec95c29a4a6f..6f7e11877d5fb 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -1,4 +1,4 @@
-//! An interpreter for MIR used in CTFE and by miri
+//! An interpreter for MIR used in CTFE and by miri.
 
 #[macro_export]
 macro_rules! err_unsup {
@@ -107,21 +107,21 @@ pub use self::allocation::{Allocation, AllocationExtra, Relocations, UndefMask};
 
 pub use self::pointer::{Pointer, PointerArithmetic, CheckInAllocMsg};
 
-use std::fmt;
 use crate::mir;
 use crate::hir::def_id::DefId;
 use crate::ty::{self, TyCtxt, Instance, subst::UnpackedKind};
+use crate::ty::codec::TyDecoder;
 use crate::ty::layout::{self, Size};
 use std::io;
+use std::fmt;
+use std::num::NonZeroU32;
+use std::sync::atomic::{AtomicU32, Ordering};
 use rustc_serialize::{Encoder, Decodable, Encodable};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::{Lock as Mutex, HashMapExt};
+use rustc_data_structures::sync::{Lock, HashMapExt};
 use rustc_data_structures::tiny_list::TinyList;
 use rustc_macros::HashStable;
 use byteorder::{WriteBytesExt, ReadBytesExt, LittleEndian, BigEndian};
-use crate::ty::codec::TyDecoder;
-use std::sync::atomic::{AtomicU32, Ordering};
-use std::num::NonZeroU32;
 
 /// Uniquely identifies a specific constant or static.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable, HashStable)]
@@ -152,8 +152,8 @@ pub fn specialized_encode_alloc_id<'tcx, E: Encoder>(
     tcx: TyCtxt<'tcx>,
     alloc_id: AllocId,
 ) -> Result<(), E::Error> {
-    let alloc: GlobalAlloc<'tcx> =
-        tcx.alloc_map.lock().get(alloc_id).expect("no value for AllocId");
+    let alloc: GlobalAlloc<'tcx> = tcx.alloc_map.lock().get(alloc_id)
+        .expect("no value for given alloc ID");
     match alloc {
         GlobalAlloc::Memory(alloc) => {
             trace!("encoding {:?} with {:#?}", alloc_id, alloc);
@@ -166,8 +166,8 @@ pub fn specialized_encode_alloc_id<'tcx, E: Encoder>(
             fn_instance.encode(encoder)?;
         }
         GlobalAlloc::Static(did) => {
-            // referring to statics doesn't need to know about their allocations,
-            // just about its DefId
+            // References to statics doesn't need to know about their allocations,
+            // just about its `DefId`.
             AllocDiscriminant::Static.encode(encoder)?;
             did.encode(encoder)?;
         }
@@ -187,19 +187,18 @@ enum State {
 }
 
 pub struct AllocDecodingState {
-    // For each AllocId we keep track of which decoding state it's currently in.
-    decoding_state: Vec<Mutex<State>>,
+    // For each `AllocId`, we keep track of which decoding state it's currently in.
+    decoding_state: Vec<Lock<State>>,
     // The offsets of each allocation in the data stream.
     data_offsets: Vec<u32>,
 }
 
 impl AllocDecodingState {
-
     pub fn new_decoding_session(&self) -> AllocDecodingSession<'_> {
         static DECODER_SESSION_ID: AtomicU32 = AtomicU32::new(0);
         let counter = DECODER_SESSION_ID.fetch_add(1, Ordering::SeqCst);
 
-        // Make sure this is never zero
+        // Make sure this is never zero.
         let session_id = DecodingSessionId::new((counter & 0x7FFFFFFF) + 1).unwrap();
 
         AllocDecodingSession {
@@ -208,10 +207,10 @@ impl AllocDecodingState {
         }
     }
 
-    pub fn new(data_offsets: Vec<u32>) -> AllocDecodingState {
-        let decoding_state = vec![Mutex::new(State::Empty); data_offsets.len()];
+    pub fn new(data_offsets: Vec<u32>) -> Self {
+        let decoding_state = vec![Lock::new(State::Empty); data_offsets.len()];
 
-        AllocDecodingState {
+        Self {
             decoding_state,
             data_offsets,
         }
@@ -225,23 +224,23 @@ pub struct AllocDecodingSession<'s> {
 }
 
 impl<'s> AllocDecodingSession<'s> {
-    // Decodes an AllocId in a thread-safe way.
+    /// Decodes an `AllocId` in a thread-safe way.
     pub fn decode_alloc_id<D>(&self, decoder: &mut D) -> Result<AllocId, D::Error>
     where
         D: TyDecoder<'tcx>,
     {
-        // Read the index of the allocation
+        // Read the index of the allocation.
         let idx = decoder.read_u32()? as usize;
         let pos = self.state.data_offsets[idx] as usize;
 
-        // Decode the AllocDiscriminant now so that we know if we have to reserve an
-        // AllocId.
+        // Decode the `AllocDiscriminant` now so that we know if we have to reserve an
+        // `AllocId`.
         let (alloc_kind, pos) = decoder.with_position(pos, |decoder| {
             let alloc_kind = AllocDiscriminant::decode(decoder)?;
             Ok((alloc_kind, decoder.position()))
         })?;
 
-        // Check the decoding state, see if it's already decoded or if we should
+        // Check the decoding state to see if it's already decoded or if we should
         // decode it here.
         let alloc_id = {
             let mut entry = self.state.decoding_state[idx].lock();
@@ -251,11 +250,11 @@ impl<'s> AllocDecodingSession<'s> {
                     return Ok(alloc_id);
                 }
                 ref mut entry @ State::Empty => {
-                    // We are allowed to decode
+                    // We are allowed to decode.
                     match alloc_kind {
                         AllocDiscriminant::Alloc => {
                             // If this is an allocation, we need to reserve an
-                            // AllocId so we can decode cyclic graphs.
+                            // `AllocId` so we can decode cyclic graphs.
                             let alloc_id = decoder.tcx().alloc_map.lock().reserve();
                             *entry = State::InProgress(
                                 TinyList::new_single(self.session_id),
@@ -263,8 +262,8 @@ impl<'s> AllocDecodingSession<'s> {
                             Some(alloc_id)
                         },
                         AllocDiscriminant::Fn | AllocDiscriminant::Static => {
-                            // Fns and statics cannot be cyclic and their AllocId
-                            // is determined later by interning
+                            // Fns and statics cannot be cyclic, and their `AllocId`
+                            // is determined later by interning.
                             *entry = State::InProgressNonAlloc(
                                 TinyList::new_single(self.session_id));
                             None
@@ -273,9 +272,9 @@ impl<'s> AllocDecodingSession<'s> {
                 }
                 State::InProgressNonAlloc(ref mut sessions) => {
                     if sessions.contains(&self.session_id) {
-                        bug!("This should be unreachable")
+                        bug!("this should be unreachable");
                     } else {
-                        // Start decoding concurrently
+                        // Start decoding concurrently.
                         sessions.insert(self.session_id);
                         None
                     }
@@ -285,7 +284,7 @@ impl<'s> AllocDecodingSession<'s> {
                         // Don't recurse.
                         return Ok(alloc_id)
                     } else {
-                        // Start decoding concurrently
+                        // Start decoding concurrently.
                         sessions.insert(self.session_id);
                         Some(alloc_id)
                     }
@@ -293,20 +292,20 @@ impl<'s> AllocDecodingSession<'s> {
             }
         };
 
-        // Now decode the actual data
+        // Now decode the actual data.
         let alloc_id = decoder.with_position(pos, |decoder| {
             match alloc_kind {
                 AllocDiscriminant::Alloc => {
-                    let allocation = <&'tcx Allocation as Decodable>::decode(decoder)?;
-                    // We already have a reserved AllocId.
+                    let alloc = <&'tcx Allocation as Decodable>::decode(decoder)?;
+                    // We already have a reserved `AllocId`.
                     let alloc_id = alloc_id.unwrap();
-                    trace!("decoded alloc {:?} {:#?}", alloc_id, allocation);
-                    decoder.tcx().alloc_map.lock().set_alloc_id_same_memory(alloc_id, allocation);
+                    trace!("decoded alloc {:?}: {:#?}", alloc_id, alloc);
+                    decoder.tcx().alloc_map.lock().set_alloc_id_same_memory(alloc_id, alloc);
                     Ok(alloc_id)
                 },
                 AllocDiscriminant::Fn => {
                     assert!(alloc_id.is_none());
-                    trace!("creating fn alloc id");
+                    trace!("creating fn alloc ID");
                     let instance = ty::Instance::decode(decoder)?;
                     trace!("decoded fn alloc instance: {:?}", instance);
                     let alloc_id = decoder.tcx().alloc_map.lock().create_fn_alloc(instance);
@@ -314,8 +313,9 @@ impl<'s> AllocDecodingSession<'s> {
                 },
                 AllocDiscriminant::Static => {
                     assert!(alloc_id.is_none());
-                    trace!("creating extern static alloc id at");
+                    trace!("creating extern static alloc ID");
                     let did = DefId::decode(decoder)?;
+                    trace!("decoded static def-ID: {:?}", did);
                     let alloc_id = decoder.tcx().alloc_map.lock().create_static_alloc(did);
                     Ok(alloc_id)
                 }
@@ -340,7 +340,7 @@ impl fmt::Display for AllocId {
 /// a static, or a "real" allocation with some data in it.
 #[derive(Debug, Clone, Eq, PartialEq, Hash, RustcDecodable, RustcEncodable, HashStable)]
 pub enum GlobalAlloc<'tcx> {
-    /// The alloc ID is used as a function pointer
+    /// The alloc ID is used as a function pointer.
     Function(Instance<'tcx>),
     /// The alloc ID points to a "lazy" static variable that did not get computed (yet).
     /// This is also used to break the cycle in recursive statics.
@@ -349,17 +349,19 @@ pub enum GlobalAlloc<'tcx> {
     Memory(&'tcx Allocation),
 }
 
+#[derive(Clone)]
 pub struct AllocMap<'tcx> {
-    /// Lets you know what an `AllocId` refers to.
+    /// Maps `AllocId`s to their corresponding allocations.
     alloc_map: FxHashMap<AllocId, GlobalAlloc<'tcx>>,
 
     /// Used to ensure that statics and functions only get one associated `AllocId`.
     /// Should never contain a `GlobalAlloc::Memory`!
-    /// FIXME: Should we just have two separate dedup maps for statics and functions each?
+    //
+    // FIXME: Should we just have two separate dedup maps for statics and functions each?
     dedup: FxHashMap<GlobalAlloc<'tcx>, AllocId>,
 
     /// The `AllocId` to assign to the next requested ID.
-    /// Always incremented, never gets smaller.
+    /// Always incremented; never gets smaller.
     next_id: AllocId,
 }
 
@@ -389,7 +391,7 @@ impl<'tcx> AllocMap<'tcx> {
         next
     }
 
-    /// Reserve a new ID *if* this allocation has not been dedup-reserved before.
+    /// Reserves a new ID *if* this allocation has not been dedup-reserved before.
     /// Should only be used for function pointers and statics, we don't want
     /// to dedup IDs for "real" memory!
     fn reserve_and_set_dedup(&mut self, alloc: GlobalAlloc<'tcx>) -> AllocId {
@@ -430,17 +432,17 @@ impl<'tcx> AllocMap<'tcx> {
             }
         });
         if is_generic {
-            // Get a fresh ID
+            // Get a fresh ID.
             let id = self.reserve();
             self.alloc_map.insert(id, GlobalAlloc::Function(instance));
             id
         } else {
-            // Deduplicate
+            // Deduplicate.
             self.reserve_and_set_dedup(GlobalAlloc::Function(instance))
         }
     }
 
-    /// Intern the `Allocation` and return a new `AllocId`, even if there's already an identical
+    /// Interns the `Allocation` and return a new `AllocId`, even if there's already an identical
     /// `Allocation` with a different `AllocId`.
     /// Statics with identical content will still point to the same `Allocation`, i.e.,
     /// their data will be deduplicated through `Allocation` interning -- but they
@@ -465,19 +467,19 @@ impl<'tcx> AllocMap<'tcx> {
     pub fn unwrap_memory(&self, id: AllocId) -> &'tcx Allocation {
         match self.get(id) {
             Some(GlobalAlloc::Memory(mem)) => mem,
-            _ => bug!("expected allocation id {} to point to memory", id),
+            _ => bug!("expected allocation ID {} to point to memory", id),
         }
     }
 
-    /// Freeze an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to
+    /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to
     /// call this function twice, even with the same `Allocation` will ICE the compiler.
     pub fn set_alloc_id_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {
         if let Some(old) = self.alloc_map.insert(id, GlobalAlloc::Memory(mem)) {
-            bug!("tried to set allocation id {}, but it was already existing as {:#?}", id, old);
+            bug!("tried to set allocation ID {}, but it was already existing as {:#?}", id, old);
         }
     }
 
-    /// Freeze an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called
+    /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called
     /// twice for the same `(AllocId, Allocation)` pair.
     fn set_alloc_id_same_memory(&mut self, id: AllocId, mem: &'tcx Allocation) {
         self.alloc_map.insert_same(id, GlobalAlloc::Memory(mem));
@@ -513,7 +515,7 @@ pub fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result
 // Methods to facilitate working with signed integers stored in a u128
 ////////////////////////////////////////////////////////////////////////////////
 
-/// Truncate `value` to `size` bits and then sign-extend it to 128 bits
+/// Truncates `value` to `size` bits and then sign-extend it to 128 bits
 /// (i.e., if it is negative, fill with 1's on the left).
 #[inline]
 pub fn sign_extend(value: u128, size: Size) -> u128 {
@@ -522,14 +524,14 @@ pub fn sign_extend(value: u128, size: Size) -> u128 {
         // Truncated until nothing is left.
         return 0;
     }
-    // sign extend
+    // Sign-extend it.
     let shift = 128 - size;
-    // shift the unsigned value to the left
-    // and back to the right as signed (essentially fills with FF on the left)
+    // Shift the unsigned value to the left, then shift back to the right as signed
+    // (essentially fills with FF on the left).
     (((value << shift) as i128) >> shift) as u128
 }
 
-/// Truncate `value` to `size` bits.
+/// Truncates `value` to `size` bits.
 #[inline]
 pub fn truncate(value: u128, size: Size) -> u128 {
     let size = size.bits();
@@ -538,6 +540,6 @@ pub fn truncate(value: u128, size: Size) -> u128 {
         return 0;
     }
     let shift = 128 - size;
-    // truncate (shift left to drop out leftover values, shift right to fill with zeroes)
+    // Truncate (shift left to drop out leftover values, shift right to fill with zeroes).
     (value << shift) >> shift
 }
diff --git a/src/librustc/mir/interpret/pointer.rs b/src/librustc/mir/interpret/pointer.rs
index b55e6bc54bc5f..1bb4d9ea4d6d9 100644
--- a/src/librustc/mir/interpret/pointer.rs
+++ b/src/librustc/mir/interpret/pointer.rs
@@ -86,18 +86,17 @@ pub trait PointerArithmetic: layout::HasDataLayout {
 
 impl<T: layout::HasDataLayout> PointerArithmetic for T {}
 
-
-/// Pointer is generic over the type that represents a reference to Allocations,
+/// `Pointer` is generic over the type that represents a reference to `Allocation`s,
 /// thus making it possible for the most convenient representation to be used in
 /// each context.
 ///
-/// Defaults to the index based and loosely coupled AllocId.
+/// Defaults to the index based and loosely coupled `AllocId`.
 ///
 /// Pointer is also generic over the `Tag` associated with each pointer,
 /// which is used to do provenance tracking during execution.
 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd,
          RustcEncodable, RustcDecodable, Hash, HashStable)]
-pub struct Pointer<Tag=(),Id=AllocId> {
+pub struct Pointer<Tag = (), Id = AllocId> {
     pub alloc_id: Id,
     pub offset: Size,
     pub tag: Tag,
@@ -117,7 +116,7 @@ impl<Id: fmt::Debug> fmt::Debug for Pointer<(), Id> {
     }
 }
 
-/// Produces a `Pointer` which points to the beginning of the Allocation
+/// Produces a `Pointer` which points to the beginning of the `Allocation`.
 impl From<AllocId> for Pointer {
     #[inline(always)]
     fn from(alloc_id: AllocId) -> Self {
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 3da5a65c37932..d72d879059369 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -91,7 +91,7 @@ impl<'tcx> ConstValue<'tcx> {
 /// of a simple value or a pointer into another `Allocation`
 #[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd,
          RustcEncodable, RustcDecodable, Hash, HashStable)]
-pub enum Scalar<Tag=(), Id=AllocId> {
+pub enum Scalar<Tag = (), Id = AllocId> {
     /// The raw bytes of a simple value.
     Raw {
         /// The first `size` bytes of `data` are the value.
@@ -359,7 +359,7 @@ impl<'tcx, Tag> Scalar<Tag> {
 
     #[inline(always)]
     pub fn assert_bits(self, target_size: Size) -> u128 {
-        self.to_bits(target_size).expect("Expected Raw bits but got a Pointer")
+        self.to_bits(target_size).expect("expected Raw bits but got a Pointer")
     }
 
     /// Do not call this method!  Use either `assert_ptr` or `force_ptr`.
@@ -374,7 +374,7 @@ impl<'tcx, Tag> Scalar<Tag> {
 
     #[inline(always)]
     pub fn assert_ptr(self) -> Pointer<Tag> {
-        self.to_ptr().expect("Expected a Pointer but got Raw bits")
+        self.to_ptr().expect("expected a Pointer but got Raw bits")
     }
 
     /// Do not call this method!  Dispatch based on the type instead.
@@ -482,8 +482,8 @@ impl<Tag> From<Pointer<Tag>> for Scalar<Tag> {
     }
 }
 
-#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
-pub enum ScalarMaybeUndef<Tag=(), Id=AllocId> {
+#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, RustcEncodable, RustcDecodable)]
+pub enum ScalarMaybeUndef<Tag = (), Id = AllocId> {
     Scalar(Scalar<Tag, Id>),
     Undef,
 }
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 8956cbb2baefc..da2faeb4e1ebf 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -18,6 +18,7 @@ use crate::ty::{
     self, AdtDef, CanonicalUserTypeAnnotations, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt,
     UserTypeAnnotationIndex,
 };
+
 use polonius_engine::Atom;
 use rustc_data_structures::bit_set::BitMatrix;
 use rustc_data_structures::fx::FxHashSet;
@@ -70,7 +71,7 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
 
 /// The various "big phases" that MIR goes through.
 ///
-/// Warning: ordering of variants is significant
+/// Warning: ordering of variants is significant.
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, PartialOrd, Ord)]
 pub enum MirPhase {
     Build = 0,
@@ -80,16 +81,16 @@ pub enum MirPhase {
 }
 
 impl MirPhase {
-    /// Gets the index of the current MirPhase within the set of all MirPhases.
+    /// Gets the index of the current MirPhase within the set of all `MirPhase`s.
     pub fn phase_index(&self) -> usize {
         *self as usize
     }
 }
 
-/// Lowered representation of a single function.
+/// The lowered representation of a single function.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Body<'tcx> {
-    /// List of basic blocks. References to basic block use a newtyped index type `BasicBlock`
+    /// A list of basic blocks. References to basic block use a newtyped index type `BasicBlock`
     /// that indexes into this vector.
     basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
 
@@ -100,7 +101,7 @@ pub struct Body<'tcx> {
     /// us to see the difference and forego optimization on the inlined promoted items.
     pub phase: MirPhase,
 
-    /// List of source scopes; these are referenced by statements
+    /// A list of source scopes; these are referenced by statements
     /// and used for debuginfo. Indexed by a `SourceScope`.
     pub source_scopes: IndexVec<SourceScope, SourceScopeData>,
 
@@ -108,10 +109,10 @@ pub struct Body<'tcx> {
     /// needn't) be tracked across crates.
     pub source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
 
-    /// Yields type of the function, if it is a generator.
+    /// The yield type of the function, if it is a generator.
     pub yield_ty: Option<Ty<'tcx>>,
 
-    /// Generator drop glue
+    /// Generator drop glue.
     pub generator_drop: Option<Box<Body<'tcx>>>,
 
     /// The layout of a generator. Produced by the state transformation.
@@ -124,10 +125,10 @@ pub struct Body<'tcx> {
     /// variables and temporaries.
     pub local_decls: LocalDecls<'tcx>,
 
-    /// User type annotations
+    /// User type annotations.
     pub user_type_annotations: CanonicalUserTypeAnnotations<'tcx>,
 
-    /// Number of arguments this function takes.
+    /// The number of arguments this function takes.
     ///
     /// Starting at local 1, `arg_count` locals will be provided by the caller
     /// and can be assumed to be initialized.
@@ -143,10 +144,11 @@ pub struct Body<'tcx> {
 
     /// Names and capture modes of all the closure upvars, assuming
     /// the first argument is either the closure or a reference to it.
+    //
     // NOTE(eddyb) This is *strictly* a temporary hack for codegen
     // debuginfo generation, and will be removed at some point.
-    // Do **NOT** use it for anything else, upvar information should not be
-    // in the MIR, please rely on local crate HIR or other side-channels.
+    // Do **NOT** use it for anything else; upvar information should not be
+    // in the MIR, so please rely on local crate HIR or other side-channels.
     pub __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
 
     /// Mark this MIR of a const context other than const functions as having converted a `&&` or
@@ -157,10 +159,10 @@ pub struct Body<'tcx> {
     /// List of places where control flow was destroyed. Used for error reporting.
     pub control_flow_destroyed: Vec<(Span, String)>,
 
-    /// A span representing this MIR, for error reporting
+    /// A span representing this MIR, for error reporting.
     pub span: Span,
 
-    /// A cache for various calculations
+    /// A cache for various calculations.
     cache: cache::Cache,
 }
 
@@ -177,7 +179,7 @@ impl<'tcx> Body<'tcx> {
         span: Span,
         control_flow_destroyed: Vec<(Span, String)>,
     ) -> Self {
-        // We need `arg_count` locals, and one for the return place
+        // We need `arg_count` locals, and one for the return place.
         assert!(
             local_decls.len() >= arg_count + 1,
             "expected at least {} locals, got {}",
@@ -384,12 +386,12 @@ impl<'tcx> Body<'tcx> {
         true
     }
 
-    /// Returns the return type, it always return first element from `local_decls` array
+    /// Returns the return type; it always return first element from `local_decls` array.
     pub fn return_ty(&self) -> Ty<'tcx> {
         self.local_decls[RETURN_PLACE].ty
     }
 
-    /// Gets the location of the terminator for the given block
+    /// Gets the location of the terminator for the given block.
     pub fn terminator_loc(&self, bb: BasicBlock) -> Location {
         Location { block: bb, statement_index: self[bb].statements.len() }
     }
@@ -463,7 +465,7 @@ impl<T: Decodable> rustc_serialize::UseSpecializedDecodable for ClearCrossCrate<
 /// Most passes can work with it as a whole, within a single function.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, HashStable)]
 pub struct SourceInfo {
-    /// Source span for the AST pertaining to this MIR entity.
+    /// The source span for the AST pertaining to this MIR entity.
     pub span: Span,
 
     /// The source scope, keeping track of which bindings can be
@@ -591,18 +593,20 @@ impl Atom for Local {
 /// Classifies locals into categories. See `Body::local_kind`.
 #[derive(PartialEq, Eq, Debug, HashStable)]
 pub enum LocalKind {
-    /// User-declared variable binding
+    /// User-declared variable binding.
     Var,
-    /// Compiler-introduced temporary
+    /// Compiler-introduced temporary.
     Temp,
-    /// Function argument
+    /// Function argument.
     Arg,
-    /// Location of function's return value
+    /// Location of function's return value.
     ReturnPointer,
 }
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct VarBindingForm<'tcx> {
+    /// The `HirId` of the variable.
+    pub var_id: hir::HirId,
     /// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`?
     pub binding_mode: ty::BindingMode,
     /// If an explicit type was provided for this variable binding,
@@ -619,7 +623,7 @@ pub struct VarBindingForm<'tcx> {
     /// (b) it gives a way to separate this case from the remaining cases
     ///     for diagnostics.
     pub opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
-    /// Span of the pattern in which this variable was bound.
+    /// The span of the pattern in which this variable was bound.
     pub pat_span: Span,
 }
 
@@ -652,6 +656,7 @@ pub enum ImplicitSelfKind {
 CloneTypeFoldableAndLiftImpls! { BindingForm<'tcx>, }
 
 impl_stable_hash_for!(struct self::VarBindingForm<'tcx> {
+    var_id,
     binding_mode,
     opt_ty_info,
     opt_match_place,
@@ -721,12 +726,12 @@ impl_stable_hash_for!(struct BlockTailInfo { tail_result_is_ignored });
 /// argument, or the return place.
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct LocalDecl<'tcx> {
-    /// `let mut x` vs `let x`.
+    /// Whether this is a mutable minding (i.e., `let x` or `let mut x`).
     ///
     /// Temporaries and the return place are always mutable.
     pub mutability: Mutability,
 
-    /// Some(binding_mode) if this corresponds to a user-declared local variable.
+    /// `Some(binding_mode)` if this corresponds to a user-declared local variable.
     ///
     /// This is solely used for local diagnostics when generating
     /// warnings/errors when compiling the current crate, and
@@ -760,7 +765,7 @@ pub struct LocalDecl<'tcx> {
     /// intervening statement context).
     pub is_block_tail: Option<BlockTailInfo>,
 
-    /// Type of this local.
+    /// The type of this local.
     pub ty: Ty<'tcx>,
 
     /// If the user manually ascribed a type to this variable,
@@ -769,7 +774,7 @@ pub struct LocalDecl<'tcx> {
     /// region inference.
     pub user_ty: UserTypeProjections,
 
-    /// Name of the local, used in debuginfo and pretty-printing.
+    /// The name of the local, used in debuginfo and pretty-printing.
     ///
     /// Note that function arguments can also have this set to `Some(_)`
     /// to generate better debuginfo.
@@ -837,8 +842,8 @@ pub struct LocalDecl<'tcx> {
     /// ROOT SCOPE
     ///  │{ argument x: &str }
     ///  │
-    ///  │ │{ #[allow(unused_mut)] } // this is actually split into 2 scopes
-    ///  │ │                        // in practice because I'm lazy.
+    ///  │ │{ #[allow(unused_mut)] } // This is actually split into 2 scopes
+    ///  │ │                         // in practice because I'm lazy.
     ///  │ │
     ///  │ │← x.source_info.scope
     ///  │ │← `x.parse().unwrap()`
@@ -852,7 +857,7 @@ pub struct LocalDecl<'tcx> {
     ///  │
     ///  │ │{ let x: u32 }
     ///  │ │← x.visibility_scope
-    ///  │ │← `drop(x)` // this accesses `x: u32`
+    ///  │ │← `drop(x)` // This accesses `x: u32`.
     /// ```
     pub source_info: SourceInfo,
 
@@ -872,9 +877,7 @@ impl<'tcx> LocalDecl<'tcx> {
         match self.is_user_variable {
             Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
                 binding_mode: ty::BindingMode::BindByValue(_),
-                opt_ty_info: _,
-                opt_match_place: _,
-                pat_span: _,
+                ..
             }))) => true,
 
             Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(ImplicitSelfKind::Imm))) => true,
@@ -890,9 +893,7 @@ impl<'tcx> LocalDecl<'tcx> {
         match self.is_user_variable {
             Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
                 binding_mode: ty::BindingMode::BindByValue(_),
-                opt_ty_info: _,
-                opt_match_place: _,
-                pat_span: _,
+                ..
             }))) => true,
 
             Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(_))) => true,
@@ -1038,16 +1039,16 @@ pub struct Terminator<'tcx> {
 
 #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum TerminatorKind<'tcx> {
-    /// block should have one successor in the graph; we jump there
+    /// Block should have one successor in the graph; we jump there.
     Goto { target: BasicBlock },
 
-    /// operand evaluates to an integer; jump depending on its value
-    /// to one of the targets, and otherwise fallback to `otherwise`
+    /// Operand evaluates to an integer; jump depending on its value
+    /// to one of the targets, and otherwise fallback to `otherwise`.
     SwitchInt {
-        /// discriminant value being tested
+        /// The discriminant value being tested.
         discr: Operand<'tcx>,
 
-        /// type of value being tested
+        /// The type of value being tested.
         switch_ty: Ty<'tcx>,
 
         /// Possible values. The locations to branch to in each case
@@ -1057,6 +1058,7 @@ pub enum TerminatorKind<'tcx> {
         /// Possible branch sites. The last element of this vector is used
         /// for the otherwise branch, so targets.len() == values.len() + 1
         /// should hold.
+        //
         // This invariant is quite non-obvious and also could be improved.
         // One way to make this invariant is to have something like this instead:
         //
@@ -1069,7 +1071,7 @@ pub enum TerminatorKind<'tcx> {
     },
 
     /// Indicates that the landing pad is finished and unwinding should
-    /// continue. Emitted by build::scope::diverge_cleanup.
+    /// continue. Emitted by `build::scope::diverge_cleanup`.
     Resume,
 
     /// Indicates that the landing pad is finished and that the process
@@ -1083,10 +1085,10 @@ pub enum TerminatorKind<'tcx> {
     /// Indicates a terminator that can never be reached.
     Unreachable,
 
-    /// Drop the Place
+    /// Drop the `Place`.
     Drop { location: Place<'tcx>, target: BasicBlock, unwind: Option<BasicBlock> },
 
-    /// Drop the Place and assign the new value over it. This ensures
+    /// Drop the `Place` and assign the new value over it. This ensures
     /// that the assignment to `P` occurs *even if* the destructor for
     /// place unwinds. Its semantics are best explained by the
     /// elaboration:
@@ -1119,9 +1121,9 @@ pub enum TerminatorKind<'tcx> {
         unwind: Option<BasicBlock>,
     },
 
-    /// Block ends with a call of a converging function
+    /// Block ends with a call of a converging function.
     Call {
-        /// The function that’s being called
+        /// The function that’s being called.
         func: Operand<'tcx>,
         /// Arguments the function is called with.
         /// These are owned by the callee, which is free to modify them.
@@ -1132,7 +1134,7 @@ pub enum TerminatorKind<'tcx> {
         destination: Option<(Place<'tcx>, BasicBlock)>,
         /// Cleanups to be done if the call unwinds.
         cleanup: Option<BasicBlock>,
-        /// Whether this is from a call in HIR, rather than from an overloaded
+        /// `true` if this is from a call in HIR rather than from an overloaded
         /// operator. True for overloaded function call.
         from_hir_call: bool,
     },
@@ -1147,40 +1149,40 @@ pub enum TerminatorKind<'tcx> {
         cleanup: Option<BasicBlock>,
     },
 
-    /// A suspend point
+    /// A suspend point.
     Yield {
-        /// The value to return
+        /// The value to return.
         value: Operand<'tcx>,
-        /// Where to resume to
+        /// Where to resume to.
         resume: BasicBlock,
-        /// Cleanup to be done if the generator is dropped at this suspend point
+        /// Cleanup to be done if the generator is dropped at this suspend point.
         drop: Option<BasicBlock>,
     },
 
-    /// Indicates the end of the dropping of a generator
+    /// Indicates the end of the dropping of a generator.
     GeneratorDrop,
 
     /// A block where control flow only ever takes one real path, but borrowck
     /// needs to be more conservative.
     FalseEdges {
-        /// The target normal control flow will take
+        /// The target normal control flow will take.
         real_target: BasicBlock,
         /// A block control flow could conceptually jump to, but won't in
-        /// practice
+        /// practice.
         imaginary_target: BasicBlock,
     },
     /// A terminator for blocks that only take one path in reality, but where we
     /// reserve the right to unwind in borrowck, even if it won't happen in practice.
     /// This can arise in infinite loops with no function calls for example.
     FalseUnwind {
-        /// The target normal control flow will take
+        /// The target normal control flow will take.
         real_target: BasicBlock,
         /// The imaginary cleanup block link. This particular path will never be taken
         /// in practice, but in order to avoid fragility we want to always
         /// consider it in borrowck. We don't want to accept programs which
-        /// pass borrowck only when panic=abort or some assertions are disabled
-        /// due to release vs. debug mode builds. This needs to be an Option because
-        /// of the remove_noop_landing_pads and no_landing_pads passes
+        /// pass borrowck only when `panic=abort` or some assertions are disabled
+        /// due to release vs. debug mode builds. This needs to be an `Option` because
+        /// of the `remove_noop_landing_pads` and `no_landing_pads` passes.
         unwind: Option<BasicBlock>,
     },
 }
@@ -1445,7 +1447,7 @@ impl<'tcx> Debug for TerminatorKind<'tcx> {
 }
 
 impl<'tcx> TerminatorKind<'tcx> {
-    /// Write the "head" part of the terminator; that is, its name and the data it uses to pick the
+    /// Writes the "head" part of the terminator; that is, its name and the data it uses to pick the
     /// successor basic block, if any. The only information not included is the list of possible
     /// successors, which may be rendered differently between the text and the graphviz format.
     pub fn fmt_head<W: Write>(&self, fmt: &mut W) -> fmt::Result {
@@ -1615,20 +1617,20 @@ pub enum StatementKind<'tcx> {
     Nop,
 }
 
-/// `RetagKind` describes what kind of retag is to be performed.
+/// Describes what kind of retag is to be performed.
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, PartialEq, Eq, HashStable)]
 pub enum RetagKind {
-    /// The initial retag when entering a function
+    /// The initial retag when entering a function.
     FnEntry,
-    /// Retag preparing for a two-phase borrow
+    /// Retag preparing for a two-phase borrow.
     TwoPhase,
-    /// Retagging raw pointers
+    /// Retagging raw pointers.
     Raw,
-    /// A "normal" retag
+    /// A "normal" retag.
     Default,
 }
 
-/// The `FakeReadCause` describes the type of pattern why a `FakeRead` statement exists.
+/// The `FakeReadCause` describes the type of pattern why a FakeRead statement exists.
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum FakeReadCause {
     /// Inject a fake read of the borrowed input at the end of each guards
@@ -2171,7 +2173,7 @@ pub struct SourceScopeData {
 
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct SourceScopeLocalData {
-    /// A HirId with lint levels equivalent to this scope's lint levels.
+    /// An `HirId` with lint levels equivalent to this scope's lint levels.
     pub lint_root: hir::HirId,
     /// The unsafe block that contains this node.
     pub safety: Safety,
@@ -2760,11 +2762,12 @@ impl<'a, 'b> graph::GraphSuccessors<'b> for Body<'a> {
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd, HashStable)]
 pub struct Location {
-    /// the location is within this block
+    /// The block that the location is within.
     pub block: BasicBlock,
 
-    /// the location is the start of the statement; or, if `statement_index`
-    /// == num-statements, then the start of the terminator.
+    /// The location is the position of the start of the statement; or, if
+    /// `statement_index` equals the number of statements, then the start of the
+    /// terminator.
     pub statement_index: usize,
 }
 
@@ -2827,7 +2830,7 @@ impl Location {
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub enum UnsafetyViolationKind {
     General,
-    /// Permitted in const fn and regular fns.
+    /// Permitted in const fns and regular fns.
     GeneralAndConstFn,
     ExternStatic(hir::HirId),
     BorrowPacked(hir::HirId),
@@ -2843,9 +2846,9 @@ pub struct UnsafetyViolation {
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct UnsafetyCheckResult {
-    /// Violations that are propagated *upwards* from this function
+    /// Violations that are propagated *upwards* from this function.
     pub violations: Lrc<[UnsafetyViolation]>,
-    /// unsafe blocks in this function, along with whether they are used. This is
+    /// Unsafe blocks in this function, along with whether they are used. This is
     /// used for the "unused_unsafe" lint.
     pub unsafe_blocks: Lrc<[(hir::HirId, bool)]>,
 }
@@ -2857,7 +2860,7 @@ newtype_index! {
     }
 }
 
-/// The layout of generator state
+/// The layout of generator state.
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct GeneratorLayout<'tcx> {
     /// The type of every local stored inside the generator.
@@ -2873,10 +2876,11 @@ pub struct GeneratorLayout<'tcx> {
     pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
 
     /// Names and scopes of all the stored generator locals.
-    /// NOTE(tmandry) This is *strictly* a temporary hack for codegen
-    /// debuginfo generation, and will be removed at some point.
-    /// Do **NOT** use it for anything else, local information should not be
-    /// in the MIR, please rely on local crate HIR or other side-channels.
+    //
+    // NOTE(tmandry) This is *strictly* a temporary hack for codegen
+    // debuginfo generation, and will be removed at some point.
+    // Do **NOT** use it for anything else, local information should not be
+    // in the MIR, please rely on local crate HIR or other side-channels.
     pub __local_debuginfo_codegen_only_do_not_use: IndexVec<GeneratorSavedLocal, LocalDecl<'tcx>>,
 }
 
@@ -2934,7 +2938,7 @@ pub struct BorrowCheckResult<'tcx> {
 /// instances assigned one of these same indices. Those regions will
 /// be substituted away by the creator. We use `ReClosureBound` in
 /// that case because the regions must be allocated in the global
-/// TyCtxt, and hence we cannot use `ReVar` (which is what we use
+/// `TyCtxt`, and hence we cannot use `ReVar` (which is what we use
 /// internally within the rest of the NLL code).
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ClosureRegionRequirements<'tcx> {
@@ -2950,8 +2954,8 @@ pub struct ClosureRegionRequirements<'tcx> {
     pub outlives_requirements: Vec<ClosureOutlivesRequirement<'tcx>>,
 }
 
-/// Indicates an outlives constraint between a type or between two
-/// free-regions declared on the closure.
+/// Indicates an outlives-constraint between a type or between two
+/// free regions declared on the closure.
 #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ClosureOutlivesRequirement<'tcx> {
     // This region or type ...
@@ -2967,11 +2971,11 @@ pub struct ClosureOutlivesRequirement<'tcx> {
     pub category: ConstraintCategory,
 }
 
-/// Outlives constraints can be categorized to determine whether and why they
+/// Outlives-constraints can be categorized to determine whether and why they
 /// are interesting (for error reporting). Order of variants indicates sort
 /// order of the category, thereby influencing diagnostic output.
 ///
-/// See also [rustc_mir::borrow_check::nll::constraints]
+/// See also [rustc_mir::borrow_check::nll::constraints].
 #[derive(
     Copy,
     Clone,
@@ -3019,7 +3023,7 @@ pub enum ConstraintCategory {
     Internal,
 }
 
-/// The subject of a ClosureOutlivesRequirement -- that is, the thing
+/// The subject of a `ClosureOutlivesRequirement` -- that is, the thing
 /// that must outlive some region.
 #[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum ClosureOutlivesSubject<'tcx> {
@@ -3037,7 +3041,7 @@ pub enum ClosureOutlivesSubject<'tcx> {
 }
 
 /*
- * TypeFoldable implementations for MIR types
+ * `TypeFoldable` implementations for MIR types
 */
 
 CloneTypeFoldableAndLiftImpls! {
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index ef838114f6c36..4ebc2e72490d4 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -17,7 +17,6 @@ use crate::traits::query::{
 use std::borrow::Cow;
 use syntax_pos::symbol::InternedString;
 
-
 // Each of these queries corresponds to a function pointer field in the
 // `Providers` struct for requesting a value of that type, and a method
 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
@@ -854,7 +853,7 @@ rustc_queries! {
             desc { "calculating the lang items map" }
         }
 
-        /// Returns all diagnostic items defined in all crates
+        /// Returns all diagnostic items defined in all crates.
         query all_diagnostic_items(_: CrateNum) -> &'tcx FxHashMap<Symbol, DefId> {
             eval_always
             desc { "calculating the diagnostic items map" }
@@ -865,7 +864,7 @@ rustc_queries! {
             desc { "calculating the lang items defined in a crate" }
         }
 
-        /// Returns the diagnostic items defined in a crate
+        /// Returns the diagnostic items defined in a crate.
         query diagnostic_items(_: CrateNum) -> &'tcx FxHashMap<Symbol, DefId> {
             desc { "calculating the diagnostic items map in a crate" }
         }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 296c6ad19c1cf..27a33ced119df 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1,36 +1,36 @@
 //! Contains infrastructure for configuring the compiler, including parsing
-//! command line options.
-
-use std::str::FromStr;
+//! command-line options.
 
+use crate::lint;
+use crate::middle::cstore;
 use crate::session::{early_error, early_warn, Session};
 use crate::session::search_paths::SearchPath;
 
+use rustc_data_structures::fx::FxHashSet;
+
 use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
 use rustc_target::spec::{Target, TargetTriple};
-use crate::lint;
-use crate::middle::cstore;
 
 use syntax;
 use syntax::ast::{self, IntTy, UintTy, MetaItemKind};
 use syntax::source_map::{FileName, FilePathMapping};
 use syntax::edition::{Edition, EDITION_NAME_LIST, DEFAULT_EDITION};
+use syntax::parse::{ParseSess, new_parser_from_source_str};
 use syntax::parse::token;
-use syntax::parse;
 use syntax::symbol::{sym, Symbol};
 use syntax::feature_gate::UnstableFeatures;
-use errors::emitter::HumanReadableErrorType;
 
+use errors::emitter::HumanReadableErrorType;
 use errors::{ColorConfig, FatalError, Handler};
 
 use getopts;
-use std::collections::{BTreeMap, BTreeSet};
-use std::collections::btree_map::Iter as BTreeMapIter;
-use std::collections::btree_map::Keys as BTreeMapKeysIter;
-use std::collections::btree_map::Values as BTreeMapValuesIter;
 
-use rustc_data_structures::fx::FxHashSet;
-use std::{fmt, str};
+use std::collections::{BTreeMap, BTreeSet};
+use std::collections::btree_map::{
+    Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
+};
+use std::fmt;
+use std::str::{self, FromStr};
 use std::hash::Hasher;
 use std::collections::hash_map::DefaultHasher;
 use std::iter::FromIterator;
@@ -241,14 +241,14 @@ pub enum ErrorOutputType {
 }
 
 impl Default for ErrorOutputType {
-    fn default() -> ErrorOutputType {
-        ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(ColorConfig::Auto))
+    fn default() -> Self {
+        Self::HumanReadable(HumanReadableErrorType::Default(ColorConfig::Auto))
     }
 }
 
-// Use tree-based collections to cheaply get a deterministic Hash implementation.
-// DO NOT switch BTreeMap out for an unsorted container type! That would break
-// dependency tracking for command-line arguments.
+/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
+/// *Do not* switch `BTreeMap` out for an unsorted container type! That would break
+/// dependency tracking for command-line arguments.
 #[derive(Clone, Hash)]
 pub struct OutputTypes(BTreeMap<OutputType, Option<PathBuf>>);
 
@@ -281,7 +281,7 @@ impl OutputTypes {
         self.0.len()
     }
 
-    // True if any of the output types require codegen or linking.
+    // Returns `true` if any of the output types require codegen or linking.
     pub fn should_codegen(&self) -> bool {
         self.0.keys().any(|k| match *k {
             OutputType::Bitcode
@@ -295,9 +295,9 @@ impl OutputTypes {
     }
 }
 
-// Use tree-based collections to cheaply get a deterministic Hash implementation.
-// DO NOT switch BTreeMap or BTreeSet out for an unsorted container type! That
-// would break dependency tracking for command-line arguments.
+/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
+/// *Do not* switch `BTreeMap` or `BTreeSet` out for an unsorted container type! That
+/// would break dependency tracking for command-line arguments.
 #[derive(Clone, Hash)]
 pub struct Externs(BTreeMap<String, ExternEntry>);
 
@@ -327,7 +327,7 @@ macro_rules! hash_option {
     ($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [TRACKED]) => ({
         if $sub_hashes.insert(stringify!($opt_name),
                               $opt_expr as &dyn dep_tracking::DepTrackingHash).is_some() {
-            bug!("Duplicate key in CLI DepTrackingHash: {}", stringify!($opt_name))
+            bug!("duplicate key in CLI DepTrackingHash: {}", stringify!($opt_name))
         }
     });
 }
@@ -362,7 +362,7 @@ macro_rules! top_level_options {
     );
 }
 
-// The top-level command-line options struct
+// The top-level command-line options struct.
 //
 // For each option, one has to specify how it behaves with regard to the
 // dependency tracking system of incremental compilation. This is done via the
@@ -376,16 +376,16 @@ macro_rules! top_level_options {
 // Incremental compilation is not influenced by this option.
 //
 // If you add a new option to this struct or one of the sub-structs like
-// CodegenOptions, think about how it influences incremental compilation. If in
+// `CodegenOptions`, think about how it influences incremental compilation. If in
 // doubt, specify [TRACKED], which is always "correct" but might lead to
 // unnecessary re-compilation.
 top_level_options!(
     pub struct Options {
         // The crate config requested for the session, which may be combined
-        // with additional crate configurations during the compile process
+        // with additional crate configurations during the compile process.
         crate_types: Vec<CrateType> [TRACKED],
         optimize: OptLevel [TRACKED],
-        // Include the debug_assertions flag into dependency tracking, since it
+        // Include the `debug_assertions` flag in dependency tracking, since it
         // can influence whether overflow checks are done or not.
         debug_assertions: bool [TRACKED],
         debuginfo: DebugInfo [TRACKED],
@@ -402,8 +402,8 @@ top_level_options!(
         test: bool [TRACKED],
         error_format: ErrorOutputType [UNTRACKED],
 
-        // if Some, enable incremental compilation, using the given
-        // directory to store intermediate results
+        // If `Some`, enable incremental compilation, using the given
+        // directory to store intermediate results.
         incremental: Option<PathBuf> [UNTRACKED],
 
         debugging_opts: DebuggingOptions [TRACKED],
@@ -418,7 +418,7 @@ top_level_options!(
         // written `extern crate name as std`. Defaults to `std`. Used by
         // out-of-tree drivers.
         alt_std_name: Option<String> [TRACKED],
-        // Indicates how the compiler should treat unstable features
+        // Indicates how the compiler should treat unstable features.
         unstable_features: UnstableFeatures [TRACKED],
 
         // Indicates whether this run of the compiler is actually rustdoc. This
@@ -434,12 +434,12 @@ top_level_options!(
         cli_forced_codegen_units: Option<usize> [UNTRACKED],
         cli_forced_thinlto_off: bool [UNTRACKED],
 
-        // Remap source path prefixes in all output (messages, object files, debug, etc)
+        // Remap source path prefixes in all output (messages, object files, debug, etc.).
         remap_path_prefix: Vec<(PathBuf, PathBuf)> [UNTRACKED],
 
         edition: Edition [TRACKED],
 
-        // Whether or not we're emitting JSON blobs about each artifact produced
+        // `true` if we're emitting JSON blobs about each artifact produced
         // by the compiler.
         json_artifact_notifications: bool [TRACKED],
     }
@@ -468,7 +468,7 @@ pub enum BorrowckMode {
 }
 
 impl BorrowckMode {
-    /// Should we run the MIR-based borrow check, but also fall back
+    /// Returns whether we should run the MIR-based borrow check, but also fall back
     /// on the AST borrow check if the MIR-based one errors.
     pub fn migrate(self) -> bool {
         match self {
@@ -477,7 +477,7 @@ impl BorrowckMode {
         }
     }
 
-    /// Should we emit the AST-based borrow checker errors?
+    /// Returns whether we should emit the AST-based borrow checker errors.
     pub fn use_ast(self) -> bool {
         match self {
             BorrowckMode::Mir => false,
@@ -487,12 +487,13 @@ impl BorrowckMode {
 }
 
 pub enum Input {
-    /// Loads source from file
+    /// Load source code from a file.
     File(PathBuf),
+    /// Load source code from a string.
     Str {
-        /// String that is shown in place of a filename
+        /// A string that is shown in place of a filename.
         name: FileName,
-        /// Anonymous source string
+        /// An anonymous string containing the source code.
         input: String,
     },
 }
@@ -651,7 +652,7 @@ impl Options {
         FilePathMapping::new(self.remap_path_prefix.clone())
     }
 
-    /// Returns `true` if there will be an output file generated
+    /// Returns `true` if there will be an output file generated.
     pub fn will_create_output_file(&self) -> bool {
         !self.debugging_opts.parse_only && // The file is just being parsed
             !self.debugging_opts.ls // The file is just being queried
@@ -709,16 +710,14 @@ impl Passes {
     }
 }
 
-/// Declare a macro that will define all CodegenOptions/DebuggingOptions fields and parsers all
-/// at once. The goal of this macro is to define an interface that can be
-/// programmatically used by the option parser in order to initialize the struct
-/// without hardcoding field names all over the place.
+/// Defines all `CodegenOptions`/`DebuggingOptions` fields and parsers all at once. The goal of this
+/// macro is to define an interface that can be programmatically used by the option parser in order
+/// to initialize the struct without hardcoding field names all over the place.
 ///
-/// The goal is to invoke this macro once with the correct fields, and then this
-/// macro generates all necessary code. The main gotcha of this macro is the
-/// cgsetters module which is a bunch of generated code to parse an option into
-/// its respective field in the struct. There are a few hand-written parsers for
-/// parsing specific types of values in this module.
+/// The goal is to invoke this macro once with the correct fields, and then this macro generates all
+/// necessary code. The main gotcha of this macro is the cgsetters module which is a bunch of
+/// generated code to parse an option into its respective field in the struct. There are a few
+/// hand-written parsers for parsing specific types of values in this module.
 macro_rules! options {
     ($struct_name:ident, $setter_name:ident, $defaultfn:ident,
      $buildfn:ident, $prefix:expr, $outputname:expr,
@@ -1539,7 +1538,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
     ret
 }
 
-/// Converts the crate cfg! configuration from String to Symbol.
+/// Converts the crate `cfg!` configuration from `String` to `Symbol`.
 /// `rustc_interface::interface::Config` accepts this in the compiler configuration,
 /// but the symbol interner is not yet set up then, so we must convert it later.
 pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> ast::CrateConfig {
@@ -1550,9 +1549,9 @@ pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> ast::CrateCo
 
 pub fn build_configuration(sess: &Session, mut user_cfg: ast::CrateConfig) -> ast::CrateConfig {
     // Combine the configuration requested by the session (command line) with
-    // some default and generated configuration items
+    // some default and generated configuration items.
     let default_cfg = default_configuration(sess);
-    // If the user wants a test runner, then add the test cfg
+    // If the user wants a test runner, then add the test cfg.
     if sess.opts.test {
         user_cfg.insert((sym::test, None));
     }
@@ -1851,13 +1850,13 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
     opts
 }
 
-// Convert strings provided as --cfg [cfgspec] into a crate_cfg
+// Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
 pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> {
     syntax::with_default_globals(move || {
         let cfg = cfgspecs.into_iter().map(|s| {
-            let sess = parse::ParseSess::new(FilePathMapping::empty());
+            let sess = ParseSess::new(FilePathMapping::empty());
             let filename = FileName::cfg_spec_source_code(&s);
-            let mut parser = parse::new_parser_from_source_str(&sess, filename, s.to_string());
+            let mut parser = new_parser_from_source_str(&sess, filename, s.to_string());
 
             macro_rules! error {($reason: expr) => {
                 early_error(ErrorOutputType::default(),
@@ -1917,7 +1916,7 @@ pub fn get_cmd_lint_options(matches: &getopts::Matches,
     (lint_opts, describe_lints, lint_cap)
 }
 
-/// Parse the `--color` flag
+/// Parses the `--color` flag.
 pub fn parse_color(matches: &getopts::Matches) -> ColorConfig {
     match matches.opt_str("color").as_ref().map(|s| &s[..]) {
         Some("auto") => ColorConfig::Auto,
@@ -1929,7 +1928,7 @@ pub fn parse_color(matches: &getopts::Matches) -> ColorConfig {
         Some(arg) => early_error(
             ErrorOutputType::default(),
             &format!(
-                "argument for --color must be auto, \
+                "argument for `--color` must be auto, \
                  always or never (instead was `{}`)",
                 arg
             ),
@@ -1974,16 +1973,16 @@ pub fn parse_json(matches: &getopts::Matches) -> (HumanReadableErrorType, bool)
     (json_rendered(json_color), json_artifact_notifications)
 }
 
-/// Parse the `--error-format` flag
+/// Parses the `--error-format` flag.
 pub fn parse_error_format(
     matches: &getopts::Matches,
     color: ColorConfig,
     json_rendered: HumanReadableErrorType,
 ) -> ErrorOutputType {
-    // We need the opts_present check because the driver will send us Matches
+    // We need the `opts_present` check because the driver will send us Matches
     // with only stable options if no unstable options are used. Since error-format
-    // is unstable, it will not be present. We have to use opts_present not
-    // opt_present because the latter will panic.
+    // is unstable, it will not be present. We have to use `opts_present` not
+    // `opt_present` because the latter will panic.
     let error_format = if matches.opts_present(&["error-format".to_owned()]) {
         match matches.opt_str("error-format").as_ref().map(|s| &s[..]) {
             None |
@@ -2116,7 +2115,7 @@ pub fn build_session_options_and_crate_config(
     let mut codegen_units = cg.codegen_units;
     let mut disable_thinlto = false;
 
-    // Issue #30063: if user requests llvm-related output to one
+    // Issue #30063: if user requests LLVM-related output to one
     // particular path, disable codegen-units.
     let incompatible: Vec<_> = output_types
         .iter()
@@ -2414,10 +2413,10 @@ pub fn build_session_options_and_crate_config(
         )
     }
 
-    // We start out with a Vec<(Option<String>, bool)>>,
-    // and later convert it into a BTreeSet<(Option<String>, bool)>
+    // We start out with a `Vec<(Option<String>, bool)>>`,
+    // and later convert it into a `BTreeSet<(Option<String>, bool)>`
     // This allows to modify entries in-place to set their correct
-    // 'public' value
+    // 'public' value.
     let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
     for (arg, private) in matches.opt_strs("extern").into_iter().map(|v| (v, false))
         .chain(matches.opt_strs("extern-private").into_iter().map(|v| (v, true))) {
@@ -2616,15 +2615,15 @@ impl fmt::Display for CrateType {
 /// The values of all command-line arguments that are relevant for dependency
 /// tracking are hashed into a single value that determines whether the
 /// incremental compilation cache can be re-used or not. This hashing is done
-/// via the DepTrackingHash trait defined below, since the standard Hash
-/// implementation might not be suitable (e.g., arguments are stored in a Vec,
+/// via the `DepTrackingHash` trait defined below, since the standard `Hash`
+/// implementation might not be suitable (e.g., arguments are stored in a `Vec`,
 /// the hash of which is order dependent, but we might not want the order of
 /// arguments to make a difference for the hash).
 ///
-/// However, since the value provided by Hash::hash often *is* suitable,
+/// However, since the value provided by `Hash::hash` often *is* suitable,
 /// especially for primitive types, there is the
-/// impl_dep_tracking_hash_via_hash!() macro that allows to simply reuse the
-/// Hash implementation for DepTrackingHash. It's important though that
+/// `impl_dep_tracking_hash_via_hash!()` macro that allows to simply reuse the
+/// `Hash` implementation for `DepTrackingHash`. It's important though that
 /// we have an opt-in scheme here, so one is hopefully forced to think about
 /// how the hash should be calculated when adding a new command-line argument.
 mod dep_tracking {
@@ -2637,9 +2636,9 @@ mod dep_tracking {
     use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes,
                 Passes, Sanitizer, LtoCli, LinkerPluginLto, SwitchWithOptPath,
                 SymbolManglingVersion};
-    use syntax::feature_gate::UnstableFeatures;
     use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel, TargetTriple};
     use syntax::edition::Edition;
+    use syntax::feature_gate::UnstableFeatures;
 
     pub trait DepTrackingHash {
         fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType);
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index f01883d9634cd..8656ebb2e6d72 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -79,12 +79,12 @@ pub struct Session {
     /// if the value stored here has been affected by path remapping.
     pub working_dir: (PathBuf, bool),
 
-    // FIXME: lint_store and buffered_lints are not thread-safe,
-    // but are only used in a single thread
+    // FIXME: `lint_store` and `buffered_lints` are not thread-safe,
+    // but are only used in a single thread.
     pub lint_store: RwLock<lint::LintStore>,
     pub buffered_lints: Lock<Option<lint::LintBuffer>>,
 
-    /// Set of (DiagnosticId, Option<Span>, message) tuples tracking
+    /// Set of `(DiagnosticId, Option<Span>, message)` tuples tracking
     /// (sub)diagnostics that have been set once, but should not be set again,
     /// in order to avoid redundantly verbose output (Issue #24690, #44953).
     pub one_time_diagnostics: Lock<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>,
@@ -92,11 +92,11 @@ pub struct Session {
     pub plugin_attributes: Lock<Vec<(Symbol, AttributeType)>>,
     pub crate_types: Once<Vec<config::CrateType>>,
     pub dependency_formats: Once<dependency_format::Dependencies>,
-    /// The crate_disambiguator is constructed out of all the `-C metadata`
+    /// The `crate_disambiguator` is constructed out of all the `-C metadata`
     /// arguments passed to the compiler. Its value together with the crate-name
     /// forms a unique global identifier for the crate. It is used to allow
     /// multiple crates with the same name to coexist. See the
-    /// rustc_codegen_llvm::back::symbol_names module for more information.
+    /// `rustc_codegen_llvm::back::symbol_names` module for more information.
     pub crate_disambiguator: Once<CrateDisambiguator>,
 
     features: Once<feature_gate::Features>,
@@ -111,7 +111,7 @@ pub struct Session {
     /// The maximum number of stackframes allowed in const eval.
     pub const_eval_stack_frame_limit: usize,
 
-    /// The metadata::creader module may inject an allocator/panic_runtime
+    /// The `metadata::creader` module may inject an allocator/`panic_runtime`
     /// dependency if it didn't already find one, and this tracks what was
     /// injected.
     pub allocator_kind: Once<Option<AllocatorKind>>,
@@ -130,7 +130,7 @@ pub struct Session {
     /// Used by `-Z profile-queries` in `util::common`.
     pub profile_channel: Lock<Option<mpsc::Sender<ProfileQueriesMsg>>>,
 
-    /// Used by -Z self-profile
+    /// Used by `-Z self-profile`.
     pub self_profiling: Option<Arc<SelfProfiler>>,
 
     /// Some measurements that are being gathered during compilation.
@@ -187,16 +187,16 @@ pub struct PerfStats {
     pub normalize_projection_ty: AtomicUsize,
 }
 
-/// Enum to support dispatch of one-time diagnostics (in Session.diag_once)
+/// Enum to support dispatch of one-time diagnostics (in `Session.diag_once`).
 enum DiagnosticBuilderMethod {
     Note,
     SpanNote,
     SpanSuggestion(String), // suggestion
-                            // add more variants as needed to support one-time diagnostics
+                            // Add more variants as needed to support one-time diagnostics.
 }
 
-/// Diagnostic message ID—used by `Session.one_time_diagnostics` to avoid
-/// emitting the same message more than once
+/// Diagnostic message ID, used by `Session.one_time_diagnostics` to avoid
+/// emitting the same message more than once.
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub enum DiagnosticMessageId {
     ErrorId(u16), // EXXXX error code as integer
@@ -408,7 +408,7 @@ impl Session {
             Some(next) => {
                 self.next_node_id.set(ast::NodeId::from_usize(next));
             }
-            None => bug!("Input too large, ran out of node ids!"),
+            None => bug!("input too large; ran out of node-IDs!"),
         }
 
         id
@@ -440,11 +440,11 @@ impl Session {
                     diag_builder.note(message);
                 }
                 DiagnosticBuilderMethod::SpanNote => {
-                    let span = span_maybe.expect("span_note needs a span");
+                    let span = span_maybe.expect("`span_note` needs a span");
                     diag_builder.span_note(span, message);
                 }
                 DiagnosticBuilderMethod::SpanSuggestion(suggestion) => {
-                    let span = span_maybe.expect("span_suggestion_* needs a span");
+                    let span = span_maybe.expect("`span_suggestion_*` needs a span");
                     diag_builder.span_suggestion(
                         span,
                         message,
@@ -688,7 +688,7 @@ impl Session {
 
     pub fn must_not_eliminate_frame_pointers(&self) -> bool {
         // "mcount" function relies on stack pointer.
-        // See https://sourceware.org/binutils/docs/gprof/Implementation.html
+        // See <https://sourceware.org/binutils/docs/gprof/Implementation.html>.
         if self.instrument_mcount() {
             true
         } else if let Some(x) = self.opts.cg.force_frame_pointers {
@@ -699,7 +699,7 @@ impl Session {
     }
 
     /// Returns the symbol name for the registrar function,
-    /// given the crate Svh and the function DefIndex.
+    /// given the crate `Svh` and the function `DefIndex`.
     pub fn generate_plugin_registrar_symbol(&self, disambiguator: CrateDisambiguator) -> String {
         format!(
             "__rustc_plugin_registrar_{}__",
@@ -719,7 +719,7 @@ impl Session {
             &self.sysroot,
             self.opts.target_triple.triple(),
             &self.opts.search_paths,
-            // target_tlib_path==None means it's the same as host_tlib_path.
+            // `target_tlib_path == None` means it's the same as `host_tlib_path`.
             self.target_tlib_path.as_ref().unwrap_or(&self.host_tlib_path),
             kind,
         )
@@ -779,12 +779,12 @@ impl Session {
         if let IncrCompSession::Active { .. } = *incr_comp_session {
         } else {
             bug!(
-                "Trying to finalize IncrCompSession `{:?}`",
+                "trying to finalize `IncrCompSession` `{:?}`",
                 *incr_comp_session
-            )
+            );
         }
 
-        // Note: This will also drop the lock file, thus unlocking the directory
+        // Note: this will also drop the lock file, thus unlocking the directory.
         *incr_comp_session = IncrCompSession::Finalized {
             session_directory: new_directory_path,
         };
@@ -800,13 +800,15 @@ impl Session {
             } => session_directory.clone(),
             IncrCompSession::InvalidBecauseOfErrors { .. } => return,
             _ => bug!(
-                "Trying to invalidate IncrCompSession `{:?}`",
+                "trying to invalidate `IncrCompSession` `{:?}`",
                 *incr_comp_session
             ),
         };
 
-        // Note: This will also drop the lock file, thus unlocking the directory
-        *incr_comp_session = IncrCompSession::InvalidBecauseOfErrors { session_directory };
+        // Note: this will also drop the lock file, thus unlocking the directory.
+        *incr_comp_session = IncrCompSession::InvalidBecauseOfErrors {
+            session_directory,
+        };
     }
 
     pub fn incr_comp_session_dir(&self) -> cell::Ref<'_, PathBuf> {
@@ -815,8 +817,8 @@ impl Session {
             incr_comp_session,
             |incr_comp_session| match *incr_comp_session {
                 IncrCompSession::NotInitialized => bug!(
-                    "Trying to get session directory from IncrCompSession `{:?}`",
-                    *incr_comp_session
+                    "trying to get session directory from `IncrCompSession`: {:?}",
+                    *incr_comp_session,
                 ),
                 IncrCompSession::Active {
                     ref session_directory,
@@ -1185,7 +1187,10 @@ fn build_session_(
     );
     let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
 
-    let p_s = parse::ParseSess::with_span_handler(span_diagnostic, source_map);
+    let parse_sess = parse::ParseSess::with_span_handler(
+        span_diagnostic,
+        source_map,
+    );
     let sysroot = match &sopts.maybe_sysroot {
         Some(sysroot) => sysroot.clone(),
         None => filesearch::get_or_default_sysroot(),
@@ -1214,7 +1219,7 @@ fn build_session_(
     let print_fuel = AtomicU64::new(0);
 
     let working_dir = env::current_dir().unwrap_or_else(|e|
-        p_s.span_diagnostic
+        parse_sess.span_diagnostic
             .fatal(&format!("Current directory is invalid: {}", e))
             .raise()
     );
@@ -1232,7 +1237,7 @@ fn build_session_(
         opts: sopts,
         host_tlib_path,
         target_tlib_path,
-        parse_sess: p_s,
+        parse_sess,
         sysroot,
         local_crate_source_file,
         working_dir,
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index c759981b8e8c9..a7990c4af69fd 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -130,13 +130,13 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// We say a method is *vtable safe* if it can be invoked on a trait
-    /// object.  Note that object-safe traits can have some
-    /// non-vtable-safe methods, so long as they require `Self:Sized` or
-    /// otherwise ensure that they cannot be used when `Self=Trait`.
+    /// object. Note that object-safe traits can have some
+    /// non-vtable-safe methods, so long as they require `Self: Sized` or
+    /// otherwise ensure that they cannot be used when `Self = Trait`.
     pub fn is_vtable_safe_method(self, trait_def_id: DefId, method: &ty::AssocItem) -> bool {
         debug_assert!(self.generics_of(trait_def_id).has_self);
         debug!("is_vtable_safe_method({:?}, {:?})", trait_def_id, method);
-        // Any method that has a `Self : Sized` requisite can't be called.
+        // Any method that has a `Self: Sized` bound cannot be called.
         if self.generics_require_sized_self(method.def_id) {
             return false;
         }
@@ -350,15 +350,15 @@ impl<'tcx> TyCtxt<'tcx> {
             &sig.map_bound(|sig| sig.inputs()[0]),
         );
 
-        // until `unsized_locals` is fully implemented, `self: Self` can't be dispatched on.
+        // Until `unsized_locals` is fully implemented, `self: Self` can't be dispatched on.
         // However, this is already considered object-safe. We allow it as a special case here.
         // FIXME(mikeyhew) get rid of this `if` statement once `receiver_is_dispatchable` allows
-        // `Receiver: Unsize<Receiver[Self => dyn Trait]>`
+        // `Receiver: Unsize<Receiver[Self => dyn Trait]>`.
         if receiver_ty != self.types.self_param {
             if !self.receiver_is_dispatchable(method, receiver_ty) {
                 return Some(MethodViolationCode::UndispatchableReceiver);
             } else {
-                // sanity check to make sure the receiver actually has the layout of a pointer
+                // Do sanity check to make sure the receiver actually has the layout of a pointer.
 
                 use crate::ty::layout::Abi;
 
@@ -373,7 +373,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     }
                 };
 
-                // e.g., Rc<()>
+                // e.g., `Rc<()>`
                 let unit_receiver_ty = self.receiver_for_self_ty(
                     receiver_ty, self.mk_unit(), method.def_id
                 );
@@ -395,7 +395,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     trait_def_id, self.mk_region(ty::ReStatic)
                 );
 
-                // e.g., Rc<dyn Trait>
+                // e.g., `Rc<dyn Trait>`
                 let trait_object_receiver = self.receiver_for_self_ty(
                     receiver_ty, trait_object_ty, method.def_id
                 );
@@ -419,8 +419,8 @@ impl<'tcx> TyCtxt<'tcx> {
         None
     }
 
-    /// Performs a type substitution to produce the version of receiver_ty when `Self = self_ty`
-    /// e.g., for receiver_ty = `Rc<Self>` and self_ty = `Foo`, returns `Rc<Foo>`.
+    /// Performs a type substitution to produce the version of `receiver_ty` when `Self = self_ty`.
+    /// For example, for `receiver_ty = Rc<Self>` and `self_ty = Foo`, returns `Rc<Foo>`.
     fn receiver_for_self_ty(
         self,
         receiver_ty: Ty<'tcx>,
diff --git a/src/librustc/traits/query/evaluate_obligation.rs b/src/librustc/traits/query/evaluate_obligation.rs
index 2ee63647aaded..b9557ceaa6d9f 100644
--- a/src/librustc/traits/query/evaluate_obligation.rs
+++ b/src/librustc/traits/query/evaluate_obligation.rs
@@ -1,7 +1,8 @@
 use crate::infer::InferCtxt;
 use crate::infer::canonical::OriginalQueryValues;
-use crate::traits::{EvaluationResult, PredicateObligation, SelectionContext,
-             TraitQueryMode, OverflowError};
+use crate::traits::{
+    EvaluationResult, PredicateObligation, SelectionContext, TraitQueryMode, OverflowError,
+};
 
 impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
     /// Evaluates whether the predicate can be satisfied (by any means)
diff --git a/src/librustc/traits/query/method_autoderef.rs b/src/librustc/traits/query/method_autoderef.rs
index 6b9bdfd63f4d0..039dea1ffcd16 100644
--- a/src/librustc/traits/query/method_autoderef.rs
+++ b/src/librustc/traits/query/method_autoderef.rs
@@ -6,11 +6,11 @@ use crate::ty::Ty;
 pub struct CandidateStep<'tcx> {
     pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
     pub autoderefs: usize,
-    // true if the type results from a dereference of a raw pointer.
-    // when assembling candidates, we include these steps, but not when
-    // picking methods. This so that if we have `foo: *const Foo` and `Foo` has methods
-    // `fn by_raw_ptr(self: *const Self)` and `fn by_ref(&self)`, then
-    // `foo.by_raw_ptr()` will work and `foo.by_ref()` won't.
+    /// `true` if the type results from a dereference of a raw pointer.
+    /// when assembling candidates, we include these steps, but not when
+    /// picking methods. This so that if we have `foo: *const Foo` and `Foo` has methods
+    /// `fn by_raw_ptr(self: *const Self)` and `fn by_ref(&self)`, then
+    /// `foo.by_raw_ptr()` will work and `foo.by_ref()` won't.
     pub from_unsafe_deref: bool,
     pub unsize: bool,
 }
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index 07d6f633143a2..7f3c62ec99470 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -512,7 +512,7 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>(
     (impl_trait_ref, impl_obligations)
 }
 
-/// See `super::obligations_for_generics`
+/// See [`super::obligations_for_generics`].
 pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
                                      recursion_depth: usize,
                                      param_env: ty::ParamEnv<'tcx>,
@@ -562,7 +562,7 @@ impl<'tcx> TyCtxt<'tcx> {
         predicate_for_trait_ref(cause, param_env, trait_ref, recursion_depth)
     }
 
-    /// Cast a trait reference into a reference to one of its super
+    /// Casts a trait reference into a reference to one of its super
     /// traits; returns `None` if `target_trait_def_id` is not a
     /// supertrait.
     pub fn upcast_choices(self,
@@ -571,7 +571,7 @@ impl<'tcx> TyCtxt<'tcx> {
                           -> Vec<ty::PolyTraitRef<'tcx>>
     {
         if source_trait_ref.def_id() == target_trait_def_id {
-            return vec![source_trait_ref]; // shorcut the most common case
+            return vec![source_trait_ref]; // Shorcut the most common case.
         }
 
         supertraits(self, source_trait_ref)
diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs
index 1ddc6780aca89..1aa21501129c8 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc/ty/codec.rs
@@ -284,9 +284,11 @@ where
 #[macro_export]
 macro_rules! __impl_decoder_methods {
     ($($name:ident -> $ty:ty;)*) => {
-        $(fn $name(&mut self) -> Result<$ty, Self::Error> {
-            self.opaque.$name()
-        })*
+        $(
+            fn $name(&mut self) -> Result<$ty, Self::Error> {
+                self.opaque.$name()
+            }
+        )*
     }
 }
 
@@ -327,14 +329,17 @@ macro_rules! impl_arena_allocatable_decoders {
 macro_rules! implement_ty_decoder {
     ($DecoderName:ident <$($typaram:tt),*>) => {
         mod __ty_decoder_impl {
-            use super::$DecoderName;
+            use std::borrow::Cow;
+
+            use rustc_serialize::{Decoder, SpecializedDecoder};
+
             use $crate::infer::canonical::CanonicalVarInfos;
             use $crate::ty;
             use $crate::ty::codec::*;
             use $crate::ty::subst::SubstsRef;
             use $crate::hir::def_id::{CrateNum};
-            use rustc_serialize::{Decoder, SpecializedDecoder};
-            use std::borrow::Cow;
+
+            use super::$DecoderName;
 
             impl<$($typaram ),*> Decoder for $DecoderName<$($typaram),*> {
                 type Error = String;
@@ -368,8 +373,8 @@ macro_rules! implement_ty_decoder {
                 }
             }
 
-            // FIXME(#36588) These impls are horribly unsound as they allow
-            // the caller to pick any lifetime for 'tcx, including 'static,
+            // FIXME(#36588): These impls are horribly unsound as they allow
+            // the caller to pick any lifetime for `'tcx`, including `'static`,
             // by using the unspecialized proxies to them.
 
             arena_types!(impl_arena_allocatable_decoders, [$DecoderName [$($typaram),*]], 'tcx);
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 17c9e520bcea2..6867230f4ec43 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-filelength
+
 //! Type context book-keeping.
 
 use crate::arena::Arena;
@@ -7,7 +9,7 @@ use crate::session::Session;
 use crate::session::config::{BorrowckMode, OutputFilenames};
 use crate::session::config::CrateType;
 use crate::middle;
-use crate::hir::{TraitCandidate, HirId, ItemKind, ItemLocalId, Node};
+use crate::hir::{self, TraitCandidate, HirId, ItemKind, ItemLocalId, Node};
 use crate::hir::def::{Res, DefKind, Export};
 use crate::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
 use crate::hir::map as hir_map;
@@ -45,15 +47,16 @@ use crate::ty::CanonicalPolyFnSig;
 use crate::util::common::ErrorReported;
 use crate::util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap, ItemLocalSet};
 use crate::util::nodemap::{FxHashMap, FxHashSet};
+
 use errors::DiagnosticBuilder;
-use smallvec::SmallVec;
-use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
-                                           StableHasher, StableHasherResult,
-                                           StableVec};
 use arena::SyncDroplessArena;
+use smallvec::SmallVec;
+use rustc_data_structures::stable_hasher::{
+    HashStable, StableHasher, StableHasherResult, StableVec, hash_stable_hashmap,
+};
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
-use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal};
 use rustc_data_structures::sharded::ShardedHashMap;
+use rustc_data_structures::sync::{Lrc, Lock, WorkerLocal};
 use std::any::Any;
 use std::borrow::Borrow;
 use std::cmp::Ordering;
@@ -74,8 +77,6 @@ use syntax::feature_gate;
 use syntax::symbol::{Symbol, InternedString, kw, sym};
 use syntax_pos::Span;
 
-use crate::hir;
-
 pub struct AllArenas {
     pub interner: SyncDroplessArena,
 }
@@ -91,10 +92,10 @@ impl AllArenas {
 type InternedSet<'tcx, T> = ShardedHashMap<Interned<'tcx, T>, ()>;
 
 pub struct CtxtInterners<'tcx> {
-    /// The arena that types, regions, etc are allocated from
+    /// The arena that types, regions, etc. are allocated from.
     arena: &'tcx SyncDroplessArena,
 
-    /// Specifically use a speedy hash algorithm for these hash sets,
+    /// Specifically use a speedy hash algorithm for these hash sets, since
     /// they're accessed quite often.
     type_: InternedSet<'tcx, TyS<'tcx>>,
     type_list: InternedSet<'tcx, List<Ty<'tcx>>>,
@@ -129,7 +130,7 @@ impl<'tcx> CtxtInterners<'tcx> {
         }
     }
 
-    /// Intern a type
+    /// Interns a type.
     #[allow(rustc::usage_of_ty_tykind)]
     #[inline(never)]
     fn intern_ty(&self,
@@ -144,7 +145,6 @@ impl<'tcx> CtxtInterners<'tcx> {
                 outer_exclusive_binder: flags.outer_exclusive_binder,
             };
 
-
             Interned(self.arena.alloc(ty_struct))
         }).0
     }
@@ -1025,7 +1025,7 @@ pub struct GlobalCtxt<'tcx> {
 
     hir_map: hir_map::Map<'tcx>,
 
-    /// A map from DefPathHash -> DefId. Includes DefIds from the local crate
+    /// A map from `DefPathHash` -> `DefId`. Includes `DefId`s from the local crate
     /// as well as all upstream crates. Only populated in incremental mode.
     pub def_path_hash_to_def_id: Option<FxHashMap<DefPathHash, DefId>>,
 
@@ -1124,9 +1124,9 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
-    /// Allocates a byte or string literal for `mir::interpret`, read-only
+    /// Allocates a read-only byte or string literal for `mir::interpret`.
     pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId {
-        // create an allocation that just contains these bytes
+        // Create an allocation that just contains these bytes.
         let alloc = interpret::Allocation::from_byte_aligned_bytes(bytes);
         let alloc = self.intern_const_alloc(alloc);
         self.alloc_map.lock().create_memory_alloc(alloc)
@@ -1346,7 +1346,7 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// Converts a `DefId` into its fully expanded `DefPath` (every
-    /// `DefId` is really just an interned def-path).
+    /// `DefId` is really just an interned `DefPath`).
     ///
     /// Note that if `id` is not local to this crate, the result will
     ///  be a non-local `DefPath`.
@@ -1402,6 +1402,10 @@ impl<'tcx> TyCtxt<'tcx> {
         self.cstore.metadata_encoding_version().to_vec()
     }
 
+    pub fn encode_metadata(self)-> EncodedMetadata {
+        self.cstore.encode_metadata(self)
+    }
+
     // Note that this is *untracked* and should only be used within the query
     // system if the result is otherwise tracked through queries
     pub fn crate_data_as_rc_any(self, cnum: CrateNum) -> Lrc<dyn Any> {
@@ -1446,25 +1450,25 @@ impl<'tcx> TyCtxt<'tcx> {
         self.queries.on_disk_cache.serialize(self.global_tcx(), encoder)
     }
 
-    /// If true, we should use the AST-based borrowck (we may *also* use
+    /// If `true`, we should use the AST-based borrowck (we may *also* use
     /// the MIR-based borrowck).
     pub fn use_ast_borrowck(self) -> bool {
         self.borrowck_mode().use_ast()
     }
 
-    /// If true, we should use the MIR-based borrow check, but also
-    /// fall back on the AST borrow check if the MIR-based one errors.
+    /// If `true`, we should use the MIR-based borrowck, but also
+    /// fall back on the AST borrowck if the MIR-based one errors.
     pub fn migrate_borrowck(self) -> bool {
         self.borrowck_mode().migrate()
     }
 
-    /// If true, make MIR codegen for `match` emit a temp that holds a
+    /// If `true`, make MIR codegen for `match` emit a temp that holds a
     /// borrow of the input to the match expression.
     pub fn generate_borrow_of_any_match_input(&self) -> bool {
         self.emit_read_for_match()
     }
 
-    /// If true, make MIR codegen for `match` emit FakeRead
+    /// If `true`, make MIR codegen for `match` emit FakeRead
     /// statements (which simulate the maximal effect of executing the
     /// patterns in a match arm).
     pub fn emit_read_for_match(&self) -> bool {
@@ -1517,7 +1521,7 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
-    // This method returns the DefId and the BoundRegion corresponding to the given region.
+    // Returns the `DefId` and the `BoundRegion` corresponding to the given region.
     pub fn is_suitable_region(&self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
         let (suitable_region_binding_scope, bound_region) = match *region {
             ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region),
@@ -1550,18 +1554,18 @@ impl<'tcx> TyCtxt<'tcx> {
         &self,
         scope_def_id: DefId,
     ) -> Option<Ty<'tcx>> {
-        // HACK: `type_of_def_id()` will fail on these (#55796), so return None
+        // HACK: `type_of_def_id()` will fail on these (#55796), so return `None`.
         let hir_id = self.hir().as_local_hir_id(scope_def_id).unwrap();
         match self.hir().get(hir_id) {
             Node::Item(item) => {
                 match item.node {
-                    ItemKind::Fn(..) => { /* type_of_def_id() will work */ }
+                    ItemKind::Fn(..) => { /* `type_of_def_id()` will work */ }
                     _ => {
                         return None;
                     }
                 }
             }
-            _ => { /* type_of_def_id() will work or panic */ }
+            _ => { /* `type_of_def_id()` will work or panic */ }
         }
 
         let ret_ty = self.type_of(scope_def_id);
@@ -1579,7 +1583,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
     }
 
-    // Here we check if the bound region is in Impl Item.
+    // Checks if the bound region is in Impl Item.
     pub fn is_bound_region_in_impl_item(
         &self,
         suitable_region_binding_scope: DefId,
@@ -1599,23 +1603,15 @@ impl<'tcx> TyCtxt<'tcx> {
         false
     }
 
-    /// Determine whether identifiers in the assembly have strict naming rules.
+    /// Determines whether identifiers in the assembly have strict naming rules.
     /// Currently, only NVPTX* targets need it.
     pub fn has_strict_asm_symbol_naming(&self) -> bool {
-        self.gcx.sess.target.target.arch.contains("nvptx")
-    }
-}
-
-impl<'tcx> TyCtxt<'tcx> {
-    pub fn encode_metadata(self)
-        -> EncodedMetadata
-    {
-        self.cstore.encode_metadata(self)
+        self.sess.target.target.arch.contains("nvptx")
     }
 }
 
 impl<'tcx> GlobalCtxt<'tcx> {
-    /// Call the closure with a local `TyCtxt` using the given arena.
+    /// Calls the closure with a local `TyCtxt` using the given arena.
     /// `interners` is a slot passed so we can create a CtxtInterners
     /// with the same lifetime as `arena`.
     pub fn enter_local<F, R>(&'tcx self, f: F) -> R
@@ -1651,7 +1647,7 @@ impl<'tcx> GlobalCtxt<'tcx> {
 /// It would be more efficient if `TypedArena` provided a way to
 /// determine whether the address is in the allocated range.
 ///
-/// None is returned if the value or one of the components is not part
+/// `None` is returned if the value or one of the components is not part
 /// of the provided context.
 /// For `Ty`, `None` can be returned if either the type interner doesn't
 /// contain the `TyKind` key or if the address of the interned
@@ -1662,7 +1658,6 @@ pub trait Lift<'tcx>: fmt::Debug {
     fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
 }
 
-
 macro_rules! nop_lift {
     ($ty:ty => $lifted:ty) => {
         impl<'a, 'tcx> Lift<'tcx> for $ty {
@@ -1709,7 +1704,7 @@ nop_list_lift!{Predicate<'a> => Predicate<'tcx>}
 nop_list_lift!{CanonicalVarInfo => CanonicalVarInfo}
 nop_list_lift!{ProjectionKind => ProjectionKind}
 
-// this is the impl for `&'a InternalSubsts<'a>`
+// This is the impl for `&'a InternalSubsts<'a>`.
 nop_list_lift!{Kind<'a> => Kind<'tcx>}
 
 pub mod tls {
@@ -1732,43 +1727,43 @@ pub mod tls {
     use rustc_rayon_core as rayon_core;
 
     /// This is the implicit state of rustc. It contains the current
-    /// TyCtxt and query. It is updated when creating a local interner or
-    /// executing a new query. Whenever there's a TyCtxt value available
-    /// you should also have access to an ImplicitCtxt through the functions
+    /// `TyCtxt` and query. It is updated when creating a local interner or
+    /// executing a new query. Whenever there's a `TyCtxt` value available
+    /// you should also have access to an `ImplicitCtxt` through the functions
     /// in this module.
     #[derive(Clone)]
     pub struct ImplicitCtxt<'a, 'tcx> {
-        /// The current TyCtxt. Initially created by `enter_global` and updated
-        /// by `enter_local` with a new local interner
+        /// The current `TyCtxt`. Initially created by `enter_global` and updated
+        /// by `enter_local` with a new local interner.
         pub tcx: TyCtxt<'tcx>,
 
-        /// The current query job, if any. This is updated by JobOwner::start in
-        /// ty::query::plumbing when executing a query
+        /// The current query job, if any. This is updated by `JobOwner::start` in
+        /// `ty::query::plumbing` when executing a query.
         pub query: Option<Lrc<query::QueryJob<'tcx>>>,
 
         /// Where to store diagnostics for the current query job, if any.
-        /// This is updated by JobOwner::start in ty::query::plumbing when executing a query
+        /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
         pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
 
         /// Used to prevent layout from recursing too deeply.
         pub layout_depth: usize,
 
         /// The current dep graph task. This is used to add dependencies to queries
-        /// when executing them
+        /// when executing them.
         pub task_deps: Option<&'a Lock<TaskDeps>>,
     }
 
-    /// Sets Rayon's thread local variable which is preserved for Rayon jobs
+    /// Sets Rayon's thread local variablem, which is preserved for Rayon jobs
     /// to `value` during the call to `f`. It is restored to its previous value after.
-    /// This is used to set the pointer to the new ImplicitCtxt.
+    /// This is used to set the pointer to the new `ImplicitCtxt`.
     #[cfg(parallel_compiler)]
     #[inline]
     fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
         rayon_core::tlv::with(value, f)
     }
 
-    /// Gets Rayon's thread local variable which is preserved for Rayon jobs.
-    /// This is used to get the pointer to the current ImplicitCtxt.
+    /// Gets Rayon's thread local variable, which is preserved for Rayon jobs.
+    /// This is used to get the pointer to the current `ImplicitCtxt`.
     #[cfg(parallel_compiler)]
     #[inline]
     fn get_tlv() -> usize {
@@ -1777,13 +1772,13 @@ pub mod tls {
 
     #[cfg(not(parallel_compiler))]
     thread_local! {
-        /// A thread local variable which stores a pointer to the current ImplicitCtxt.
+        /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
         static TLV: Cell<usize> = Cell::new(0);
     }
 
     /// Sets TLV to `value` during the call to `f`.
     /// It is restored to its previous value after.
-    /// This is used to set the pointer to the new ImplicitCtxt.
+    /// This is used to set the pointer to the new `ImplicitCtxt`.
     #[cfg(not(parallel_compiler))]
     #[inline]
     fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
@@ -1793,14 +1788,14 @@ pub mod tls {
         f()
     }
 
-    /// This is used to get the pointer to the current ImplicitCtxt.
+    /// Gets the pointer to the current `ImplicitCtxt`.
     #[cfg(not(parallel_compiler))]
     fn get_tlv() -> usize {
         TLV.with(|tlv| tlv.get())
     }
 
     /// This is a callback from libsyntax as it cannot access the implicit state
-    /// in librustc otherwise
+    /// in librustc otherwise.
     fn span_debug(span: syntax_pos::Span, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         with_opt(|tcx| {
             if let Some(tcx) = tcx {
@@ -1825,7 +1820,7 @@ pub mod tls {
         })
     }
 
-    /// Sets up the callbacks from libsyntax on the current thread
+    /// Sets up the callbacks from libsyntax on the current thread.
     pub fn with_thread_locals<F, R>(f: F) -> R
         where F: FnOnce() -> R
     {
@@ -1850,7 +1845,7 @@ pub mod tls {
         })
     }
 
-    /// Sets `context` as the new current ImplicitCtxt for the duration of the function `f`
+    /// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
     #[inline]
     pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) -> R
     where
@@ -1861,19 +1856,19 @@ pub mod tls {
         })
     }
 
-    /// Enters GlobalCtxt by setting up libsyntax callbacks and
-    /// creating a initial TyCtxt and ImplicitCtxt.
-    /// This happens once per rustc session and TyCtxts only exists
+    /// Enters `GlobalCtxt` by setting up libsyntax callbacks and
+    /// creating a initial `TyCtxt` and `ImplicitCtxt`.
+    /// This happens once per rustc session and `TyCtxt`s only exists
     /// inside the `f` function.
     pub fn enter_global<'tcx, F, R>(gcx: &'tcx GlobalCtxt<'tcx>, f: F) -> R
     where
         F: FnOnce(TyCtxt<'tcx>) -> R,
     {
-        // Update GCX_PTR to indicate there's a GlobalCtxt available
+        // Update `GCX_PTR` to indicate there's a `GlobalCtxt` available.
         GCX_PTR.with(|lock| {
             *lock.lock() = gcx as *const _ as usize;
         });
-        // Set GCX_PTR back to 0 when we exit
+        // Set `GCX_PTR` back to 0 when we exit.
         let _on_drop = OnDrop(move || {
             GCX_PTR.with(|lock| *lock.lock() = 0);
         });
@@ -1894,12 +1889,12 @@ pub mod tls {
     }
 
     scoped_thread_local! {
-        /// Stores a pointer to the GlobalCtxt if one is available.
-        /// This is used to access the GlobalCtxt in the deadlock handler given to Rayon.
+        /// Stores a pointer to the `GlobalCtxt` if one is available.
+        /// This is used to access the `GlobalCtxt` in the deadlock handler given to Rayon.
         pub static GCX_PTR: Lock<usize>
     }
 
-    /// Creates a TyCtxt and ImplicitCtxt based on the GCX_PTR thread local.
+    /// Creates a `TyCtxt` and `ImplicitCtxt` based on the `GCX_PTR` thread local.
     /// This is used in the deadlock handler.
     pub unsafe fn with_global<F, R>(f: F) -> R
     where
@@ -1921,7 +1916,7 @@ pub mod tls {
         enter_context(&icx, |_| f(tcx))
     }
 
-    /// Allows access to the current ImplicitCtxt in a closure if one is available
+    /// Allows access to the current `ImplicitCtxt` in a closure if one is available.
     #[inline]
     pub fn with_context_opt<F, R>(f: F) -> R
     where
@@ -1931,16 +1926,16 @@ pub mod tls {
         if context == 0 {
             f(None)
         } else {
-            // We could get a ImplicitCtxt pointer from another thread.
-            // Ensure that ImplicitCtxt is Sync
+            // We could get a `ImplicitCtxt` pointer from another thread.
+            // Ensure that `ImplicitCtxt` is `Sync`.
             sync::assert_sync::<ImplicitCtxt<'_, '_>>();
 
             unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_>))) }
         }
     }
 
-    /// Allows access to the current ImplicitCtxt.
-    /// Panics if there is no ImplicitCtxt available
+    /// Allows access to the current `ImplicitCtxt`.
+    /// Panics if there is no `ImplicitCtxt` available.
     #[inline]
     pub fn with_context<F, R>(f: F) -> R
     where
@@ -1949,11 +1944,11 @@ pub mod tls {
         with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
     }
 
-    /// Allows access to the current ImplicitCtxt whose tcx field has the same global
-    /// interner as the tcx argument passed in. This means the closure is given an ImplicitCtxt
-    /// with the same 'tcx lifetime as the TyCtxt passed in.
-    /// This will panic if you pass it a TyCtxt which has a different global interner from
-    /// the current ImplicitCtxt's tcx field.
+    /// Allows access to the current `ImplicitCtxt` whose tcx field has the same global
+    /// interner as the tcx argument passed in. This means the closure is given an `ImplicitCtxt`
+    /// with the same `'tcx` lifetime as the `TyCtxt` passed in.
+    /// This will panic if you pass it a `TyCtxt` which has a different global interner from
+    /// the current `ImplicitCtxt`'s `tcx` field.
     #[inline]
     pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
     where
@@ -1968,8 +1963,8 @@ pub mod tls {
         })
     }
 
-    /// Allows access to the TyCtxt in the current ImplicitCtxt.
-    /// Panics if there is no ImplicitCtxt available
+    /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
+    /// Panics if there is no `ImplicitCtxt` available.
     #[inline]
     pub fn with<F, R>(f: F) -> R
     where
@@ -1978,8 +1973,8 @@ pub mod tls {
         with_context(|context| f(context.tcx))
     }
 
-    /// Allows access to the TyCtxt in the current ImplicitCtxt.
-    /// The closure is passed None if there is no ImplicitCtxt available
+    /// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
+    /// The closure is passed None if there is no `ImplicitCtxt` available.
     #[inline]
     pub fn with_opt<F, R>(f: F) -> R
     where
@@ -1991,7 +1986,7 @@ pub mod tls {
 
 macro_rules! sty_debug_print {
     ($ctxt: expr, $($variant: ident),*) => {{
-        // curious inner module to allow variant names to be used as
+        // Curious inner module to allow variant names to be used as
         // variable names.
         #[allow(non_snake_case)]
         mod inner {
@@ -2265,9 +2260,9 @@ slice_interners!(
     projs: _intern_projs(ProjectionKind)
 );
 
-// This isn't a perfect fit: CanonicalVarInfo slices are always
+// This isn't a perfect fit: `CanonicalVarInfo` slices are always
 // allocated in the global arena, so this `intern_method!` macro is
-// overly general.  But we just return false for the code that checks
+// overly general. However, we just return `false` for the code that checks
 // whether they belong in the thread-local arena, so no harm done, and
 // seems better than open-coding the rest.
 intern_method! {
@@ -2366,7 +2361,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
     #[inline]
     pub fn mk_adt(self, def: &'tcx AdtDef, substs: SubstsRef<'tcx>) -> Ty<'tcx> {
-        // take a copy of substs so that we own the vectors inside
+        // Take a copy of substs so that we own the vectors inside.
         self.mk_ty(Adt(def, substs))
     }
 
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index 4b30412b41954..1e08ae45951d1 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -39,8 +39,8 @@ use std::collections::BTreeMap;
 use std::fmt;
 use crate::util::nodemap::FxHashSet;
 
-/// The TypeFoldable trait is implemented for every type that can be folded.
-/// Basically, every type that has a corresponding method in TypeFolder.
+/// This trait is implemented for every type that can be folded.
+/// Basically, every type that has a corresponding method in `TypeFolder`.
 ///
 /// To implement this conveniently, use the
 /// `BraceStructTypeFoldableImpl` etc macros found in `macros.rs`.
diff --git a/src/librustc/ty/inhabitedness/def_id_forest.rs b/src/librustc/ty/inhabitedness/def_id_forest.rs
index 4453624fa4502..63cc60d80aada 100644
--- a/src/librustc/ty/inhabitedness/def_id_forest.rs
+++ b/src/librustc/ty/inhabitedness/def_id_forest.rs
@@ -4,20 +4,20 @@ use rustc::hir::CRATE_HIR_ID;
 use crate::ty::context::TyCtxt;
 use crate::ty::{DefId, DefIdTree};
 
-/// Represents a forest of DefIds closed under the ancestor relation. That is,
-/// if a DefId representing a module is contained in the forest then all
-/// DefIds defined in that module or submodules are also implicitly contained
+/// Represents a forest of `DefId`s closed under the ancestor relation. That is,
+/// if a `DefId` representing a module is contained in the forest then all
+/// `DefId`s defined in that module or submodules are also implicitly contained
 /// in the forest.
 ///
 /// This is used to represent a set of modules in which a type is visibly
 /// uninhabited.
 #[derive(Clone)]
 pub struct DefIdForest {
-    /// The minimal set of DefIds required to represent the whole set.
-    /// If A and B are DefIds in the DefIdForest, and A is a descendant
-    /// of B, then only B will be in root_ids.
-    /// We use a SmallVec here because (for its use for caching inhabitedness)
-    /// its rare that this will contain even two ids.
+    /// The minimal set of `DefId`s required to represent the whole set.
+    /// If A and B are DefIds in the `DefIdForest`, and A is a descendant
+    /// of B, then only B will be in `root_ids`.
+    /// We use a `SmallVec` here because (for its use for caching inhabitedness)
+    /// its rare that this will contain even two IDs.
     root_ids: SmallVec<[DefId; 1]>,
 }
 
@@ -37,7 +37,7 @@ impl<'tcx> DefIdForest {
         DefIdForest::from_id(crate_id)
     }
 
-    /// Creates a forest containing a DefId and all its descendants.
+    /// Creates a forest containing a `DefId` and all its descendants.
     pub fn from_id(id: DefId) -> DefIdForest {
         let mut root_ids = SmallVec::new();
         root_ids.push(id);
diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs
index 2b3291656653f..1a0e351733877 100644
--- a/src/librustc/ty/inhabitedness/mod.rs
+++ b/src/librustc/ty/inhabitedness/mod.rs
@@ -1,3 +1,5 @@
+pub use self::def_id_forest::DefIdForest;
+
 use crate::ty::context::TyCtxt;
 use crate::ty::{AdtDef, VariantDef, FieldDef, Ty, TyS};
 use crate::ty::{DefId, SubstsRef};
@@ -5,12 +7,10 @@ use crate::ty::{AdtKind, Visibility};
 use crate::ty::TyKind::*;
 use crate::ty;
 
-pub use self::def_id_forest::DefIdForest;
-
 mod def_id_forest;
 
-// The methods in this module calculate DefIdForests of modules in which a
-// AdtDef/VariantDef/FieldDef is visibly uninhabited.
+// The methods in this module calculate `DefIdForest`s of modules in which a
+// `AdtDef`/`VariantDef`/`FieldDef` is visibly uninhabited.
 //
 // # Example
 // ```rust
@@ -36,24 +36,25 @@ mod def_id_forest;
 //     y: c::AlsoSecretlyUninhabited,
 // }
 // ```
-// In this code, the type Foo will only be visibly uninhabited inside the
-// modules b, c and d. Calling uninhabited_from on Foo or its AdtDef will
-// return the forest of modules {b, c->d} (represented in a DefIdForest by the
-// set {b, c})
+// In this code, the type `Foo` will only be visibly uninhabited inside the
+// modules `b`, `c` and `d`. Calling `uninhabited_from` on `Foo` or its `AdtDef` will
+// return the forest of modules {`b`, `c`->`d`} (represented in a `DefIdForest` by the
+// set {`b`, `c`}).
 //
-// We need this information for pattern-matching on Foo or types that contain
-// Foo.
+// We need this information for pattern-matching on `Foo` or types that contain
+// `Foo`.
 //
 // # Example
 // ```rust
 // let foo_result: Result<T, Foo> = ... ;
 // let Ok(t) = foo_result;
 // ```
-// This code should only compile in modules where the uninhabitedness of Foo is
+// This code should only compile in modules where the uninhabitedness of `Foo` is
 // visible.
 
 impl<'tcx> TyCtxt<'tcx> {
     /// Checks whether a type is visibly uninhabited from a particular module.
+    ///
     /// # Example
     /// ```rust
     /// enum Void {}
@@ -91,7 +92,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// visible.
     pub fn is_ty_uninhabited_from(self, module: DefId, ty: Ty<'tcx>) -> bool {
         // To check whether this type is uninhabited at all (not just from the
-        // given node) you could check whether the forest is empty.
+        // given node), you could check whether the forest is empty.
         // ```
         // forest.is_empty()
         // ```
@@ -108,7 +109,7 @@ impl<'tcx> TyCtxt<'tcx> {
 }
 
 impl<'tcx> AdtDef {
-    /// Calculate the forest of DefIds from which this adt is visibly uninhabited.
+    /// Calculates the forest of `DefId`s from which this ADT is visibly uninhabited.
     fn uninhabited_from(&self, tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>) -> DefIdForest {
         // Non-exhaustive ADTs from other crates are always considered inhabited.
         if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
@@ -122,7 +123,7 @@ impl<'tcx> AdtDef {
 }
 
 impl<'tcx> VariantDef {
-    /// Calculate the forest of DefIds from which this variant is visibly uninhabited.
+    /// Calculates the forest of `DefId`s from which this variant is visibly uninhabited.
     pub fn uninhabited_from(
         &self,
         tcx: TyCtxt<'tcx>,
@@ -148,7 +149,7 @@ impl<'tcx> VariantDef {
 }
 
 impl<'tcx> FieldDef {
-    /// Calculate the forest of DefIds from which this field is visibly uninhabited.
+    /// Calculates the forest of `DefId`s from which this field is visibly uninhabited.
     fn uninhabited_from(
         &self,
         tcx: TyCtxt<'tcx>,
@@ -159,7 +160,7 @@ impl<'tcx> FieldDef {
             self.ty(tcx, substs).uninhabited_from(tcx)
         };
         // FIXME(canndrew): Currently enum fields are (incorrectly) stored with
-        // Visibility::Invisible so we need to override self.vis if we're
+        // `Visibility::Invisible` so we need to override `self.vis` if we're
         // dealing with an enum.
         if is_enum {
             data_uninhabitedness()
@@ -178,7 +179,7 @@ impl<'tcx> FieldDef {
 }
 
 impl<'tcx> TyS<'tcx> {
-    /// Calculate the forest of DefIds from which this type is visibly uninhabited.
+    /// Calculates the forest of `DefId`s from which this type is visibly uninhabited.
     fn uninhabited_from(&self, tcx: TyCtxt<'tcx>) -> DefIdForest {
         match self.sty {
             Adt(def, substs) => def.uninhabited_from(tcx, substs),
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 2da50f37409ae..41e4295caecce 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -590,7 +590,7 @@ impl<'tcx> rustc_serialize::UseSpecializedDecodable for Ty<'tcx> {}
 pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>;
 
 extern {
-    /// A dummy type used to force List to by unsized without requiring fat pointers
+    /// A dummy type used to force `List` to by unsized without requiring fat pointers.
     type OpaqueListContents;
 }
 
diff --git a/src/librustc/ty/print/mod.rs b/src/librustc/ty/print/mod.rs
index 092e7c6f3fffb..50789bf6213b6 100644
--- a/src/librustc/ty/print/mod.rs
+++ b/src/librustc/ty/print/mod.rs
@@ -27,7 +27,8 @@ pub trait Print<'tcx, P> {
 /// which the associated types allow passing through the methods.
 ///
 /// For pretty-printing/formatting in particular, see `PrettyPrinter`.
-// FIXME(eddyb) find a better name, this is more general than "printing".
+//
+// FIXME(eddyb) find a better name; this is more general than "printing".
 pub trait Printer<'tcx>: Sized {
     type Error;
 
@@ -46,6 +47,7 @@ pub trait Printer<'tcx>: Sized {
     ) -> Result<Self::Path, Self::Error> {
         self.default_print_def_path(def_id, substs)
     }
+
     fn print_impl_path(
         self,
         impl_def_id: DefId,
@@ -80,6 +82,7 @@ pub trait Printer<'tcx>: Sized {
         self,
         cnum: CrateNum,
     ) -> Result<Self::Path, Self::Error>;
+
     fn path_qualified(
         self,
         self_ty: Ty<'tcx>,
@@ -93,11 +96,13 @@ pub trait Printer<'tcx>: Sized {
         self_ty: Ty<'tcx>,
         trait_ref: Option<ty::TraitRef<'tcx>>,
     ) -> Result<Self::Path, Self::Error>;
+
     fn path_append(
         self,
         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
         disambiguated_data: &DisambiguatedDefPathData,
     ) -> Result<Self::Path, Self::Error>;
+
     fn path_generic_args(
         self,
         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index a72ecdb5745bb..419a815074b5e 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -8,10 +8,11 @@ use crate::ty::{self, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
 use crate::ty::subst::{Kind, Subst, UnpackedKind};
 use crate::ty::layout::{Integer, IntegerExt, Size};
 use crate::mir::interpret::{ConstValue, sign_extend, Scalar, truncate};
-use syntax::ast;
+
 use rustc_apfloat::ieee::{Double, Single};
 use rustc_apfloat::Float;
 use rustc_target::spec::abi::Abi;
+use syntax::ast;
 use syntax::attr::{SignedInt, UnsignedInt};
 use syntax::symbol::{kw, InternedString};
 
@@ -194,7 +195,7 @@ pub trait PrettyPrinter<'tcx>:
         value.skip_binder().print(self)
     }
 
-    /// Print comma-separated elements.
+    /// Prints comma-separated elements.
     fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, Self::Error>
     where
         T: Print<'tcx, Self, Output = Self, Error = Self::Error>,
@@ -209,14 +210,14 @@ pub trait PrettyPrinter<'tcx>:
         Ok(self)
     }
 
-    /// Print `<...>` around what `f` prints.
+    /// Prints `<...>` around what `f` prints.
     fn generic_delimiters(
         self,
         f: impl FnOnce(Self) -> Result<Self, Self::Error>,
     ) -> Result<Self, Self::Error>;
 
-    /// Return `true` if the region should be printed in
-    /// optional positions, e.g. `&'a T` or `dyn Tr + 'b`.
+    /// Returns `true` if the region should be printed in
+    /// optional positions, e.g., `&'a T` or `dyn Tr + 'b`.
     /// This is typically the case for all non-`'_` regions.
     fn region_should_not_be_omitted(
         &self,
@@ -226,7 +227,7 @@ pub trait PrettyPrinter<'tcx>:
     // Defaults (should not be overriden):
 
     /// If possible, this returns a global path resolving to `def_id` that is visible
-    /// from at least one local module and returns true. If the crate defining `def_id` is
+    /// from at least one local module, and returns `true`. If the crate defining `def_id` is
     /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
     fn try_print_visible_def_path(
         self,
@@ -267,11 +268,11 @@ pub trait PrettyPrinter<'tcx>:
             // In local mode, when we encounter a crate other than
             // LOCAL_CRATE, execution proceeds in one of two ways:
             //
-            // 1. for a direct dependency, where user added an
+            // 1. For a direct dependency, where user added an
             //    `extern crate` manually, we put the `extern
             //    crate` as the parent. So you wind up with
             //    something relative to the current crate.
-            // 2. for an extern inferred from a path or an indirect crate,
+            // 2. For an extern inferred from a path or an indirect crate,
             //    where there is no explicit `extern crate`, we just prepend
             //    the crate name.
             match self.tcx().extern_crate(def_id) {
@@ -304,13 +305,13 @@ pub trait PrettyPrinter<'tcx>:
         let mut cur_def_key = self.tcx().def_key(def_id);
         debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key);
 
-        // For a constructor we want the name of its parent rather than <unnamed>.
+        // For a constructor, we want the name of its parent rather than <unnamed>.
         match cur_def_key.disambiguated_data.data {
             DefPathData::Ctor => {
                 let parent = DefId {
                     krate: def_id.krate,
                     index: cur_def_key.parent
-                        .expect("DefPathData::Ctor/VariantData missing a parent"),
+                        .expect("`DefPathData::Ctor` / `VariantData` missing a parent"),
                 };
 
                 cur_def_key = self.tcx().def_key(parent);
@@ -630,7 +631,7 @@ pub trait PrettyPrinter<'tcx>:
                         sep = ", ";
                     }
                 } else {
-                    // cross-crate closure types should only be
+                    // Cross-crate closure types should only be
                     // visible in codegen bug reports, I imagine.
                     p!(write("@{:?}", did));
                     let mut sep = " ";
@@ -673,7 +674,7 @@ pub trait PrettyPrinter<'tcx>:
                         sep = ", ";
                     }
                 } else {
-                    // cross-crate closure types should only be
+                    // Cross-crate closure types should only be
                     // visible in codegen bug reports, I imagine.
                     p!(write("@{:?}", did));
                     let mut sep = " ";
@@ -1092,35 +1093,38 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
         }
 
         let key = self.tcx.def_key(def_id);
-        if let DefPathData::Impl = key.disambiguated_data.data {
-            // Always use types for non-local impls, where types are always
-            // available, and filename/line-number is mostly uninteresting.
-            let use_types =
-                !def_id.is_local() || {
-                    // Otherwise, use filename/line-number if forced.
-                    let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
-                    !force_no_types
-                };
+        match key.disambiguated_data.data {
+            DefPathData::Impl => {
+                // Always use types for non-local impls, where types are always
+                // available, and filename/line-number is mostly uninteresting.
+                let use_types =
+                    !def_id.is_local() || {
+                        // Otherwise, use filename/line-number if forced.
+                        let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
+                        !force_no_types
+                    };
 
-            if !use_types {
-                // If no type info is available, fall back to
-                // pretty printing some span information. This should
-                // only occur very early in the compiler pipeline.
-                let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
-                let span = self.tcx.def_span(def_id);
+                if !use_types {
+                    // If no type info is available, fall back to
+                    // pretty-printing some span information. This should
+                    // only occur very early in the compiler pipeline.
+                    let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
+                    let span = self.tcx.def_span(def_id);
 
-                self = self.print_def_path(parent_def_id, &[])?;
+                    self = self.print_def_path(parent_def_id, &[])?;
 
-                // HACK(eddyb) copy of `path_append` to avoid
-                // constructing a `DisambiguatedDefPathData`.
-                if !self.empty_path {
-                    write!(self, "::")?;
-                }
-                write!(self, "<impl at {:?}>", span)?;
-                self.empty_path = false;
+                    // HACK(eddyb) copy of `path_append` to avoid
+                    // constructing a `DisambiguatedDefPathData`.
+                    if !self.empty_path {
+                        write!(self, "::")?;
+                    }
+                    write!(self, "<impl at {:?}>", span)?;
+                    self.empty_path = false;
 
-                return Ok(self);
+                    return Ok(self);
+                }
             }
+            _ => {}
         }
 
         self.default_print_def_path(def_id, substs)
@@ -1173,6 +1177,7 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
         }
         Ok(self)
     }
+
     fn path_qualified(
         mut self,
         self_ty: Ty<'tcx>,
@@ -1201,6 +1206,7 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
         self.empty_path = false;
         Ok(self)
     }
+
     fn path_append(
         mut self,
         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
@@ -1238,6 +1244,7 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
 
         Ok(self)
     }
+
     fn path_generic_args(
         mut self,
         print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 674f8944f261a..d24143ced5be2 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -5,9 +5,6 @@ use crate::hir::map::definitions::DefPathHash;
 use crate::ich::{CachingSourceMapView, Fingerprint};
 use crate::mir::{self, interpret};
 use crate::mir::interpret::{AllocDecodingSession, AllocDecodingState};
-use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque,
-                      SpecializedDecoder, SpecializedEncoder,
-                      UseSpecializedDecodable, UseSpecializedEncodable};
 use crate::session::{CrateDisambiguator, Session};
 use crate::ty::{self, Ty};
 use crate::ty::codec::{self as ty_codec, TyDecoder, TyEncoder};
@@ -19,6 +16,10 @@ 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 rustc_serialize::{
+    Decodable, Decoder, Encodable, Encoder, SpecializedDecoder, SpecializedEncoder,
+    UseSpecializedDecodable, UseSpecializedEncodable, opaque,
+};
 use std::mem;
 use syntax::ast::{Ident, NodeId};
 use syntax::source_map::{SourceMap, StableSourceFileId};
@@ -37,17 +38,16 @@ const TAG_EXPN_DATA_INLINE: u8 = 2;
 const TAG_VALID_SPAN: u8 = 0;
 const TAG_INVALID_SPAN: u8 = 1;
 
-/// `OnDiskCache` provides an interface to incr. comp. data cached from the
+/// Provides an interface to incremental compilation data cached from the
 /// previous compilation session. This data will eventually include the results
 /// of a few selected queries (like `typeck_tables_of` and `mir_optimized`) and
 /// any diagnostics that have been emitted during a query.
 pub struct OnDiskCache<'sess> {
-
     // The complete cache data in serialized form.
     serialized_data: Vec<u8>,
 
-    // This field collects all Diagnostics emitted during the current
-    // compilation session.
+    // Collects all `Diagnostic`s emitted during the current compilation
+    // session.
     current_diagnostics: Lock<FxHashMap<DepNodeIndex, Vec<Diagnostic>>>,
 
     prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
@@ -56,7 +56,7 @@ pub struct OnDiskCache<'sess> {
     source_map: &'sess SourceMap,
     file_index_to_stable_id: FxHashMap<SourceFileIndex, StableSourceFileId>,
 
-    // These two fields caches that are populated lazily during decoding.
+    // Caches that are populated lazily during decoding.
     file_index_to_file: Lock<FxHashMap<SourceFileIndex, Lrc<SourceFile>>>,
     synthetic_syntax_contexts: Lock<FxHashMap<AbsoluteBytePos, SyntaxContext>>,
 
@@ -78,7 +78,7 @@ struct Footer {
     prev_cnums: Vec<(u32, String, CrateDisambiguator)>,
     query_result_index: EncodedQueryResultIndex,
     diagnostics_index: EncodedQueryResultIndex,
-    // the location of all allocations
+    // The location of all allocations.
     interpret_alloc_index: Vec<u32>,
 }
 
@@ -104,28 +104,28 @@ impl AbsoluteBytePos {
 }
 
 impl<'sess> OnDiskCache<'sess> {
-    /// Creates a new OnDiskCache instance from the serialized data in `data`.
-    pub fn new(sess: &'sess Session, data: Vec<u8>, start_pos: usize) -> OnDiskCache<'sess> {
+    /// Creates a new `OnDiskCache` instance from the serialized data in `data`.
+    pub fn new(sess: &'sess Session, data: Vec<u8>, start_pos: usize) -> Self {
         debug_assert!(sess.opts.incremental.is_some());
 
-        // Wrapping in a scope so we can borrow `data`
+        // Wrap in a scope so we can borrow `data`.
         let footer: Footer = {
             let mut decoder = opaque::Decoder::new(&data[..], start_pos);
 
-            // Decode the *position* of the footer which can be found in the
+            // Decode the *position* of the footer, which can be found in the
             // last 8 bytes of the file.
             decoder.set_position(data.len() - IntEncodedWithFixedSize::ENCODED_SIZE);
-            let query_result_index_pos = IntEncodedWithFixedSize::decode(&mut decoder)
-                .expect("Error while trying to decode query result index position.")
+            let footer_pos = IntEncodedWithFixedSize::decode(&mut decoder)
+                .expect("error while trying to decode footer position")
                 .0 as usize;
 
-            // Decoder the file footer which contains all the lookup tables, etc.
-            decoder.set_position(query_result_index_pos);
+            // Decode the file footer, which contains all the lookup tables, etc.
+            decoder.set_position(footer_pos);
             decode_tagged(&mut decoder, TAG_FILE_FOOTER)
-                .expect("Error while trying to decode query result index position.")
+                .expect("error while trying to decode footer position")
         };
 
-        OnDiskCache {
+        Self {
             serialized_data: data,
             file_index_to_stable_id: footer.file_index_to_stable_id,
             file_index_to_file: Default::default(),
@@ -140,8 +140,8 @@ impl<'sess> OnDiskCache<'sess> {
         }
     }
 
-    pub fn new_empty(source_map: &'sess SourceMap) -> OnDiskCache<'sess> {
-        OnDiskCache {
+    pub fn new_empty(source_map: &'sess SourceMap) -> Self {
+        Self {
             serialized_data: Vec::new(),
             file_index_to_stable_id: Default::default(),
             file_index_to_file: Default::default(),
@@ -158,11 +158,11 @@ impl<'sess> OnDiskCache<'sess> {
 
     pub fn serialize<'tcx, E>(&self, tcx: TyCtxt<'tcx>, encoder: &mut E) -> Result<(), E::Error>
     where
-        E: ty_codec::TyEncoder,
+        E: TyEncoder,
     {
-        // Serializing the DepGraph should not modify it:
+        // Serializing the `DepGraph` should not modify it.
         tcx.dep_graph.with_ignore(|| {
-            // Allocate SourceFileIndices
+            // Allocate `SourceFileIndex`es.
             let (file_to_file_index, file_index_to_stable_id) = {
                 let files = tcx.sess.source_map().files();
                 let mut file_to_file_index = FxHashMap::with_capacity_and_hasher(
@@ -197,7 +197,7 @@ impl<'sess> OnDiskCache<'sess> {
             // be in memory, so this should be a cheap operation.
             tcx.dep_graph.exec_cache_promotions(tcx);
 
-            // Encode query results
+            // Encode query results.
             let mut query_result_index = EncodedQueryResultIndex::new();
 
             time(tcx.sess, "encode query results", || {
@@ -221,29 +221,28 @@ impl<'sess> OnDiskCache<'sess> {
                 Ok(())
             })?;
 
-            // Encode diagnostics
+            // Encode diagnostics.
             let diagnostics_index: EncodedDiagnosticsIndex = self.current_diagnostics.borrow()
                 .iter()
-                .map(|(dep_node_index, diagnostics)|
-            {
-                let pos = AbsoluteBytePos::new(encoder.position());
-                // Let's make sure we get the expected type here:
-                let diagnostics: &EncodedDiagnostics = diagnostics;
-                let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index());
-                encoder.encode_tagged(dep_node_index, diagnostics)?;
-
-                Ok((dep_node_index, pos))
-            })
-            .collect::<Result<_, _>>()?;
+                .map(|(dep_node_index, diagnostics)| {
+                    let pos = AbsoluteBytePos::new(encoder.position());
+                    // Let's make sure we get the expected type here.
+                    let diagnostics: &EncodedDiagnostics = diagnostics;
+                    let dep_node_index = SerializedDepNodeIndex::new(dep_node_index.index());
+                    encoder.encode_tagged(dep_node_index, diagnostics)?;
+
+                    Ok((dep_node_index, pos))
+                })
+                .collect::<Result<_, _>>()?;
 
             let interpret_alloc_index = {
                 let mut interpret_alloc_index = Vec::new();
                 let mut n = 0;
                 loop {
                     let new_n = encoder.interpret_allocs_inverse.len();
-                    // if we have found new ids, serialize those, too
+                    // If we have found new IDs, serialize those too.
                     if n == new_n {
-                        // otherwise, abort
+                        // Otherwise, abort.
                         break;
                     }
                     interpret_alloc_index.reserve(new_n - n);
@@ -263,13 +262,15 @@ impl<'sess> OnDiskCache<'sess> {
             };
 
             let sorted_cnums = sorted_cnums_including_local_crate(tcx);
-            let prev_cnums: Vec<_> = sorted_cnums.iter().map(|&cnum| {
-                let crate_name = tcx.original_crate_name(cnum).as_str().to_string();
-                let crate_disambiguator = tcx.crate_disambiguator(cnum);
-                (cnum.as_u32(), crate_name, crate_disambiguator)
-            }).collect();
-
-            // Encode the file footer
+            let prev_cnums: Vec<_> = sorted_cnums.iter()
+                .map(|&cnum| {
+                    let crate_name = tcx.original_crate_name(cnum).as_str().to_string();
+                    let crate_disambiguator = tcx.crate_disambiguator(cnum);
+                    (cnum.as_u32(), crate_name, crate_disambiguator)
+                })
+                .collect();
+
+            // Encode the file footer.
             let footer_pos = encoder.position() as u64;
             encoder.encode_tagged(TAG_FILE_FOOTER, &Footer {
                 file_index_to_stable_id,
@@ -371,7 +372,7 @@ impl<'sess> OnDiskCache<'sess> {
     {
         let pos = index.get(&dep_node_index).cloned()?;
 
-        // Initialize the cnum_map using the value from the thread which finishes the closure first
+        // Initialize `cnum_map` using the value from the thread that finishes the closure first.
         self.cnum_map.init_nonlocking_same(|| {
             Self::compute_cnum_map(tcx, &self.prev_cnums[..])
         });
@@ -381,25 +382,21 @@ impl<'sess> OnDiskCache<'sess> {
             opaque: opaque::Decoder::new(&self.serialized_data[..], pos.to_usize()),
             source_map: self.source_map,
             cnum_map: self.cnum_map.get(),
+            synthetic_syntax_contexts: &self.synthetic_syntax_contexts,
             file_index_to_file: &self.file_index_to_file,
             file_index_to_stable_id: &self.file_index_to_stable_id,
-            synthetic_syntax_contexts: &self.synthetic_syntax_contexts,
             alloc_decoding_session: self.alloc_decoding_state.new_decoding_session(),
         };
 
         match decode_tagged(&mut decoder, dep_node_index) {
-            Ok(value) => {
-                Some(value)
-            }
-            Err(e) => {
-                bug!("Could not decode cached {}: {}", debug_tag, e)
-            }
+            Ok(v) => Some(v),
+            Err(e) => bug!("could not decode cached {}: {}", debug_tag, e),
         }
     }
 
-    // This function builds mapping from previous-session-CrateNum to
-    // current-session-CrateNum. There might be CrateNums from the previous
-    // Session that don't occur in the current one. For these, the mapping
+    // This function builds mapping from previous-session-`CrateNum` to
+    // current-session-`CrateNum`. There might be `CrateNum`s from the previous
+    // `Session` that don't occur in the current one. For these, the mapping
     // maps to None.
     fn compute_cnum_map(
         tcx: TyCtxt<'_>,
@@ -432,9 +429,9 @@ impl<'sess> OnDiskCache<'sess> {
 
 //- DECODING -------------------------------------------------------------------
 
-/// A decoder that can read the incr. comp. cache. It is similar to the one
-/// we use for crate metadata decoding in that it can rebase spans and
-/// eventually will also handle things that contain `Ty` instances.
+/// A decoder that can read fro the incr. comp. cache. It is similar to the onem
+/// we use for crate metadata decoding in that it can rebase spans and eventually
+/// will also handle things that contain `Ty` instances.
 struct CacheDecoder<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     opaque: opaque::Decoder<'a>,
@@ -458,30 +455,32 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> {
         file_index_to_file.borrow_mut().entry(index).or_insert_with(|| {
             let stable_id = file_index_to_stable_id[&index];
             source_map.source_file_by_stable_id(stable_id)
-                .expect("Failed to lookup SourceFile in new context.")
+                .expect("failed to lookup `SourceFile` in new context")
         }).clone()
     }
 }
 
-trait DecoderWithPosition: Decoder {
+pub trait DecoderWithPosition: Decoder {
     fn position(&self) -> usize;
 }
 
 impl<'a> DecoderWithPosition for opaque::Decoder<'a> {
+    #[inline]
     fn position(&self) -> usize {
         self.position()
     }
 }
 
 impl<'a, 'tcx> DecoderWithPosition for CacheDecoder<'a, 'tcx> {
+    #[inline]
     fn position(&self) -> usize {
         self.opaque.position()
     }
 }
 
-// Decode something that was encoded with encode_tagged() and verify that the
+// Decodes something that was encoded with `encode_tagged()` and verify that the
 // tag matches and the correct amount of bytes was read.
-fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> Result<V, D::Error>
+pub fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> Result<V, D::Error>
 where
     T: Decodable + Eq + ::std::fmt::Debug,
     V: Decodable,
@@ -500,7 +499,7 @@ where
     Ok(value)
 }
 
-impl<'a, 'tcx> ty_codec::TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
+impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
     #[inline]
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
@@ -534,7 +533,7 @@ impl<'a, 'tcx> ty_codec::TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
         }
 
         let ty = or_insert_with(self)?;
-        // This may overwrite the entry, but it should overwrite with the same value
+        // This may overwrite the entry, but it should overwrite with the same value.
         tcx.rcache.borrow_mut().insert_same(cache_key, ty);
         Ok(ty)
     }
@@ -553,7 +552,7 @@ impl<'a, 'tcx> ty_codec::TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
 
     fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
         self.cnum_map[cnum].unwrap_or_else(|| {
-            bug!("Could not find new CrateNum for {:?}", cnum)
+            bug!("could not find new `CrateNum` for {:?}", cnum)
         })
     }
 }
@@ -635,25 +634,25 @@ impl<'a, 'tcx> SpecializedDecoder<Ident> for CacheDecoder<'a, 'tcx> {
 }
 
 // This impl makes sure that we get a runtime error when we try decode a
-// DefIndex that is not contained in a DefId. Such a case would be problematic
-// because we would not know how to transform the DefIndex to the current
+// `DefIndex` that is not contained in a `DefId`. Such a case would be problematic
+// because we would not know how to transform the `DefIndex` to the current
 // context.
 impl<'a, 'tcx> SpecializedDecoder<DefIndex> for CacheDecoder<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<DefIndex, Self::Error> {
-        bug!("Trying to decode DefIndex outside the context of a DefId")
+        bug!("trying to decode `DefIndex` outside the context of a `DefId`")
     }
 }
 
-// Both the CrateNum and the DefIndex of a DefId can change in between two
-// compilation sessions. We use the DefPathHash, which is stable across
-// sessions, to map the old DefId to the new one.
+// Both the `CrateNum` and the `DefIndex` of a `DefId` can change in between two
+// compilation sessions. We use the `DefPathHash`, which is stable across
+// sessions, to map the old DefId`` to the new one.
 impl<'a, 'tcx> SpecializedDecoder<DefId> for CacheDecoder<'a, 'tcx> {
     #[inline]
     fn specialized_decode(&mut self) -> Result<DefId, Self::Error> {
-        // Load the DefPathHash which is was we encoded the DefId as.
+        // Load the `DefPathHash` which is was we encoded the `DefId` as.
         let def_path_hash = DefPathHash::decode(self)?;
 
-        // Using the DefPathHash, we can lookup the new DefId
+        // Using the `DefPathHash`, we can lookup the new `DefId`.
         Ok(self.tcx().def_path_hash_to_def_id.as_ref().unwrap()[&def_path_hash])
     }
 }
@@ -667,10 +666,10 @@ impl<'a, 'tcx> SpecializedDecoder<LocalDefId> for CacheDecoder<'a, 'tcx> {
 
 impl<'a, 'tcx> SpecializedDecoder<hir::HirId> for CacheDecoder<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<hir::HirId, Self::Error> {
-        // Load the DefPathHash which is was we encoded the DefIndex as.
+        // Load the `DefPathHash` which is what we encoded the `DefIndex` as.
         let def_path_hash = DefPathHash::decode(self)?;
 
-        // Use the DefPathHash to map to the current DefId.
+        // Use the `DefPathHash` to map to the current `DefId`.
         let def_id = self.tcx()
                          .def_path_hash_to_def_id
                          .as_ref()
@@ -678,10 +677,10 @@ impl<'a, 'tcx> SpecializedDecoder<hir::HirId> for CacheDecoder<'a, 'tcx> {
 
         debug_assert!(def_id.is_local());
 
-        // The ItemLocalId needs no remapping.
+        // The `ItemLocalId` needs no remapping.
         let local_id = hir::ItemLocalId::decode(self)?;
 
-        // Reconstruct the HirId and look up the corresponding NodeId in the
+        // Reconstruct the `HirId` and look up the corresponding `NodeId` in the
         // context of the current session.
         Ok(hir::HirId {
             owner: def_id.index,
@@ -690,8 +689,8 @@ impl<'a, 'tcx> SpecializedDecoder<hir::HirId> for CacheDecoder<'a, 'tcx> {
     }
 }
 
-// NodeIds are not stable across compilation sessions, so we store them in their
-// HirId representation. This allows use to map them to the current NodeId.
+// `NodeId`s are not stable across compilation sessions, so we store them in their
+// `HirId` representation. This allows use to map them to the current `NodeId`.
 impl<'a, 'tcx> SpecializedDecoder<NodeId> for CacheDecoder<'a, 'tcx> {
     #[inline]
     fn specialized_decode(&mut self) -> Result<NodeId, Self::Error> {
@@ -701,6 +700,7 @@ impl<'a, 'tcx> SpecializedDecoder<NodeId> for CacheDecoder<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for CacheDecoder<'a, 'tcx> {
+    #[inline]
     fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
         Fingerprint::decode_opaque(&mut self.opaque)
     }
@@ -728,6 +728,7 @@ impl<'a, 'tcx, T: Decodable> SpecializedDecoder<mir::ClearCrossCrate<T>>
 
 //- ENCODING -------------------------------------------------------------------
 
+/// An encoder that can write the incr. comp. cache.
 struct CacheEncoder<'a, 'tcx, E: ty_codec::TyEncoder> {
     tcx: TyCtxt<'tcx>,
     encoder: &'a mut E,
@@ -742,7 +743,7 @@ struct CacheEncoder<'a, 'tcx, E: ty_codec::TyEncoder> {
 
 impl<'a, 'tcx, E> CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     fn source_file_index(&mut self, source_file: Lrc<SourceFile>) -> SourceFileIndex {
         self.file_to_file_index[&(&*source_file as *const SourceFile)]
@@ -753,11 +754,11 @@ where
     /// encode the specified tag, then the given value, then the number of
     /// bytes taken up by tag and value. On decoding, we can then verify that
     /// we get the expected tag and read the expected number of bytes.
-    fn encode_tagged<T: Encodable, V: Encodable>(&mut self,
-                                                 tag: T,
-                                                 value: &V)
-                                                 -> Result<(), E::Error>
-    {
+    pub fn encode_tagged<T: Encodable, V: Encodable>(
+        &mut self,
+        tag: T,
+        value: &V
+    ) -> Result<(), E::Error> {
         let start_pos = self.position();
 
         tag.encode(self)?;
@@ -770,7 +771,7 @@ where
 
 impl<'a, 'tcx, E> SpecializedEncoder<interpret::AllocId> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
         use std::collections::hash_map::Entry;
@@ -790,10 +791,9 @@ where
 
 impl<'a, 'tcx, E> SpecializedEncoder<Span> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     fn specialized_encode(&mut self, span: &Span) -> Result<(), Self::Error> {
-
         if *span == DUMMY_SP {
             return TAG_INVALID_SPAN.encode(self);
         }
@@ -849,14 +849,14 @@ where
         // We don't currently encode enough information to ensure hygiene works
         // with incremental, so panic rather than risk incremental bugs.
 
-        // FIXME: Handle hygiene in incremental
-        bug!("Trying to encode Ident for incremental")
+        // FIXME: handle hygiene in incremental.
+        bug!("trying to encode `Ident` for incremental");
     }
 }
 
 impl<'a, 'tcx, E> ty_codec::TyEncoder for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     #[inline]
     fn position(&self) -> usize {
@@ -866,7 +866,7 @@ where
 
 impl<'a, 'tcx, E> SpecializedEncoder<CrateNum> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     #[inline]
     fn specialized_encode(&mut self, cnum: &CrateNum) -> Result<(), Self::Error> {
@@ -876,7 +876,7 @@ where
 
 impl<'a, 'tcx, E> SpecializedEncoder<Ty<'tcx>> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     #[inline]
     fn specialized_encode(&mut self, ty: &Ty<'tcx>) -> Result<(), Self::Error> {
@@ -887,7 +887,7 @@ where
 
 impl<'a, 'tcx, E> SpecializedEncoder<ty::GenericPredicates<'tcx>> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     #[inline]
     fn specialized_encode(&mut self,
@@ -900,7 +900,7 @@ where
 
 impl<'a, 'tcx, E> SpecializedEncoder<hir::HirId> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     #[inline]
     fn specialized_encode(&mut self, id: &hir::HirId) -> Result<(), Self::Error> {
@@ -918,7 +918,7 @@ where
 
 impl<'a, 'tcx, E> SpecializedEncoder<DefId> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     #[inline]
     fn specialized_encode(&mut self, id: &DefId) -> Result<(), Self::Error> {
@@ -929,7 +929,7 @@ where
 
 impl<'a, 'tcx, E> SpecializedEncoder<LocalDefId> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     #[inline]
     fn specialized_encode(&mut self, id: &LocalDefId) -> Result<(), Self::Error> {
@@ -939,18 +939,18 @@ where
 
 impl<'a, 'tcx, E> SpecializedEncoder<DefIndex> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     fn specialized_encode(&mut self, _: &DefIndex) -> Result<(), Self::Error> {
-        bug!("Encoding DefIndex without context.")
+        bug!("encoding `DefIndex` without context");
     }
 }
 
-// NodeIds are not stable across compilation sessions, so we store them in their
-// HirId representation. This allows use to map them to the current NodeId.
+// `NodeId`s are not stable across compilation sessions, so we store them in their
+// `HirId` representation. This allows use to map them to the current `NodeId`.
 impl<'a, 'tcx, E> SpecializedEncoder<NodeId> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     #[inline]
     fn specialized_encode(&mut self, node_id: &NodeId) -> Result<(), Self::Error> {
@@ -960,6 +960,7 @@ where
 }
 
 impl<'a, 'tcx> SpecializedEncoder<Fingerprint> for CacheEncoder<'a, 'tcx, opaque::Encoder> {
+    #[inline]
     fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
         f.encode_opaque(&mut self.encoder)
     }
@@ -967,7 +968,7 @@ impl<'a, 'tcx> SpecializedEncoder<Fingerprint> for CacheEncoder<'a, 'tcx, opaque
 
 impl<'a, 'tcx, E, T> SpecializedEncoder<mir::ClearCrossCrate<T>> for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
     T: Encodable,
 {
     #[inline]
@@ -996,7 +997,7 @@ macro_rules! encoder_methods {
 
 impl<'a, 'tcx, E> Encoder for CacheEncoder<'a, 'tcx, E>
 where
-    E: 'a + ty_codec::TyEncoder,
+    E: 'a + TyEncoder,
 {
     type Error = E::Error;
 
@@ -1040,7 +1041,7 @@ impl UseSpecializedDecodable for IntEncodedWithFixedSize {}
 impl SpecializedEncoder<IntEncodedWithFixedSize> for opaque::Encoder {
     fn specialized_encode(&mut self, x: &IntEncodedWithFixedSize) -> Result<(), Self::Error> {
         let start_pos = self.position();
-        for i in 0 .. IntEncodedWithFixedSize::ENCODED_SIZE {
+        for i in 0..IntEncodedWithFixedSize::ENCODED_SIZE {
             ((x.0 >> i * 8) as u8).encode(self)?;
         }
         let end_pos = self.position();
@@ -1085,10 +1086,10 @@ where
             if Q::cache_on_disk(tcx, key.clone(), Some(&entry.value)) {
                 let dep_node = SerializedDepNodeIndex::new(entry.index.index());
 
-                // Record position of the cache entry
+                // Record position of the cache entry.
                 query_result_index.push((dep_node, AbsoluteBytePos::new(encoder.position())));
 
-                // Encode the type check tables with the SerializedDepNodeIndex
+                // Encode the type check tables with the `SerializedDepNodeIndex`
                 // as tag.
                 encoder.encode_tagged(dep_node, &entry.value)?;
             }
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index 4dce55f589233..d199a26475be7 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -61,7 +61,7 @@ impl<'tcx, M: QueryConfig<'tcx>> Default for QueryCache<'tcx, M> {
     }
 }
 
-// If enabled, send a message to the profile-queries thread
+// If enabled, sends a message to the profile-queries thread.
 macro_rules! profq_msg {
     ($tcx:expr, $msg:expr) => {
         if cfg!(debug_assertions) {
@@ -72,7 +72,7 @@ macro_rules! profq_msg {
     }
 }
 
-// If enabled, format a key using its debug string, which can be
+// If enabled, formats a key using its debug string, which can be
 // expensive to compute (in terms of time).
 macro_rules! profq_query_msg {
     ($query:expr, $tcx:expr, $key:expr) => {{
@@ -98,7 +98,7 @@ pub(super) struct JobOwner<'a, 'tcx, Q: QueryDescription<'tcx>> {
 
 impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> {
     /// Either gets a `JobOwner` corresponding the query, allowing us to
-    /// start executing the query, or it returns with the result of the query.
+    /// start executing the query, or returns with the result of the query.
     /// If the query is executing elsewhere, this will wait for it.
     /// If the query panicked, this will silently panic.
     ///
@@ -215,30 +215,30 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> Drop for JobOwner<'a, 'tcx, Q> {
     #[inline(never)]
     #[cold]
     fn drop(&mut self) {
-        // Poison the query so jobs waiting on it panic
+        // Poison the query so jobs waiting on it panic.
         let shard = self.cache.get_shard_by_value(&self.key);
         shard.lock().active.insert(self.key.clone(), QueryResult::Poisoned);
         // Also signal the completion of the job, so waiters
-        // will continue execution
+        // will continue execution.
         self.job.signal_complete();
     }
 }
 
 #[derive(Clone)]
 pub struct CycleError<'tcx> {
-    /// The query and related span which uses the cycle
+    /// The query and related span that uses the cycle.
     pub(super) usage: Option<(Span, Query<'tcx>)>,
     pub(super) cycle: Vec<QueryInfo<'tcx>>,
 }
 
-/// The result of `try_get_lock`
+/// The result of `try_get_lock`.
 pub(super) enum TryGetJob<'a, 'tcx, D: QueryDescription<'tcx>> {
     /// The query is not yet started. Contains a guard to the cache eventually used to start it.
     NotYetStarted(JobOwner<'a, 'tcx, D>),
 
     /// The query was already completed.
-    /// Returns the result of the query and its dep node index
-    /// if it succeeded or a cycle error if it failed
+    /// Returns the result of the query and its dep-node index
+    /// if it succeeded or a cycle error if it failed.
     JobCompleted((D::Value, DepNodeIndex)),
 
     /// Trying to execute the query resulted in a cycle.
@@ -246,7 +246,7 @@ pub(super) enum TryGetJob<'a, 'tcx, D: QueryDescription<'tcx>> {
 }
 
 impl<'tcx> TyCtxt<'tcx> {
-    /// Executes a job by changing the ImplicitCtxt to point to the
+    /// Executes a job by changing the `ImplicitCtxt` to point to the
     /// new query job while it executes. It returns the diagnostics
     /// captured during execution and the actual result.
     #[inline(always)]
@@ -259,11 +259,11 @@ impl<'tcx> TyCtxt<'tcx> {
     where
         F: FnOnce(TyCtxt<'tcx>) -> R,
     {
-        // The TyCtxt stored in TLS has the same global interner lifetime
+        // The `TyCtxt` stored in TLS has the same global interner lifetime
         // as `self`, so we use `with_related_context` to relate the 'tcx lifetimes
-        // when accessing the ImplicitCtxt
+        // when accessing the `ImplicitCtxt`.
         tls::with_related_context(self, move |current_icx| {
-            // Update the ImplicitCtxt to point to our new query job
+            // Update the `ImplicitCtxt` to point to our new query job.
             let new_icx = tls::ImplicitCtxt {
                 tcx: self.global_tcx(),
                 query: Some(job),
@@ -272,7 +272,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 task_deps: current_icx.task_deps,
             };
 
-            // Use the ImplicitCtxt while we execute the query
+            // Use the `ImplicitCtxt` while we execute the query.
             tls::enter_context(&new_icx, |_| {
                 compute(self.global_tcx())
             })
@@ -372,7 +372,7 @@ impl<'tcx> TyCtxt<'tcx> {
         };
 
         // Fast path for when incr. comp. is off. `to_dep_node` is
-        // expensive for some DepKinds.
+        // expensive for some `DepKind`s.
         if !self.dep_graph.is_fully_enabled() {
             let null_dep_node = DepNode::new_no_params(crate::dep_graph::DepKind::Null);
             return self.force_query_with_job::<Q>(key, job, null_dep_node).0;
@@ -410,7 +410,7 @@ impl<'tcx> TyCtxt<'tcx> {
         if !Q::EVAL_ALWAYS {
             // The diagnostics for this query will be
             // promoted to the current session during
-            // try_mark_green(), so we can ignore them here.
+            // `try_mark_green()`, so we can ignore them here.
             let loaded = self.start_query(job.job.clone(), None, |tcx| {
                 let marked = tcx.dep_graph.try_mark_green_and_read(tcx, &dep_node);
                 marked.map(|(prev_dep_node_index, dep_node_index)| {
@@ -441,11 +441,11 @@ impl<'tcx> TyCtxt<'tcx> {
         dep_node: &DepNode,
     ) -> Q::Value {
         // Note this function can be called concurrently from the same query
-        // We must ensure that this is handled correctly
+        // We must ensure that this is handled correctly.
 
         debug_assert!(self.dep_graph.is_green(dep_node));
 
-        // First we try to load the result from the on-disk cache
+        // First we try to load the result from the on-disk cache.
         let result = if Q::cache_on_disk(self.global_tcx(), key.clone(), None) &&
                         self.sess.opts.debugging_opts.incremental_queries {
             self.sess.profiler(|p| p.incremental_load_result_start(Q::NAME));
@@ -453,10 +453,10 @@ impl<'tcx> TyCtxt<'tcx> {
             self.sess.profiler(|p| p.incremental_load_result_end(Q::NAME));
 
             // We always expect to find a cached result for things that
-            // can be forced from DepNode.
+            // can be forced from `DepNode`.
             debug_assert!(!dep_node.kind.can_reconstruct_query_key() ||
                           result.is_some(),
-                          "Missing on-disk cache entry for {:?}",
+                          "missing on-disk cache entry for {:?}",
                           dep_node);
             result
         } else {
@@ -475,8 +475,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
             self.sess.profiler(|p| p.start_query(Q::NAME));
 
-            // The dep-graph for this computation is already in
-            // place
+            // The dep-graph for this computation is already in-place.
             let result = self.dep_graph.with_ignore(|| {
                 Q::compute(self, key)
             });
@@ -485,7 +484,7 @@ impl<'tcx> TyCtxt<'tcx> {
             result
         };
 
-        // If -Zincremental-verify-ich is specified, re-hash results from
+        // If `-Zincremental-verify-ich` is specified, re-hash results from
         // the cache and make sure that they have the expected fingerprint.
         if unlikely!(self.sess.opts.debugging_opts.incremental_verify_ich) {
             self.incremental_verify_ich::<Q>(&result, dep_node, dep_node_index);
@@ -508,10 +507,12 @@ impl<'tcx> TyCtxt<'tcx> {
     ) {
         use crate::ich::Fingerprint;
 
-        assert!(Some(self.dep_graph.fingerprint_of(dep_node_index)) ==
+        assert!(
+            Some(self.dep_graph.fingerprint_of(dep_node_index)) ==
                 self.dep_graph.prev_fingerprint_of(dep_node),
-                "Fingerprint for green query instance not loaded \
-                    from cache: {:?}", dep_node);
+            "fingerprint for green query instance not loaded from cache: {:?}",
+            dep_node,
+        );
 
         debug!("BEGIN verify_ich({:?})", dep_node);
         let mut hcx = self.create_stable_hashing_context();
@@ -521,8 +522,11 @@ impl<'tcx> TyCtxt<'tcx> {
 
         let old_hash = self.dep_graph.fingerprint_of(dep_node_index);
 
-        assert!(new_hash == old_hash, "Found unstable fingerprints \
-            for {:?}", dep_node);
+        assert!(
+            new_hash == old_hash,
+            "found unstable fingerprints for {:?}",
+            dep_node,
+        );
     }
 
     #[inline(always)]
@@ -534,11 +538,11 @@ impl<'tcx> TyCtxt<'tcx> {
     ) -> (Q::Value, DepNodeIndex) {
         // If the following assertion triggers, it can have two reasons:
         // 1. Something is wrong with DepNode creation, either here or
-        //    in DepGraph::try_mark_green()
-        // 2. Two distinct query keys get mapped to the same DepNode
-        //    (see for example #48923)
+        //    in `DepGraph::try_mark_green()`.
+        // 2. Two distinct query keys get mapped to the same `DepNode`
+        //    (see for example #48923).
         assert!(!self.dep_graph.dep_node_exists(&dep_node),
-                "Forcing query with already existing DepNode.\n\
+                "forcing query with already existing `DepNode`\n\
                  - query-key: {:?}\n\
                  - dep-node: {:?}",
                 key, dep_node);
@@ -584,7 +588,7 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// Ensure that either this query has all green inputs or been executed.
-    /// Executing query::ensure(D) is considered a read of the dep-node D.
+    /// Executing `query::ensure(D)` is considered a read of the dep-node `D`.
     ///
     /// This function is particularly useful when executing passes for their
     /// side-effects -- e.g., in order to report errors for erroneous programs.
@@ -899,13 +903,13 @@ macro_rules! define_queries_inner {
                 }
             }
 
-            // FIXME(eddyb) Get more valid Span's on queries.
+            // FIXME(eddyb) Get more valid `Span`s on queries.
             pub fn default_span(&self, tcx: TyCtxt<$tcx>, span: Span) -> Span {
                 if !span.is_dummy() {
                     return span;
                 }
-                // The def_span query is used to calculate default_span,
-                // so exit to avoid infinite recursion
+                // The `def_span` query is used to calculate `default_span`,
+                // so exit to avoid infinite recursion.
                 if let Query::def_span(..) = *self {
                     return span
                 }
@@ -1116,7 +1120,7 @@ macro_rules! define_provider_struct {
         impl<$tcx> Default for Providers<$tcx> {
             fn default() -> Self {
                 $(fn $name<$tcx>(_: TyCtxt<$tcx>, key: $K) -> $R {
-                    bug!("tcx.{}({:?}) unsupported by its crate",
+                    bug!("`tcx.{}({:?})` unsupported by its crate",
                          stringify!($name), key);
                 })*
                 Providers { $($name),* }
@@ -1128,26 +1132,26 @@ macro_rules! define_provider_struct {
 
 /// The red/green evaluation system will try to mark a specific DepNode in the
 /// dependency graph as green by recursively trying to mark the dependencies of
-/// that DepNode as green. While doing so, it will sometimes encounter a DepNode
+/// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode`
 /// where we don't know if it is red or green and we therefore actually have
 /// to recompute its value in order to find out. Since the only piece of
-/// information that we have at that point is the DepNode we are trying to
+/// information that we have at that point is the `DepNode` we are trying to
 /// re-evaluate, we need some way to re-run a query from just that. This is what
 /// `force_from_dep_node()` implements.
 ///
-/// In the general case, a DepNode consists of a DepKind and an opaque
+/// In the general case, a `DepNode` consists of a `DepKind` and an opaque
 /// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
 /// is usually constructed by computing a stable hash of the query-key that the
-/// DepNode corresponds to. Consequently, it is not in general possible to go
+/// `DepNode` corresponds to. Consequently, it is not in general possible to go
 /// back from hash to query-key (since hash functions are not reversible). For
 /// this reason `force_from_dep_node()` is expected to fail from time to time
-/// because we just cannot find out, from the DepNode alone, what the
+/// because we just cannot find out, from the `DepNode` alone, what the
 /// corresponding query-key is and therefore cannot re-run the query.
 ///
 /// The system deals with this case letting `try_mark_green` fail which forces
 /// the root query to be re-evaluated.
 ///
-/// Now, if force_from_dep_node() would always fail, it would be pretty useless.
+/// Now, if `force_from_dep_node()` would always fail, it would be pretty useless.
 /// Fortunately, we can use some contextual information that will allow us to
 /// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we
 /// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a
@@ -1171,9 +1175,9 @@ macro_rules! define_provider_struct {
 pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool {
     use crate::dep_graph::RecoverKey;
 
-    // We must avoid ever having to call force_from_dep_node() for a
-    // DepNode::codegen_unit:
-    // Since we cannot reconstruct the query key of a DepNode::codegen_unit, we
+    // We must avoid ever having to call `force_from_dep_node()` for a
+    // `DepNode::codegen_unit`:
+    // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we
     // would always end up having to evaluate the first caller of the
     // `codegen_unit` query that *is* reconstructible. This might very well be
     // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just
@@ -1196,7 +1200,7 @@ pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool {
             if let Some(def_id) = dep_node.extract_def_id(tcx) {
                 def_id
             } else {
-                // return from the whole function
+                // Return from the whole function.
                 return false
             }
         }
@@ -1224,20 +1228,20 @@ pub fn force_from_dep_node(tcx: TyCtxt<'_>, dep_node: &DepNode) -> bool {
 
     rustc_dep_node_force!([dep_node, tcx]
         // These are inputs that are expected to be pre-allocated and that
-        // should therefore always be red or green already
+        // should therefore always be red or green already.
         DepKind::AllLocalTraitImpls |
         DepKind::Krate |
         DepKind::CrateMetadata |
         DepKind::HirBody |
         DepKind::Hir |
 
-        // This are anonymous nodes
+        // These are anonymous nodes.
         DepKind::TraitSelect |
 
         // We don't have enough information to reconstruct the query key of
-        // these
+        // these.
         DepKind::CompileCodegenUnit => {
-            bug!("force_from_dep_node() - Encountered {:?}", dep_node)
+            bug!("force_from_dep_node: encountered {:?}", dep_node)
         }
 
         DepKind::Analysis => { force!(analysis, krate!()); }
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index d2edf6fb1ee80..e73a51e6f78e5 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -644,7 +644,7 @@ impl<'tcx> Binder<ExistentialPredicate<'tcx>> {
 impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {}
 
 impl<'tcx> List<ExistentialPredicate<'tcx>> {
-    /// Returns the "principal def id" of this set of existential predicates.
+    /// Returns the "principal `DefId`" of this set of existential predicates.
     ///
     /// A Rust trait object type consists (in addition to a lifetime bound)
     /// of a set of trait bounds, which are separated into any number
@@ -1052,7 +1052,7 @@ impl<'tcx> PolyGenSig<'tcx> {
     }
 }
 
-/// Signature of a function type, which I have arbitrarily
+/// Signature of a function type, which we have arbitrarily
 /// decided to use to refer to the input/output types.
 ///
 /// - `inputs`: is the list of arguments and their modes.
@@ -1076,7 +1076,8 @@ impl<'tcx> FnSig<'tcx> {
         self.inputs_and_output[self.inputs_and_output.len() - 1]
     }
 
-    // Create a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible method
+    // Creates a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible
+    // method.
     fn fake() -> FnSig<'tcx> {
         FnSig {
             inputs_and_output: List::empty(),
@@ -1118,7 +1119,6 @@ impl<'tcx> PolyFnSig<'tcx> {
 
 pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<FnSig<'tcx>>>;
 
-
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
          Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ParamTy {
diff --git a/src/librustc_ast_borrowck/cfg/construct.rs b/src/librustc_ast_borrowck/cfg/construct.rs
index 339d92145c64f..0dc999083a91a 100644
--- a/src/librustc_ast_borrowck/cfg/construct.rs
+++ b/src/librustc_ast_borrowck/cfg/construct.rs
@@ -1,11 +1,12 @@
 use crate::cfg::*;
-use rustc_data_structures::graph::implementation as graph;
-use rustc::middle::region;
-use rustc::ty::{self, TyCtxt};
 
 use rustc::hir::{self, PatKind};
 use rustc::hir::def_id::DefId;
 use rustc::hir::ptr::P;
+use rustc::middle::region;
+use rustc::ty::{self, TyCtxt};
+
+use rustc_data_structures::graph::implementation as graph;
 
 struct CFGBuilder<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -19,15 +20,15 @@ struct CFGBuilder<'a, 'tcx> {
 
 #[derive(Copy, Clone)]
 struct BlockScope {
-    block_expr_id: hir::ItemLocalId, // id of breakable block expr node
+    block_expr_id: hir::ItemLocalId, // ID of breakable block expr node
     break_index: CFGIndex, // where to go on `break`
 }
 
 #[derive(Copy, Clone)]
 struct LoopScope {
-    loop_id: hir::ItemLocalId,     // id of loop/while node
+    loop_id: hir::ItemLocalId, // ID of `loop`/`while` node
     continue_index: CFGIndex, // where to go on a `loop`
-    break_index: CFGIndex,    // where to go on a `break`
+    break_index: CFGIndex, // where to go on a `break`
 }
 
 pub(super) fn construct(tcx: TyCtxt<'_>, body: &hir::Body) -> CFG {
@@ -103,9 +104,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 let init_exit = self.opt_expr(&local.init, pred);
                 self.pat(&local.pat, init_exit)
             }
-            hir::StmtKind::Item(_) => {
-                pred
-            }
+            hir::StmtKind::Item(_) => pred,
             hir::StmtKind::Expr(ref expr) |
             hir::StmtKind::Semi(ref expr) => {
                 self.expr(&expr, pred)
@@ -154,12 +153,12 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         }
     }
 
-    fn pats_all<'b, I: Iterator<Item=&'b P<hir::Pat>>>(
+    /// Handles case where all of the patterns must match.
+    fn pats_all<'b, I: Iterator<Item = &'b P<hir::Pat>>>(
         &mut self,
         pats: I,
-        pred: CFGIndex
+        pred: CFGIndex,
     ) -> CFGIndex {
-        //! Handles case where all of the patterns must match.
         pats.fold(pred, |pred, pat| self.pat(&pat, pred))
     }
 
@@ -185,15 +184,15 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 // Note that `break` and `loop` statements
                 // may cause additional edges.
 
-                let loopback = self.add_dummy_node(&[pred]);              // 1
-                let expr_exit = self.add_ast_node(expr.hir_id.local_id, &[]);          // 2
+                let loopback = self.add_dummy_node(&[pred]); // 1
+                let expr_exit = self.add_ast_node(expr.hir_id.local_id, &[]); // 2
                 self.loop_scopes.push(LoopScope {
                     loop_id: expr.hir_id.local_id,
                     continue_index: loopback,
                     break_index: expr_exit,
                 });
-                let body_exit = self.block(&body, loopback);           // 3
-                self.add_contained_edge(body_exit, loopback);            // 4
+                let body_exit = self.block(&body, loopback); // 3
+                self.add_contained_edge(body_exit, loopback); // 4
                 self.loop_scopes.pop();
                 expr_exit
             }
@@ -217,9 +216,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 //    v 3  v 4
                 //   [..exit..]
                 //
-                let l_exit = self.expr(&l, pred);                      // 1
-                let r_exit = self.expr(&r, l_exit);                    // 2
-                self.add_ast_node(expr.hir_id.local_id, &[l_exit, r_exit])            // 3,4
+                let l_exit = self.expr(&l, pred); // 1
+                let r_exit = self.expr(&r, l_exit); // 2
+                self.add_ast_node(expr.hir_id.local_id, &[l_exit, r_exit]) // 3,4
             }
 
             hir::ExprKind::Ret(ref v) => {
@@ -313,11 +312,13 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         }
     }
 
-    fn call<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
-            call_expr: &hir::Expr,
-            pred: CFGIndex,
-            func_or_rcvr: &hir::Expr,
-            args: I) -> CFGIndex {
+    fn call<'b, I: Iterator<Item = &'b hir::Expr>>(
+        &mut self,
+        call_expr: &hir::Expr,
+        pred: CFGIndex,
+        func_or_rcvr: &hir::Expr,
+        args: I,
+    ) -> CFGIndex {
         let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
         let ret = self.straightline(call_expr, func_or_rcvr_exit, args);
         let m = self.tcx.hir().get_module_parent(call_expr.hir_id);
@@ -328,33 +329,38 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         }
     }
 
-    fn exprs<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
-                                             exprs: I,
-                                             pred: CFGIndex) -> CFGIndex {
-        //! Constructs graph for `exprs` evaluated in order
+    /// Constructs graph for `exprs` evaluated in order.
+    fn exprs<'b, I: Iterator<Item = &'b hir::Expr>>(
+        &mut self,
+        exprs: I,
+        pred: CFGIndex,
+    ) -> CFGIndex {
         exprs.fold(pred, |p, e| self.expr(e, p))
     }
 
-    fn opt_expr(&mut self,
-                opt_expr: &Option<P<hir::Expr>>,
-                pred: CFGIndex) -> CFGIndex {
-        //! Constructs graph for `opt_expr` evaluated, if Some
+    /// Constructs graph for `opt_expr` evaluated, if `Some`.
+    fn opt_expr(
+        &mut self,
+        opt_expr: &Option<P<hir::Expr>>,
+        pred: CFGIndex,
+    ) -> CFGIndex {
         opt_expr.iter().fold(pred, |p, e| self.expr(&e, p))
     }
 
-    fn straightline<'b, I: Iterator<Item=&'b hir::Expr>>(&mut self,
-                    expr: &hir::Expr,
-                    pred: CFGIndex,
-                    subexprs: I) -> CFGIndex {
-        //! Handles case of an expression that evaluates `subexprs` in order
-
+    /// Handles case of an expression that evaluates `subexprs` in order.
+    fn straightline<'b, I: Iterator<Item = &'b hir::Expr>>(
+        &mut self,
+        expr: &hir::Expr,
+        pred: CFGIndex,
+        subexprs: I,
+    ) -> CFGIndex {
         let subexprs_exit = self.exprs(subexprs, pred);
         self.add_ast_node(expr.hir_id.local_id, &[subexprs_exit])
     }
 
     fn match_(&mut self, id: hir::ItemLocalId, discr: &hir::Expr,
               arms: &[hir::Arm], pred: CFGIndex) -> CFGIndex {
-        // The CFG for match expression is quite complex, so no ASCII
+        // The CFG for match expressions is quite complex, so no ASCII
         // art for it (yet).
         //
         // The CFG generated below matches roughly what MIR contains.
@@ -369,13 +375,13 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         //
         // What is going on is explained in further comments.
 
-        // Visit the discriminant expression
+        // Visit the discriminant expression.
         let discr_exit = self.expr(discr, pred);
 
         // Add a node for the exit of the match expression as a whole.
         let expr_exit = self.add_ast_node(id, &[]);
 
-        // Keep track of the previous guard expressions
+        // Keep track of the previous guard expressions.
         let mut prev_guard = None;
         let match_scope = region::Scope { id, data: region::ScopeData::Node };
 
@@ -388,12 +394,12 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                 // Visit the pattern, coming from the discriminant exit
                 let mut pat_exit = self.pat(&pat, discr_exit);
 
-                // If there is a guard expression, handle it here
+                // If there is a guard expression, handle it here.
                 if let Some(ref guard) = arm.guard {
                     // Add a dummy node for the previous guard
-                    // expression to target
+                    // expression to target.
                     let guard_start = self.add_dummy_node(&[pat_exit]);
-                    // Visit the guard expression
+                    // Visit the guard expression.
                     let guard_exit = match guard {
                         hir::Guard::If(ref e) => (&**e, self.expr(e, guard_start)),
                     };
@@ -407,24 +413,23 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                         self.add_exiting_edge(prev_guard, prev_index, match_scope, guard_start);
                     }
 
-                    // Push the guard onto the list of previous guards
+                    // Push the guard onto the list of previous guards.
                     prev_guard = Some(guard_exit);
 
-                    // Update the exit node for the pattern
+                    // Update the exit node for the pattern.
                     pat_exit = guard_exit.1;
                 }
 
-                // Add an edge from the exit of this pattern to the
-                // exit of the arm
+                // Add an edge from the exit of this pattern to the exit of the arm.
                 self.add_contained_edge(pat_exit, bindings_exit);
             }
 
-            // Visit the body of this arm
+            // Visit the body of this arm.
             let body_exit = self.expr(&arm.body, bindings_exit);
 
             let arm_exit = self.add_ast_node(arm.hir_id.local_id, &[body_exit]);
 
-            // Link the body to the exit of the expression
+            // Link the body to the exit of the expression.
             self.add_contained_edge(arm_exit, expr_exit);
         }
 
@@ -451,18 +456,22 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         node
     }
 
-    fn add_contained_edge(&mut self,
-                          source: CFGIndex,
-                          target: CFGIndex) {
+    fn add_contained_edge(
+        &mut self,
+        source: CFGIndex,
+        target: CFGIndex,
+    ) {
         let data = CFGEdgeData {exiting_scopes: vec![] };
         self.graph.add_edge(source, target, data);
     }
 
-    fn add_exiting_edge(&mut self,
-                        from_expr: &hir::Expr,
-                        from_index: CFGIndex,
-                        target_scope: region::Scope,
-                        to_index: CFGIndex) {
+    fn add_exiting_edge(
+        &mut self,
+        from_expr: &hir::Expr,
+        from_index: CFGIndex,
+        target_scope: region::Scope,
+        to_index: CFGIndex,
+    ) {
         let mut data = CFGEdgeData { exiting_scopes: vec![] };
         let mut scope = region::Scope {
             id: from_expr.hir_id.local_id,
@@ -476,9 +485,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         self.graph.add_edge(from_index, to_index, data);
     }
 
-    fn add_returning_edge(&mut self,
-                          _from_expr: &hir::Expr,
-                          from_index: CFGIndex) {
+    fn add_returning_edge(
+        &mut self,
+        _from_expr: &hir::Expr,
+        from_index: CFGIndex,
+    ) {
         let data = CFGEdgeData {
             exiting_scopes: self.loop_scopes.iter()
                                             .rev()
@@ -488,11 +499,12 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
         self.graph.add_edge(from_index, self.fn_exit, data);
     }
 
-    fn find_scope_edge(&self,
-                  expr: &hir::Expr,
-                  destination: hir::Destination,
-                  scope_cf_kind: ScopeCfKind) -> (region::Scope, CFGIndex) {
-
+    fn find_scope_edge(
+        &self,
+        expr: &hir::Expr,
+        destination: hir::Destination,
+        scope_cf_kind: ScopeCfKind,
+    ) -> (region::Scope, CFGIndex) {
         match destination.target_id {
             Ok(loop_id) => {
                 for b in &self.breakable_block_scopes {
@@ -519,7 +531,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
                         });
                     }
                 }
-                span_bug!(expr.span, "no scope for id {}", loop_id);
+                span_bug!(expr.span, "no scope for ID {}", loop_id);
             }
             Err(err) => span_bug!(expr.span, "scope error: {}",  err),
         }
diff --git a/src/librustc_ast_borrowck/cfg/graphviz.rs b/src/librustc_ast_borrowck/cfg/graphviz.rs
index 46409f1a1cebf..99c6b49cad5d9 100644
--- a/src/librustc_ast_borrowck/cfg/graphviz.rs
+++ b/src/librustc_ast_borrowck/cfg/graphviz.rs
@@ -1,4 +1,4 @@
-/// This module provides linkage between rustc::middle::graph and
+/// This module provides linkage between `rustc::middle::graph` and
 /// libgraphviz traits.
 
 use crate::cfg;
@@ -12,7 +12,7 @@ pub struct LabelledCFG<'a, 'tcx> {
     pub tcx: TyCtxt<'tcx>,
     pub cfg: &'a cfg::CFG,
     pub name: String,
-    /// `labelled_edges` controls whether we emit labels on the edges
+    /// `labelled_edges` controls whether we emit labels on the edges.
     pub labelled_edges: bool,
 }
 
@@ -25,12 +25,12 @@ impl<'a, 'tcx> LabelledCFG<'a, 'tcx> {
         };
         let s = self.tcx.hir().node_to_string(hir_id);
 
-        // Replacing newlines with \\l causes each line to be left-aligned,
+        // Replacing newlines with `\\l` causes each line to be left-aligned,
         // improving presentation of (long) pretty-printed expressions.
         if s.contains("\n") {
             let mut s = s.replace("\n", "\\l");
             // Apparently left-alignment applies to the line that precedes
-            // \l, not the line that follows; so, add \l at end of string
+            // `\l`, not the line that follows; so, add `\l` at end of string
             // if not already present, ensuring last line gets left-aligned
             // as well.
             let mut last_two: Vec<_> =
@@ -109,8 +109,7 @@ impl<'a> dot::GraphWalk<'a> for &'a cfg::CFG {
     }
 }
 
-impl<'a, 'hir> dot::GraphWalk<'a> for LabelledCFG<'a, 'hir>
-{
+impl<'a, 'hir> dot::GraphWalk<'a> for LabelledCFG<'a, 'hir> {
     type Node = Node<'a>;
     type Edge = Edge<'a>;
     fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { self.cfg.nodes() }

From fd48ca20d366cff016cb0f9cfd8e98c44a91da10 Mon Sep 17 00:00:00 2001
From: Alexander Regueiro <alex@noldorin.com>
Date: Fri, 6 Sep 2019 21:05:37 +0100
Subject: [PATCH 574/943] Apply suggestions from code review

Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
---
 src/librustc/hir/lowering.rs             |  2 +-
 src/librustc/mir/interpret/allocation.rs |  9 +++--
 src/librustc/mir/interpret/mod.rs        |  1 -
 src/librustc/mir/mod.rs                  | 27 +++++++------
 src/librustc/session/config.rs           |  4 +-
 src/librustc/traits/util.rs              |  2 +-
 src/librustc/ty/context.rs               |  6 +--
 src/librustc/ty/print/pretty.rs          | 51 +++++++++++-------------
 src/librustc/ty/query/on_disk_cache.rs   | 12 ++----
 9 files changed, 54 insertions(+), 60 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index fd6445ea3c4d4..b50cfa00f09ef 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -126,7 +126,7 @@ pub struct LoweringContext<'a> {
     /// lifetime definitions in the corresponding impl or function generics.
     lifetimes_to_define: Vec<(Span, ParamName)>,
 
-    /// `true` ifs in-band lifetimes are being collected. This is used to
+    /// `true` if in-band lifetimes are being collected. This is used to
     /// indicate whether or not we're in a place where new lifetimes will result
     /// in in-band lifetime definitions, such a function or an impl header,
     /// including implicit lifetimes from `impl_header_lifetime_elision`.
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index e81096c3066f1..755cda792ba79 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -4,13 +4,14 @@ use super::{
     Pointer, InterpResult, AllocId, ScalarMaybeUndef, write_target_uint, read_target_uint, Scalar,
 };
 
+use crate::mir;
 use crate::ty::layout::{Size, Align};
+
+use rustc_data_structures::sorted_map::SortedMap;
+use rustc_target::abi::HasDataLayout;
 use syntax::ast::Mutability;
 use std::iter;
-use crate::mir;
 use std::ops::{Range, Deref, DerefMut};
-use rustc_data_structures::sorted_map::SortedMap;
-use rustc_target::abi::HasDataLayout;
 use std::borrow::Cow;
 
 // NOTE: When adding new fields, make sure to adjust the `Snapshot` impl in
@@ -765,7 +766,7 @@ impl<Tag: Copy, Extra> Allocation<Tag, Extra> {
         }
     }
 
-    /// Apply a relocation copy.
+    /// Applies a relocation copy.
     /// The affected range, as defined in the parameters to `prepare_relocation_copy` is expected
     /// to be clear of relocations.
     pub fn mark_relocation_range(
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index 6f7e11877d5fb..23433c2e8834d 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -349,7 +349,6 @@ pub enum GlobalAlloc<'tcx> {
     Memory(&'tcx Allocation),
 }
 
-#[derive(Clone)]
 pub struct AllocMap<'tcx> {
     /// Maps `AllocId`s to their corresponding allocations.
     alloc_map: FxHashMap<AllocId, GlobalAlloc<'tcx>>,
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index da2faeb4e1ebf..18a5142208d2d 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -605,8 +605,6 @@ pub enum LocalKind {
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct VarBindingForm<'tcx> {
-    /// The `HirId` of the variable.
-    pub var_id: hir::HirId,
     /// Is variable bound via `x`, `mut x`, `ref x`, or `ref mut x`?
     pub binding_mode: ty::BindingMode,
     /// If an explicit type was provided for this variable binding,
@@ -656,7 +654,6 @@ pub enum ImplicitSelfKind {
 CloneTypeFoldableAndLiftImpls! { BindingForm<'tcx>, }
 
 impl_stable_hash_for!(struct self::VarBindingForm<'tcx> {
-    var_id,
     binding_mode,
     opt_ty_info,
     opt_match_place,
@@ -877,7 +874,9 @@ impl<'tcx> LocalDecl<'tcx> {
         match self.is_user_variable {
             Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
                 binding_mode: ty::BindingMode::BindByValue(_),
-                ..
+                opt_ty_info: _,
+                opt_match_place: _,
+                pat_span: _,
             }))) => true,
 
             Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(ImplicitSelfKind::Imm))) => true,
@@ -893,7 +892,9 @@ impl<'tcx> LocalDecl<'tcx> {
         match self.is_user_variable {
             Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
                 binding_mode: ty::BindingMode::BindByValue(_),
-                ..
+                opt_ty_info: _,
+                opt_match_place: _,
+                pat_span: _,
             }))) => true,
 
             Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(_))) => true,
@@ -2830,7 +2831,7 @@ impl Location {
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub enum UnsafetyViolationKind {
     General,
-    /// Permitted in const fns and regular fns.
+    /// Permitted both in `const fn`s and regular `fn`s.
     GeneralAndConstFn,
     ExternStatic(hir::HirId),
     BorrowPacked(hir::HirId),
@@ -2848,7 +2849,7 @@ pub struct UnsafetyViolation {
 pub struct UnsafetyCheckResult {
     /// Violations that are propagated *upwards* from this function.
     pub violations: Lrc<[UnsafetyViolation]>,
-    /// Unsafe blocks in this function, along with whether they are used. This is
+    /// `unsafe` blocks in this function, along with whether they are used. This is
     /// used for the "unused_unsafe" lint.
     pub unsafe_blocks: Lrc<[(hir::HirId, bool)]>,
 }
@@ -2875,12 +2876,14 @@ pub struct GeneratorLayout<'tcx> {
     /// layout.
     pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
 
-    /// Names and scopes of all the stored generator locals.
+    /// The names and scopes of all the stored generator locals.
+    ///
+    /// N.B., this is *strictly* a temporary hack for codegen
+    /// debuginfo generation, and will be removed at some point.
+    /// Do **NOT** use it for anything else, local information should not be
+    /// in the MIR, please rely on local crate HIR or other side-channels.
     //
-    // NOTE(tmandry) This is *strictly* a temporary hack for codegen
-    // debuginfo generation, and will be removed at some point.
-    // Do **NOT** use it for anything else, local information should not be
-    // in the MIR, please rely on local crate HIR or other side-channels.
+    // FIXME(tmandry): see above.
     pub __local_debuginfo_codegen_only_do_not_use: IndexVec<GeneratorSavedLocal, LocalDecl<'tcx>>,
 }
 
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 27a33ced119df..c74b2fee41d6c 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -711,11 +711,11 @@ impl Passes {
 }
 
 /// Defines all `CodegenOptions`/`DebuggingOptions` fields and parsers all at once. The goal of this
-/// macro is to define an interface that can be programmatically used by the option parser in order
+/// macro is to define an interface that can be programmatically used by the option parser
 /// to initialize the struct without hardcoding field names all over the place.
 ///
 /// The goal is to invoke this macro once with the correct fields, and then this macro generates all
-/// necessary code. The main gotcha of this macro is the cgsetters module which is a bunch of
+/// necessary code. The main gotcha of this macro is the `cgsetters` module which is a bunch of
 /// generated code to parse an option into its respective field in the struct. There are a few
 /// hand-written parsers for parsing specific types of values in this module.
 macro_rules! options {
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index 7f3c62ec99470..3d36790c94b8c 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -571,7 +571,7 @@ impl<'tcx> TyCtxt<'tcx> {
                           -> Vec<ty::PolyTraitRef<'tcx>>
     {
         if source_trait_ref.def_id() == target_trait_def_id {
-            return vec![source_trait_ref]; // Shorcut the most common case.
+            return vec![source_trait_ref]; // Shortcut the most common case.
         }
 
         supertraits(self, source_trait_ref)
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 6867230f4ec43..8e8472a5aacc9 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-filelength
-
 //! Type context book-keeping.
 
 use crate::arena::Arena;
@@ -1753,7 +1751,7 @@ pub mod tls {
         pub task_deps: Option<&'a Lock<TaskDeps>>,
     }
 
-    /// Sets Rayon's thread local variablem, which is preserved for Rayon jobs
+    /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
     /// to `value` during the call to `f`. It is restored to its previous value after.
     /// This is used to set the pointer to the new `ImplicitCtxt`.
     #[cfg(parallel_compiler)]
@@ -1762,7 +1760,7 @@ pub mod tls {
         rayon_core::tlv::with(value, f)
     }
 
-    /// Gets Rayon's thread local variable, which is preserved for Rayon jobs.
+    /// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
     /// This is used to get the pointer to the current `ImplicitCtxt`.
     #[cfg(parallel_compiler)]
     #[inline]
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index 419a815074b5e..d99580116e4ae 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -1093,38 +1093,35 @@ impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
         }
 
         let key = self.tcx.def_key(def_id);
-        match key.disambiguated_data.data {
-            DefPathData::Impl => {
-                // Always use types for non-local impls, where types are always
-                // available, and filename/line-number is mostly uninteresting.
-                let use_types =
-                    !def_id.is_local() || {
-                        // Otherwise, use filename/line-number if forced.
-                        let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
-                        !force_no_types
-                    };
-
-                if !use_types {
-                    // If no type info is available, fall back to
-                    // pretty-printing some span information. This should
-                    // only occur very early in the compiler pipeline.
-                    let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
-                    let span = self.tcx.def_span(def_id);
+        if let DefPathData::Impl = key.disambiguated_data.data {
+            // Always use types for non-local impls, where types are always
+            // available, and filename/line-number is mostly uninteresting.
+            let use_types =
+                !def_id.is_local() || {
+                    // Otherwise, use filename/line-number if forced.
+                    let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
+                    !force_no_types
+                };
 
-                    self = self.print_def_path(parent_def_id, &[])?;
+            if !use_types {
+                // If no type info is available, fall back to
+                // pretty printing some span information. This should
+                // only occur very early in the compiler pipeline.
+                let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
+                let span = self.tcx.def_span(def_id);
 
-                    // HACK(eddyb) copy of `path_append` to avoid
-                    // constructing a `DisambiguatedDefPathData`.
-                    if !self.empty_path {
-                        write!(self, "::")?;
-                    }
-                    write!(self, "<impl at {:?}>", span)?;
-                    self.empty_path = false;
+                self = self.print_def_path(parent_def_id, &[])?;
 
-                    return Ok(self);
+                // HACK(eddyb) copy of `path_append` to avoid
+                // constructing a `DisambiguatedDefPathData`.
+                if !self.empty_path {
+                    write!(self, "::")?;
                 }
+                write!(self, "<impl at {:?}>", span)?;
+                self.empty_path = false;
+
+                return Ok(self);
             }
-            _ => {}
         }
 
         self.default_print_def_path(def_id, substs)
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index d24143ced5be2..4cef6a09925ad 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -429,7 +429,7 @@ impl<'sess> OnDiskCache<'sess> {
 
 //- DECODING -------------------------------------------------------------------
 
-/// A decoder that can read fro the incr. comp. cache. It is similar to the onem
+/// A decoder that can read fro the incr. comp. cache. It is similar to the one
 /// we use for crate metadata decoding in that it can rebase spans and eventually
 /// will also handle things that contain `Ty` instances.
 struct CacheDecoder<'a, 'tcx> {
@@ -460,19 +460,17 @@ impl<'a, 'tcx> CacheDecoder<'a, 'tcx> {
     }
 }
 
-pub trait DecoderWithPosition: Decoder {
+trait DecoderWithPosition: Decoder {
     fn position(&self) -> usize;
 }
 
 impl<'a> DecoderWithPosition for opaque::Decoder<'a> {
-    #[inline]
     fn position(&self) -> usize {
         self.position()
     }
 }
 
 impl<'a, 'tcx> DecoderWithPosition for CacheDecoder<'a, 'tcx> {
-    #[inline]
     fn position(&self) -> usize {
         self.opaque.position()
     }
@@ -480,7 +478,7 @@ impl<'a, 'tcx> DecoderWithPosition for CacheDecoder<'a, 'tcx> {
 
 // Decodes something that was encoded with `encode_tagged()` and verify that the
 // tag matches and the correct amount of bytes was read.
-pub fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> Result<V, D::Error>
+fn decode_tagged<D, T, V>(decoder: &mut D, expected_tag: T) -> Result<V, D::Error>
 where
     T: Decodable + Eq + ::std::fmt::Debug,
     V: Decodable,
@@ -700,7 +698,6 @@ impl<'a, 'tcx> SpecializedDecoder<NodeId> for CacheDecoder<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> SpecializedDecoder<Fingerprint> for CacheDecoder<'a, 'tcx> {
-    #[inline]
     fn specialized_decode(&mut self) -> Result<Fingerprint, Self::Error> {
         Fingerprint::decode_opaque(&mut self.opaque)
     }
@@ -754,7 +751,7 @@ where
     /// encode the specified tag, then the given value, then the number of
     /// bytes taken up by tag and value. On decoding, we can then verify that
     /// we get the expected tag and read the expected number of bytes.
-    pub fn encode_tagged<T: Encodable, V: Encodable>(
+    fn encode_tagged<T: Encodable, V: Encodable>(
         &mut self,
         tag: T,
         value: &V
@@ -960,7 +957,6 @@ where
 }
 
 impl<'a, 'tcx> SpecializedEncoder<Fingerprint> for CacheEncoder<'a, 'tcx, opaque::Encoder> {
-    #[inline]
     fn specialized_encode(&mut self, f: &Fingerprint) -> Result<(), Self::Error> {
         f.encode_opaque(&mut self.encoder)
     }

From 49d2fd1725510fd3bf6f2937e178b1aa055ddb02 Mon Sep 17 00:00:00 2001
From: Alexander Regueiro <alexreg@me.com>
Date: Fri, 6 Sep 2019 03:56:45 +0100
Subject: [PATCH 575/943] Aggregation of cosmetic changes made during work on
 REPL PRs: libsyntax

---
 src/libsyntax/ast.rs                        |  52 ++++----
 src/libsyntax/attr/mod.rs                   |  43 +++---
 src/libsyntax/ext/base.rs                   |   2 +-
 src/libsyntax/feature_gate/active.rs        |  18 +--
 src/libsyntax/feature_gate/builtin_attrs.rs |   2 +-
 src/libsyntax/feature_gate/check.rs         |   4 +-
 src/libsyntax/mut_visit.rs                  |  28 ++--
 src/libsyntax/mut_visit/tests.rs            |  10 +-
 src/libsyntax/parse/attr.rs                 |  38 +++---
 src/libsyntax/parse/diagnostics.rs          |  76 +++++------
 src/libsyntax/parse/lexer/tests.rs          |  17 +--
 src/libsyntax/parse/mod.rs                  |  53 ++++----
 src/libsyntax/parse/parser.rs               |  50 +++----
 src/libsyntax/parse/parser/expr.rs          | 141 ++++++++++----------
 src/libsyntax/parse/parser/item.rs          | 115 ++++++++--------
 src/libsyntax/parse/parser/module.rs        |   6 +-
 src/libsyntax/parse/parser/pat.rs           |   4 +-
 src/libsyntax/parse/parser/stmt.rs          |  64 ++++-----
 src/libsyntax/parse/tests.rs                |   8 +-
 src/libsyntax/print/pprust.rs               |  52 ++++----
 src/libsyntax/print/pprust/tests.rs         |   5 +-
 src/libsyntax/source_map.rs                 | 128 +++++++++---------
 src/libsyntax/source_map/tests.rs           |  98 ++++++++------
 src/libsyntax/tests.rs                      |  18 +--
 src/libsyntax/tokenstream.rs                |   7 +-
 src/libsyntax/visit.rs                      |  23 ++--
 26 files changed, 538 insertions(+), 524 deletions(-)

diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index c93e6d11ce711..bfb2db9596363 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -413,11 +413,11 @@ impl WherePredicate {
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct WhereBoundPredicate {
     pub span: Span,
-    /// Any generics from a `for` binding
+    /// Any generics from a `for` binding.
     pub bound_generic_params: Vec<GenericParam>,
-    /// The type being bounded
+    /// The type being bounded.
     pub bounded_ty: P<Ty>,
-    /// Trait and lifetime bounds (`Clone+Send+'static`)
+    /// Trait and lifetime bounds (`Clone + Send + 'static`).
     pub bounds: GenericBounds,
 }
 
@@ -495,15 +495,15 @@ pub enum MetaItemKind {
     NameValue(Lit),
 }
 
-/// A Block (`{ .. }`).
+/// A block (`{ .. }`).
 ///
 /// E.g., `{ .. }` as in `fn foo() { .. }`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Block {
-    /// Statements in a block
+    /// The statements in the block.
     pub stmts: Vec<Stmt>,
     pub id: NodeId,
-    /// Distinguishes between `unsafe { ... }` and `{ ... }`
+    /// Distinguishes between `unsafe { ... }` and `{ ... }`.
     pub rules: BlockCheckMode,
     pub span: Span,
 }
@@ -908,11 +908,11 @@ pub enum MacStmtStyle {
 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`.
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub struct Local {
+    pub id: NodeId,
     pub pat: P<Pat>,
     pub ty: Option<P<Ty>>,
     /// Initializer expression to set the value, if any.
     pub init: Option<P<Expr>>,
-    pub id: NodeId,
     pub span: Span,
     pub attrs: ThinVec<Attribute>,
 }
@@ -970,7 +970,7 @@ pub struct AnonConst {
     pub value: P<Expr>,
 }
 
-/// An expression
+/// An expression.
 #[derive(Clone, RustcEncodable, RustcDecodable)]
 pub struct Expr {
     pub id: NodeId,
@@ -984,26 +984,26 @@ pub struct Expr {
 static_assert_size!(Expr, 96);
 
 impl Expr {
-    /// Whether this expression would be valid somewhere that expects a value; for example, an `if`
-    /// condition.
+    /// Returns `true` if this expression would be valid somewhere that expects a value;
+    /// for example, an `if` condition.
     pub fn returns(&self) -> bool {
         if let ExprKind::Block(ref block, _) = self.node {
             match block.stmts.last().map(|last_stmt| &last_stmt.node) {
-                // implicit return
+                // Implicit return
                 Some(&StmtKind::Expr(_)) => true,
                 Some(&StmtKind::Semi(ref expr)) => {
                     if let ExprKind::Ret(_) = expr.node {
-                        // last statement is explicit return
+                        // Last statement is explicit return.
                         true
                     } else {
                         false
                     }
                 }
-                // This is a block that doesn't end in either an implicit or explicit return
+                // This is a block that doesn't end in either an implicit or explicit return.
                 _ => false,
             }
         } else {
-            // This is not a block, it is a value
+            // This is not a block, it is a value.
             true
         }
     }
@@ -2307,37 +2307,37 @@ impl Default for FnHeader {
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
 pub enum ItemKind {
-    /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
+    /// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
     ///
     /// E.g., `extern crate foo` or `extern crate foo_bar as foo`.
     ExternCrate(Option<Name>),
-    /// A use declaration (`use` or `pub use`) item.
+    /// A use declaration item (`use`).
     ///
     /// E.g., `use foo;`, `use foo::bar;` or `use foo::bar as FooBar;`.
     Use(P<UseTree>),
-    /// A static item (`static` or `pub static`).
+    /// A static item (`static`).
     ///
     /// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
     Static(P<Ty>, Mutability, P<Expr>),
-    /// A constant item (`const` or `pub const`).
+    /// A constant item (`const`).
     ///
     /// E.g., `const FOO: i32 = 42;`.
     Const(P<Ty>, P<Expr>),
-    /// A function declaration (`fn` or `pub fn`).
+    /// A function declaration (`fn`).
     ///
     /// E.g., `fn foo(bar: usize) -> usize { .. }`.
     Fn(P<FnDecl>, FnHeader, Generics, P<Block>),
-    /// A module declaration (`mod` or `pub mod`).
+    /// A module declaration (`mod`).
     ///
     /// E.g., `mod foo;` or `mod foo { .. }`.
     Mod(Mod),
-    /// An external module (`extern` or `pub extern`).
+    /// An external module (`extern`).
     ///
     /// E.g., `extern {}` or `extern "C" {}`.
     ForeignMod(ForeignMod),
     /// Module-level inline assembly (from `global_asm!()`).
     GlobalAsm(P<GlobalAsm>),
-    /// A type alias (`type` or `pub type`).
+    /// A type alias (`type`).
     ///
     /// E.g., `type Foo = Bar<u8>;`.
     TyAlias(P<Ty>, Generics),
@@ -2345,19 +2345,19 @@ pub enum ItemKind {
     ///
     /// E.g., `type Foo = impl Bar + Boo;`.
     OpaqueTy(GenericBounds, Generics),
-    /// An enum definition (`enum` or `pub enum`).
+    /// An enum definition (`enum`).
     ///
     /// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
     Enum(EnumDef, Generics),
-    /// A struct definition (`struct` or `pub struct`).
+    /// A struct definition (`struct`).
     ///
     /// E.g., `struct Foo<A> { x: A }`.
     Struct(VariantData, Generics),
-    /// A union definition (`union` or `pub union`).
+    /// A union definition (`union`).
     ///
     /// E.g., `union Foo<A, B> { x: A, y: B }`.
     Union(VariantData, Generics),
-    /// A Trait declaration (`trait` or `pub trait`).
+    /// A trait declaration (`trait`).
     ///
     /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`.
     Trait(IsAuto, Unsafety, Generics, GenericBounds, Vec<TraitItem>),
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index 69de3150354e7..1f954064944dc 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -1,4 +1,4 @@
-//! Functions dealing with attributes and meta items
+//! Functions dealing with attributes and meta items.
 
 mod builtin;
 
@@ -61,7 +61,7 @@ pub fn is_known_lint_tool(m_item: Ident) -> bool {
 }
 
 impl NestedMetaItem {
-    /// Returns the MetaItem if self is a NestedMetaItem::MetaItem.
+    /// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem`.
     pub fn meta_item(&self) -> Option<&MetaItem> {
         match *self {
             NestedMetaItem::MetaItem(ref item) => Some(item),
@@ -69,7 +69,7 @@ impl NestedMetaItem {
         }
     }
 
-    /// Returns the Lit if self is a NestedMetaItem::Literal.
+    /// Returns the `Lit` if `self` is a `NestedMetaItem::Literal`s.
     pub fn literal(&self) -> Option<&Lit> {
         match *self {
             NestedMetaItem::Literal(ref lit) => Some(lit),
@@ -82,7 +82,7 @@ impl NestedMetaItem {
         self.meta_item().map_or(false, |meta_item| meta_item.check_name(name))
     }
 
-    /// For a single-segment meta-item returns its name, otherwise returns `None`.
+    /// For a single-segment meta item, returns its name; otherwise, returns `None`.
     pub fn ident(&self) -> Option<Ident> {
         self.meta_item().and_then(|meta_item| meta_item.ident())
     }
@@ -90,13 +90,13 @@ impl NestedMetaItem {
         self.ident().unwrap_or(Ident::invalid()).name
     }
 
-    /// Gets the string value if self is a MetaItem and the MetaItem is a
-    /// MetaItemKind::NameValue variant containing a string, otherwise None.
+    /// Gets the string value if `self` is a `MetaItem` and the `MetaItem` is a
+    /// `MetaItemKind::NameValue` variant containing a string, otherwise `None`.
     pub fn value_str(&self) -> Option<Symbol> {
         self.meta_item().and_then(|meta_item| meta_item.value_str())
     }
 
-    /// Returns a name and single literal value tuple of the MetaItem.
+    /// Returns a name and single literal value tuple of the `MetaItem`.
     pub fn name_value_literal(&self) -> Option<(Name, &Lit)> {
         self.meta_item().and_then(
             |meta_item| meta_item.meta_item_list().and_then(
@@ -112,32 +112,32 @@ impl NestedMetaItem {
                 }))
     }
 
-    /// Gets a list of inner meta items from a list MetaItem type.
+    /// Gets a list of inner meta items from a list `MetaItem` type.
     pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> {
         self.meta_item().and_then(|meta_item| meta_item.meta_item_list())
     }
 
-    /// Returns `true` if the variant is MetaItem.
+    /// Returns `true` if the variant is `MetaItem`.
     pub fn is_meta_item(&self) -> bool {
         self.meta_item().is_some()
     }
 
-    /// Returns `true` if the variant is Literal.
+    /// Returns `true` if the variant is `Literal`.
     pub fn is_literal(&self) -> bool {
         self.literal().is_some()
     }
 
-    /// Returns `true` if self is a MetaItem and the meta item is a word.
+    /// Returns `true` if `self` is a `MetaItem` and the meta item is a word.
     pub fn is_word(&self) -> bool {
         self.meta_item().map_or(false, |meta_item| meta_item.is_word())
     }
 
-    /// Returns `true` if self is a MetaItem and the meta item is a ValueString.
+    /// Returns `true` if `self` is a `MetaItem` and the meta item is a `ValueString`.
     pub fn is_value_str(&self) -> bool {
         self.value_str().is_some()
     }
 
-    /// Returns `true` if self is a MetaItem and the meta item is a list.
+    /// Returns `true` if `self` is a `MetaItem` and the meta item is a list.
     pub fn is_meta_item_list(&self) -> bool {
         self.meta_item_list().is_some()
     }
@@ -156,7 +156,7 @@ impl Attribute {
         matches
     }
 
-    /// For a single-segment attribute returns its name, otherwise returns `None`.
+    /// For a single-segment attribute, returns its name; otherwise, returns `None`.
     pub fn ident(&self) -> Option<Ident> {
         if self.path.segments.len() == 1 {
             Some(self.path.segments[0].ident)
@@ -187,14 +187,14 @@ impl Attribute {
         self.meta_item_list().is_some()
     }
 
-    /// Indicates if the attribute is a Value String.
+    /// Indicates if the attribute is a `ValueString`.
     pub fn is_value_str(&self) -> bool {
         self.value_str().is_some()
     }
 }
 
 impl MetaItem {
-    /// For a single-segment meta-item returns its name, otherwise returns `None`.
+    /// For a single-segment meta item, returns its name; otherwise, returns `None`.
     pub fn ident(&self) -> Option<Ident> {
         if self.path.segments.len() == 1 {
             Some(self.path.segments[0].ident)
@@ -206,8 +206,9 @@ impl MetaItem {
         self.ident().unwrap_or(Ident::invalid()).name
     }
 
-    // #[attribute(name = "value")]
-    //             ^^^^^^^^^^^^^^
+    // Example:
+    //     #[attribute(name = "value")]
+    //                 ^^^^^^^^^^^^^^
     pub fn name_value_literal(&self) -> Option<&Lit> {
         match &self.node {
             MetaItemKind::NameValue(v) => Some(v),
@@ -255,7 +256,7 @@ impl MetaItem {
 }
 
 impl Attribute {
-    /// Extracts the MetaItem from inside this Attribute.
+    /// Extracts the `MetaItem` from inside this `Attribute`.
     pub fn meta(&self) -> Option<MetaItem> {
         let mut tokens = self.tokens.trees().peekable();
         Some(MetaItem {
@@ -318,8 +319,8 @@ impl Attribute {
         })
     }
 
-    /// Converts self to a normal #[doc="foo"] comment, if it is a
-    /// comment like `///` or `/** */`. (Returns self unchanged for
+    /// Converts `self` to a normal `#[doc="foo"]` comment, if it is a
+    /// comment like `///` or `/** */`. (Returns `self` unchanged for
     /// non-sugared doc attributes.)
     pub fn with_desugared_doc<T, F>(&self, f: F) -> T where
         F: FnOnce(&Attribute) -> T,
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 5b2515d20cbab..c4569b3fba1be 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -958,7 +958,7 @@ impl<'a> ExtCtxt<'a> {
         self.resolver.check_unused_macros();
     }
 
-    /// Resolve a path mentioned inside Rust code.
+    /// Resolves a path mentioned inside Rust code.
     ///
     /// This unifies the logic used for resolving `include_X!`, and `#[doc(include)]` file paths.
     ///
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index c947b09fdcb57..a15fc050141a3 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -1,9 +1,11 @@
 //! List of the active feature gates.
 
+use super::{State, Feature};
+
 use crate::edition::Edition;
 use crate::symbol::{Symbol, sym};
+
 use syntax_pos::Span;
-use super::{State, Feature};
 
 macro_rules! set {
     ($field: ident) => {{
@@ -37,9 +39,9 @@ macro_rules! declare_features {
         /// A set of features to be used by later passes.
         #[derive(Clone)]
         pub struct Features {
-            /// `#![feature]` attrs for language features, for error reporting
+            /// `#![feature]` attrs for language features, for error reporting.
             pub declared_lang_features: Vec<(Symbol, Span, Option<Symbol>)>,
-            /// `#![feature]` attrs for non-language (library) features
+            /// `#![feature]` attrs for non-language (library) features.
             pub declared_lib_features: Vec<(Symbol, Span)>,
             $(
                 $(#[doc = $doc])*
@@ -66,11 +68,11 @@ macro_rules! declare_features {
 }
 
 impl Feature {
-    /// Set this feature in `Features`. Panics if called on a non-active feature.
+    /// Sets this feature in `Features`. Panics if called on a non-active feature.
     pub fn set(&self, features: &mut Features, span: Span) {
         match self.state {
             State::Active { set } => set(features, span),
-            _ => panic!("Called `set` on feature `{}` which is not `active`", self.name)
+            _ => panic!("called `set` on feature `{}` which is not `active`", self.name)
         }
     }
 }
@@ -478,7 +480,7 @@ declare_features! (
     (active, precise_pointer_size_matching, "1.32.0", Some(56354), None),
 
     /// Allows relaxing the coherence rules such that
-    /// `impl<T> ForeignTrait<LocalType> for ForeignType<T> is permitted.
+    /// `impl<T> ForeignTrait<LocalType> for ForeignType<T>` is permitted.
     (active, re_rebalance_coherence, "1.32.0", Some(55437), None),
 
     /// Allows using `#[ffi_returns_twice]` on foreign functions.
@@ -520,7 +522,7 @@ declare_features! (
     /// Allows `async || body` closures.
     (active, async_closure, "1.37.0", Some(62290), None),
 
-    /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests
+    /// Allows the use of `#[cfg(doctest)]`; set when rustdoc is collecting doctests.
     (active, cfg_doctest, "1.37.0", Some(62210), None),
 
     /// Allows `[x; N]` where `x` is a constant (RFC 2203).
@@ -529,7 +531,7 @@ declare_features! (
     /// Allows `impl Trait` to be used inside type aliases (RFC 2515).
     (active, type_alias_impl_trait, "1.38.0", Some(63063), None),
 
-    /// Allows the use of or-patterns, e.g. `0 | 1`.
+    /// Allows the use of or-patterns (e.g., `0 | 1`).
     (active, or_patterns, "1.38.0", Some(54883), None),
 
     // -------------------------------------------------------------------------
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index ee7ac3b15d955..763c3ffd782df 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -169,7 +169,7 @@ const INTERAL_UNSTABLE: &str = "this is an internal attribute that will never be
 
 pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate);
 
-/// Attributes that have a special meaning to rustc or rustdoc
+/// Attributes that have a special meaning to rustc or rustdoc.
 pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     // ==========================================================================
     // Stable attributes:
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index f3a9d135125ae..5711b269ff092 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -920,9 +920,9 @@ pub enum UnstableFeatures {
 
 impl UnstableFeatures {
     pub fn from_environment() -> UnstableFeatures {
-        // Whether this is a feature-staged build, i.e., on the beta or stable channel
+        // `true` if this is a feature-staged build, i.e., on the beta or stable channel.
         let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
-        // Whether we should enable unstable features for bootstrapping
+        // `true` if we should enable unstable features for bootstrapping.
         let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok();
         match (disable_unstable_features, bootstrap) {
             (_, true) => UnstableFeatures::Cheat,
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 6023c5149d05b..1c35688666836 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -1,10 +1,10 @@
-//! A MutVisitor represents an AST modification; it accepts an AST piece and
-//! and mutates it in place. So, for instance, macro expansion is a MutVisitor
+//! A `MutVisitor` represents an AST modification; it accepts an AST piece and
+//! and mutates it in place. So, for instance, macro expansion is a `MutVisitor`
 //! that walks over an AST and modifies it.
 //!
-//! Note: using a MutVisitor (other than the MacroExpander MutVisitor) on
+//! Note: using a `MutVisitor` (other than the `MacroExpander` `MutVisitor`) on
 //! an AST before macro expansion is probably a bad idea. For instance,
-//! a MutVisitor renaming item names in a module will miss all of those
+//! a `MutVisitor` renaming item names in a module will miss all of those
 //! that are created by the expansion of a macro.
 
 use crate::ast::*;
@@ -614,7 +614,7 @@ pub fn noop_visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &m
     })
 }
 
-// Apply ident visitor if it's an ident, apply other visits to interpolated nodes.
+// Applies ident visitor if it's an ident; applies other visits to interpolated nodes.
 // In practice the ident part is not actually used by specific visitors right now,
 // but there's a test below checking that it works.
 pub fn noop_visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
@@ -625,7 +625,7 @@ pub fn noop_visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
             vis.visit_ident(&mut ident);
             *name = ident.name;
             *span = ident.span;
-            return; // avoid visiting the span for the second time
+            return; // Avoid visiting the span for the second time.
         }
         token::Interpolated(nt) => {
             let mut nt = Lrc::make_mut(nt);
@@ -636,28 +636,28 @@ pub fn noop_visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
     vis.visit_span(span);
 }
 
-/// Apply visitor to elements of interpolated nodes.
+/// Applies the visitor to elements of interpolated nodes.
 //
 // N.B., this can occur only when applying a visitor to partially expanded
 // code, where parsed pieces have gotten implanted ito *other* macro
 // invocations. This is relevant for macro hygiene, but possibly not elsewhere.
 //
 // One problem here occurs because the types for flat_map_item, flat_map_stmt,
-// etc. allow the visitor to return *multiple* items; this is a problem for the
+// etc., allow the visitor to return *multiple* items; this is a problem for the
 // nodes here, because they insist on having exactly one piece. One solution
 // would be to mangle the MutVisitor trait to include one-to-many and
 // one-to-one versions of these entry points, but that would probably confuse a
 // lot of people and help very few. Instead, I'm just going to put in dynamic
 // checks. I think the performance impact of this will be pretty much
-// nonexistent. The danger is that someone will apply a MutVisitor to a
+// nonexistent. The danger is that someone will apply a `MutVisitor` to a
 // partially expanded node, and will be confused by the fact that their
-// "flat_map_item" or "flat_map_stmt" isn't getting called on NtItem or NtStmt
+// `flat_map_item` or `flat_map_stmt` isn't getting called on `NtItem` or `NtStmt`
 // nodes. Hopefully they'll wind up reading this comment, and doing something
 // appropriate.
 //
-// BTW, design choice: I considered just changing the type of, e.g., NtItem to
+// BTW, design choice: I considered just changing the type of, e.g., `NtItem` to
 // contain multiple items, but decided against it when I looked at
-// parse_item_or_view_item and tried to figure out what I would do with
+// `parse_item_or_view_item` and tried to figure out what I would do with
 // multiple items there....
 pub fn noop_visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T) {
     match nt {
@@ -1014,7 +1014,7 @@ pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
     });
 }
 
-// Mutate one item into possibly many items.
+// Mutates one item into possibly many items.
 pub fn noop_flat_map_item<T: MutVisitor>(mut item: P<Item>, visitor: &mut T)
                                          -> SmallVec<[P<Item>; 1]> {
     let Item { ident, attrs, id, node, vis, span, tokens: _ } = item.deref_mut();
@@ -1224,7 +1224,7 @@ pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr,
         ExprKind::Paren(expr) => {
             vis.visit_expr(expr);
 
-            // Nodes that are equal modulo `Paren` sugar no-ops should have the same ids.
+            // Nodes that are equal modulo `Paren` sugar no-ops should have the same IDs.
             *id = expr.id;
             vis.visit_span(span);
             visit_thin_attrs(attrs, vis);
diff --git a/src/libsyntax/mut_visit/tests.rs b/src/libsyntax/mut_visit/tests.rs
index 6868736976b25..f779e0d0a6014 100644
--- a/src/libsyntax/mut_visit/tests.rs
+++ b/src/libsyntax/mut_visit/tests.rs
@@ -6,13 +6,13 @@ use crate::print::pprust;
 use crate::mut_visit;
 use crate::with_default_globals;
 
-// this version doesn't care about getting comments or docstrings in.
+// This version doesn't care about getting comments or doc-strings in.
 fn fake_print_crate(s: &mut pprust::State<'_>,
                     krate: &ast::Crate) {
     s.print_mod(&krate.module, &krate.attrs)
 }
 
-// change every identifier to "zz"
+// Change every identifier to "zz".
 struct ToZzIdentMutVisitor;
 
 impl MutVisitor for ToZzIdentMutVisitor {
@@ -24,7 +24,7 @@ impl MutVisitor for ToZzIdentMutVisitor {
     }
 }
 
-// maybe add to expand.rs...
+// Maybe add to `expand.rs`.
 macro_rules! assert_pred {
     ($pred:expr, $predname:expr, $a:expr , $b:expr) => (
         {
@@ -39,7 +39,7 @@ macro_rules! assert_pred {
     )
 }
 
-// make sure idents get transformed everywhere
+// Make sure idents get transformed everywhere.
 #[test] fn ident_transformation () {
     with_default_globals(|| {
         let mut zz_visitor = ToZzIdentMutVisitor;
@@ -54,7 +54,7 @@ macro_rules! assert_pred {
     })
 }
 
-// even inside macro defs....
+// Make sure idents get transformed even inside macro defs.
 #[test] fn ident_transformation_in_defs () {
     with_default_globals(|| {
         let mut zz_visitor = ToZzIdentMutVisitor;
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index d9c4baad49ded..9aa1ec0b14fe9 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -26,7 +26,7 @@ impl<'a> Parser<'a> {
         Ok(attrs)
     }
 
-    /// Parse attributes that appear before an item
+    /// Parses attributes that appear before an item.
     crate fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let mut attrs: Vec<ast::Attribute> = Vec::new();
         let mut just_parsed_doc_comment = false;
@@ -69,10 +69,10 @@ impl<'a> Parser<'a> {
         Ok(attrs)
     }
 
-    /// Matches `attribute = # ! [ meta_item ]`
+    /// Matches `attribute = # ! [ meta_item ]`.
     ///
-    /// If permit_inner is true, then a leading `!` indicates an inner
-    /// attribute
+    /// If `permit_inner` is `true`, then a leading `!` indicates an inner
+    /// attribute.
     pub fn parse_attribute(&mut self, permit_inner: bool) -> PResult<'a, ast::Attribute> {
         debug!("parse_attribute: permit_inner={:?} self.token={:?}",
                permit_inner,
@@ -167,14 +167,14 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Parse an inner part of attribute - path and following tokens.
+    /// Parses an inner part of an attribute (the path and following tokens).
     /// The tokens must be either a delimited token stream, or empty token stream,
     /// or the "legacy" key-value form.
-    /// PATH `(` TOKEN_STREAM `)`
-    /// PATH `[` TOKEN_STREAM `]`
-    /// PATH `{` TOKEN_STREAM `}`
-    /// PATH
-    /// PATH `=` TOKEN_TREE
+    ///     PATH `(` TOKEN_STREAM `)`
+    ///     PATH `[` TOKEN_STREAM `]`
+    ///     PATH `{` TOKEN_STREAM `}`
+    ///     PATH
+    ///     PATH `=` TOKEN_TREE
     /// The delimiters or `=` are still put into the resulting token stream.
     pub fn parse_meta_item_unrestricted(&mut self) -> PResult<'a, (ast::Path, TokenStream)> {
         let meta = match self.token.kind {
@@ -217,11 +217,11 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// Parse attributes that appear after the opening of an item. These should
+    /// Parses attributes that appear after the opening of an item. These should
     /// be preceded by an exclamation mark, but we accept and warn about one
     /// terminated by a semicolon.
-
-    /// matches inner_attrs*
+    ///
+    /// Matches `inner_attrs*`.
     crate fn parse_inner_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let mut attrs: Vec<ast::Attribute> = vec![];
         loop {
@@ -237,7 +237,7 @@ impl<'a> Parser<'a> {
                     attrs.push(attr);
                 }
                 token::DocComment(s) => {
-                    // we need to get the position of this token before we bump.
+                    // We need to get the position of this token before we bump.
                     let attr = attr::mk_sugared_doc_attr(s, self.token.span);
                     if attr.style == ast::AttrStyle::Inner {
                         attrs.push(attr);
@@ -268,10 +268,10 @@ impl<'a> Parser<'a> {
         Ok(lit)
     }
 
-    /// Per RFC#1559, matches the following grammar:
+    /// Matches the following grammar (per RFC 1559).
     ///
-    /// meta_item : IDENT ( '=' UNSUFFIXED_LIT | '(' meta_item_inner? ')' )? ;
-    /// meta_item_inner : (meta_item | UNSUFFIXED_LIT) (',' meta_item_inner)? ;
+    ///     meta_item : IDENT ( '=' UNSUFFIXED_LIT | '(' meta_item_inner? ')' )? ;
+    ///     meta_item_inner : (meta_item | UNSUFFIXED_LIT) (',' meta_item_inner)? ;
     pub fn parse_meta_item(&mut self) -> PResult<'a, ast::MetaItem> {
         let nt_meta = match self.token.kind {
             token::Interpolated(ref nt) => match **nt {
@@ -303,7 +303,7 @@ impl<'a> Parser<'a> {
         })
     }
 
-    /// matches meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;
+    /// Matches `meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;`.
     fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
         match self.parse_unsuffixed_lit() {
             Ok(lit) => {
@@ -324,7 +324,7 @@ impl<'a> Parser<'a> {
         Err(self.diagnostic().struct_span_err(self.token.span, &msg))
     }
 
-    /// matches meta_seq = ( COMMASEP(meta_item_inner) )
+    /// Matches `meta_seq = ( COMMASEP(meta_item_inner) )`.
     fn parse_meta_seq(&mut self) -> PResult<'a, Vec<ast::NestedMetaItem>> {
         self.parse_seq_to_end(&token::CloseDelim(token::Paren),
                               SeqSep::trailing_allowed(token::Comma),
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index d050d4f4ce705..2890a8e721e65 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -240,7 +240,7 @@ impl<'a> Parser<'a> {
     ) -> PResult<'a, bool /* recovered */> {
         fn tokens_to_string(tokens: &[TokenType]) -> String {
             let mut i = tokens.iter();
-            // This might be a sign we need a connect method on Iterator.
+            // This might be a sign we need a connect method on `Iterator`.
             let b = i.next()
                      .map_or(String::new(), |t| t.to_string());
             i.enumerate().fold(b, |mut b, (i, a)| {
@@ -301,7 +301,7 @@ impl<'a> Parser<'a> {
             );
         }
         let sp = if self.token == token::Eof {
-            // This is EOF, don't want to point at the following char, but rather the last token
+            // This is EOF; don't want to point at the following char, but rather the last token.
             self.prev_span
         } else {
             label_sp
@@ -317,9 +317,9 @@ impl<'a> Parser<'a> {
         }
 
         let is_semi_suggestable = expected.iter().any(|t| match t {
-            TokenType::Token(token::Semi) => true, // we expect a `;` here
+            TokenType::Token(token::Semi) => true, // We expect a `;` here.
             _ => false,
-        }) && ( // a `;` would be expected before the current keyword
+        }) && ( // A `;` would be expected before the current keyword.
             self.token.is_keyword(kw::Break) ||
             self.token.is_keyword(kw::Continue) ||
             self.token.is_keyword(kw::For) ||
@@ -541,16 +541,16 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Produce an error if comparison operators are chained (RFC #558).
-    /// We only need to check lhs, not rhs, because all comparison ops
-    /// have same precedence and are left-associative
+    /// Produces an error if comparison operators are chained (RFC #558).
+    /// We only need to check the LHS, not the RHS, because all comparison ops
+    /// have same precedence and are left-associative.
     crate fn check_no_chained_comparison(&self, lhs: &Expr, outer_op: &AssocOp) -> PResult<'a, ()> {
         debug_assert!(outer_op.is_comparison(),
                       "check_no_chained_comparison: {:?} is not comparison",
                       outer_op);
         match lhs.node {
             ExprKind::Binary(op, _, _) if op.node.is_comparison() => {
-                // respan to include both operators
+                // Respan to include both operators.
                 let op_span = op.span.to(self.token.span);
                 let mut err = self.struct_span_err(
                     op_span,
@@ -691,9 +691,9 @@ impl<'a> Parser<'a> {
         Ok(())
     }
 
-    /// Try to recover from associated item paths like `[T]::AssocItem`/`(T, U)::AssocItem`.
-    /// Attempt to convert the base expression/pattern/type into a type, parse the `::AssocItem`
-    /// tail, and combine them into a `<Ty>::AssocItem` expression/pattern/type.
+    /// Tries to recover from associated item paths like `[T]::AssocItem` / `(T, U)::AssocItem`.
+    /// Attempts to convert the base expression/pattern/type into a type, parses the `::AssocItem`
+    /// tail, and combines them into a `<Ty>::AssocItem` expression/pattern/type.
     crate fn maybe_recover_from_bad_qpath<T: RecoverQPath>(
         &mut self,
         base: P<T>,
@@ -708,8 +708,8 @@ impl<'a> Parser<'a> {
         Ok(base)
     }
 
-    /// Given an already parsed `Ty` parse the `::AssocItem` tail and
-    /// combine them into a `<Ty>::AssocItem` expression/pattern/type.
+    /// Given an already parsed `Ty`, parses the `::AssocItem` tail and
+    /// combines them into a `<Ty>::AssocItem` expression/pattern/type.
     crate fn maybe_recover_from_bad_qpath_stage_2<T: RecoverQPath>(
         &mut self,
         ty_span: Span,
@@ -730,7 +730,7 @@ impl<'a> Parser<'a> {
         self.diagnostic()
             .struct_span_err(path.span, "missing angle brackets in associated item path")
             .span_suggestion(
-                // this is a best-effort recovery
+                // This is a best-effort recovery.
                 path.span,
                 "try",
                 format!("<{}>::{}", ty_str, path),
@@ -738,7 +738,7 @@ impl<'a> Parser<'a> {
             )
             .emit();
 
-        let path_span = ty_span.shrink_to_hi(); // use an empty path since `position` == 0
+        let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`.
         Ok(P(T::recovered(
             Some(QSelf {
                 ty,
@@ -761,8 +761,8 @@ impl<'a> Parser<'a> {
             if !items.is_empty() {
                 let previous_item = &items[items.len() - 1];
                 let previous_item_kind_name = match previous_item.node {
-                    // say "braced struct" because tuple-structs and
-                    // braceless-empty-struct declarations do take a semicolon
+                    // Say "braced struct" because tuple-structs and
+                    // braceless-empty-struct declarations do take a semicolon.
                     ItemKind::Struct(..) => Some("braced struct"),
                     ItemKind::Enum(..) => Some("enum"),
                     ItemKind::Trait(..) => Some("trait"),
@@ -783,7 +783,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Create a `DiagnosticBuilder` for an unexpected token `t` and try to recover if it is a
+    /// Creates a `DiagnosticBuilder` for an unexpected token `t` and tries to recover if it is a
     /// closing delimiter.
     pub fn unexpected_try_recover(
         &mut self,
@@ -841,7 +841,7 @@ impl<'a> Parser<'a> {
         extern_sp: Span,
     ) -> PResult<'a, ()> {
         if self.token != token::Semi {
-            // this might be an incorrect fn definition (#62109)
+            // This might be an incorrect fn definition (#62109).
             let parser_snapshot = self.clone();
             match self.parse_inner_attrs_and_block() {
                 Ok((_, body)) => {
@@ -871,7 +871,7 @@ impl<'a> Parser<'a> {
         Ok(())
     }
 
-    /// Consume alternative await syntaxes like `await!(<expr>)`, `await <expr>`,
+    /// Consumes alternative await syntaxes like `await!(<expr>)`, `await <expr>`,
     /// `await? <expr>`, `await(<expr>)`, and `await { <expr> }`.
     crate fn parse_incorrect_await_syntax(
         &mut self,
@@ -924,7 +924,7 @@ impl<'a> Parser<'a> {
         sp
     }
 
-    /// If encountering `future.await()`, consume and emit error.
+    /// If encountering `future.await()`, consumes and emits an error.
     crate fn recover_from_await_method_call(&mut self) {
         if self.token == token::OpenDelim(token::Paren) &&
             self.look_ahead(1, |t| t == &token::CloseDelim(token::Paren))
@@ -944,7 +944,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Recover a situation like `for ( $pat in $expr )`
+    /// Recovers a situation like `for ( $pat in $expr )`
     /// and suggest writing `for $pat in $expr` instead.
     ///
     /// This should be called before parsing the `$block`.
@@ -1010,7 +1010,7 @@ impl<'a> Parser<'a> {
             Ok(x) => x,
             Err(mut err) => {
                 err.emit();
-                // recover from parse error
+                // Recover from parse error.
                 self.consume_block(delim);
                 self.mk_expr(lo.to(self.prev_span), ExprKind::Err, ThinVec::new())
             }
@@ -1023,7 +1023,7 @@ impl<'a> Parser<'a> {
         mut err: DiagnosticBuilder<'a>,
     ) -> PResult<'a, bool> {
         let mut pos = None;
-        // we want to use the last closing delim that would apply
+        // We want to use the last closing delim that would apply.
         for (i, unmatched) in self.unclosed_delims.iter().enumerate().rev() {
             if tokens.contains(&token::CloseDelim(unmatched.expected_delim))
                 && Some(self.token.span) > unmatched.unclosed_span
@@ -1041,7 +1041,7 @@ impl<'a> Parser<'a> {
                 let unmatched = self.unclosed_delims.remove(pos);
                 let delim = TokenType::Token(token::CloseDelim(unmatched.expected_delim));
 
-                 // We want to suggest the inclusion of the closing delimiter where it makes
+                // We want to suggest the inclusion of the closing delimiter where it makes
                 // the most sense, which is immediately after the last token:
                 //
                 //  {foo(bar {}}
@@ -1067,7 +1067,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Recover from `pub` keyword in places where it seems _reasonable_ but isn't valid.
+    /// Recovers from `pub` keyword in places where it seems _reasonable_ but isn't valid.
     crate fn eat_bad_pub(&mut self) {
         if self.token.is_keyword(kw::Pub) {
             match self.parse_visibility(false) {
@@ -1082,21 +1082,21 @@ impl<'a> Parser<'a> {
         }
     }
 
-    // Eat tokens until we can be relatively sure we reached the end of the
-    // statement. This is something of a best-effort heuristic.
-    //
-    // We terminate when we find an unmatched `}` (without consuming it).
-    crate fn recover_stmt(&mut self) {
+    /// Eats tokens until we can be relatively sure we reached the end of the
+    /// statement. This is something of a best-effort heuristic.
+    ///
+    /// We terminate when we find an unmatched `}` (without consuming it).
+    pub fn recover_stmt(&mut self) {
         self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore)
     }
 
-    // If `break_on_semi` is `Break`, then we will stop consuming tokens after
-    // finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
-    // approximate - it can mean we break too early due to macros, but that
-    // should only lead to sub-optimal recovery, not inaccurate parsing).
-    //
-    // If `break_on_block` is `Break`, then we will stop consuming tokens
-    // after finding (and consuming) a brace-delimited block.
+    /// If `break_on_semi` is `Break`, then we will stop consuming tokens after
+    /// finding (and consuming) a `;` outside of `{}` or `[]` (note that this is
+    /// approximate -- it can mean we break too early due to macros, but that
+    /// should only lead to sub-optimal recovery, not inaccurate parsing).
+    ///
+    /// If `break_on_block` is `Break`, then we will stop consuming tokens
+    /// after finding (and consuming) a brace-delimited block.
     crate fn recover_stmt_(&mut self, break_on_semi: SemiColonMode, break_on_block: BlockMode) {
         let mut brace_depth = 0;
         let mut bracket_depth = 0;
diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs
index 652ae95c85349..d965bf28ee7df 100644
--- a/src/libsyntax/parse/lexer/tests.rs
+++ b/src/libsyntax/parse/lexer/tests.rs
@@ -4,9 +4,10 @@ use crate::symbol::Symbol;
 use crate::source_map::{SourceMap, FilePathMapping};
 use crate::parse::token;
 use crate::with_default_globals;
+
+use errors::{Handler, emitter::EmitterWriter};
 use std::io;
 use std::path::PathBuf;
-use errors::{Handler, emitter::EmitterWriter};
 use syntax_pos::{BytePos, Span};
 
 fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess {
@@ -21,7 +22,7 @@ fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess {
     ParseSess::with_span_handler(Handler::with_emitter(true, None, Box::new(emitter)), sm)
 }
 
-// open a string reader for the given string
+// Creates a string reader for the given string.
 fn setup<'a>(sm: &SourceMap,
                 sess: &'a ParseSess,
                 teststr: String)
@@ -38,7 +39,7 @@ fn t1() {
         let mut string_reader = setup(
             &sm,
             &sh,
-            "/* my source file */ fn main() { println!(\"zebra\"); }\n".to_string(),
+            "/* my source file */ fn main() { println!(\"zebra\"); }\n".to_owned(),
         );
         assert_eq!(string_reader.next_token(), token::Comment);
         assert_eq!(string_reader.next_token(), token::Whitespace);
@@ -50,7 +51,7 @@ fn t1() {
         assert_eq!(tok1.kind, tok2.kind);
         assert_eq!(tok1.span, tok2.span);
         assert_eq!(string_reader.next_token(), token::Whitespace);
-        // read another token:
+        // Read another token.
         let tok3 = string_reader.next_token();
         assert_eq!(string_reader.pos.clone(), BytePos(28));
         let tok4 = Token::new(
@@ -65,15 +66,15 @@ fn t1() {
     })
 }
 
-// check that the given reader produces the desired stream
-// of tokens (stop checking after exhausting the expected vec)
+// Checks that the given reader produces the desired stream
+// of tokens (stop checking after exhausting `expected`).
 fn check_tokenization(mut string_reader: StringReader<'_>, expected: Vec<TokenKind>) {
     for expected_tok in &expected {
         assert_eq!(&string_reader.next_token(), expected_tok);
     }
 }
 
-// make the identifier by looking up the string in the interner
+// Makes the identifier by looking up the string in the interner.
 fn mk_ident(id: &str) -> TokenKind {
     token::Ident(Symbol::intern(id), false)
 }
@@ -201,7 +202,7 @@ fn literal_suffixes() {
                     setup(&sm, &sh, format!("{}suffix", $input)).next_token(),
                     mk_lit(token::$tok_type, $tok_contents, Some("suffix")),
                 );
-                // with a whitespace separator:
+                // with a whitespace separator
                 assert_eq!(
                     setup(&sm, &sh, format!("{} suffix", $input)).next_token(),
                     mk_lit(token::$tok_type, $tok_contents, None),
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index b1af4806e2d78..aa57c3954e352 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -13,12 +13,12 @@ use crate::print::pprust;
 use crate::symbol::Symbol;
 
 use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
+use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use rustc_data_structures::sync::{Lrc, Lock, Once};
 use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
 use syntax_pos::edition::Edition;
 use syntax_pos::hygiene::ExpnId;
 
-use rustc_data_structures::fx::{FxHashSet, FxHashMap};
 use std::borrow::Cow;
 use std::path::{Path, PathBuf};
 use std::str;
@@ -81,25 +81,27 @@ pub struct ParseSess {
 impl ParseSess {
     pub fn new(file_path_mapping: FilePathMapping) -> Self {
         let cm = Lrc::new(SourceMap::new(file_path_mapping));
-        let handler = Handler::with_tty_emitter(ColorConfig::Auto,
-                                                true,
-                                                None,
-                                                Some(cm.clone()));
+        let handler = Handler::with_tty_emitter(
+            ColorConfig::Auto,
+            true,
+            None,
+            Some(cm.clone()),
+        );
         ParseSess::with_span_handler(handler, cm)
     }
 
-    pub fn with_span_handler(handler: Handler, source_map: Lrc<SourceMap>) -> ParseSess {
-        ParseSess {
+    pub fn with_span_handler(handler: Handler, source_map: Lrc<SourceMap>) -> Self {
+        Self {
             span_diagnostic: handler,
             unstable_features: UnstableFeatures::from_environment(),
             config: FxHashSet::default(),
+            edition: ExpnId::root().expn_data().edition,
             missing_fragment_specifiers: Lock::new(FxHashSet::default()),
             raw_identifier_spans: Lock::new(Vec::new()),
             registered_diagnostics: Lock::new(ErrorMap::new()),
             included_mod_stack: Lock::new(vec![]),
             source_map,
             buffered_lints: Lock::new(vec![]),
-            edition: ExpnId::root().expn_data().edition,
             ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
             injected_crate_name: Once::new(),
             gated_spans: GatedSpans::default(),
@@ -155,17 +157,17 @@ pub struct Directory<'a> {
 #[derive(Copy, Clone)]
 pub enum DirectoryOwnership {
     Owned {
-        // None if `mod.rs`, `Some("foo")` if we're in `foo.rs`
+        // None if `mod.rs`, `Some("foo")` if we're in `foo.rs`.
         relative: Option<ast::Ident>,
     },
     UnownedViaBlock,
     UnownedViaMod(bool /* legacy warnings? */),
 }
 
-// a bunch of utility functions of the form parse_<thing>_from_<source>
+// A bunch of utility functions of the form `parse_<thing>_from_<source>`
 // where <thing> includes crate, expr, item, stmt, tts, and one that
 // uses a HOF to parse anything, and <source> includes file and
-// source_str.
+// `source_str`.
 
 pub fn parse_crate_from_file<'a>(input: &Path, sess: &'a ParseSess) -> PResult<'a, ast::Crate> {
     let mut parser = new_parser_from_file(sess, input);
@@ -219,14 +221,13 @@ pub fn maybe_new_parser_from_source_str(sess: &ParseSess, name: FileName, source
     Ok(parser)
 }
 
-/// Creates a new parser, handling errors as appropriate
-/// if the file doesn't exist
+/// Creates a new parser, handling errors as appropriate if the file doesn't exist.
 pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) -> Parser<'a> {
     source_file_to_parser(sess, file_to_source_file(sess, path, None))
 }
 
-/// Creates a new parser, returning buffered diagnostics if the file doesn't
-/// exist or from lexing the initial token stream.
+/// Creates a new parser, returning buffered diagnostics if the file doesn't exist,
+/// or from lexing the initial token stream.
 pub fn maybe_new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path)
     -> Result<Parser<'a>, Vec<Diagnostic>> {
     let file = try_file_to_source_file(sess, path, None).map_err(|db| vec![db])?;
@@ -234,8 +235,8 @@ pub fn maybe_new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path)
 }
 
 /// Given a session, a crate config, a path, and a span, add
-/// the file at the given path to the source_map, and return a parser.
-/// On an error, use the given span as the source of the problem.
+/// the file at the given path to the `source_map`, and returns a parser.
+/// On an error, uses the given span as the source of the problem.
 pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess,
                                     path: &Path,
                                     directory_ownership: DirectoryOwnership,
@@ -247,13 +248,13 @@ pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess,
     p
 }
 
-/// Given a source_file and config, return a parser
+/// Given a `source_file` and config, returns a parser.
 fn source_file_to_parser(sess: &ParseSess, source_file: Lrc<SourceFile>) -> Parser<'_> {
     panictry_buffer!(&sess.span_diagnostic,
                      maybe_source_file_to_parser(sess, source_file))
 }
 
-/// Given a source_file and config, return a parser. Returns any buffered errors from lexing the
+/// Given a `source_file` and config, return a parser. Returns any buffered errors from lexing the
 /// initial token stream.
 fn maybe_source_file_to_parser(
     sess: &ParseSess,
@@ -270,14 +271,14 @@ fn maybe_source_file_to_parser(
     Ok(parser)
 }
 
-// must preserve old name for now, because quote! from the *existing*
-// compiler expands into it
+// Must preserve old name for now, because `quote!` from the *existing*
+// compiler expands into it.
 pub fn new_parser_from_tts(sess: &ParseSess, tts: Vec<TokenTree>) -> Parser<'_> {
     stream_to_parser(sess, tts.into_iter().collect(), crate::MACRO_ARGUMENTS)
 }
 
 
-// base abstractions
+// Base abstractions
 
 /// Given a session and a path and an optional span (for error reporting),
 /// add the path to the session's source_map and return the new source_file or
@@ -296,7 +297,7 @@ fn try_file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
 }
 
 /// Given a session and a path and an optional span (for error reporting),
-/// add the path to the session's `source_map` and return the new `source_file`.
+/// adds the path to the session's `source_map` and returns the new `source_file`.
 fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
                    -> Lrc<SourceFile> {
     match try_file_to_source_file(sess, path, spanopt) {
@@ -308,7 +309,7 @@ fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
     }
 }
 
-/// Given a source_file, produces a sequence of token trees.
+/// Given a `source_file`, produces a sequence of token trees.
 pub fn source_file_to_stream(
     sess: &ParseSess,
     source_file: Lrc<SourceFile>,
@@ -352,7 +353,7 @@ pub fn maybe_file_to_stream(
     }
 }
 
-/// Given stream and the `ParseSess`, produces a parser.
+/// Given a stream and the `ParseSess`, produces a parser.
 pub fn stream_to_parser<'a>(
     sess: &'a ParseSess,
     stream: TokenStream,
@@ -361,7 +362,7 @@ pub fn stream_to_parser<'a>(
     Parser::new(sess, stream, None, true, false, subparser_name)
 }
 
-/// Given stream, the `ParseSess` and the base directory, produces a parser.
+/// Given a stream, the `ParseSess` and the base directory, produces a parser.
 ///
 /// Use this function when you are creating a parser from the token stream
 /// and also care about the current working directory of the parser (e.g.,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index ab5462baaf721..fcaf5065dac78 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -10,22 +10,22 @@ pub use path::PathStyle;
 mod stmt;
 mod generics;
 
-use crate::ast::{self, AttrStyle, Attribute, Param, BindingMode, StrStyle, SelfKind};
-use crate::ast::{FnDecl, Ident, IsAsync, MacDelimiter, Mutability, TyKind};
-use crate::ast::{Visibility, VisibilityKind, Unsafety, CrateSugar};
-use crate::source_map::{self, respan};
-use crate::parse::{SeqSep, literal, token};
+use crate::ast::{
+    self, DUMMY_NODE_ID, AttrStyle, Attribute, BindingMode, CrateSugar, FnDecl, Ident,
+    IsAsync, MacDelimiter, Mutability, Param, StrStyle, SelfKind, TyKind, Visibility,
+    VisibilityKind, Unsafety,
+};
+use crate::parse::{ParseSess, PResult, Directory, DirectoryOwnership, SeqSep, literal, token};
+use crate::parse::diagnostics::{Error, dummy_arg};
 use crate::parse::lexer::UnmatchedBrace;
 use crate::parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
 use crate::parse::token::{Token, TokenKind, DelimToken};
-use crate::parse::{ParseSess, Directory, DirectoryOwnership};
 use crate::print::pprust;
 use crate::ptr::P;
-use crate::parse::PResult;
-use crate::ThinVec;
-use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
+use crate::source_map::{self, respan};
 use crate::symbol::{kw, sym, Symbol};
-use crate::parse::diagnostics::{Error, dummy_arg};
+use crate::tokenstream::{self, DelimSpan, TokenTree, TokenStream, TreeAndJoint};
+use crate::ThinVec;
 
 use errors::{Applicability, DiagnosticId, FatalError};
 use rustc_target::spec::abi::{self, Abi};
@@ -56,7 +56,7 @@ crate enum BlockMode {
     Ignore,
 }
 
-/// As maybe_whole_expr, but for things other than expressions
+/// Like `maybe_whole_expr`, but for things other than expressions.
 #[macro_export]
 macro_rules! maybe_whole {
     ($p:expr, $constructor:ident, |$x:ident| $e:expr) => {
@@ -116,11 +116,11 @@ pub struct Parser<'a> {
     /// with non-interpolated identifier and lifetime tokens they refer to.
     /// Perhaps the normalized / non-normalized setup can be simplified somehow.
     pub token: Token,
-    /// Span of the current non-normalized token.
+    /// The span of the current non-normalized token.
     meta_var_span: Option<Span>,
-    /// Span of the previous non-normalized token.
+    /// The span of the previous non-normalized token.
     pub prev_span: Span,
-    /// Kind of the previous normalized token (in simplified form).
+    /// The kind of the previous normalized token (in simplified form).
     prev_token_kind: PrevTokenKind,
     restrictions: Restrictions,
     /// Used to determine the path to externally loaded source files.
@@ -143,7 +143,7 @@ pub struct Parser<'a> {
     /// See the comments in the `parse_path_segment` function for more details.
     crate unmatched_angle_bracket_count: u32,
     crate max_angle_bracket_count: u32,
-    /// List of all unclosed delimiters found by the lexer. If an entry is used for error recovery
+    /// A list of all unclosed delimiters found by the lexer. If an entry is used for error recovery
     /// it gets removed from here. Every entry left at the end gets emitted as an independent
     /// error.
     crate unclosed_delims: Vec<UnmatchedBrace>,
@@ -799,14 +799,14 @@ impl<'a> Parser<'a> {
                             break;
                         }
                         Err(mut e) => {
-                            // Attempt to keep parsing if it was a similar separator
+                            // Attempt to keep parsing if it was a similar separator.
                             if let Some(ref tokens) = t.similar_tokens() {
                                 if tokens.contains(&self.token.kind) {
                                     self.bump();
                                 }
                             }
                             e.emit();
-                            // Attempt to keep parsing if it was an omitted separator
+                            // Attempt to keep parsing if it was an omitted separator.
                             match f(self) {
                                 Ok(t) => {
                                     v.push(t);
@@ -871,7 +871,7 @@ impl<'a> Parser<'a> {
         self.parse_delim_comma_seq(token::Paren, f)
     }
 
-    /// Advance the parser by one token
+    /// Advance the parser by one token.
     pub fn bump(&mut self) {
         if self.prev_token_kind == PrevTokenKind::Eof {
             // Bumping after EOF is a bad sign, usually an infinite loop.
@@ -894,17 +894,17 @@ impl<'a> Parser<'a> {
 
         self.token = self.next_tok();
         self.expected_tokens.clear();
-        // check after each token
+        // Check after each token.
         self.process_potential_macro_variable();
     }
 
-    /// Advance the parser using provided token as a next one. Use this when
+    /// Advances the parser using provided token as a next one. Use this when
     /// consuming a part of a token. For example a single `<` from `<<`.
     fn bump_with(&mut self, next: TokenKind, span: Span) {
         self.prev_span = self.token.span.with_hi(span.lo());
         // It would be incorrect to record the kind of the current token, but
         // fortunately for tokens currently using `bump_with`, the
-        // prev_token_kind will be of no use anyway.
+        // `prev_token_kind` will be of no use anyway.
         self.prev_token_kind = PrevTokenKind::Other;
         self.token = Token::new(next, span);
         self.expected_tokens.clear();
@@ -937,8 +937,8 @@ impl<'a> Parser<'a> {
     fn parse_asyncness(&mut self) -> IsAsync {
         if self.eat_keyword(kw::Async) {
             IsAsync::Async {
-                closure_id: ast::DUMMY_NODE_ID,
-                return_impl_trait_id: ast::DUMMY_NODE_ID,
+                closure_id: DUMMY_NODE_ID,
+                return_impl_trait_id: DUMMY_NODE_ID,
             }
         } else {
             IsAsync::NotAsync
@@ -1040,7 +1040,7 @@ impl<'a> Parser<'a> {
 
         let span = lo.to(self.token.span);
 
-        Ok(Param { attrs: attrs.into(), id: ast::DUMMY_NODE_ID, pat, span, ty })
+        Ok(Param { attrs: attrs.into(), id: DUMMY_NODE_ID, pat, span, ty })
     }
 
     /// Parses mutability (`mut` or nothing).
@@ -1497,7 +1497,7 @@ impl<'a> Parser<'a> {
                         format!("in {}", path),
                         Applicability::MachineApplicable,
                     )
-                    .emit();  // emit diagnostic, but continue with public visibility
+                    .emit(); // Emit diagnostic, but continue with public visibility.
             }
         }
 
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index e8c8e199fd06b..f70c607198fa9 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -1,26 +1,26 @@
-use super::{Parser, PResult, Restrictions, PrevTokenKind, TokenType, PathStyle};
-use super::{BlockMode, SemiColonMode};
-use super::{SeqSep, TokenExpectType};
+use super::{
+    Parser, PResult, Restrictions, PrevTokenKind, TokenType, PathStyle, BlockMode, SemiColonMode,
+    SeqSep, TokenExpectType,
+};
 use super::pat::{GateOr, PARAM_EXPECTED};
 
+use crate::ast::{
+    self, DUMMY_NODE_ID, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode,
+    Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm, Ty, TyKind,
+    FunctionRetTy, Param, FnDecl, BinOpKind, BinOp, UnOp, Mac, AnonConst, Field,
+};
 use crate::maybe_recover_from_interpolated_ty_qpath;
-use crate::ptr::P;
-use crate::ast::{self, Attribute, AttrStyle, Ident, CaptureBy, BlockCheckMode};
-use crate::ast::{Expr, ExprKind, RangeLimits, Label, Movability, IsAsync, Arm};
-use crate::ast::{Ty, TyKind, FunctionRetTy, Param, FnDecl};
-use crate::ast::{BinOpKind, BinOp, UnOp};
-use crate::ast::{Mac, AnonConst, Field};
-
 use crate::parse::classify;
 use crate::parse::token::{self, Token};
-use crate::parse::diagnostics::{Error};
+use crate::parse::diagnostics::Error;
 use crate::print::pprust;
+use crate::ptr::P;
 use crate::source_map::{self, Span};
 use crate::symbol::{kw, sym};
 use crate::util::parser::{AssocOp, Fixity, prec_let_scrutinee_needs_par};
 
-use std::mem;
 use errors::Applicability;
+use std::mem;
 use rustc_data_structures::thin_vec::ThinVec;
 
 /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
@@ -51,7 +51,7 @@ macro_rules! maybe_whole_expr {
                         $p.token.span, ExprKind::Block(block, None), ThinVec::new()
                     ));
                 }
-                // N.B: `NtIdent(ident)` is normalized to `Ident` in `fn bump`.
+                // N.B., `NtIdent(ident)` is normalized to `Ident` in `fn bump`.
                 _ => {},
             };
         }
@@ -340,7 +340,7 @@ impl<'a> Parser<'a> {
 
     fn is_at_start_of_range_notation_rhs(&self) -> bool {
         if self.token.can_begin_expr() {
-            // parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
+            // Parse `for i in 1.. { }` as infinite loop, not as `for i in (1..{})`.
             if self.token == token::OpenDelim(token::Brace) {
                 return !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
             }
@@ -350,12 +350,12 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parse prefix-forms of range notation: `..expr`, `..`, `..=expr`
+    /// Parses prefix-forms of range notation: `..expr`, `..`, `..=expr`.
     fn parse_prefix_range_expr(
         &mut self,
         already_parsed_attrs: Option<ThinVec<Attribute>>
     ) -> PResult<'a, P<Expr>> {
-        // Check for deprecated `...` syntax
+        // Check for deprecated `...` syntax.
         if self.token == token::DotDotDot {
             self.err_dotdotdot_syntax(self.token.span);
         }
@@ -389,7 +389,7 @@ impl<'a> Parser<'a> {
         Ok(self.mk_expr(lo.to(hi), r, attrs))
     }
 
-    /// Parse a prefix-unary-operator expr
+    /// Parses a prefix-unary-operator expr.
     fn parse_prefix_expr(
         &mut self,
         already_parsed_attrs: Option<ThinVec<Attribute>>
@@ -549,7 +549,7 @@ impl<'a> Parser<'a> {
                         let expr = mk_expr(self, P(Ty {
                             span: path.span,
                             node: TyKind::Path(None, path),
-                            id: ast::DUMMY_NODE_ID
+                            id: DUMMY_NODE_ID,
                         }));
 
                         let expr_str = self.span_to_snippet(expr.span)
@@ -565,7 +565,7 @@ impl<'a> Parser<'a> {
                                 expr.span,
                                 &format!("try {} the cast value", op_verb),
                                 format!("({})", expr_str),
-                                Applicability::MachineApplicable
+                                Applicability::MachineApplicable,
                             )
                             .emit();
 
@@ -741,7 +741,6 @@ impl<'a> Parser<'a> {
         })
     }
 
-
     /// At the bottom (top?) of the precedence hierarchy,
     /// Parses things like parenthesized exprs, macros, `return`, etc.
     ///
@@ -755,7 +754,7 @@ impl<'a> Parser<'a> {
         // added to the return value after the fact.
         //
         // Therefore, prevent sub-parser from parsing
-        // attributes by giving them a empty "already parsed" list.
+        // attributes by giving them a empty "already-parsed" list.
         let mut attrs = ThinVec::new();
 
         let lo = self.token.span;
@@ -778,7 +777,7 @@ impl<'a> Parser<'a> {
             }
         }
 
-        // Note: when adding new syntax here, don't forget to adjust TokenKind::can_begin_expr().
+        // Note: when adding new syntax here, don't forget to adjust `TokenKind::can_begin_expr()`.
         match self.token.kind {
             // This match arm is a special-case of the `_` match arm below and
             // could be removed without changing functionality, but it's faster
@@ -791,8 +790,8 @@ impl<'a> Parser<'a> {
 
                 attrs.extend(self.parse_inner_attributes()?);
 
-                // (e) is parenthesized e
-                // (e,) is a tuple with only one field, e
+                // `(e)` is parenthesized `e`.
+                // `(e,)` is a tuple with only one field, `e`.
                 let mut es = vec![];
                 let mut trailing_comma = false;
                 let mut recovered = false;
@@ -800,7 +799,7 @@ impl<'a> Parser<'a> {
                     es.push(match self.parse_expr() {
                         Ok(es) => es,
                         Err(mut err) => {
-                            // recover from parse error in tuple list
+                            // Recover from parse error in tuple list.
                             match self.token.kind {
                                 token::Ident(name, false)
                                 if name == kw::Underscore && self.look_ahead(1, |t| {
@@ -844,7 +843,7 @@ impl<'a> Parser<'a> {
                 return self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs);
             }
             token::BinOp(token::Or) | token::OrOr => {
-                return self.parse_lambda_expr(attrs);
+                return self.parse_closure(attrs);
             }
             token::OpenDelim(token::Bracket) => {
                 self.bump();
@@ -852,21 +851,21 @@ impl<'a> Parser<'a> {
                 attrs.extend(self.parse_inner_attributes()?);
 
                 if self.eat(&token::CloseDelim(token::Bracket)) {
-                    // Empty vector.
+                    // Empty vector
                     ex = ExprKind::Array(Vec::new());
                 } else {
-                    // Nonempty vector.
+                    // Non-empty vector
                     let first_expr = self.parse_expr()?;
                     if self.eat(&token::Semi) {
-                        // Repeating array syntax: [ 0; 512 ]
+                        // Repeating array syntax: `[ 0; 512 ]`
                         let count = AnonConst {
-                            id: ast::DUMMY_NODE_ID,
+                            id: DUMMY_NODE_ID,
                             value: self.parse_expr()?,
                         };
                         self.expect(&token::CloseDelim(token::Bracket))?;
                         ex = ExprKind::Repeat(first_expr, count);
                     } else if self.eat(&token::Comma) {
-                        // Vector with two or more elements.
+                        // Vector with two or more elements
                         let remaining_exprs = self.parse_seq_to_end(
                             &token::CloseDelim(token::Bracket),
                             SeqSep::trailing_allowed(token::Comma),
@@ -876,7 +875,7 @@ impl<'a> Parser<'a> {
                         exprs.extend(remaining_exprs);
                         ex = ExprKind::Array(exprs);
                     } else {
-                        // Vector with one element.
+                        // Vector with one element
                         self.expect(&token::CloseDelim(token::Bracket))?;
                         ex = ExprKind::Array(vec![first_expr]);
                     }
@@ -892,7 +891,7 @@ impl<'a> Parser<'a> {
                 if self.token.is_path_start() {
                     let path = self.parse_path(PathStyle::Expr)?;
 
-                    // `!`, as an operator, is prefix, so we know this isn't that
+                    // `!`, as an operator, is prefix, so we know this isn't that.
                     if self.eat(&token::Not) {
                         // MACRO INVOCATION expression
                         let (delim, tts) = self.expect_delimited_token_tree()?;
@@ -920,7 +919,7 @@ impl<'a> Parser<'a> {
                     return self.maybe_recover_from_bad_qpath(expr, true);
                 }
                 if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
-                    return self.parse_lambda_expr(attrs);
+                    return self.parse_closure(attrs);
                 }
                 if self.eat_keyword(kw::If) {
                     return self.parse_if_expr(attrs);
@@ -991,13 +990,13 @@ impl<'a> Parser<'a> {
                     return self.parse_try_block(lo, attrs);
                 }
 
-                // Span::rust_2018() is somewhat expensive; don't get it repeatedly.
+                // `Span::rust_2018()` is somewhat expensive; don't get it repeatedly.
                 let is_span_rust_2018 = self.token.span.rust_2018();
                 if is_span_rust_2018 && self.check_keyword(kw::Async) {
-                    return if self.is_async_block() { // check for `async {` and `async move {`
+                    return if self.is_async_block() { // Check for `async {` and `async move {`.
                         self.parse_async_block(attrs)
                     } else {
-                        self.parse_lambda_expr(attrs)
+                        self.parse_closure(attrs)
                     };
                 }
                 if self.eat_keyword(kw::Return) {
@@ -1043,13 +1042,12 @@ impl<'a> Parser<'a> {
                         // recovery in order to keep the error count down. Fixing the
                         // delimiters will possibly also fix the bare semicolon found in
                         // expression context. For example, silence the following error:
-                        // ```
-                        // error: expected expression, found `;`
-                        //  --> file.rs:2:13
-                        //   |
-                        // 2 |     foo(bar(;
-                        //   |             ^ expected expression
-                        // ```
+                        //
+                        //     error: expected expression, found `;`
+                        //      --> file.rs:2:13
+                        //       |
+                        //     2 |     foo(bar(;
+                        //       |             ^ expected expression
                         self.bump();
                         return Ok(self.mk_expr(self.token.span, ExprKind::Err, ThinVec::new()));
                     }
@@ -1096,11 +1094,11 @@ impl<'a> Parser<'a> {
         attrs.extend(self.parse_inner_attributes()?);
 
         let blk = self.parse_block_tail(lo, blk_mode)?;
-        return Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs));
+        Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs))
     }
 
-    /// Parses `move |args| expr`.
-    fn parse_lambda_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
+    /// Parses a closure (e.g., `move |args| expr`).
+    fn parse_closure(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
 
         let movability = if self.eat_keyword(kw::Static) {
@@ -1115,7 +1113,7 @@ impl<'a> Parser<'a> {
             IsAsync::NotAsync
         };
         if asyncness.is_async() {
-            // Feature gate `async ||` closures.
+            // Feature-gate `async ||` closures.
             self.sess.gated_spans.async_closure.borrow_mut().push(self.prev_span);
         }
 
@@ -1128,8 +1126,7 @@ impl<'a> Parser<'a> {
                 self.parse_expr_res(restrictions, None)?
             },
             _ => {
-                // If an explicit return type is given, require a
-                // block to appear (RFC 968).
+                // If an explicit return type is given, require a block to appear (RFC 968).
                 let body_lo = self.token.span;
                 self.parse_block_expr(None, body_lo, BlockCheckMode::Default, ThinVec::new())?
             }
@@ -1141,7 +1138,7 @@ impl<'a> Parser<'a> {
             attrs))
     }
 
-    /// Parse an optional `move` prefix to a closure lke construct.
+    /// Parses an optional `move` prefix to a closure lke construct.
     fn parse_capture_clause(&mut self) -> CaptureBy {
         if self.eat_keyword(kw::Move) {
             CaptureBy::Value
@@ -1176,7 +1173,7 @@ impl<'a> Parser<'a> {
         }))
     }
 
-    /// Parses a parameter in a lambda header (e.g., `|arg, arg|`).
+    /// Parses a parameter in a closure header (e.g., `|arg, arg|`).
     fn parse_fn_block_param(&mut self) -> PResult<'a, Param> {
         let lo = self.token.span;
         let attrs = self.parse_param_attributes()?;
@@ -1185,7 +1182,7 @@ impl<'a> Parser<'a> {
             self.parse_ty()?
         } else {
             P(Ty {
-                id: ast::DUMMY_NODE_ID,
+                id: DUMMY_NODE_ID,
                 node: TyKind::Infer,
                 span: self.prev_span,
             })
@@ -1196,7 +1193,7 @@ impl<'a> Parser<'a> {
             ty: t,
             pat,
             span,
-            id: ast::DUMMY_NODE_ID
+            id: DUMMY_NODE_ID
         })
     }
 
@@ -1233,7 +1230,7 @@ impl<'a> Parser<'a> {
         Ok(self.mk_expr(lo.to(hi), ExprKind::If(cond, thn, els), attrs))
     }
 
-    /// Parse the condition of a `if`- or `while`-expression
+    /// Parses the condition of a `if` or `while` expression.
     fn parse_cond_expr(&mut self) -> PResult<'a, P<Expr>> {
         let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?;
 
@@ -1261,7 +1258,7 @@ impl<'a> Parser<'a> {
         Ok(self.mk_expr(span, ExprKind::Let(pat, expr), attrs))
     }
 
-    /// `else` token already eaten
+    /// Parses an `else { ... }` expression (`else` token already eaten).
     fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> {
         if self.eat_keyword(kw::If) {
             return self.parse_if_expr(ThinVec::new());
@@ -1271,7 +1268,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parse a 'for' .. 'in' expression ('for' token already eaten)
+    /// Parses a `for ... in` expression (`for` token already eaten).
     fn parse_for_expr(
         &mut self,
         opt_label: Option<Label>,
@@ -1327,7 +1324,7 @@ impl<'a> Parser<'a> {
         Ok(self.mk_expr(span, ExprKind::While(cond, body, opt_label), attrs))
     }
 
-    /// Parse `loop {...}`, `loop` token already eaten.
+    /// Parses `loop { ... }` (`loop` token already eaten).
     fn parse_loop_expr(
         &mut self,
         opt_label: Option<Label>,
@@ -1350,7 +1347,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    // `match` token already eaten
+    /// Parses a `match ... { ... }` expression (`match` token already eaten).
     fn parse_match_expr(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         let match_span = self.prev_span;
         let lo = self.prev_span;
@@ -1457,7 +1454,7 @@ impl<'a> Parser<'a> {
             guard,
             body: expr,
             span: lo.to(hi),
-            id: ast::DUMMY_NODE_ID,
+            id: DUMMY_NODE_ID,
         })
     }
 
@@ -1491,7 +1488,7 @@ impl<'a> Parser<'a> {
         self.token.is_keyword(kw::Try) &&
         self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) &&
         self.token.span.rust_2018() &&
-        // prevent `while try {} {}`, `if try {} {} else {}`, etc.
+        // Prevent `while try {} {}`, `if try {} {} else {}`, etc.
         !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL)
     }
 
@@ -1504,7 +1501,7 @@ impl<'a> Parser<'a> {
         attrs.extend(iattrs);
         Ok(self.mk_expr(
             span_lo.to(body.span),
-            ExprKind::Async(capture_clause, ast::DUMMY_NODE_ID, body), attrs))
+            ExprKind::Async(capture_clause, DUMMY_NODE_ID, body), attrs))
     }
 
     fn is_async_block(&self) -> bool {
@@ -1527,18 +1524,18 @@ impl<'a> Parser<'a> {
     ) -> Option<PResult<'a, P<Expr>>> {
         let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL);
         let certainly_not_a_block = || self.look_ahead(1, |t| t.is_ident()) && (
-            // `{ ident, ` cannot start a block
+            // `{ ident, ` cannot start a block.
             self.look_ahead(2, |t| t == &token::Comma) ||
             self.look_ahead(2, |t| t == &token::Colon) && (
-                // `{ ident: token, ` cannot start a block
+                // `{ ident: token, ` cannot start a block.
                 self.look_ahead(4, |t| t == &token::Comma) ||
-                // `{ ident: ` cannot start a block unless it's a type ascription `ident: Type`
+                // `{ ident: ` cannot start a block unless it's a type ascription `ident: Type`.
                 self.look_ahead(3, |t| !t.can_begin_type())
             )
         );
 
         if struct_allowed || certainly_not_a_block() {
-            // This is a struct literal, but we don't can't accept them here
+            // This is a struct literal, but we don't can't accept them here.
             let expr = self.parse_struct_expr(lo, path.clone(), attrs.clone());
             if let (Ok(expr), false) = (&expr, struct_allowed) {
                 self.struct_span_err(
@@ -1606,14 +1603,14 @@ impl<'a> Parser<'a> {
             let mut recovery_field = None;
             if let token::Ident(name, _) = self.token.kind {
                 if !self.token.is_reserved_ident() && self.look_ahead(1, |t| *t == token::Colon) {
-                    // Use in case of error after field-looking code: `S { foo: () with a }`
+                    // Use in case of error after field-looking code: `S { foo: () with a }`.
                     recovery_field = Some(ast::Field {
                         ident: Ident::new(name, self.token.span),
                         span: self.token.span,
                         expr: self.mk_expr(self.token.span, ExprKind::Err, ThinVec::new()),
                         is_shorthand: false,
                         attrs: ThinVec::new(),
-                        id: ast::DUMMY_NODE_ID,
+                        id: DUMMY_NODE_ID,
                     });
                 }
             }
@@ -1639,7 +1636,7 @@ impl<'a> Parser<'a> {
             match self.expect_one_of(&[token::Comma],
                                      &[token::CloseDelim(token::Brace)]) {
                 Ok(_) => if let Some(f) = parsed_field.or(recovery_field) {
-                    // only include the field if there's no parse error for the field name
+                    // Only include the field if there's no parse error for the field name.
                     fields.push(f);
                 }
                 Err(mut e) => {
@@ -1659,7 +1656,7 @@ impl<'a> Parser<'a> {
         return Ok(self.mk_expr(span, ExprKind::Struct(pth, fields, base), attrs));
     }
 
-    /// Parse ident (COLON expr)?
+    /// Parses `ident (COLON expr)?`.
     fn parse_field(&mut self) -> PResult<'a, Field> {
         let attrs = self.parse_outer_attributes()?;
         let lo = self.token.span;
@@ -1699,7 +1696,7 @@ impl<'a> Parser<'a> {
             expr,
             is_shorthand,
             attrs: attrs.into(),
-            id: ast::DUMMY_NODE_ID,
+            id: DUMMY_NODE_ID,
         })
     }
 
@@ -1772,6 +1769,6 @@ impl<'a> Parser<'a> {
     }
 
     crate fn mk_expr(&self, span: Span, node: ExprKind, attrs: ThinVec<Attribute>) -> P<Expr> {
-        P(Expr { node, span, attrs, id: ast::DUMMY_NODE_ID })
+        P(Expr { node, span, attrs, id: DUMMY_NODE_ID })
     }
 }
diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index 59a3ade9c30e5..be7fc48fdaf66 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -2,34 +2,36 @@ use super::{Parser, PResult, PathStyle, SemiColonMode, BlockMode};
 
 use crate::maybe_whole;
 use crate::ptr::P;
-use crate::ast::{self, Ident, Attribute, AttrStyle};
-use crate::ast::{Item, ItemKind, ImplItem, TraitItem, TraitItemKind};
-use crate::ast::{UseTree, UseTreeKind, PathSegment};
-use crate::ast::{IsAuto, Constness, IsAsync, Unsafety, Defaultness};
-use crate::ast::{Visibility, VisibilityKind, Mutability, FnDecl, FnHeader};
-use crate::ast::{ForeignItem, ForeignItemKind};
-use crate::ast::{Ty, TyKind, GenericBounds, TraitRef};
-use crate::ast::{EnumDef, VariantData, StructField, AnonConst};
-use crate::ast::{Mac, MacDelimiter};
+use crate::ast::{
+    self, DUMMY_NODE_ID, Ident, Attribute, AttrStyle,
+    Item, ItemKind, ImplItem, TraitItem, TraitItemKind,
+    UseTree, UseTreeKind, PathSegment,
+    IsAuto, Constness, IsAsync, Unsafety, Defaultness,
+    Visibility, VisibilityKind, Mutability, FnDecl, FnHeader,
+    ForeignItem, ForeignItemKind,
+    Ty, TyKind, Generics, GenericBounds, TraitRef,
+    EnumDef, VariantData, StructField, AnonConst,
+    Mac, MacDelimiter,
+};
 use crate::ext::base::DummyResult;
 use crate::parse::token;
 use crate::parse::parser::maybe_append;
-use crate::parse::diagnostics::{Error};
+use crate::parse::diagnostics::Error;
 use crate::tokenstream::{TokenTree, TokenStream};
 use crate::source_map::{respan, Span, Spanned};
 use crate::symbol::{kw, sym};
 
 use std::mem;
 use log::debug;
-use rustc_target::spec::abi::{Abi};
+use rustc_target::spec::abi::Abi;
 use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
 
-/// Whether the type alias or associated type is a concrete type or an opaque type
+/// Whether the type alias or associated type is a concrete type or an opaque type.
 #[derive(Debug)]
 pub enum AliasKind {
-    /// Just a new name for the same type
+    /// Just a new name for the same type.
     Weak(P<Ty>),
-    /// Only trait impls of the type will be usable, not the actual type itself
+    /// Only trait impls of the type will be usable, not the actual type itself.
     OpaqueTy(GenericBounds),
 }
 
@@ -200,7 +202,7 @@ impl<'a> Parser<'a> {
             return Ok(Some(item));
         }
 
-        // Parse `async unsafe? fn`.
+        // Parses `async unsafe? fn`.
         if self.check_keyword(kw::Async) {
             let async_span = self.token.span;
             if self.is_keyword_ahead(1, &[kw::Fn])
@@ -214,8 +216,8 @@ impl<'a> Parser<'a> {
                 let (ident, item_, extra_attrs) =
                     self.parse_item_fn(unsafety,
                                     respan(async_span, IsAsync::Async {
-                                        closure_id: ast::DUMMY_NODE_ID,
-                                        return_impl_trait_id: ast::DUMMY_NODE_ID,
+                                        closure_id: DUMMY_NODE_ID,
+                                        return_impl_trait_id: DUMMY_NODE_ID,
                                     }),
                                     respan(fn_span, Constness::NotConst),
                                     Abi::Rust)?;
@@ -286,7 +288,7 @@ impl<'a> Parser<'a> {
             && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) {
             // UNSAFE FUNCTION ITEM
             self.bump(); // `unsafe`
-            // `{` is also expected after `unsafe`, in case of error, include it in the diagnostic
+            // `{` is also expected after `unsafe`; in case of error, include it in the diagnostic.
             self.check(&token::OpenDelim(token::Brace));
             let abi = if self.eat_keyword(kw::Extern) {
                 self.parse_opt_abi()?.unwrap_or(Abi::C)
@@ -521,7 +523,7 @@ impl<'a> Parser<'a> {
 
             let mac_lo = self.token.span;
 
-            // item macro.
+            // Item macro
             let path = self.parse_path(PathStyle::Mod)?;
             self.expect(&token::Not)?;
             let (delim, tts) = self.expect_delimited_token_tree()?;
@@ -659,7 +661,7 @@ impl<'a> Parser<'a> {
         let mut generics = if self.choose_generics_over_qpath() {
             self.parse_generics()?
         } else {
-            ast::Generics::default()
+            Generics::default()
         };
 
         // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
@@ -676,7 +678,7 @@ impl<'a> Parser<'a> {
                           self.look_ahead(1, |t| t != &token::Lt) {
             let span = self.prev_span.between(self.token.span);
             self.struct_span_err(span, "missing trait in a trait impl").emit();
-            P(Ty { node: TyKind::Path(None, err_path(span)), span, id: ast::DUMMY_NODE_ID })
+            P(Ty { node: TyKind::Path(None, err_path(span)), span, id: DUMMY_NODE_ID })
         } else {
             self.parse_ty()?
         };
@@ -798,7 +800,7 @@ impl<'a> Parser<'a> {
             self.expect(&token::Eq)?;
             let expr = self.parse_expr()?;
             self.expect(&token::Semi)?;
-            (name, ast::ImplItemKind::Const(typ, expr), ast::Generics::default())
+            (name, ast::ImplItemKind::Const(typ, expr), Generics::default())
         } else {
             let (name, inner_attrs, generics, node) = self.parse_impl_method(&vis, at_end)?;
             attrs.extend(inner_attrs);
@@ -806,7 +808,7 @@ impl<'a> Parser<'a> {
         };
 
         Ok(ImplItem {
-            id: ast::DUMMY_NODE_ID,
+            id: DUMMY_NODE_ID,
             span: lo.to(self.prev_span),
             ident: name,
             vis,
@@ -847,14 +849,13 @@ impl<'a> Parser<'a> {
             !self.is_keyword_ahead(1, &[kw::Fn, kw::Unsafe])
     }
 
-    /// Parse a method or a macro invocation in a trait impl.
+    /// Parses a method or a macro invocation in a trait impl.
     fn parse_impl_method(&mut self, vis: &Visibility, at_end: &mut bool)
-                         -> PResult<'a, (Ident, Vec<Attribute>, ast::Generics,
-                             ast::ImplItemKind)> {
-        // code copied from parse_macro_use_or_failure... abstraction!
+                         -> PResult<'a, (Ident, Vec<Attribute>, Generics, ast::ImplItemKind)> {
+        // FIXME: code copied from `parse_macro_use_or_failure` -- use abstraction!
         if let Some(mac) = self.parse_assoc_macro_invoc("impl", Some(vis), at_end)? {
             // method macro
-            Ok((Ident::invalid(), vec![], ast::Generics::default(),
+            Ok((Ident::invalid(), vec![], Generics::default(),
                 ast::ImplItemKind::Macro(mac)))
         } else {
             let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
@@ -930,7 +931,7 @@ impl<'a> Parser<'a> {
         };
 
         if self.eat(&token::Eq) {
-            // it's a trait alias
+            // It's a trait alias.
             let bounds = self.parse_generic_bounds(None)?;
             tps.where_clause = self.parse_where_clause()?;
             self.expect(&token::Semi)?;
@@ -948,7 +949,7 @@ impl<'a> Parser<'a> {
             }
             Ok((ident, ItemKind::TraitAlias(tps, bounds), None))
         } else {
-            // it's a normal trait
+            // It's a normal trait.
             tps.where_clause = self.parse_where_clause()?;
             self.expect(&token::OpenDelim(token::Brace))?;
             let mut trait_items = vec![];
@@ -1023,10 +1024,10 @@ impl<'a> Parser<'a> {
                 self.expect(&token::Semi)?;
                 None
             };
-            (ident, TraitItemKind::Const(ty, default), ast::Generics::default())
+            (ident, TraitItemKind::Const(ty, default), Generics::default())
         } else if let Some(mac) = self.parse_assoc_macro_invoc("trait", None, &mut false)? {
             // trait item macro.
-            (Ident::invalid(), ast::TraitItemKind::Macro(mac), ast::Generics::default())
+            (Ident::invalid(), ast::TraitItemKind::Macro(mac), Generics::default())
         } else {
             let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
 
@@ -1089,7 +1090,7 @@ impl<'a> Parser<'a> {
         };
 
         Ok(TraitItem {
-            id: ast::DUMMY_NODE_ID,
+            id: DUMMY_NODE_ID,
             ident: name,
             attrs,
             generics,
@@ -1103,7 +1104,7 @@ impl<'a> Parser<'a> {
     ///
     ///     TraitItemAssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
     fn parse_trait_item_assoc_ty(&mut self)
-        -> PResult<'a, (Ident, TraitItemKind, ast::Generics)> {
+        -> PResult<'a, (Ident, TraitItemKind, Generics)> {
         let ident = self.parse_ident()?;
         let mut generics = self.parse_generics()?;
 
@@ -1165,7 +1166,7 @@ impl<'a> Parser<'a> {
                     UseTreeKind::Nested(self.parse_use_tree_list()?)
                 }
             } else {
-                UseTreeKind::Simple(self.parse_rename()?, ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID)
+                UseTreeKind::Simple(self.parse_rename()?, DUMMY_NODE_ID, DUMMY_NODE_ID)
             }
         };
 
@@ -1178,7 +1179,7 @@ impl<'a> Parser<'a> {
     /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`]
     /// ```
     fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> {
-        self.parse_delim_comma_seq(token::Brace, |p| Ok((p.parse_use_tree()?, ast::DUMMY_NODE_ID)))
+        self.parse_delim_comma_seq(token::Brace, |p| Ok((p.parse_use_tree()?, DUMMY_NODE_ID)))
             .map(|(r, _)| r)
     }
 
@@ -1240,9 +1241,9 @@ impl<'a> Parser<'a> {
         let mut idents = vec![];
         let mut replacement = vec![];
         let mut fixed_crate_name = false;
-        // Accept `extern crate name-like-this` for better diagnostics
+        // Accept `extern crate name-like-this` for better diagnostics.
         let dash = token::BinOp(token::BinOpToken::Minus);
-        if self.token == dash {  // Do not include `-` as part of the expected tokens list
+        if self.token == dash {  // Do not include `-` as part of the expected tokens list.
             while self.eat(&dash) {
                 fixed_crate_name = true;
                 replacement.push((self.prev_span, "_".to_string()));
@@ -1283,7 +1284,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses the name and optional generic types of a function header.
-    fn parse_fn_header(&mut self) -> PResult<'a, (Ident, ast::Generics)> {
+    fn parse_fn_header(&mut self) -> PResult<'a, (Ident, Generics)> {
         let id = self.parse_ident()?;
         let generics = self.parse_generics()?;
         Ok((id, generics))
@@ -1379,7 +1380,7 @@ impl<'a> Parser<'a> {
                     ForeignItem {
                         ident: Ident::invalid(),
                         span: lo.to(self.prev_span),
-                        id: ast::DUMMY_NODE_ID,
+                        id: DUMMY_NODE_ID,
                         attrs,
                         vis: visibility,
                         node: ForeignItemKind::Macro(mac),
@@ -1415,7 +1416,7 @@ impl<'a> Parser<'a> {
             ident,
             attrs,
             node: ForeignItemKind::Fn(decl, generics),
-            id: ast::DUMMY_NODE_ID,
+            id: DUMMY_NODE_ID,
             span: lo.to(hi),
             vis,
         })
@@ -1435,7 +1436,7 @@ impl<'a> Parser<'a> {
             ident,
             attrs,
             node: ForeignItemKind::Static(ty, mutbl),
-            id: ast::DUMMY_NODE_ID,
+            id: DUMMY_NODE_ID,
             span: lo.to(hi),
             vis,
         })
@@ -1453,7 +1454,7 @@ impl<'a> Parser<'a> {
             ident,
             attrs,
             node: ForeignItemKind::Ty,
-            id: ast::DUMMY_NODE_ID,
+            id: DUMMY_NODE_ID,
             span: lo.to(hi),
             vis
         })
@@ -1461,7 +1462,7 @@ impl<'a> Parser<'a> {
 
     fn is_static_global(&mut self) -> bool {
         if self.check_keyword(kw::Static) {
-            // Check if this could be a closure
+            // Check if this could be a closure.
             !self.look_ahead(1, |token| {
                 if token.is_keyword(kw::Move) {
                     return true;
@@ -1492,7 +1493,7 @@ impl<'a> Parser<'a> {
 
     /// Parses `type Foo = Bar;` or returns `None`
     /// without modifying the parser state.
-    fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, ast::Generics)>> {
+    fn eat_type(&mut self) -> Option<PResult<'a, (Ident, AliasKind, Generics)>> {
         // This parses the grammar:
         //     Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
         if self.eat_keyword(kw::Type) {
@@ -1503,7 +1504,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a type alias or opaque type.
-    fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, ast::Generics)> {
+    fn parse_type_alias(&mut self) -> PResult<'a, (Ident, AliasKind, Generics)> {
         let ident = self.parse_ident()?;
         let mut tps = self.parse_generics()?;
         tps.where_clause = self.parse_where_clause()?;
@@ -1536,7 +1537,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses the part of an enum declaration following the `{`.
-    fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<'a, EnumDef> {
+    fn parse_enum_def(&mut self, _generics: &Generics) -> PResult<'a, EnumDef> {
         let mut variants = Vec::new();
         while self.token != token::CloseDelim(token::Brace) {
             let variant_attrs = self.parse_outer_attributes()?;
@@ -1552,15 +1553,15 @@ impl<'a> Parser<'a> {
             } else if self.check(&token::OpenDelim(token::Paren)) {
                 VariantData::Tuple(
                     self.parse_tuple_struct_body()?,
-                    ast::DUMMY_NODE_ID,
+                    DUMMY_NODE_ID,
                 )
             } else {
-                VariantData::Unit(ast::DUMMY_NODE_ID)
+                VariantData::Unit(DUMMY_NODE_ID)
             };
 
             let disr_expr = if self.eat(&token::Eq) {
                 Some(AnonConst {
-                    id: ast::DUMMY_NODE_ID,
+                    id: DUMMY_NODE_ID,
                     value: self.parse_expr()?,
                 })
             } else {
@@ -1569,7 +1570,7 @@ impl<'a> Parser<'a> {
 
             let vr = ast::Variant {
                 ident,
-                id: ast::DUMMY_NODE_ID,
+                id: DUMMY_NODE_ID,
                 attrs: variant_attrs,
                 data: struct_def,
                 disr_expr,
@@ -1622,7 +1623,7 @@ impl<'a> Parser<'a> {
             generics.where_clause = self.parse_where_clause()?;
             if self.eat(&token::Semi) {
                 // If we see a: `struct Foo<T> where T: Copy;` style decl.
-                VariantData::Unit(ast::DUMMY_NODE_ID)
+                VariantData::Unit(DUMMY_NODE_ID)
             } else {
                 // If we see: `struct Foo<T> where T: Copy { ... }`
                 let (fields, recovered) = self.parse_record_struct_body()?;
@@ -1630,14 +1631,14 @@ impl<'a> Parser<'a> {
             }
         // No `where` so: `struct Foo<T>;`
         } else if self.eat(&token::Semi) {
-            VariantData::Unit(ast::DUMMY_NODE_ID)
+            VariantData::Unit(DUMMY_NODE_ID)
         // Record-style struct definition
         } else if self.token == token::OpenDelim(token::Brace) {
             let (fields, recovered) = self.parse_record_struct_body()?;
             VariantData::Struct(fields, recovered)
         // Tuple-style struct definition with optional where-clause.
         } else if self.token == token::OpenDelim(token::Paren) {
-            let body = VariantData::Tuple(self.parse_tuple_struct_body()?, ast::DUMMY_NODE_ID);
+            let body = VariantData::Tuple(self.parse_tuple_struct_body()?, DUMMY_NODE_ID);
             generics.where_clause = self.parse_where_clause()?;
             self.expect(&token::Semi)?;
             body
@@ -1726,7 +1727,7 @@ impl<'a> Parser<'a> {
                 span: lo.to(ty.span),
                 vis,
                 ident: None,
-                id: ast::DUMMY_NODE_ID,
+                id: DUMMY_NODE_ID,
                 ty,
                 attrs,
             })
@@ -1817,7 +1818,7 @@ impl<'a> Parser<'a> {
             span: lo.to(self.prev_span),
             ident: Some(name),
             vis,
-            id: ast::DUMMY_NODE_ID,
+            id: DUMMY_NODE_ID,
             ty,
             attrs,
         })
@@ -1909,7 +1910,7 @@ impl<'a> Parser<'a> {
         P(Item {
             ident,
             attrs,
-            id: ast::DUMMY_NODE_ID,
+            id: DUMMY_NODE_ID,
             node,
             vis,
             span,
diff --git a/src/libsyntax/parse/parser/module.rs b/src/libsyntax/parse/parser/module.rs
index 3f6f87b1c44b6..2d2fb487d7df2 100644
--- a/src/libsyntax/parse/parser/module.rs
+++ b/src/libsyntax/parse/parser/module.rs
@@ -36,12 +36,12 @@ impl<'a> Parser<'a> {
         krate
     }
 
-    /// Parse a `mod <foo> { ... }` or `mod <foo>;` item
+    /// Parses a `mod <foo> { ... }` or `mod <foo>;` item.
     pub(super) fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo> {
         let (in_cfg, outer_attrs) = {
             let mut strip_unconfigured = crate::config::StripUnconfigured {
                 sess: self.sess,
-                features: None, // don't perform gated feature checking
+                features: None, // Don't perform gated feature checking.
             };
             let mut outer_attrs = outer_attrs.to_owned();
             strip_unconfigured.process_cfg_attrs(&mut outer_attrs);
@@ -57,7 +57,7 @@ impl<'a> Parser<'a> {
                     self.submod_path(id, &outer_attrs, id_span)?;
                 let (module, mut attrs) =
                     self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?;
-                // Record that we fetched the mod from an external file
+                // Record that we fetched the mod from an external file.
                 if warn {
                     let attr = attr::mk_attr_outer(
                         attr::mk_word_item(Ident::with_dummy_span(sym::warn_directory_ownership)));
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 669f657160b3e..49f8d58c6a762 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -844,14 +844,14 @@ impl<'a> Parser<'a> {
         // Check if a colon exists one ahead. This means we're parsing a fieldname.
         let hi;
         let (subpat, fieldname, is_shorthand) = if self.look_ahead(1, |t| t == &token::Colon) {
-            // Parsing a pattern of the form "fieldname: pat"
+            // Parsing a pattern of the form `fieldname: pat`.
             let fieldname = self.parse_field_name()?;
             self.bump();
             let pat = self.parse_pat_with_or_inner()?;
             hi = pat.span;
             (pat, fieldname, false)
         } else {
-            // Parsing a pattern of the form "(box) (ref) (mut) fieldname"
+            // Parsing a pattern of the form `(box) (ref) (mut) fieldname`.
             let is_box = self.eat_keyword(kw::Box);
             let boxed_span = self.token.span;
             let is_ref = self.eat_keyword(kw::Ref);
diff --git a/src/libsyntax/parse/parser/stmt.rs b/src/libsyntax/parse/parser/stmt.rs
index 748c1a168b0b2..6a3ac2d73f8b2 100644
--- a/src/libsyntax/parse/parser/stmt.rs
+++ b/src/libsyntax/parse/parser/stmt.rs
@@ -5,12 +5,12 @@ use super::pat::GateOr;
 
 use crate::ptr::P;
 use crate::{maybe_whole, ThinVec};
-use crate::ast::{self, Stmt, StmtKind, Local, Block, BlockCheckMode, Expr, ExprKind};
+use crate::ast::{self, DUMMY_NODE_ID, Stmt, StmtKind, Local, Block, BlockCheckMode, Expr, ExprKind};
 use crate::ast::{Attribute, AttrStyle, VisibilityKind, MacStmtStyle, Mac, MacDelimiter};
 use crate::ext::base::DummyResult;
 use crate::parse::{classify, DirectoryOwnership};
 use crate::parse::diagnostics::Error;
-use crate::parse::token::{self};
+use crate::parse::token;
 use crate::source_map::{respan, Span};
 use crate::symbol::{kw, sym};
 
@@ -18,7 +18,7 @@ use std::mem;
 use errors::Applicability;
 
 impl<'a> Parser<'a> {
-    /// Parse a statement. This stops just before trailing semicolons on everything but items.
+    /// Parses a statement. This stops just before trailing semicolons on everything but items.
     /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
     pub fn parse_stmt(&mut self) -> PResult<'a, Option<Stmt>> {
         Ok(self.parse_stmt_(true))
@@ -43,7 +43,7 @@ impl<'a> Parser<'a> {
 
         Ok(Some(if self.eat_keyword(kw::Let) {
             Stmt {
-                id: ast::DUMMY_NODE_ID,
+                id: DUMMY_NODE_ID,
                 node: StmtKind::Local(self.parse_local(attrs.into())?),
                 span: lo.to(self.prev_span),
             }
@@ -53,7 +53,7 @@ impl<'a> Parser<'a> {
             lo,
         )? {
             Stmt {
-                id: ast::DUMMY_NODE_ID,
+                id: DUMMY_NODE_ID,
                 node: StmtKind::Item(macro_def),
                 span: lo.to(self.prev_span),
             }
@@ -85,7 +85,7 @@ impl<'a> Parser<'a> {
                 })?;
 
                 return Ok(Some(Stmt {
-                    id: ast::DUMMY_NODE_ID,
+                    id: DUMMY_NODE_ID,
                     node: StmtKind::Expr(expr),
                     span: lo.to(self.prev_span),
                 }));
@@ -114,17 +114,17 @@ impl<'a> Parser<'a> {
             // We used to incorrectly stop parsing macro-expanded statements here.
             // If the next token will be an error anyway but could have parsed with the
             // earlier behavior, stop parsing here and emit a warning to avoid breakage.
-            else if macro_legacy_warnings &&
-                    self.token.can_begin_expr() &&
-                    match self.token.kind {
-                // These can continue an expression, so we can't stop parsing and warn.
-                token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) |
-                token::BinOp(token::Minus) | token::BinOp(token::Star) |
-                token::BinOp(token::And) | token::BinOp(token::Or) |
-                token::AndAnd | token::OrOr |
-                token::DotDot | token::DotDotDot | token::DotDotEq => false,
-                _ => true,
-            } {
+            else if macro_legacy_warnings && self.token.can_begin_expr() &&
+                match self.token.kind {
+                    // These can continue an expression, so we can't stop parsing and warn.
+                    token::OpenDelim(token::Paren) | token::OpenDelim(token::Bracket) |
+                    token::BinOp(token::Minus) | token::BinOp(token::Star) |
+                    token::BinOp(token::And) | token::BinOp(token::Or) |
+                    token::AndAnd | token::OrOr |
+                    token::DotDot | token::DotDotDot | token::DotDotEq => false,
+                    _ => true,
+                }
+            {
                 self.warn_missing_semicolon();
                 StmtKind::Mac(P((mac, style, attrs.into())))
             } else {
@@ -135,7 +135,7 @@ impl<'a> Parser<'a> {
                 StmtKind::Expr(e)
             };
             Stmt {
-                id: ast::DUMMY_NODE_ID,
+                id: DUMMY_NODE_ID,
                 span: lo.to(hi),
                 node,
             }
@@ -148,7 +148,7 @@ impl<'a> Parser<'a> {
 
             match item {
                 Some(i) => Stmt {
-                    id: ast::DUMMY_NODE_ID,
+                    id: DUMMY_NODE_ID,
                     span: lo.to(i.span),
                     node: StmtKind::Item(i),
                 },
@@ -178,7 +178,7 @@ impl<'a> Parser<'a> {
                         // an empty tuple that spans the excess semicolons
                         // to preserve this info until the lint stage
                         return Ok(Some(Stmt {
-                            id: ast::DUMMY_NODE_ID,
+                            id: DUMMY_NODE_ID,
                             span: lo.to(last_semi),
                             node: StmtKind::Semi(self.mk_expr(lo.to(last_semi),
                                 ExprKind::Tup(Vec::new()),
@@ -196,7 +196,7 @@ impl<'a> Parser<'a> {
                     let e = self.parse_expr_res(
                         Restrictions::STMT_EXPR, Some(attrs.into()))?;
                     Stmt {
-                        id: ast::DUMMY_NODE_ID,
+                        id: DUMMY_NODE_ID,
                         span: lo.to(e.span),
                         node: StmtKind::Expr(e),
                     }
@@ -218,7 +218,7 @@ impl<'a> Parser<'a> {
             match self.parse_ty() {
                 Ok(ty) => (None, Some(ty)),
                 Err(mut err) => {
-                    // Rewind to before attempting to parse the type and continue parsing
+                    // Rewind to before attempting to parse the type and continue parsing.
                     let parser_snapshot_after_type = self.clone();
                     mem::replace(self, parser_snapshot_before_type);
 
@@ -272,7 +272,7 @@ impl<'a> Parser<'a> {
             ty,
             pat,
             init,
-            id: ast::DUMMY_NODE_ID,
+            id: DUMMY_NODE_ID,
             span: lo.to(hi),
             attrs,
         }))
@@ -334,18 +334,18 @@ impl<'a> Parser<'a> {
             //    if (cond)
             //      bar;
             //
-            // Which is valid in other languages, but not Rust.
+            // which is valid in other languages, but not Rust.
             match self.parse_stmt_without_recovery(false) {
                 Ok(Some(stmt)) => {
                     if self.look_ahead(1, |t| t == &token::OpenDelim(token::Brace))
                         || do_not_suggest_help {
-                        // if the next token is an open brace (e.g., `if a b {`), the place-
-                        // inside-a-block suggestion would be more likely wrong than right
+                        // If the next token is an open brace (e.g., `if a b {`), the place-
+                        // inside-a-block suggestion would be more likely wrong than right.
                         e.span_label(sp, "expected `{`");
                         return Err(e);
                     }
                     let mut stmt_span = stmt.span;
-                    // expand the span to include the semicolon, if it exists
+                    // Expand the span to include the semicolon, if it exists.
                     if self.eat(&token::Semi) {
                         stmt_span = stmt_span.with_hi(self.prev_span.hi());
                     }
@@ -354,7 +354,7 @@ impl<'a> Parser<'a> {
                             stmt_span,
                             "try placing this code inside a block",
                             format!("{{ {} }}", snippet),
-                            // speculative, has been misleading in the past (#46836)
+                            // Speculative; has been misleading in the past (#46836).
                             Applicability::MaybeIncorrect,
                         );
                     }
@@ -399,7 +399,7 @@ impl<'a> Parser<'a> {
                     err.emit();
                     self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore);
                     Some(Stmt {
-                        id: ast::DUMMY_NODE_ID,
+                        id: DUMMY_NODE_ID,
                         node: StmtKind::Expr(DummyResult::raw_expr(self.token.span, true)),
                         span: self.token.span,
                     })
@@ -415,15 +415,15 @@ impl<'a> Parser<'a> {
         }
         Ok(P(ast::Block {
             stmts,
-            id: ast::DUMMY_NODE_ID,
+            id: DUMMY_NODE_ID,
             rules: s,
             span: lo.to(self.prev_span),
         }))
     }
 
     /// Parses a statement, including the trailing semicolon.
-    crate fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> {
-        // skip looking for a trailing semicolon when we have an interpolated statement
+    pub fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> {
+        // Skip looking for a trailing semicolon when we have an interpolated statement.
         maybe_whole!(self, NtStmt, |x| Some(x));
 
         let mut stmt = match self.parse_stmt_without_recovery(macro_legacy_warnings)? {
diff --git a/src/libsyntax/parse/tests.rs b/src/libsyntax/parse/tests.rs
index 6a789ef99d672..5cb59b3f82790 100644
--- a/src/libsyntax/parse/tests.rs
+++ b/src/libsyntax/parse/tests.rs
@@ -25,12 +25,12 @@ fn parse_item_from_source_str(name: FileName, source: String, sess: &ParseSess)
     new_parser_from_source_str(sess, name, source).parse_item()
 }
 
-// produce a syntax_pos::span
+// Produces a `syntax_pos::span`.
 fn sp(a: u32, b: u32) -> Span {
     Span::with_root_ctxt(BytePos(a), BytePos(b))
 }
 
-/// Parse a string, return an expr
+/// Parses a string, return an expression.
 fn string_to_expr(source_str : String) -> P<ast::Expr> {
     let ps = ParseSess::new(FilePathMapping::empty());
     with_error_checking_parse(source_str, &ps, |p| {
@@ -38,7 +38,7 @@ fn string_to_expr(source_str : String) -> P<ast::Expr> {
     })
 }
 
-/// Parse a string, return an item
+/// Parses a string, returns an item.
 fn string_to_item(source_str : String) -> Option<P<ast::Item>> {
     let ps = ParseSess::new(FilePathMapping::empty());
     with_error_checking_parse(source_str, &ps, |p| {
@@ -53,7 +53,7 @@ fn string_to_item(source_str : String) -> Option<P<ast::Item>> {
     })
 }
 
-// check the token-tree-ization of macros
+// Checks the token-tree-ization of macros.
 #[test]
 fn string_to_tts_macro () {
     with_default_globals(|| {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 8c1632dc7808d..5d8498f8b5d26 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -119,19 +119,19 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
     if is_expanded && sess.injected_crate_name.try_get().is_some() {
         // We need to print `#![no_std]` (and its feature gate) so that
         // compiling pretty-printed source won't inject libstd again.
-        // However we don't want these attributes in the AST because
+        // However, we don't want these attributes in the AST because
         // of the feature gate, so we fake them up here.
 
-        // #![feature(prelude_import)]
+        // `#![feature(prelude_import)]`
         let pi_nested = attr::mk_nested_word_item(ast::Ident::with_dummy_span(sym::prelude_import));
         let list = attr::mk_list_item(ast::Ident::with_dummy_span(sym::feature), vec![pi_nested]);
         let fake_attr = attr::mk_attr_inner(list);
         s.print_attribute(&fake_attr);
 
-        // Currently on Rust 2018 we don't have `extern crate std;` at the crate
+        // Currently, in Rust 2018 we don't have `extern crate std;` at the crate
         // root, so this is not needed, and actually breaks things.
         if sess.edition == syntax_pos::edition::Edition::Edition2015 {
-            // #![no_std]
+            // `#![no_std]`
             let no_std_meta = attr::mk_word_item(ast::Ident::with_dummy_span(sym::no_std));
             let fake_attr = attr::mk_attr_inner(no_std_meta);
             s.print_attribute(&fake_attr);
@@ -398,9 +398,9 @@ pub fn vis_to_string(v: &ast::Visibility) -> String {
 
 fn block_to_string(blk: &ast::Block) -> String {
     to_string(|s| {
-        // containing cbox, will be closed by print-block at }
+        // Containing cbox, will be closed by `print_block` at `}`.
         s.cbox(INDENT_UNIT);
-        // head-ibox, will be closed by print-block after {
+        // Head-ibox, will be closed by `print_block` after `{`.
         s.ibox(0);
         s.print_block(blk)
     })
@@ -443,7 +443,7 @@ impl std::ops::DerefMut for State<'_> {
     }
 }
 
-pub trait PrintState<'a>: std::ops::Deref<Target=pp::Printer> + std::ops::DerefMut {
+pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::DerefMut {
     fn comments(&mut self) -> &mut Option<Comments<'a>>;
     fn print_ident(&mut self, ident: ast::Ident);
     fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool);
@@ -495,7 +495,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target=pp::Printer> + std::ops::DerefM
                 self.hardbreak_if_not_bol();
                 for line in &cmnt.lines {
                     // Don't print empty lines because they will end up as trailing
-                    // whitespace
+                    // whitespace.
                     if !line.is_empty() {
                         self.word(line.clone());
                     }
@@ -783,11 +783,11 @@ pub trait PrintState<'a>: std::ops::Deref<Target=pp::Printer> + std::ops::DerefM
 
     fn head<S: Into<Cow<'static, str>>>(&mut self, w: S) {
         let w = w.into();
-        // outer-box is consistent
+        // Outer-box is consistent.
         self.cbox(INDENT_UNIT);
-        // head-box is inconsistent
+        // Head-box is inconsistent.
         self.ibox(w.len() + 1);
-        // keyword that starts the head
+        // Keyword that starts the head.
         if !w.is_empty() {
             self.word_nbsp(w);
         }
@@ -795,7 +795,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target=pp::Printer> + std::ops::DerefM
 
     fn bopen(&mut self) {
         self.word("{");
-        self.end(); // close the head-box
+        self.end(); // Close the head-box.
     }
 
     fn bclose_maybe_open(&mut self, span: syntax_pos::Span, close_box: bool) {
@@ -803,7 +803,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target=pp::Printer> + std::ops::DerefM
         self.break_offset_if_not_bol(1, -(INDENT_UNIT as isize));
         self.word("}");
         if close_box {
-            self.end(); // close the outer-box
+            self.end(); // Close the outer-box.
         }
     }
 
@@ -900,8 +900,6 @@ impl<'a> State<'a> {
         self.s.word("*/")
     }
 
-
-
     crate fn commasep_cmnt<T, F, G>(&mut self,
                                   b: Breaks,
                                   elts: &[T],
@@ -928,12 +926,12 @@ impl<'a> State<'a> {
     }
 
     crate fn commasep_exprs(&mut self, b: Breaks,
-                          exprs: &[P<ast::Expr>]) {
+                            exprs: &[P<ast::Expr>]) {
         self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span)
     }
 
     crate fn print_mod(&mut self, _mod: &ast::Mod,
-                     attrs: &[ast::Attribute]) {
+                       attrs: &[ast::Attribute]) {
         self.print_inner_attributes(attrs);
         for item in &_mod.items {
             self.print_item(item);
@@ -941,7 +939,7 @@ impl<'a> State<'a> {
     }
 
     crate fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
-                             attrs: &[ast::Attribute]) {
+                               attrs: &[ast::Attribute]) {
         self.print_inner_attributes(attrs);
         for item in &nmod.items {
             self.print_foreign_item(item);
@@ -1136,7 +1134,7 @@ impl<'a> State<'a> {
         self.s.word(";")
     }
 
-    /// Pretty-print an item
+    /// Pretty-prints an item.
     crate fn print_item(&mut self, item: &ast::Item) {
         self.hardbreak_if_not_bol();
         self.maybe_print_comment(item.span.lo());
@@ -1489,7 +1487,7 @@ impl<'a> State<'a> {
                     self.s.word(";");
                 }
                 self.end();
-                self.end(); // close the outer-box
+                self.end(); // Close the outer-box.
             }
             ast::VariantData::Struct(..) => {
                 self.print_where_clause(&generics.where_clause);
@@ -1793,7 +1791,7 @@ impl<'a> State<'a> {
         self.print_expr_cond_paren(expr, expr.precedence().order() < prec)
     }
 
-    /// Print an expr using syntax that's acceptable in a condition position, such as the `cond` in
+    /// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
     /// `if cond { ... }`.
     crate fn print_expr_as_cond(&mut self, expr: &ast::Expr) {
         self.print_expr_cond_paren(expr, Self::cond_needs_par(expr))
@@ -1812,7 +1810,7 @@ impl<'a> State<'a> {
         }
     }
 
-    /// Print `expr` or `(expr)` when `needs_par` holds.
+    /// Prints `expr` or `(expr)` when `needs_par` holds.
     fn print_expr_cond_paren(&mut self, expr: &ast::Expr, needs_par: bool) {
         if needs_par {
             self.popen();
@@ -2456,7 +2454,7 @@ impl<'a> State<'a> {
     }
 
     fn print_arm(&mut self, arm: &ast::Arm) {
-        // I have no idea why this check is necessary, but here it is :(
+        // Note, I have no idea why this check is necessary, but here it is.
         if arm.attrs.is_empty() {
             self.s.space();
         }
@@ -2480,21 +2478,21 @@ impl<'a> State<'a> {
                     self.word_space(":");
                 }
 
-                // the block will close the pattern's ibox
+                // The block will close the pattern's ibox.
                 self.print_block_unclosed_indent(blk);
 
-                // If it is a user-provided unsafe block, print a comma after it
+                // If it is a user-provided unsafe block, print a comma after it.
                 if let BlockCheckMode::Unsafe(ast::UserProvided) = blk.rules {
                     self.s.word(",");
                 }
             }
             _ => {
-                self.end(); // close the ibox for the pattern
+                self.end(); // Close the ibox for the pattern.
                 self.print_expr(&arm.body);
                 self.s.word(",");
             }
         }
-        self.end(); // close enclosing cbox
+        self.end(); // Close enclosing cbox.
     }
 
     fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) {
diff --git a/src/libsyntax/print/pprust/tests.rs b/src/libsyntax/print/pprust/tests.rs
index 25214673e6935..afd1726adf36b 100644
--- a/src/libsyntax/print/pprust/tests.rs
+++ b/src/libsyntax/print/pprust/tests.rs
@@ -12,8 +12,8 @@ fn fun_to_string(
         s.head("");
         s.print_fn(decl, header, Some(name),
                    generics, &source_map::dummy_spanned(ast::VisibilityKind::Inherited));
-        s.end(); // Close the head box
-        s.end(); // Close the outer box
+        s.end(); // Close the head box.
+        s.end(); // Close the outer box.
     })
 }
 
@@ -58,7 +58,6 @@ fn test_variant_to_string() {
             ident,
             attrs: Vec::new(),
             id: ast::DUMMY_NODE_ID,
-            // making this up as I go.... ?
             data: ast::VariantData::Unit(ast::DUMMY_NODE_ID),
             disr_expr: None,
             span: syntax_pos::DUMMY_SP,
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index 7190cfd72a959..393723b02b2d3 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -1,10 +1,10 @@
-//! The SourceMap tracks all the source code used within a single crate, mapping
+//! The `SourceMap` tracks all the source code used within a single crate, mapping
 //! from integer byte positions to the original source code location. Each bit
 //! of source parsed during crate parsing (typically files, in-memory strings,
 //! or various bits of macro expansion) cover a continuous range of bytes in the
-//! SourceMap and are represented by SourceFiles. Byte positions are stored in
-//! `spans` and used pervasively in the compiler. They are absolute positions
-//! within the SourceMap, which upon request can be converted to line and column
+//! `SourceMap` and are represented by `SourceFile`s. Byte positions are stored in
+//! `Span`` and used pervasively in the compiler. They are absolute positions
+//! within the `SourceMap`, which upon request can be converted to line and column
 //! information, source code snippets, etc.
 
 pub use syntax_pos::*;
@@ -94,7 +94,7 @@ impl FileLoader for RealFileLoader {
     }
 }
 
-// This is a SourceFile identifier that is used to correlate SourceFiles between
+// This is a `SourceFile` identifier that is used to correlate `SourceFile`s between
 // subsequent compilation sessions (which is something we need to do during
 // incremental compilation).
 #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)]
@@ -103,8 +103,8 @@ pub struct StableSourceFileId(u128);
 impl StableSourceFileId {
     pub fn new(source_file: &SourceFile) -> StableSourceFileId {
         StableSourceFileId::new_from_pieces(&source_file.name,
-                                         source_file.name_was_remapped,
-                                         source_file.unmapped_path.as_ref())
+                                            source_file.name_was_remapped,
+                                            source_file.unmapped_path.as_ref())
     }
 
     pub fn new_from_pieces(name: &FileName,
@@ -134,7 +134,7 @@ pub struct SourceMap {
     files: Lock<SourceMapFiles>,
     file_loader: Box<dyn FileLoader + Sync + Send>,
     // This is used to apply the file path remapping as specified via
-    // --remap-path-prefix to all SourceFiles allocated within this SourceMap.
+    // `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`.
     path_mapping: FilePathMapping,
 }
 
@@ -204,14 +204,14 @@ impl SourceMap {
         match self.files.borrow().source_files.last() {
             None => 0,
             // Add one so there is some space between files. This lets us distinguish
-            // positions in the source_map, even in the presence of zero-length files.
+            // positions in the `SourceMap`, even in the presence of zero-length files.
             Some(last) => last.end_pos.to_usize() + 1,
         }
     }
 
-    /// Creates a new source_file.
-    /// If a file already exists in the source_map with the same id, that file is returned
-    /// unmodified
+    /// Creates a new `SourceFile`.
+    /// If a file already exists in the `SourceMap` with the same ID, that file is returned
+    /// unmodified.
     pub fn new_source_file(&self, filename: FileName, src: String) -> Lrc<SourceFile> {
         self.try_new_source_file(filename, src)
             .unwrap_or_else(|OffsetOverflowError| {
@@ -268,8 +268,8 @@ impl SourceMap {
         Ok(lrc_sf)
     }
 
-    /// Allocates a new SourceFile representing a source file from an external
-    /// crate. The source code of such an "imported source_file" is not available,
+    /// Allocates a new `SourceFile` representing a source file from an external
+    /// crate. The source code of such an "imported `SourceFile`" is not available,
     /// but we still know enough to generate accurate debuginfo location
     /// information for things inlined from other crates.
     pub fn new_imported_source_file(
@@ -334,7 +334,7 @@ impl SourceMap {
                  pos.col.to_usize() + 1)
     }
 
-    // If there is a doctest_offset, apply it to the line
+    // If there is a doctest offset, applies it to the line.
     pub fn doctest_offset_line(&self, file: &FileName, orig: usize) -> usize {
         return match file {
             FileName::DocTest(_, offset) => {
@@ -348,7 +348,7 @@ impl SourceMap {
         }
     }
 
-    /// Lookup source information about a BytePos
+    /// Looks up source information about a `BytePos`.
     pub fn lookup_char_pos(&self, pos: BytePos) -> Loc {
         let chpos = self.bytepos_to_file_charpos(pos);
         match self.lookup_line(pos) {
@@ -411,7 +411,7 @@ impl SourceMap {
         }
     }
 
-    // If the relevant source_file is empty, we don't return a line number.
+    // If the corresponding `SourceFile` is empty, does not return a line number.
     pub fn lookup_line(&self, pos: BytePos) -> Result<SourceFileAndLine, Lrc<SourceFile>> {
         let idx = self.lookup_source_file_idx(pos);
 
@@ -423,15 +423,15 @@ impl SourceMap {
         }
     }
 
-    /// Returns `Some(span)`, a union of the lhs and rhs span. The lhs must precede the rhs. If
-    /// there are gaps between lhs and rhs, the resulting union will cross these gaps.
-    /// For this to work, the spans have to be:
+    /// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If
+    /// there are gaps between LHS and RHS, the resulting union will cross these gaps.
+    /// For this to work,
     ///
-    ///    * the ctxt of both spans much match
-    ///    * the lhs span needs to end on the same line the rhs span begins
-    ///    * the lhs span must start at or before the rhs span
+    ///    * the syntax contexts of both spans much match,
+    ///    * the LHS span needs to end on the same line the RHS span begins,
+    ///    * the LHS span must start at or before the RHS span.
     pub fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option<Span> {
-        // make sure we're at the same expansion id
+        // Ensure we're at the same expansion ID.
         if sp_lhs.ctxt() != sp_rhs.ctxt() {
             return None;
         }
@@ -445,12 +445,12 @@ impl SourceMap {
             Err(_) => return None
         };
 
-        // if we must cross lines to merge, don't merge
+        // If we must cross lines to merge, don't merge.
         if lhs_end.line != rhs_begin.line {
             return None;
         }
 
-        // ensure these follow the expected order and we don't overlap
+        // Ensure these follow the expected order and that we don't overlap.
         if (sp_lhs.lo() <= sp_rhs.lo()) && (sp_lhs.hi() <= sp_rhs.lo()) {
             Some(sp_lhs.to(sp_rhs))
         } else {
@@ -466,11 +466,12 @@ impl SourceMap {
         let lo = self.lookup_char_pos(sp.lo());
         let hi = self.lookup_char_pos(sp.hi());
         format!("{}:{}:{}: {}:{}",
-                        lo.file.name,
-                        lo.line,
-                        lo.col.to_usize() + 1,
-                        hi.line,
-                        hi.col.to_usize() + 1)
+            lo.file.name,
+            lo.line,
+            lo.col.to_usize() + 1,
+            hi.line,
+            hi.col.to_usize() + 1,
+        )
     }
 
     pub fn span_to_filename(&self, sp: Span) -> FileName {
@@ -478,8 +479,8 @@ impl SourceMap {
     }
 
     pub fn span_to_unmapped_path(&self, sp: Span) -> FileName {
-        self.lookup_char_pos(sp.lo()).file.unmapped_path.clone()
-            .expect("SourceMap::span_to_unmapped_path called for imported SourceFile?")
+        let source_file = self.lookup_char_pos(sp.lo()).file;
+        source_file.unmapped_path.clone().unwrap_or(source_file.name.clone())
     }
 
     pub fn is_multiline(&self, sp: Span) -> bool {
@@ -586,7 +587,7 @@ impl SourceMap {
         }
     }
 
-    /// Returns the source snippet as `String` corresponding to the given `Span`
+    /// Returns the source snippet as `String` corresponding to the given `Span`.
     pub fn span_to_snippet(&self, sp: Span) -> Result<String, SpanSnippetError> {
         self.span_to_source(sp, |src, start_index, end_index| src.get(start_index..end_index)
             .map(|s| s.to_string())
@@ -602,14 +603,14 @@ impl SourceMap {
         }
     }
 
-    /// Returns the source snippet as `String` before the given `Span`
+    /// Returns the source snippet as `String` before the given `Span`.
     pub fn span_to_prev_source(&self, sp: Span) -> Result<String, SpanSnippetError> {
         self.span_to_source(sp, |src, start_index, _| src.get(..start_index)
             .map(|s| s.to_string())
             .ok_or_else(|| SpanSnippetError::IllFormedSpan(sp)))
     }
 
-    /// Extend the given `Span` to just after the previous occurrence of `c`. Return the same span
+    /// Extends the given `Span` to just after the previous occurrence of `c`. Return the same span
     /// if no character could be found or if an error occurred while retrieving the code snippet.
     pub fn span_extend_to_prev_char(&self, sp: Span, c: char) -> Span {
         if let Ok(prev_source) = self.span_to_prev_source(sp) {
@@ -622,8 +623,8 @@ impl SourceMap {
         sp
     }
 
-    /// Extend the given `Span` to just after the previous occurrence of `pat` when surrounded by
-    /// whitespace. Return the same span if no character could be found or if an error occurred
+    /// Extends the given `Span` to just after the previous occurrence of `pat` when surrounded by
+    /// whitespace. Returns the same span if no character could be found or if an error occurred
     /// while retrieving the code snippet.
     pub fn span_extend_to_prev_str(&self, sp: Span, pat: &str, accept_newlines: bool) -> Span {
         // assure that the pattern is delimited, to avoid the following
@@ -643,7 +644,8 @@ impl SourceMap {
         sp
     }
 
-    /// Given a `Span`, try to get a shorter span ending before the first occurrence of `c` `char`
+    /// Given a `Span`, tries to get a shorter span ending before the first occurrence of `char`
+    /// ``c`.
     pub fn span_until_char(&self, sp: Span, c: char) -> Span {
         match self.span_to_snippet(sp) {
             Ok(snippet) => {
@@ -658,7 +660,7 @@ impl SourceMap {
         }
     }
 
-    /// Given a `Span`, try to get a shorter span ending just after the first occurrence of `char`
+    /// Given a `Span`, tries to get a shorter span ending just after the first occurrence of `char`
     /// `c`.
     pub fn span_through_char(&self, sp: Span, c: char) -> Span {
         if let Ok(snippet) = self.span_to_snippet(sp) {
@@ -669,8 +671,8 @@ impl SourceMap {
         sp
     }
 
-    /// Given a `Span`, get a new `Span` covering the first token and all its trailing whitespace or
-    /// the original `Span`.
+    /// Given a `Span`, gets a new `Span` covering the first token and all its trailing whitespace
+    /// or the original `Span`.
     ///
     /// If `sp` points to `"let mut x"`, then a span pointing at `"let "` will be returned.
     pub fn span_until_non_whitespace(&self, sp: Span) -> Span {
@@ -689,15 +691,15 @@ impl SourceMap {
         })
     }
 
-    /// Given a `Span`, get a new `Span` covering the first token without its trailing whitespace or
-    /// the original `Span` in case of error.
+    /// Given a `Span`, gets a new `Span` covering the first token without its trailing whitespace
+    /// or the original `Span` in case of error.
     ///
     /// If `sp` points to `"let mut x"`, then a span pointing at `"let"` will be returned.
     pub fn span_until_whitespace(&self, sp: Span) -> Span {
         self.span_take_while(sp, |c| !c.is_whitespace())
     }
 
-    /// Given a `Span`, get a shorter one until `predicate` yields false.
+    /// Given a `Span`, gets a shorter one until `predicate` yields `false`.
     pub fn span_take_while<P>(&self, sp: Span, predicate: P) -> Span
         where P: for <'r> FnMut(&'r char) -> bool
     {
@@ -717,7 +719,7 @@ impl SourceMap {
         self.span_until_char(sp, '{')
     }
 
-    /// Returns a new span representing just the start-point of this span
+    /// Returns a new span representing just the start point of this span.
     pub fn start_point(&self, sp: Span) -> Span {
         let pos = sp.lo().0;
         let width = self.find_width_of_character_at_span(sp, false);
@@ -726,7 +728,7 @@ impl SourceMap {
         sp.with_hi(end_point)
     }
 
-    /// Returns a new span representing just the end-point of this span
+    /// Returns a new span representing just the end point of this span.
     pub fn end_point(&self, sp: Span) -> Span {
         let pos = sp.hi().0;
 
@@ -737,7 +739,7 @@ impl SourceMap {
         sp.with_lo(end_point)
     }
 
-    /// Returns a new span representing the next character after the end-point of this span
+    /// Returns a new span representing the next character after the end-point of this span.
     pub fn next_point(&self, sp: Span) -> Span {
         let start_of_next_point = sp.hi().0;
 
@@ -840,7 +842,7 @@ impl SourceMap {
         None
     }
 
-    /// For a global BytePos compute the local offset within the containing SourceFile
+    /// For a global `BytePos`, computes the local offset within the containing `SourceFile`.
     pub fn lookup_byte_offset(&self, bpos: BytePos) -> SourceFileAndBytePos {
         let idx = self.lookup_source_file_idx(bpos);
         let sf = (*self.files.borrow().source_files)[idx].clone();
@@ -848,22 +850,22 @@ impl SourceMap {
         SourceFileAndBytePos {sf, pos: offset}
     }
 
-    /// Converts an absolute BytePos to a CharPos relative to the source_file.
+    /// Converts an absolute `BytePos` to a `CharPos` relative to the `SourceFile`.
     pub fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
         let idx = self.lookup_source_file_idx(bpos);
         let map = &(*self.files.borrow().source_files)[idx];
 
-        // The number of extra bytes due to multibyte chars in the SourceFile
+        // The number of extra bytes due to multibyte chars in the `SourceFile`.
         let mut total_extra_bytes = 0;
 
         for mbc in map.multibyte_chars.iter() {
             debug!("{}-byte char at {:?}", mbc.bytes, mbc.pos);
             if mbc.pos < bpos {
-                // every character is at least one byte, so we only
+                // Every character is at least one byte, so we only
                 // count the actual extra bytes.
                 total_extra_bytes += mbc.bytes as u32 - 1;
                 // We should never see a byte position in the middle of a
-                // character
+                // character.
                 assert!(bpos.to_u32() >= mbc.pos.to_u32() + mbc.bytes as u32);
             } else {
                 break;
@@ -874,13 +876,13 @@ impl SourceMap {
         CharPos(bpos.to_usize() - map.start_pos.to_usize() - total_extra_bytes as usize)
     }
 
-    // Return the index of the source_file (in self.files) which contains pos.
+    // Returns the index of the `SourceFile` (in `self.files`) that contains `pos`.
     pub fn lookup_source_file_idx(&self, pos: BytePos) -> usize {
         let files = self.files.borrow();
         let files = &files.source_files;
         let count = files.len();
 
-        // Binary search for the source_file.
+        // Binary search for the `SourceFile`.
         let mut a = 0;
         let mut b = count;
         while b - a > 1 {
@@ -911,8 +913,8 @@ impl SourceMap {
         }).ok()
     }
 
-    /// Take the span of a type parameter in a function signature and try to generate a span for the
-    /// function name (with generics) and a new snippet for this span with the pointed type
+    /// Takes the span of a type parameter in a function signature and try to generate a span for
+    /// the function name (with generics) and a new snippet for this span with the pointed type
     /// parameter as a new local type parameter.
     ///
     /// For instance:
@@ -928,18 +930,18 @@ impl SourceMap {
     ///
     /// Attention: The method used is very fragile since it essentially duplicates the work of the
     /// parser. If you need to use this function or something similar, please consider updating the
-    /// source_map functions and this function to something more robust.
+    /// `SourceMap` functions and this function to something more robust.
     pub fn generate_local_type_param_snippet(&self, span: Span) -> Option<(Span, String)> {
         // Try to extend the span to the previous "fn" keyword to retrieve the function
-        // signature
+        // signature.
         let sugg_span = self.span_extend_to_prev_str(span, "fn", false);
         if sugg_span != span {
             if let Ok(snippet) = self.span_to_snippet(sugg_span) {
-                // Consume the function name
+                // Consume the function name.
                 let mut offset = snippet.find(|c: char| !c.is_alphanumeric() && c != '_')
                     .expect("no label after fn");
 
-                // Consume the generics part of the function signature
+                // Consume the generics part of the function signature.
                 let mut bracket_counter = 0;
                 let mut last_char = None;
                 for c in snippet[offset..].chars() {
@@ -953,11 +955,11 @@ impl SourceMap {
                     last_char = Some(c);
                 }
 
-                // Adjust the suggestion span to encompass the function name with its generics
+                // Adjust the suggestion span to encompass the function name with its generics.
                 let sugg_span = sugg_span.with_hi(BytePos(sugg_span.lo().0 + offset as u32));
 
                 // Prepare the new suggested snippet to append the type parameter that triggered
-                // the error in the generics of the function signature
+                // the error in the generics of the function signature.
                 let mut new_snippet = if last_char == Some('>') {
                     format!("{}, ", &snippet[..(offset - '>'.len_utf8())])
                 } else {
diff --git a/src/libsyntax/source_map/tests.rs b/src/libsyntax/source_map/tests.rs
index c7b8332c53ef7..28fc19093242a 100644
--- a/src/libsyntax/source_map/tests.rs
+++ b/src/libsyntax/source_map/tests.rs
@@ -4,18 +4,24 @@ use rustc_data_structures::sync::Lrc;
 
 fn init_source_map() -> SourceMap {
     let sm = SourceMap::new(FilePathMapping::empty());
-    sm.new_source_file(PathBuf::from("blork.rs").into(),
-                    "first line.\nsecond line".to_string());
-    sm.new_source_file(PathBuf::from("empty.rs").into(),
-                    String::new());
-    sm.new_source_file(PathBuf::from("blork2.rs").into(),
-                    "first line.\nsecond line".to_string());
+    sm.new_source_file(
+        PathBuf::from("blork.rs").into(),
+        "first line.\nsecond line".to_string(),
+    );
+    sm.new_source_file(
+        PathBuf::from("empty.rs").into(),
+        String::new(),
+    );
+    sm.new_source_file(
+        PathBuf::from("blork2.rs").into(),
+        "first line.\nsecond line".to_string(),
+    );
     sm
 }
 
+/// Tests `lookup_byte_offset`.
 #[test]
 fn t3() {
-    // Test lookup_byte_offset
     let sm = init_source_map();
 
     let srcfbp1 = sm.lookup_byte_offset(BytePos(23));
@@ -31,9 +37,9 @@ fn t3() {
     assert_eq!(srcfbp2.pos, BytePos(0));
 }
 
+/// Tests `bytepos_to_file_charpos`.
 #[test]
 fn t4() {
-    // Test bytepos_to_file_charpos
     let sm = init_source_map();
 
     let cp1 = sm.bytepos_to_file_charpos(BytePos(22));
@@ -43,9 +49,9 @@ fn t4() {
     assert_eq!(cp2, CharPos(0));
 }
 
+/// Tests zero-length `SourceFile`s.
 #[test]
 fn t5() {
-    // Test zero-length source_files.
     let sm = init_source_map();
 
     let loc1 = sm.lookup_char_pos(BytePos(22));
@@ -61,7 +67,7 @@ fn t5() {
 
 fn init_source_map_mbc() -> SourceMap {
     let sm = SourceMap::new(FilePathMapping::empty());
-    // € is a three byte utf8 char.
+    // "€" is a three-byte UTF8 char.
     sm.new_source_file(PathBuf::from("blork.rs").into(),
                     "fir€st €€€€ line.\nsecond line".to_string());
     sm.new_source_file(PathBuf::from("blork2.rs").into(),
@@ -69,9 +75,9 @@ fn init_source_map_mbc() -> SourceMap {
     sm
 }
 
+/// Tests `bytepos_to_file_charpos` in the presence of multi-byte chars.
 #[test]
 fn t6() {
-    // Test bytepos_to_file_charpos in the presence of multi-byte chars
     let sm = init_source_map_mbc();
 
     let cp1 = sm.bytepos_to_file_charpos(BytePos(3));
@@ -87,11 +93,11 @@ fn t6() {
     assert_eq!(cp4, CharPos(15));
 }
 
+/// Test `span_to_lines` for a span ending at the end of a `SourceFile`.
 #[test]
 fn t7() {
-    // Test span_to_lines for a span ending at the end of source_file
     let sm = init_source_map();
-    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
+    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
     let file_lines = sm.span_to_lines(span).unwrap();
 
     assert_eq!(file_lines.file.name, PathBuf::from("blork.rs").into());
@@ -107,10 +113,10 @@ fn span_from_selection(input: &str, selection: &str) -> Span {
     assert_eq!(input.len(), selection.len());
     let left_index = selection.find('~').unwrap() as u32;
     let right_index = selection.rfind('~').map(|x|x as u32).unwrap_or(left_index);
-    Span::with_root_ctxt(BytePos(left_index), BytePos(right_index + 1))
+    Span::new(BytePos(left_index), BytePos(right_index + 1), NO_EXPANSION)
 }
 
-/// Tests span_to_snippet and span_to_lines for a span converting 3
+/// Tests `span_to_snippet` and `span_to_lines` for a span converting 3
 /// lines in the middle of a file.
 #[test]
 fn span_to_snippet_and_lines_spanning_multiple_lines() {
@@ -120,10 +126,10 @@ fn span_to_snippet_and_lines_spanning_multiple_lines() {
     sm.new_source_file(Path::new("blork.rs").to_owned().into(), inputtext.to_string());
     let span = span_from_selection(inputtext, selection);
 
-    // check that we are extracting the text we thought we were extracting
+    // Check that we are extracting the text we thought we were extracting.
     assert_eq!(&sm.span_to_snippet(span).unwrap(), "BB\nCCC\nDDDDD");
 
-    // check that span_to_lines gives us the complete result with the lines/cols we expected
+    // Check that span_to_lines gives us the complete result with the lines/cols we expected.
     let lines = sm.span_to_lines(span).unwrap();
     let expected = vec![
         LineInfo { line_index: 1, start_col: CharPos(4), end_col: CharPos(6) },
@@ -133,27 +139,27 @@ fn span_to_snippet_and_lines_spanning_multiple_lines() {
     assert_eq!(lines.lines, expected);
 }
 
+/// Test span_to_snippet for a span ending at the end of a `SourceFile`.
 #[test]
 fn t8() {
-    // Test span_to_snippet for a span ending at the end of source_file
     let sm = init_source_map();
-    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
+    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
     let snippet = sm.span_to_snippet(span);
 
     assert_eq!(snippet, Ok("second line".to_string()));
 }
 
+/// Test `span_to_str` for a span ending at the end of a `SourceFile`.
 #[test]
 fn t9() {
-    // Test span_to_str for a span ending at the end of source_file
     let sm = init_source_map();
-    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
+    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
     let sstr =  sm.span_to_string(span);
 
     assert_eq!(sstr, "blork.rs:2:1: 2:12");
 }
 
-/// Tests failing to merge two spans on different lines
+/// Tests failing to merge two spans on different lines.
 #[test]
 fn span_merging_fail() {
     let sm = SourceMap::new(FilePathMapping::empty());
@@ -167,43 +173,47 @@ fn span_merging_fail() {
     assert!(sm.merge_spans(span1, span2).is_none());
 }
 
-/// Returns the span corresponding to the `n`th occurrence of
-/// `substring` in `source_text`.
+/// Returns the span corresponding to the `n`th occurrence of `substring` in `source_text`.
 trait SourceMapExtension {
-    fn span_substr(&self,
-                file: &Lrc<SourceFile>,
-                source_text: &str,
-                substring: &str,
-                n: usize)
-                -> Span;
+    fn span_substr(
+        self,
+        file: &Lrc<SourceFile>,
+        source_text: &str,
+        substring: &str,
+        n: usize,
+    ) -> Span;
 }
 
 impl SourceMapExtension for SourceMap {
-    fn span_substr(&self,
-                file: &Lrc<SourceFile>,
-                source_text: &str,
-                substring: &str,
-                n: usize)
-                -> Span
-    {
-        println!("span_substr(file={:?}/{:?}, substring={:?}, n={})",
-                file.name, file.start_pos, substring, n);
+    fn span_substr(
+        &self,
+        file: &Lrc<SourceFile>,
+        source_text: &str,
+        substring: &str,
+        n: usize,
+    ) -> Span {
+        println!(
+            "span_substr(file={:?}/{:?}, substring={:?}, n={})",
+            file.name, file.start_pos, substring, n
+        );
         let mut i = 0;
         let mut hi = 0;
         loop {
             let offset = source_text[hi..].find(substring).unwrap_or_else(|| {
-                panic!("source_text `{}` does not have {} occurrences of `{}`, only {}",
-                    source_text, n, substring, i);
+                panic!(
+                    "source_text `{}` does not have {} occurrences of `{}`, only {}",
+                    source_text, n, substring, i
+                );
             });
             let lo = hi + offset;
             hi = lo + substring.len();
             if i == n {
-                let span = Span::with_root_ctxt(
+                let span = Span::new(
                     BytePos(lo as u32 + file.start_pos.0),
                     BytePos(hi as u32 + file.start_pos.0),
+                    NO_EXPANSION,
                 );
-                assert_eq!(&self.span_to_snippet(span).unwrap()[..],
-                        substring);
+                assert_eq!(&self.span_to_snippet(span).unwrap()[..], substring);
                 return span;
             }
             i += 1;
diff --git a/src/libsyntax/tests.rs b/src/libsyntax/tests.rs
index 9b90b31f2d2a2..540881b0a5496 100644
--- a/src/libsyntax/tests.rs
+++ b/src/libsyntax/tests.rs
@@ -18,7 +18,7 @@ use std::path::{Path, PathBuf};
 use std::str;
 use std::sync::{Arc, Mutex};
 
-/// Map string to parser (via tts)
+/// Map string to parser (via tts).
 fn string_to_parser(ps: &ParseSess, source_str: String) -> Parser<'_> {
     new_parser_from_source_str(ps, PathBuf::from("bogofile").into(), source_str)
 }
@@ -32,7 +32,7 @@ crate fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F)
     x
 }
 
-/// Map a string to tts, using a made-up filename:
+/// Maps a string to tts, using a made-up filename.
 crate fn string_to_stream(source_str: String) -> TokenStream {
     let ps = ParseSess::new(FilePathMapping::empty());
     source_file_to_stream(
@@ -42,7 +42,7 @@ crate fn string_to_stream(source_str: String) -> TokenStream {
     ), None).0
 }
 
-/// Parse a string, return a crate.
+/// Parses a string, returns a crate.
 crate fn string_to_crate(source_str : String) -> ast::Crate {
     let ps = ParseSess::new(FilePathMapping::empty());
     with_error_checking_parse(source_str, &ps, |p| {
@@ -64,7 +64,7 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
             (None, _) => return false,
             (Some(&a), None) => {
                 if rustc_lexer::is_whitespace(a) {
-                    break // trailing whitespace check is out of loop for borrowck
+                    break // Trailing whitespace check is out of loop for borrowck.
                 } else {
                     return false
                 }
@@ -73,11 +73,11 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
         };
 
         if rustc_lexer::is_whitespace(a) && rustc_lexer::is_whitespace(b) {
-            // skip whitespace for a and b
+            // Skip whitespace for `a` and `b`.
             scan_for_non_ws_or_end(&mut a_iter);
             scan_for_non_ws_or_end(&mut b_iter);
         } else if rustc_lexer::is_whitespace(a) {
-            // skip whitespace for a
+            // Skip whitespace for `a`.
             scan_for_non_ws_or_end(&mut a_iter);
         } else if a == b {
             a_iter.next();
@@ -87,18 +87,18 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
         }
     }
 
-    // check if a has *only* trailing whitespace
+    // Check if a has *only* trailing whitespace.
     a_iter.all(rustc_lexer::is_whitespace)
 }
 
-/// Advances the given peekable `Iterator` until it reaches a non-whitespace character
+/// Advances the given peekable `Iterator` until it reaches a non-whitespace character.
 fn scan_for_non_ws_or_end<I: Iterator<Item = char>>(iter: &mut Peekable<I>) {
     while iter.peek().copied().map(|c| rustc_lexer::is_whitespace(c)) == Some(true) {
         iter.next();
     }
 }
 
-/// Identify a position in the text by the Nth occurrence of a string.
+/// Identifies a position in the text by the n'th occurrence of a string.
 struct Position {
     string: &'static str,
     count: usize,
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 480553586197e..d702038f54ec3 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -6,7 +6,7 @@
 //!
 //! ## Ownership
 //!
-//! `TokenStreams` are persistent data structures constructed as ropes with reference
+//! `TokenStream`s are persistent data structures constructed as ropes with reference
 //! counted-children. In general, this means that calling an operation on a `TokenStream`
 //! (such as `slice`) produces an entirely new `TokenStream` from the borrowed reference to
 //! the original. This essentially coerces `TokenStream`s into 'views' of their subparts,
@@ -147,9 +147,8 @@ impl TokenTree {
     }
 }
 
-/// # Token Streams
-///
 /// A `TokenStream` is an abstract sequence of tokens, organized into `TokenTree`s.
+///
 /// The goal is for procedural macros to work with `TokenStream`s and `TokenTree`s
 /// instead of a representation of the abstract syntax tree.
 /// Today's `TokenTree`s can still contain AST via `token::Interpolated` for back-compat.
@@ -304,7 +303,7 @@ impl TokenStream {
         Cursor::new(self)
     }
 
-    /// Compares two TokenStreams, checking equality without regarding span information.
+    /// Compares two `TokenStream`s, checking equality without regarding span information.
     pub fn eq_unspanned(&self, other: &TokenStream) -> bool {
         let mut t1 = self.trees();
         let mut t2 = other.trees();
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 421c327aa414d..1cff834b7ad5c 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -21,13 +21,13 @@ use syntax_pos::Span;
 
 #[derive(Copy, Clone)]
 pub enum FnKind<'a> {
-    /// fn foo() or extern "Abi" fn foo()
+    /// E.g., `fn foo()` or `extern "Abi" fn foo()`.
     ItemFn(Ident, &'a FnHeader, &'a Visibility, &'a Block),
 
-    /// fn foo(&self)
+    /// E.g., `fn foo(&self)`.
     Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a Block),
 
-    /// |x, y| body
+    /// E.g., `|x, y| body`.
     Closure(&'a Expr),
 }
 
@@ -41,7 +41,7 @@ impl<'a> FnKind<'a> {
     }
 }
 
-/// Each method of the Visitor trait is a hook to be potentially
+/// Each method of the `Visitor` trait is a hook to be potentially
 /// overridden. Each method's default implementation recursively visits
 /// the substructure of the input via the corresponding `walk` method;
 /// e.g., the `visit_mod` method by default calls `visit::walk_mod`.
@@ -302,10 +302,12 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
     walk_list!(visitor, visit_attribute, &item.attrs);
 }
 
-pub fn walk_enum_def<'a, V: Visitor<'a>>(visitor: &mut V,
-                                 enum_definition: &'a EnumDef,
-                                 _: &'a Generics,
-                                 _: NodeId) {
+pub fn walk_enum_def<'a, V: Visitor<'a>>(
+    visitor: &mut V,
+    enum_definition: &'a EnumDef,
+    _: &'a Generics,
+    _: NodeId,
+) {
     walk_list!(visitor, visit_variant, &enum_definition.variants);
 }
 
@@ -342,7 +344,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
             walk_list!(visitor, visit_lifetime, opt_lifetime);
             visitor.visit_ty(&mutable_type.ty)
         }
-        TyKind::Never | TyKind::CVarArgs => {}
+        TyKind::Never => {}
         TyKind::Tup(ref tuple_element_types) => {
             walk_list!(visitor, visit_ty, tuple_element_types);
         }
@@ -371,6 +373,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
         TyKind::Mac(ref mac) => {
             visitor.visit_mac(mac)
         }
+        TyKind::CVarArgs => {}
     }
 }
 
@@ -386,7 +389,7 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(
     visitor.visit_path(&use_tree.prefix, id);
     match use_tree.kind {
         UseTreeKind::Simple(rename, ..) => {
-            // the extra IDs are handled during HIR lowering
+            // The extra IDs are handled during HIR lowering.
             if let Some(rename) = rename {
                 visitor.visit_ident(rename);
             }

From 553a56dd98cee2e42fe8de0e3ad02a41a4a0eb13 Mon Sep 17 00:00:00 2001
From: Alexander Regueiro <alexreg@me.com>
Date: Fri, 6 Sep 2019 22:38:07 +0100
Subject: [PATCH 576/943] Apply suggestions from code review

---
 src/libsyntax/parse/diagnostics.rs |  2 +-
 src/libsyntax/parse/lexer/tests.rs |  2 +-
 src/libsyntax/parse/parser/expr.rs | 10 +++++-----
 src/libsyntax/parse/parser/stmt.rs |  2 +-
 src/libsyntax/source_map.rs        |  4 ++--
 src/libsyntax/source_map/tests.rs  | 13 ++++++-------
 src/libsyntax/visit.rs             |  2 +-
 7 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index 2890a8e721e65..3120d0e35173d 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -1086,7 +1086,7 @@ impl<'a> Parser<'a> {
     /// statement. This is something of a best-effort heuristic.
     ///
     /// We terminate when we find an unmatched `}` (without consuming it).
-    pub fn recover_stmt(&mut self) {
+    crate fn recover_stmt(&mut self) {
         self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore)
     }
 
diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs
index d965bf28ee7df..c1ec41902e2be 100644
--- a/src/libsyntax/parse/lexer/tests.rs
+++ b/src/libsyntax/parse/lexer/tests.rs
@@ -39,7 +39,7 @@ fn t1() {
         let mut string_reader = setup(
             &sm,
             &sh,
-            "/* my source file */ fn main() { println!(\"zebra\"); }\n".to_owned(),
+            "/* my source file */ fn main() { println!(\"zebra\"); }\n".to_string(),
         );
         assert_eq!(string_reader.next_token(), token::Comment);
         assert_eq!(string_reader.next_token(), token::Whitespace);
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index f70c607198fa9..4dbb5ff75eb21 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -843,7 +843,7 @@ impl<'a> Parser<'a> {
                 return self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs);
             }
             token::BinOp(token::Or) | token::OrOr => {
-                return self.parse_closure(attrs);
+                return self.parse_closure_expr(attrs);
             }
             token::OpenDelim(token::Bracket) => {
                 self.bump();
@@ -919,7 +919,7 @@ impl<'a> Parser<'a> {
                     return self.maybe_recover_from_bad_qpath(expr, true);
                 }
                 if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
-                    return self.parse_closure(attrs);
+                    return self.parse_closure_expr(attrs);
                 }
                 if self.eat_keyword(kw::If) {
                     return self.parse_if_expr(attrs);
@@ -996,7 +996,7 @@ impl<'a> Parser<'a> {
                     return if self.is_async_block() { // Check for `async {` and `async move {`.
                         self.parse_async_block(attrs)
                     } else {
-                        self.parse_closure(attrs)
+                        self.parse_closure_expr(attrs)
                     };
                 }
                 if self.eat_keyword(kw::Return) {
@@ -1097,8 +1097,8 @@ impl<'a> Parser<'a> {
         Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs))
     }
 
-    /// Parses a closure (e.g., `move |args| expr`).
-    fn parse_closure(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
+    /// Parses a closure expression (e.g., `move |args| expr`).
+    fn parse_closure_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
 
         let movability = if self.eat_keyword(kw::Static) {
diff --git a/src/libsyntax/parse/parser/stmt.rs b/src/libsyntax/parse/parser/stmt.rs
index 6a3ac2d73f8b2..04bd61a4cfb5b 100644
--- a/src/libsyntax/parse/parser/stmt.rs
+++ b/src/libsyntax/parse/parser/stmt.rs
@@ -422,7 +422,7 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses a statement, including the trailing semicolon.
-    pub fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> {
+    crate fn parse_full_stmt(&mut self, macro_legacy_warnings: bool) -> PResult<'a, Option<Stmt>> {
         // Skip looking for a trailing semicolon when we have an interpolated statement.
         maybe_whole!(self, NtStmt, |x| Some(x));
 
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index 393723b02b2d3..d7ea799e00459 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -479,8 +479,8 @@ impl SourceMap {
     }
 
     pub fn span_to_unmapped_path(&self, sp: Span) -> FileName {
-        let source_file = self.lookup_char_pos(sp.lo()).file;
-        source_file.unmapped_path.clone().unwrap_or(source_file.name.clone())
+        self.lookup_char_pos(sp.lo()).file.unmapped_path.clone()
+            .expect("`SourceMap::span_to_unmapped_path` called for imported `SourceFile`?")
     }
 
     pub fn is_multiline(&self, sp: Span) -> bool {
diff --git a/src/libsyntax/source_map/tests.rs b/src/libsyntax/source_map/tests.rs
index 28fc19093242a..15254336bbfa5 100644
--- a/src/libsyntax/source_map/tests.rs
+++ b/src/libsyntax/source_map/tests.rs
@@ -97,7 +97,7 @@ fn t6() {
 #[test]
 fn t7() {
     let sm = init_source_map();
-    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
+    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
     let file_lines = sm.span_to_lines(span).unwrap();
 
     assert_eq!(file_lines.file.name, PathBuf::from("blork.rs").into());
@@ -113,7 +113,7 @@ fn span_from_selection(input: &str, selection: &str) -> Span {
     assert_eq!(input.len(), selection.len());
     let left_index = selection.find('~').unwrap() as u32;
     let right_index = selection.rfind('~').map(|x|x as u32).unwrap_or(left_index);
-    Span::new(BytePos(left_index), BytePos(right_index + 1), NO_EXPANSION)
+    Span::with_root_ctxt(BytePos(left_index), BytePos(right_index + 1))
 }
 
 /// Tests `span_to_snippet` and `span_to_lines` for a span converting 3
@@ -143,7 +143,7 @@ fn span_to_snippet_and_lines_spanning_multiple_lines() {
 #[test]
 fn t8() {
     let sm = init_source_map();
-    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
+    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
     let snippet = sm.span_to_snippet(span);
 
     assert_eq!(snippet, Ok("second line".to_string()));
@@ -153,7 +153,7 @@ fn t8() {
 #[test]
 fn t9() {
     let sm = init_source_map();
-    let span = Span::new(BytePos(12), BytePos(23), NO_EXPANSION);
+    let span = Span::with_root_ctxt(BytePos(12), BytePos(23));
     let sstr =  sm.span_to_string(span);
 
     assert_eq!(sstr, "blork.rs:2:1: 2:12");
@@ -176,7 +176,7 @@ fn span_merging_fail() {
 /// Returns the span corresponding to the `n`th occurrence of `substring` in `source_text`.
 trait SourceMapExtension {
     fn span_substr(
-        self,
+        &self,
         file: &Lrc<SourceFile>,
         source_text: &str,
         substring: &str,
@@ -208,10 +208,9 @@ impl SourceMapExtension for SourceMap {
             let lo = hi + offset;
             hi = lo + substring.len();
             if i == n {
-                let span = Span::new(
+                let span = Span::with_root_ctxt(
                     BytePos(lo as u32 + file.start_pos.0),
                     BytePos(hi as u32 + file.start_pos.0),
-                    NO_EXPANSION,
                 );
                 assert_eq!(&self.span_to_snippet(span).unwrap()[..], substring);
                 return span;
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 1cff834b7ad5c..d7c537be89668 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -344,7 +344,6 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
             walk_list!(visitor, visit_lifetime, opt_lifetime);
             visitor.visit_ty(&mutable_type.ty)
         }
-        TyKind::Never => {}
         TyKind::Tup(ref tuple_element_types) => {
             walk_list!(visitor, visit_ty, tuple_element_types);
         }
@@ -373,6 +372,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
         TyKind::Mac(ref mac) => {
             visitor.visit_mac(mac)
         }
+        TyKind::Never |
         TyKind::CVarArgs => {}
     }
 }

From 2bcabf67378cc4bceb3d66c72f88c95fc97cb4a1 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Mon, 2 Sep 2019 22:10:10 -0500
Subject: [PATCH 577/943] compiletest: Match suffixed environments

This fixes a case where an `ignore-musl` test was not ignored on
`armv7-unknown-linux-musleabihf` because the environment did not exactly
match. Only enforce that the environment starts with the argument to
`ignore-`.
---
 src/tools/compiletest/src/header.rs | 2 +-
 src/tools/compiletest/src/util.rs   | 8 ++++++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 3ba8cffe2b559..819d399f34a41 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -835,10 +835,10 @@ impl Config {
 
             if name == "test" ||
                 util::matches_os(&self.target, name) ||             // target
+                util::matches_env(&self.target, name) ||            // env
                 name == util::get_arch(&self.target) ||             // architecture
                 name == util::get_pointer_width(&self.target) ||    // pointer width
                 name == self.stage_id.split('-').next().unwrap() || // stage
-                Some(name) == util::get_env(&self.target) ||        // env
                 (self.target != self.host && name == "cross-compile") ||
                 match self.compare_mode {
                     Some(CompareMode::Nll) => name == "compare-mode-nll",
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 56ebea7c20f36..3a2ee445087d5 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -105,8 +105,12 @@ pub fn get_arch(triple: &str) -> &'static str {
     panic!("Cannot determine Architecture from triple");
 }
 
-pub fn get_env(triple: &str) -> Option<&str> {
-    triple.split('-').nth(3)
+pub fn matches_env(triple: &str, name: &str) -> bool {
+    if let Some(env) = triple.split('-').nth(3) {
+        env.starts_with(name)
+    } else {
+        false
+    }
 }
 
 pub fn get_pointer_width(triple: &str) -> &'static str {

From 0f0e1c1691422132a40e5f534ff579004a79ef9c Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Sat, 7 Sep 2019 17:04:19 +0100
Subject: [PATCH 578/943] Move `libcore/bool/mod.rs` to `libcore/bool.rs`

---
 src/libcore/{bool/mod.rs => bool.rs} | 2 --
 src/libcore/lib.rs                   | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)
 rename src/libcore/{bool/mod.rs => bool.rs} (95%)

diff --git a/src/libcore/bool/mod.rs b/src/libcore/bool.rs
similarity index 95%
rename from src/libcore/bool/mod.rs
rename to src/libcore/bool.rs
index 0fbd3b8c2bbce..54faa7047d5b8 100644
--- a/src/libcore/bool/mod.rs
+++ b/src/libcore/bool.rs
@@ -1,7 +1,5 @@
 //! impl bool {}
 
-#![stable(feature = "core_bool", since = "1.39.0")]
-
 #[cfg(not(boostrap_stdarch_ignore_this))]
 #[lang = "bool"]
 impl bool {
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 03b6aa68d3c27..690cff483b07c 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -198,7 +198,6 @@ pub mod borrow;
 pub mod any;
 pub mod array;
 pub mod ascii;
-pub mod bool;
 pub mod sync;
 pub mod cell;
 pub mod char;
@@ -228,6 +227,7 @@ pub mod task;
 pub mod alloc;
 
 // note: does not need to be public
+mod bool;
 mod tuple;
 mod unit;
 

From 6dc763eed59295d0907a2780d66d4adf6f41a644 Mon Sep 17 00:00:00 2001
From: Aleksi Juvani <aleksi@aleksijuvani.com>
Date: Sat, 7 Sep 2019 19:04:59 +0300
Subject: [PATCH 579/943] Fix nits

---
 src/librustc_target/spec/apple_base.rs | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs
index aa5080aaaf6e6..297e64d4aebaa 100644
--- a/src/librustc_target/spec/apple_base.rs
+++ b/src/librustc_target/spec/apple_base.rs
@@ -54,24 +54,24 @@ pub fn macos_llvm_target(arch: &str) -> String {
 
 pub fn sysroot(sdk: &str) -> Result<String, String> {
     let actual_sdk_path = sdk_path(sdk)?;
-    // Like Clang, allow the SDKROOT environment variable used by Xcode to define the sysroot
+    // Like Clang, allow the `SDKROOT` environment variable used by Xcode to define the sysroot.
     if let Some(sdk_root) = env::var("SDKROOT").ok() {
         let sdk_root_p = Path::new(&sdk_root);
-        // Ignore SDKROOT if it's not a valid path
+        // Ignore `SDKROOT` if it's not a valid path.
         if !sdk_root_p.is_absolute() || sdk_root_p == Path::new("/") || !sdk_root_p.exists() {
             return Ok(actual_sdk_path);
         }
-        // Ignore SDKROOT if it's clearly set for the wrong platform, which may occur when we're
-        // compiling a custom build script while targeting iOS for example
-        match sdk {
+        // Ignore `SDKROOT` if it's clearly set for the wrong platform, which may occur when we're
+        // compiling a custom build script while targeting iOS for example.
+        return Ok(match sdk {
             "iphoneos" if sdk_root.contains("iPhoneSimulator.platform")
-                || sdk_root.contains("MacOSX.platform") => return Ok(actual_sdk_path),
+                || sdk_root.contains("MacOSX.platform") => actual_sdk_path,
             "iphonesimulator" if sdk_root.contains("iPhoneOS.platform")
-                || sdk_root.contains("MacOSX.platform") => return Ok(actual_sdk_path),
+                || sdk_root.contains("MacOSX.platform") => actual_sdk_path,
             "macosx" | "macosx10.15" if sdk_root.contains("iPhoneOS.platform")
-                || sdk_root.contains("iPhoneSimulator.platform") => return Ok(actual_sdk_path),
-            _ => return Ok(sdk_root),
-        }
+                || sdk_root.contains("iPhoneSimulator.platform") => actual_sdk_path,
+            _ => sdk_root,
+        })
     }
     Ok(actual_sdk_path)
 }

From 7b3f72906ffea5a8aec9e3d109d8e012f771a672 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Sat, 7 Sep 2019 17:06:39 +0100
Subject: [PATCH 580/943] Add tracking issue

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

diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs
index 54faa7047d5b8..32ec26975e375 100644
--- a/src/libcore/bool.rs
+++ b/src/libcore/bool.rs
@@ -13,7 +13,7 @@ impl bool {
     /// assert_eq!(false.then(0), None);
     /// assert_eq!(true.then(0), Some(0));
     /// ```
-    #[unstable(feature = "bool_to_option", issue = "0")]
+    #[unstable(feature = "bool_to_option", issue = "64260")]
     #[inline]
     pub fn then<T>(self, t: T) -> Option<T> {
         if self {
@@ -33,7 +33,7 @@ impl bool {
     /// assert_eq!(false.then_with(|| 0), None);
     /// assert_eq!(true.then_with(|| 0), Some(0));
     /// ```
-    #[unstable(feature = "bool_to_option", issue = "0")]
+    #[unstable(feature = "bool_to_option", issue = "64260")]
     #[inline]
     pub fn then_with<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
         if self {

From 7dc3839b50d1ddb623aef0fbe76e982af460a18a Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sat, 7 Sep 2019 19:34:25 +0300
Subject: [PATCH 581/943] resolve: Mark more erroneous imports as used

---
 src/librustc_resolve/resolve_imports.rs       |  8 ++++++
 .../ui/imports/unresolved-imports-used.rs     | 14 +++++++---
 .../ui/imports/unresolved-imports-used.stderr | 26 ++++++++++++++-----
 3 files changed, 37 insertions(+), 11 deletions(-)

diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index ca189e71800b3..132690dcd7df2 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -673,6 +673,10 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             self.throw_unresolved_import_error(errors.clone(), None);
         }
 
+        for import in &self.r.indeterminate_imports {
+            // Consider erroneous imports used to avoid duplicate diagnostics.
+            self.r.used_imports.insert((import.id, TypeNS));
+        }
         // Report unresolved imports only if no hard error was already reported
         // to avoid generating multiple errors on the same import.
         if !has_errors {
@@ -839,6 +843,10 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                                          true, directive.span, directive.crate_lint());
         let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
         directive.vis.set(orig_vis);
+        if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res {
+            // Consider erroneous imports used to avoid duplicate diagnostics.
+            self.r.used_imports.insert((directive.id, TypeNS));
+        }
         let module = match path_res {
             PathResult::Module(module) => {
                 // Consistency checks, analogous to `finalize_macro_resolutions`.
diff --git a/src/test/ui/imports/unresolved-imports-used.rs b/src/test/ui/imports/unresolved-imports-used.rs
index d1461e7b041c5..5398dd63c8929 100644
--- a/src/test/ui/imports/unresolved-imports-used.rs
+++ b/src/test/ui/imports/unresolved-imports-used.rs
@@ -1,12 +1,18 @@
-// There should be *no* unused import errors.
+// There should be *one* unused import error.
 #![deny(unused_imports)]
 
 mod qux {
    fn quz() {}
+   pub fn quy() {}
 }
 
-use qux::quz; //~ ERROR function `quz` is private
-use qux::bar; //~ ERROR unresolved import `qux::bar`
-use foo::bar; //~ ERROR unresolved import `foo`
+use qux::quz;  //~ ERROR function `quz` is private
+use qux::bar;  //~ ERROR unresolved import `qux::bar`
+use foo::bar;
+use baz::*;
+use qux::bar2; //~ ERROR unresolved import `qux::bar2`
+use foo2::bar2;
+use baz2::*;
+use qux::quy;  //~ ERROR unused import
 
 fn main() {}
diff --git a/src/test/ui/imports/unresolved-imports-used.stderr b/src/test/ui/imports/unresolved-imports-used.stderr
index e8c827a6179bb..c9342d17a49d7 100644
--- a/src/test/ui/imports/unresolved-imports-used.stderr
+++ b/src/test/ui/imports/unresolved-imports-used.stderr
@@ -1,22 +1,34 @@
 error[E0432]: unresolved import `qux::bar`
-  --> $DIR/unresolved-imports-used.rs:9:5
+  --> $DIR/unresolved-imports-used.rs:10:5
    |
 LL | use qux::bar;
    |     ^^^^^^^^ no `bar` in `qux`
 
-error[E0432]: unresolved import `foo`
-  --> $DIR/unresolved-imports-used.rs:10:5
+error[E0432]: unresolved import `qux::bar2`
+  --> $DIR/unresolved-imports-used.rs:13:5
    |
-LL | use foo::bar;
-   |     ^^^ maybe a missing crate `foo`?
+LL | use qux::bar2;
+   |     ^^^^^^^^^ no `bar2` in `qux`
 
 error[E0603]: function `quz` is private
-  --> $DIR/unresolved-imports-used.rs:8:10
+  --> $DIR/unresolved-imports-used.rs:9:10
    |
 LL | use qux::quz;
    |          ^^^
 
-error: aborting due to 3 previous errors
+error: unused import: `qux::quy`
+  --> $DIR/unresolved-imports-used.rs:16:5
+   |
+LL | use qux::quy;
+   |     ^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/unresolved-imports-used.rs:2:9
+   |
+LL | #![deny(unused_imports)]
+   |         ^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0432, E0603.
 For more information about an error, try `rustc --explain E0432`.

From f7434aef26bc413469fc0dfeadecabf75e18bd38 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sun, 1 Sep 2019 14:54:57 +0300
Subject: [PATCH 582/943] Support "soft" feature-gating using a lint

Use it for feature-gating `#[bench]`
---
 src/libcore/macros.rs                  |  6 ++++--
 src/librustc/ich/impls_syntax.rs       |  3 ++-
 src/librustc/lint/builtin.rs           |  7 +++++++
 src/librustc/middle/stability.rs       | 22 ++++++++++++++------
 src/librustc_resolve/macros.rs         |  4 ++--
 src/libsyntax/attr/builtin.rs          | 28 +++++++++++---------------
 src/libsyntax_pos/symbol.rs            |  1 +
 src/test/ui/feature-gates/bench.rs     |  4 ++++
 src/test/ui/feature-gates/bench.stderr | 10 +++++++++
 9 files changed, 58 insertions(+), 27 deletions(-)
 create mode 100644 src/test/ui/feature-gates/bench.rs
 create mode 100644 src/test/ui/feature-gates/bench.stderr

diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index ffaca029a8a78..384bc87499887 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -1236,8 +1236,10 @@ pub(crate) mod builtin {
     pub macro test($item:item) { /* compiler built-in */ }
 
     /// Attribute macro applied to a function to turn it into a benchmark test.
-    #[unstable(feature = "test", issue = "50297",
-               reason = "`bench` is a part of custom test frameworks which are unstable")]
+    #[cfg_attr(not(boostrap_stdarch_ignore_this), unstable(soft, feature = "test", issue = "50297",
+               reason = "`bench` is a part of custom test frameworks which are unstable"))]
+    #[cfg_attr(boostrap_stdarch_ignore_this, unstable(feature = "test", issue = "50297",
+               reason = "`bench` is a part of custom test frameworks which are unstable"))]
     #[allow_internal_unstable(test, rustc_attrs)]
     #[rustc_builtin_macro]
     pub macro bench($item:item) { /* compiler built-in */ }
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 646060bc8be77..a33181e5925cd 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -115,9 +115,10 @@ for ::syntax::attr::StabilityLevel {
                                           hasher: &mut StableHasher<W>) {
         mem::discriminant(self).hash_stable(hcx, hasher);
         match *self {
-            ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => {
+            ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue, ref is_soft } => {
                 reason.hash_stable(hcx, hasher);
                 issue.hash_stable(hcx, hasher);
+                is_soft.hash_stable(hcx, hasher);
             }
             ::syntax::attr::StabilityLevel::Stable { ref since } => {
                 since.hash_stable(hcx, hasher);
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 6d9a6bb77dd55..dd290572d7bb7 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -395,6 +395,12 @@ declare_lint! {
     "reservation of a two-phased borrow conflicts with other shared borrows"
 }
 
+declare_lint! {
+    pub SOFT_UNSTABLE,
+    Deny,
+    "a feature gate that doesn't break dependent crates"
+}
+
 declare_lint_pass! {
     /// Does nothing as a lint pass, but registers some `Lint`s
     /// that are used by other parts of the compiler.
@@ -460,6 +466,7 @@ declare_lint_pass! {
         NESTED_IMPL_TRAIT,
         MUTABLE_BORROW_RESERVATION_CONFLICT,
         INDIRECT_STRUCTURAL_MATCH,
+        SOFT_UNSTABLE,
     ]
 }
 
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index d02259bf3010b..c06a0feb6a993 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -438,6 +438,7 @@ impl<'tcx> Index<'tcx> {
                     level: attr::StabilityLevel::Unstable {
                         reason: Some(Symbol::intern(reason)),
                         issue: 27812,
+                        is_soft: false,
                     },
                     feature: sym::rustc_private,
                     rustc_depr: None,
@@ -480,7 +481,7 @@ pub fn provide(providers: &mut Providers<'_>) {
 }
 
 pub fn report_unstable(
-    sess: &Session, feature: Symbol, reason: Option<Symbol>, issue: u32, span: Span
+    sess: &Session, feature: Symbol, reason: Option<Symbol>, issue: u32, is_soft: bool, span: Span
 ) {
     let msg = match reason {
         Some(r) => format!("use of unstable library feature '{}': {}", feature, r),
@@ -505,7 +506,13 @@ pub fn report_unstable(
     let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
     let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id);
     if fresh {
-        emit_feature_err(&sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg);
+        if is_soft {
+            sess.buffer_lint(lint::builtin::SOFT_UNSTABLE, CRATE_NODE_ID, span, &msg);
+        } else {
+            emit_feature_err(
+                &sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg
+            );
+        }
     }
 }
 
@@ -621,6 +628,7 @@ pub enum EvalResult {
         feature: Symbol,
         reason: Option<Symbol>,
         issue: u32,
+        is_soft: bool,
     },
     /// The item does not have the `#[stable]` or `#[unstable]` marker assigned.
     Unmarked,
@@ -720,7 +728,9 @@ impl<'tcx> TyCtxt<'tcx> {
         }
 
         match stability {
-            Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => {
+            Some(&Stability {
+                level: attr::Unstable { reason, issue, is_soft }, feature, ..
+            }) => {
                 if span.allows_unstable(feature) {
                     debug!("stability: skipping span={:?} since it is internal", span);
                     return EvalResult::Allow;
@@ -744,7 +754,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     }
                 }
 
-                EvalResult::Deny { feature, reason, issue }
+                EvalResult::Deny { feature, reason, issue, is_soft }
             }
             Some(_) => {
                 // Stable APIs are always ok to call and deprecated APIs are
@@ -767,8 +777,8 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
         match self.eval_stability(def_id, id, span) {
             EvalResult::Allow => {}
-            EvalResult::Deny { feature, reason, issue } =>
-                report_unstable(self.sess, feature, reason, issue, span),
+            EvalResult::Deny { feature, reason, issue, is_soft } =>
+                report_unstable(self.sess, feature, reason, issue, is_soft, span),
             EvalResult::Unmarked => {
                 // The API could be uncallable for other reasons, for example when a private module
                 // was referenced.
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 054b17fec7849..87439440463b3 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -774,10 +774,10 @@ impl<'a> Resolver<'a> {
     fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, path: &ast::Path) {
         let span = path.span;
         if let Some(stability) = &ext.stability {
-            if let StabilityLevel::Unstable { reason, issue } = stability.level {
+            if let StabilityLevel::Unstable { reason, issue, is_soft } = stability.level {
                 let feature = stability.feature;
                 if !self.active_features.contains(&feature) && !span.allows_unstable(feature) {
-                    stability::report_unstable(self.session, feature, reason, issue, span);
+                    stability::report_unstable(self.session, feature, reason, issue, is_soft, span);
                 }
             }
             if let Some(depr) = &stability.rustc_depr {
diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs
index 5fb513783fbaa..b5037b75f79e7 100644
--- a/src/libsyntax/attr/builtin.rs
+++ b/src/libsyntax/attr/builtin.rs
@@ -154,23 +154,10 @@ pub struct Stability {
 #[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
 pub enum StabilityLevel {
     // Reason for the current stability level and the relevant rust-lang issue
-    Unstable { reason: Option<Symbol>, issue: u32 },
+    Unstable { reason: Option<Symbol>, issue: u32, is_soft: bool },
     Stable { since: Symbol },
 }
 
-impl Stability {
-    pub fn unstable(feature: Symbol, reason: Option<Symbol>, issue: u32) -> Stability {
-        Stability {
-            level: StabilityLevel::Unstable { reason, issue },
-            feature,
-            rustc_depr: None,
-            const_stability: None,
-            promotable: false,
-            allow_const_fn_ptr: false,
-        }
-    }
-}
-
 impl StabilityLevel {
     pub fn is_unstable(&self) -> bool {
         if let StabilityLevel::Unstable {..} = *self {
@@ -356,19 +343,27 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
                     let mut feature = None;
                     let mut reason = None;
                     let mut issue = None;
+                    let mut is_soft = false;
                     for meta in metas {
                         if let Some(mi) = meta.meta_item() {
                             match mi.name_or_empty() {
                                 sym::feature => if !get(mi, &mut feature) { continue 'outer },
                                 sym::reason => if !get(mi, &mut reason) { continue 'outer },
                                 sym::issue => if !get(mi, &mut issue) { continue 'outer },
+                                sym::soft => {
+                                    if !mi.is_word() {
+                                        let msg = "`soft` should not have any arguments";
+                                        sess.span_diagnostic.span_err(mi.span, msg);
+                                    }
+                                    is_soft = true;
+                                }
                                 _ => {
                                     handle_errors(
                                         sess,
                                         meta.span(),
                                         AttrError::UnknownMetaItem(
                                             mi.path.to_string(),
-                                            &["feature", "reason", "issue"]
+                                            &["feature", "reason", "issue", "soft"]
                                         ),
                                     );
                                     continue 'outer
@@ -400,7 +395,8 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
                                                       "incorrect 'issue'");
                                             continue
                                         }
-                                    }
+                                    },
+                                    is_soft,
                                 },
                                 feature,
                                 rustc_depr: None,
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index ecc31cfeb3d1f..ab32d4461ef87 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -626,6 +626,7 @@ symbols! {
         size,
         slice_patterns,
         slicing_syntax,
+        soft,
         Some,
         specialization,
         speed,
diff --git a/src/test/ui/feature-gates/bench.rs b/src/test/ui/feature-gates/bench.rs
new file mode 100644
index 0000000000000..d8a09625e9639
--- /dev/null
+++ b/src/test/ui/feature-gates/bench.rs
@@ -0,0 +1,4 @@
+#[bench] //~ ERROR use of unstable library feature 'test'
+fn bench() {}
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/bench.stderr b/src/test/ui/feature-gates/bench.stderr
new file mode 100644
index 0000000000000..25ddcc5e36169
--- /dev/null
+++ b/src/test/ui/feature-gates/bench.stderr
@@ -0,0 +1,10 @@
+error: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
+  --> $DIR/bench.rs:1:3
+   |
+LL | #[bench]
+   |   ^^^^^
+   |
+   = note: `#[deny(soft_unstable)]` on by default
+
+error: aborting due to previous error
+

From fb387088e2e327e4060290edc92a90d49669b04c Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Sat, 7 Sep 2019 12:21:32 -0700
Subject: [PATCH 583/943] rustdoc: fix diagnostic with mixed code block styles

---
 src/librustdoc/html/markdown.rs           |  5 ++++-
 src/test/rustdoc-ui/invalid-syntax.rs     |  8 ++++++++
 src/test/rustdoc-ui/invalid-syntax.stderr | 18 ++++++++++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 74413a7f905d4..8bf01d2cc1aac 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -931,7 +931,10 @@ crate fn rust_code_blocks(md: &str) -> Vec<RustCodeBlock> {
                             is_fenced = true;
                             previous_offset + fence_idx
                         }
-                        None => offset,
+                        None => {
+                            is_fenced = false;
+                            offset
+                        }
                     };
                 }
             }
diff --git a/src/test/rustdoc-ui/invalid-syntax.rs b/src/test/rustdoc-ui/invalid-syntax.rs
index 3ef66e273d0d0..97a0f4aaec1eb 100644
--- a/src/test/rustdoc-ui/invalid-syntax.rs
+++ b/src/test/rustdoc-ui/invalid-syntax.rs
@@ -74,3 +74,11 @@ pub fn empty_rust() {}
 ///
 /// ```
 pub fn empty_rust_with_whitespace() {}
+
+/// ```
+/// let x = 1;
+/// ```
+///
+///     \____/
+///
+pub fn indent_after_fenced() {}
diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr
index 36209e2927771..6f50edae65034 100644
--- a/src/test/rustdoc-ui/invalid-syntax.stderr
+++ b/src/test/rustdoc-ui/invalid-syntax.stderr
@@ -201,6 +201,24 @@ help: mark blocks that do not contain Rust code as text
 LL | /// ```text
    |     ^^^^^^^
 
+error: unknown start of token: \
+ --> <doctest>:1:1
+  |
+1 | \____/
+  | ^
+
+warning: could not parse code block as Rust code
+  --> $DIR/invalid-syntax.rs:82:9
+   |
+LL | ///     \____/
+   |         ^^^^^^
+
+error: unknown start of token: \
+ --> <rustdoc-highlighting>:1:1
+  |
+1 | \____/
+  | ^
+
 error: unknown start of token: \
  --> <rustdoc-highlighting>:1:1
   |

From 74d8679eff1819a8b7aae6f38ca521dc893b448d Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sat, 7 Sep 2019 22:23:53 +0300
Subject: [PATCH 584/943] Turn `soft_unstable` into a future-compatibility lint

---
 src/librustc_lint/lib.rs               | 7 ++++++-
 src/test/ui/feature-gates/bench.rs     | 1 +
 src/test/ui/feature-gates/bench.stderr | 2 ++
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 27833161ef23d..2c0ef2989c7a6 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -436,7 +436,12 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
             id: LintId::of(INDIRECT_STRUCTURAL_MATCH),
             reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
             edition: None,
-        }
+        },
+        FutureIncompatibleInfo {
+            id: LintId::of(SOFT_UNSTABLE),
+            reference: "issue #64266 <https://github.com/rust-lang/rust/issues/64266>",
+            edition: None,
+        },
         ]);
 
     // Register renamed and removed lints.
diff --git a/src/test/ui/feature-gates/bench.rs b/src/test/ui/feature-gates/bench.rs
index d8a09625e9639..afe4dc7d54c9b 100644
--- a/src/test/ui/feature-gates/bench.rs
+++ b/src/test/ui/feature-gates/bench.rs
@@ -1,4 +1,5 @@
 #[bench] //~ ERROR use of unstable library feature 'test'
+         //~| WARN this was previously accepted
 fn bench() {}
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/bench.stderr b/src/test/ui/feature-gates/bench.stderr
index 25ddcc5e36169..b9e24e931d42b 100644
--- a/src/test/ui/feature-gates/bench.stderr
+++ b/src/test/ui/feature-gates/bench.stderr
@@ -5,6 +5,8 @@ LL | #[bench]
    |   ^^^^^
    |
    = note: `#[deny(soft_unstable)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
 
 error: aborting due to previous error
 

From d42e60331fb08efce78e7fc9739bf42620e51f8f Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sun, 1 Sep 2019 14:10:50 +0300
Subject: [PATCH 585/943] Improve hygiene of `alloc::format!`

---
 src/liballoc/lib.rs    | 6 ++++++
 src/liballoc/macros.rs | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 4a48945adc37a..370e5cf4b303f 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -171,3 +171,9 @@ pub mod vec;
 mod std {
     pub use core::ops; // RangeFull
 }
+
+#[doc(hidden)]
+#[unstable(feature = "liballoc_internals", issue = "0", reason = "implementation detail")]
+pub mod __export {
+    pub use core::format_args;
+}
diff --git a/src/liballoc/macros.rs b/src/liballoc/macros.rs
index 0b5e186d4c77b..2f2cdc39c633d 100644
--- a/src/liballoc/macros.rs
+++ b/src/liballoc/macros.rs
@@ -98,5 +98,5 @@ macro_rules! vec {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! format {
-    ($($arg:tt)*) => ($crate::fmt::format(::core::format_args!($($arg)*)))
+    ($($arg:tt)*) => ($crate::fmt::format($crate::__export::format_args!($($arg)*)))
 }

From 961a4da08e7ec1ed15cce6170566332646bd65cb Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 29 Jul 2019 23:29:14 +0200
Subject: [PATCH 586/943] Stabilize bind_by_move_pattern_guards in 1.39.0.

---
 src/librustc_mir/hair/pattern/check_match.rs | 90 +-------------------
 src/libsyntax/feature_gate/accepted.rs       |  2 +
 src/libsyntax/feature_gate/active.rs         |  3 -
 3 files changed, 6 insertions(+), 89 deletions(-)

diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 5352888006c30..1b4b56082a696 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -5,11 +5,6 @@ use super::_match::WitnessPreference::*;
 use super::{Pattern, PatternContext, PatternError, PatternKind};
 
 use rustc::middle::borrowck::SignalledError;
-use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor};
-use rustc::middle::expr_use_visitor::{LoanCause, MutateMode};
-use rustc::middle::expr_use_visitor as euv;
-use rustc::middle::mem_categorization::cmt_;
-use rustc::middle::region;
 use rustc::session::Session;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::subst::{InternalSubsts, SubstsRef};
@@ -36,9 +31,7 @@ crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) -> SignalledError {
 
     let mut visitor = MatchVisitor {
         tcx,
-        body_owner: def_id,
         tables: tcx.body_tables(body_id),
-        region_scope_tree: &tcx.region_scope_tree(def_id),
         param_env: tcx.param_env(def_id),
         identity_substs: InternalSubsts::identity_for_item(tcx, def_id),
         signalled_error: SignalledError::NoErrorsSeen,
@@ -53,11 +46,9 @@ fn create_e0004(sess: &Session, sp: Span, error_message: String) -> DiagnosticBu
 
 struct MatchVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
-    body_owner: DefId,
     tables: &'a ty::TypeckTables<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     identity_substs: SubstsRef<'tcx>,
-    region_scope_tree: &'a region::ScopeTree,
     signalled_error: SignalledError,
 }
 
@@ -151,11 +142,8 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
 
             // Second, if there is a guard on each arm, make sure it isn't
             // assigning or borrowing anything mutably.
-            if let Some(ref guard) = arm.guard {
+            if arm.guard.is_some() {
                 self.signalled_error = SignalledError::SawSomeError;
-                if !self.tcx.features().bind_by_move_pattern_guards {
-                    check_for_mutation_in_guard(self, &guard);
-                }
             }
 
             // Third, perform some lints.
@@ -582,19 +570,10 @@ fn check_legality_of_move_bindings(
                              "cannot bind by-move with sub-bindings")
                 .span_label(p.span, "binds an already bound by-move value by moving it")
                 .emit();
-        } else if has_guard {
-            if !cx.tcx.features().bind_by_move_pattern_guards {
-                let mut err = struct_span_err!(cx.tcx.sess, p.span, E0008,
-                                            "cannot bind by-move into a pattern guard");
-                err.span_label(p.span, "moves value into pattern guard");
-                if cx.tcx.sess.opts.unstable_features.is_nightly_build() {
-                    err.help("add `#![feature(bind_by_move_pattern_guards)]` to the \
-                            crate attributes to enable");
-                }
-                err.emit();
+        } else if !has_guard {
+            if let Some(_by_ref_span) = by_ref_span {
+                span_vec.push(p.span);
             }
-        } else if let Some(_by_ref_span) = by_ref_span {
-            span_vec.push(p.span);
         }
     };
 
@@ -636,67 +615,6 @@ fn check_legality_of_move_bindings(
     }
 }
 
-/// Ensures that a pattern guard doesn't borrow by mutable reference or assign.
-//
-// FIXME: this should be done by borrowck.
-fn check_for_mutation_in_guard(cx: &MatchVisitor<'_, '_>, guard: &hir::Guard) {
-    let mut checker = MutationChecker {
-        cx,
-    };
-    match guard {
-        hir::Guard::If(expr) =>
-            ExprUseVisitor::new(&mut checker,
-                                cx.tcx,
-                                cx.body_owner,
-                                cx.param_env,
-                                cx.region_scope_tree,
-                                cx.tables,
-                                None).walk_expr(expr),
-    };
-}
-
-struct MutationChecker<'a, 'tcx> {
-    cx: &'a MatchVisitor<'a, 'tcx>,
-}
-
-impl<'a, 'tcx> Delegate<'tcx> for MutationChecker<'a, 'tcx> {
-    fn matched_pat(&mut self, _: &Pat, _: &cmt_<'_>, _: euv::MatchMode) {}
-    fn consume(&mut self, _: hir::HirId, _: Span, _: &cmt_<'_>, _: ConsumeMode) {}
-    fn consume_pat(&mut self, _: &Pat, _: &cmt_<'_>, _: ConsumeMode) {}
-    fn borrow(&mut self,
-              _: hir::HirId,
-              span: Span,
-              _: &cmt_<'_>,
-              _: ty::Region<'tcx>,
-              kind:ty:: BorrowKind,
-              _: LoanCause) {
-        match kind {
-            ty::MutBorrow => {
-                let mut err = struct_span_err!(self.cx.tcx.sess, span, E0301,
-                          "cannot mutably borrow in a pattern guard");
-                err.span_label(span, "borrowed mutably in pattern guard");
-                if self.cx.tcx.sess.opts.unstable_features.is_nightly_build() {
-                    err.help("add `#![feature(bind_by_move_pattern_guards)]` to the \
-                              crate attributes to enable");
-                }
-                err.emit();
-            }
-            ty::ImmBorrow | ty::UniqueImmBorrow => {}
-        }
-    }
-    fn decl_without_init(&mut self, _: hir::HirId, _: Span) {}
-    fn mutate(&mut self, _: hir::HirId, span: Span, _: &cmt_<'_>, mode: MutateMode) {
-        match mode {
-            MutateMode::JustWrite | MutateMode::WriteAndRead => {
-                struct_span_err!(self.cx.tcx.sess, span, E0302, "cannot assign in a pattern guard")
-                    .span_label(span, "assignment in pattern guard")
-                    .emit();
-            }
-            MutateMode::Init => {}
-        }
-    }
-}
-
 /// Forbids bindings in `@` patterns. This is necessary for memory safety,
 /// because of the way rvalues are handled in the borrow check. (See issue
 /// #14587.)
diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs
index 6c0b271c6c5e9..eff9f90a8619e 100644
--- a/src/libsyntax/feature_gate/accepted.rs
+++ b/src/libsyntax/feature_gate/accepted.rs
@@ -241,6 +241,8 @@ declare_features! (
     (accepted, underscore_const_names, "1.37.0", Some(54912), None),
     /// Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions.
     (accepted, async_await, "1.39.0", Some(50547), None),
+    /// Allows mixing bind-by-move in patterns and references to those identifiers in guards.
+    (accepted, bind_by_move_pattern_guards, "1.39.0", Some(15287), None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index 5a248df6af252..dd78777b56986 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -461,9 +461,6 @@ declare_features! (
     /// Allows non-builtin attributes in inner attribute position.
     (active, custom_inner_attributes, "1.30.0", Some(54726), None),
 
-    /// Allows mixing bind-by-move in patterns and references to those identifiers in guards.
-    (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None),
-
     /// Allows `impl Trait` in bindings (`let`, `const`, `static`).
     (active, impl_trait_in_bindings, "1.30.0", Some(63065), None),
 

From 2a21c0f6d10ad843c12f23140cab797aeab0b675 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 29 Jul 2019 23:35:43 +0200
Subject: [PATCH 587/943] Update bind_and_guard_matched_candidate docs.

---
 src/librustc_mir/build/matches/mod.rs | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 94323b15b696f..f949b529e9762 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -1345,13 +1345,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// any, and then branches to the arm. Returns the block for the case where
     /// the guard fails.
     ///
-    /// Note: we check earlier that if there is a guard, there cannot be move
-    /// bindings (unless feature(bind_by_move_pattern_guards) is used). This
-    /// isn't really important for the self-consistency of this fn, but the
-    /// reason for it should be clear: after we've done the assignments, if
-    /// there were move bindings, further tests would be a use-after-move.
-    /// bind_by_move_pattern_guards avoids this by only moving the binding once
-    /// the guard has evaluated to true (see below).
+    /// Note: we do not check earlier that if there is a guard,
+    /// there cannot be move bindings. We avoid a use-after-move by only
+    /// moving the binding once the guard has evaluated to true (see below).
     fn bind_and_guard_matched_candidate<'pat>(
         &mut self,
         candidate: Candidate<'pat, 'tcx>,

From 0356813b27262bf9ceec5f0fa48302262d501cd4 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 29 Jul 2019 23:36:58 +0200
Subject: [PATCH 588/943] Dont use gate bind_by_move_pattern_guards internally.

---
 src/libcore/lib.rs         | 2 +-
 src/librustc_passes/lib.rs | 2 +-
 src/librustdoc/lib.rs      | 2 +-
 src/libstd/lib.rs          | 2 +-
 src/libsyntax/lib.rs       | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index c168d5c8a2eac..0b4b6322534f2 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -87,7 +87,7 @@
 #![feature(link_llvm_intrinsics)]
 #![feature(never_type)]
 #![feature(nll)]
-#![feature(bind_by_move_pattern_guards)]
+#![cfg_attr(bootstrap, feature(bind_by_move_pattern_guards))]
 #![feature(exhaustive_patterns)]
 #![feature(no_core)]
 #![feature(on_unimplemented)]
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index cf2da4ffa2af0..a5a8315a1e73f 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -8,7 +8,7 @@
 
 #![feature(in_band_lifetimes)]
 #![feature(nll)]
-#![feature(bind_by_move_pattern_guards)]
+#![cfg_attr(bootstrap, feature(bind_by_move_pattern_guards))]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 301946733dc55..25ee8b4273d52 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -1,7 +1,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/",
        html_playground_url = "https://play.rust-lang.org/")]
 
-#![feature(bind_by_move_pattern_guards)]
+#![cfg_attr(bootstrap, feature(bind_by_move_pattern_guards))]
 #![feature(rustc_private)]
 #![feature(arbitrary_self_types)]
 #![feature(box_patterns)]
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 71050b0dcd1f5..8a7b66f019669 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -238,7 +238,7 @@
 #![feature(array_error_internals)]
 #![feature(asm)]
 #![feature(associated_type_bounds)]
-#![feature(bind_by_move_pattern_guards)]
+#![cfg_attr(bootstrap, feature(bind_by_move_pattern_guards))]
 #![feature(box_syntax)]
 #![feature(c_variadic)]
 #![feature(cfg_target_has_atomic)]
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 49efbce482fa3..aaf6f3e537eb6 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -7,7 +7,7 @@
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/",
        test(attr(deny(warnings))))]
 
-#![feature(bind_by_move_pattern_guards)]
+#![cfg_attr(bootstrap, feature(bind_by_move_pattern_guards))]
 #![feature(box_syntax)]
 #![feature(const_fn)]
 #![feature(const_transmute)]

From 072942d569b898ef65569a21bd1b73d15cc1caf6 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sun, 1 Sep 2019 17:05:02 -0400
Subject: [PATCH 589/943] run-pass tests shouldn't have unused contents

---
 src/tools/compiletest/src/header.rs  | 5 +++++
 src/tools/compiletest/src/runtest.rs | 6 +++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 819d399f34a41..48dd68d0f61ee 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -628,6 +628,11 @@ impl TestProps {
         }
         self.pass_mode
     }
+
+    // does not consider CLI override for pass mode
+    pub fn local_pass_mode(&self) -> Option<PassMode> {
+        self.pass_mode
+    }
 }
 
 fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 9a3d24facc2c8..aff554678a3f4 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1557,7 +1557,11 @@ impl<'test> TestCx<'test> {
                 // want to actually assert warnings about all this code. Instead
                 // let's just ignore unused code warnings by defaults and tests
                 // can turn it back on if needed.
-                if !self.config.src_base.ends_with("rustdoc-ui") {
+                if !self.config.src_base.ends_with("rustdoc-ui") &&
+                    // Note that we don't call pass_mode() here as we don't want
+                    // to set unused to allow if we've overriden the pass mode
+                    // via command line flags.
+                    self.props.local_pass_mode() != Some(PassMode::Run) {
                     rustc.args(&["-A", "unused"]);
                 }
             }

From f35eae9934c227a094e23c378a330b03b9d2ec01 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Tue, 27 Aug 2019 17:09:13 -0400
Subject: [PATCH 590/943] Add buffer abstraction

---
 src/librustdoc/html/format.rs | 65 +++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 313734e3fdd6b..941d2c4acb1a8 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -18,6 +18,71 @@ use crate::clean::{self, PrimitiveType};
 use crate::html::item_type::ItemType;
 use crate::html::render::{self, cache, CURRENT_DEPTH};
 
+pub trait Print {
+    fn print(&self, buffer: &mut Buffer);
+}
+
+#[derive(Debug, Clone)]
+pub struct Buffer {
+    for_html: bool,
+    buffer: String,
+}
+
+impl Buffer {
+    crate fn empty_from(v: &Buffer) -> Buffer {
+        Buffer {
+            for_html: v.for_html,
+            buffer: String::new(),
+        }
+    }
+
+    crate fn html() -> Buffer {
+        Buffer {
+            for_html: true,
+            buffer: String::new(),
+        }
+    }
+
+    crate fn is_empty(&self) -> bool {
+        self.buffer.is_empty()
+    }
+
+    crate fn into_inner(self) -> String {
+        self.buffer
+    }
+
+    crate fn insert_str(&mut self, idx: usize, s: &str) {
+        self.buffer.insert_str(idx, s);
+    }
+
+    crate fn push_str(&mut self, s: &str) {
+        self.buffer.push_str(s);
+    }
+
+    // Intended for consumption by write! and writeln! (std::fmt) but without
+    // the fmt::Result return type imposed by fmt::Write (and avoiding the trait
+    // import).
+    crate fn write_str(&mut self, s: &str) {
+        self.buffer.push_str(s);
+    }
+
+    // Intended for consumption by write! and writeln! (std::fmt) but without
+    // the fmt::Result return type imposed by fmt::Write (and avoiding the trait
+    // import).
+    crate fn write_fmt(&mut self, v: fmt::Arguments<'_>) {
+        use fmt::Write;
+        self.buffer.write_fmt(v).unwrap();
+    }
+
+    crate fn display<T: fmt::Display>(&mut self, t: T) {
+        if self.for_html {
+            write!(self, "{}", t);
+        } else {
+            write!(self, "{:#}", t);
+        }
+    }
+}
+
 /// Helper to render an optional visibility with a space after it (if the
 /// visibility is preset)
 #[derive(Copy, Clone)]

From eebd0265c328b80d67f89df04879ef64bd229a5f Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Fri, 30 Aug 2019 10:24:42 -0400
Subject: [PATCH 591/943] Migrate top-level rendering to Buffer

---
 src/librustdoc/html/layout.rs  |  8 ++--
 src/librustdoc/html/render.rs  | 83 +++++++++++++++++-----------------
 src/librustdoc/html/sources.rs | 10 ++--
 3 files changed, 49 insertions(+), 52 deletions(-)

diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index ae0bd1aafa8f1..2856db7ef9843 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -1,9 +1,9 @@
 use std::fmt;
-use std::io;
 use std::path::PathBuf;
 
 use crate::externalfiles::ExternalHtml;
 use crate::html::render::SlashChecker;
+use crate::html::format::Buffer;
 
 #[derive(Clone)]
 pub struct Layout {
@@ -26,7 +26,7 @@ pub struct Page<'a> {
 }
 
 pub fn render<T: fmt::Display, S: fmt::Display>(
-    dst: &mut dyn io::Write,
+    dst: &mut Buffer,
     layout: &Layout,
     page: &Page<'_>,
     sidebar: &S,
@@ -34,7 +34,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
     css_file_extension: bool,
     themes: &[PathBuf],
     generate_search_filter: bool,
-) -> io::Result<()> {
+) {
     let static_root_path = page.static_root_path.unwrap_or(page.root_path);
     write!(dst,
 "<!DOCTYPE html>\
@@ -238,7 +238,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
     )
 }
 
-pub fn redirect(dst: &mut dyn io::Write, url: &str) -> io::Result<()> {
+pub fn redirect(dst: &mut Buffer, url: &str) {
     // <script> triggers a redirect before refresh, so this is fine.
     write!(dst,
 r##"<!DOCTYPE html>
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 0e046b8cd4456..d86071e68b290 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -65,7 +65,7 @@ use crate::docfs::{DocFS, ErrorStorage, PathError};
 use crate::doctree;
 use crate::fold::DocFolder;
 use crate::html::escape::Escape;
-use crate::html::format::{AsyncSpace, ConstnessSpace};
+use crate::html::format::{Buffer, AsyncSpace, ConstnessSpace};
 use crate::html::format::{GenericBounds, WhereClause, href, AbiSpace, DefaultSpace};
 use crate::html::format::{VisSpace, Function, UnsafetySpace, MutableSpace};
 use crate::html::format::fmt_impl_for_trait_page;
@@ -1185,13 +1185,13 @@ themePicker.onblur = handleThemeButtonsBlur;
                                                 SlashChecker(s), s)
                                     })
                                     .collect::<String>());
-            let mut v = Vec::new();
-            try_err!(layout::render(&mut v, &cx.shared.layout,
-                                    &page, &(""), &content,
-                                    cx.shared.css_file_extension.is_some(),
-                                    &cx.shared.themes,
-                                    cx.shared.generate_search_filter), &dst);
-            cx.shared.fs.write(&dst, &v)?;
+            let mut v = Buffer::html();
+            layout::render(&mut v, &cx.shared.layout,
+                           &page, &(""), &content,
+                           cx.shared.css_file_extension.is_some(),
+                           &cx.shared.themes,
+                           cx.shared.generate_search_filter);
+            cx.shared.fs.write(&dst, v.into_inner().as_bytes())?;
         }
     }
 
@@ -1939,14 +1939,13 @@ impl Context {
         } else {
             String::new()
         };
-        let mut v = Vec::new();
-        try_err!(layout::render(&mut v, &self.shared.layout,
-                                &page, &sidebar, &all,
-                                self.shared.css_file_extension.is_some(),
-                                &self.shared.themes,
-                                self.shared.generate_search_filter),
-                 &final_file);
-        self.shared.fs.write(&final_file, &v)?;
+        let mut v = Buffer::html();
+        layout::render(&mut v, &self.shared.layout,
+                       &page, &sidebar, &all,
+                       self.shared.css_file_extension.is_some(),
+                       &self.shared.themes,
+                       self.shared.generate_search_filter);
+        self.shared.fs.write(&final_file, v.into_inner().as_bytes())?;
 
         // Generating settings page.
         let settings = Settings::new(self.shared.static_root_path.as_deref().unwrap_or("./"),
@@ -1959,23 +1958,24 @@ impl Context {
         let sidebar = "<p class='location'>Settings</p><div class='sidebar-elems'></div>";
         themes.push(PathBuf::from("settings.css"));
         let layout = self.shared.layout.clone();
-        let mut v = Vec::new();
-        try_err!(layout::render(&mut v, &layout,
-                                &page, &sidebar, &settings,
-                                self.shared.css_file_extension.is_some(),
-                                &themes,
-                                self.shared.generate_search_filter),
-                 &settings_file);
-        self.shared.fs.write(&settings_file, &v)?;
+        let mut v = Buffer::html();
+        layout::render(
+            &mut v,
+            &layout,
+            &page, &sidebar, &settings,
+            self.shared.css_file_extension.is_some(),
+            &themes,
+            self.shared.generate_search_filter,
+        );
+        self.shared.fs.write(&settings_file, v.into_inner().as_bytes())?;
 
         Ok(())
     }
 
     fn render_item(&self,
-                   writer: &mut dyn io::Write,
+                   writer: &mut Buffer,
                    it: &clean::Item,
-                   pushname: bool)
-                   -> io::Result<()> {
+                   pushname: bool) {
         // A little unfortunate that this is done like this, but it sure
         // does make formatting *a lot* nicer.
         CURRENT_DEPTH.with(|slot| {
@@ -2027,7 +2027,7 @@ impl Context {
                            &Item{ cx: self, item: it },
                            self.shared.css_file_extension.is_some(),
                            &self.shared.themes,
-                           self.shared.generate_search_filter)?;
+                           self.shared.generate_search_filter);
         } else {
             let mut url = self.root_path();
             if let Some(&(ref names, ty)) = cache().paths.get(&it.def_id) {
@@ -2036,10 +2036,9 @@ impl Context {
                     url.push_str("/");
                 }
                 url.push_str(&item_path(ty, names.last().unwrap()));
-                layout::redirect(writer, &url)?;
+                layout::redirect(writer, &url);
             }
         }
-        Ok(())
     }
 
     /// Non-parallelized version of rendering an item. This will take the input
@@ -2075,13 +2074,13 @@ impl Context {
 
             info!("Recursing into {}", self.dst.display());
 
-            let mut buf = Vec::new();
-            self.render_item(&mut buf, &item, false).unwrap();
+            let mut buf = Buffer::html();
+            self.render_item(&mut buf, &item, false);
             // buf will be empty if the module is stripped and there is no redirect for it
             if !buf.is_empty() {
                 self.shared.ensure_dir(&self.dst)?;
                 let joint_dst = self.dst.join("index.html");
-                scx.fs.write(&joint_dst, buf)?;
+                scx.fs.write(&joint_dst, buf.into_inner().as_bytes())?;
             }
 
             let m = match item.inner {
@@ -2110,8 +2109,8 @@ impl Context {
             self.dst = prev;
             self.current.pop().unwrap();
         } else if item.name.is_some() {
-            let mut buf = Vec::new();
-            self.render_item(&mut buf, &item, true).unwrap();
+            let mut buf = Buffer::html();
+            self.render_item(&mut buf, &item, true);
             // buf will be empty if the item is stripped and there is no redirect for it
             if !buf.is_empty() {
                 let name = item.name.as_ref().unwrap();
@@ -2119,7 +2118,7 @@ impl Context {
                 let file_name = &item_path(item_type, name);
                 self.shared.ensure_dir(&self.dst)?;
                 let joint_dst = self.dst.join(file_name);
-                self.shared.fs.write(&joint_dst, buf)?;
+                self.shared.fs.write(&joint_dst, buf.into_inner().as_bytes())?;
 
                 if !self.render_redirect_pages {
                     all.append(full_path(self, &item), &item_type);
@@ -2129,18 +2128,18 @@ impl Context {
                     // URL for the page.
                     let redir_name = format!("{}.{}.html", name, item_type.name_space());
                     let redir_dst = self.dst.join(redir_name);
-                    let mut v = Vec::new();
-                    try_err!(layout::redirect(&mut v, file_name), &redir_dst);
-                    self.shared.fs.write(&redir_dst, &v)?;
+                    let mut v = Buffer::html();
+                    layout::redirect(&mut v, file_name);
+                    self.shared.fs.write(&redir_dst, v.into_inner().as_bytes())?;
                 }
                 // If the item is a macro, redirect from the old macro URL (with !)
                 // to the new one (without).
                 if item_type == ItemType::Macro {
                     let redir_name = format!("{}.{}!.html", item_type, name);
                     let redir_dst = self.dst.join(redir_name);
-                    let mut v = Vec::new();
-                    try_err!(layout::redirect(&mut v, file_name), &redir_dst);
-                    self.shared.fs.write(&redir_dst, &v)?;
+                    let mut v = Buffer::html();
+                    layout::redirect(&mut v, file_name);
+                    self.shared.fs.write(&redir_dst, v.into_inner().as_bytes())?;
                 }
             }
         }
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index c1f1f59d9149a..a2a35b94c4fe7 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -4,6 +4,7 @@ use crate::fold::DocFolder;
 use crate::html::layout;
 use crate::html::render::{Error, SharedContext, BASIC_KEYWORDS};
 use crate::html::highlight;
+use crate::html::format::Buffer;
 use std::ffi::OsStr;
 use std::fs;
 use std::path::{Component, Path, PathBuf};
@@ -105,7 +106,7 @@ impl<'a> SourceCollector<'a> {
         cur.push(&fname);
         href.push_str(&fname.to_string_lossy());
 
-        let mut v = Vec::new();
+        let mut v = Buffer::html();
         let title = format!("{} -- source", cur.file_name().expect("failed to get file name")
                                                .to_string_lossy());
         let desc = format!("Source to the Rust file `{}`.", filename);
@@ -120,15 +121,12 @@ impl<'a> SourceCollector<'a> {
             extra_scripts: &[&format!("source-files{}", self.scx.resource_suffix)],
             static_extra_scripts: &[&format!("source-script{}", self.scx.resource_suffix)],
         };
-        let result = layout::render(&mut v, &self.scx.layout,
+        layout::render(&mut v, &self.scx.layout,
                        &page, &(""), &Source(contents),
                        self.scx.css_file_extension.is_some(),
                        &self.scx.themes,
                        self.scx.generate_search_filter);
-        if let Err(e) = result {
-            return Err(Error::new(e, &cur));
-        }
-        self.scx.fs.write(&cur, &v)?;
+        self.scx.fs.write(&cur, v.into_inner().as_bytes())?;
         self.scx.local_sources.insert(p.clone(), href);
         Ok(())
     }

From 9e52ba94faa49d44e8ad08046e0de7538a19b2de Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Fri, 30 Aug 2019 10:35:14 -0400
Subject: [PATCH 592/943] Create buffers in top-level rendering

This avoids needlessly creating and threading the buffers through when
we only use them once.
---
 src/librustdoc/html/layout.rs  | 11 ++++----
 src/librustdoc/html/render.rs  | 49 +++++++++++++++-------------------
 src/librustdoc/html/sources.rs |  6 ++---
 3 files changed, 29 insertions(+), 37 deletions(-)

diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 2856db7ef9843..3b6d4f3b92d50 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -26,7 +26,6 @@ pub struct Page<'a> {
 }
 
 pub fn render<T: fmt::Display, S: fmt::Display>(
-    dst: &mut Buffer,
     layout: &Layout,
     page: &Page<'_>,
     sidebar: &S,
@@ -34,7 +33,8 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
     css_file_extension: bool,
     themes: &[PathBuf],
     generate_search_filter: bool,
-) {
+) -> String {
+    let mut dst = Buffer::html();
     let static_root_path = page.static_root_path.unwrap_or(page.root_path);
     write!(dst,
 "<!DOCTYPE html>\
@@ -235,12 +235,13 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
     } else {
         ""
     },
-    )
+    );
+    dst.into_inner()
 }
 
-pub fn redirect(dst: &mut Buffer, url: &str) {
+pub fn redirect(url: &str) -> String {
     // <script> triggers a redirect before refresh, so this is fine.
-    write!(dst,
+    format!(
 r##"<!DOCTYPE html>
 <html lang="en">
 <head>
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index d86071e68b290..7ac606f89d2b9 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -65,7 +65,7 @@ use crate::docfs::{DocFS, ErrorStorage, PathError};
 use crate::doctree;
 use crate::fold::DocFolder;
 use crate::html::escape::Escape;
-use crate::html::format::{Buffer, AsyncSpace, ConstnessSpace};
+use crate::html::format::{AsyncSpace, ConstnessSpace};
 use crate::html::format::{GenericBounds, WhereClause, href, AbiSpace, DefaultSpace};
 use crate::html::format::{VisSpace, Function, UnsafetySpace, MutableSpace};
 use crate::html::format::fmt_impl_for_trait_page;
@@ -1185,13 +1185,12 @@ themePicker.onblur = handleThemeButtonsBlur;
                                                 SlashChecker(s), s)
                                     })
                                     .collect::<String>());
-            let mut v = Buffer::html();
-            layout::render(&mut v, &cx.shared.layout,
+            let v = layout::render(&cx.shared.layout,
                            &page, &(""), &content,
                            cx.shared.css_file_extension.is_some(),
                            &cx.shared.themes,
                            cx.shared.generate_search_filter);
-            cx.shared.fs.write(&dst, v.into_inner().as_bytes())?;
+            cx.shared.fs.write(&dst, v.as_bytes())?;
         }
     }
 
@@ -1939,13 +1938,12 @@ impl Context {
         } else {
             String::new()
         };
-        let mut v = Buffer::html();
-        layout::render(&mut v, &self.shared.layout,
+        let v = layout::render(&self.shared.layout,
                        &page, &sidebar, &all,
                        self.shared.css_file_extension.is_some(),
                        &self.shared.themes,
                        self.shared.generate_search_filter);
-        self.shared.fs.write(&final_file, v.into_inner().as_bytes())?;
+        self.shared.fs.write(&final_file, v.as_bytes())?;
 
         // Generating settings page.
         let settings = Settings::new(self.shared.static_root_path.as_deref().unwrap_or("./"),
@@ -1958,24 +1956,21 @@ impl Context {
         let sidebar = "<p class='location'>Settings</p><div class='sidebar-elems'></div>";
         themes.push(PathBuf::from("settings.css"));
         let layout = self.shared.layout.clone();
-        let mut v = Buffer::html();
-        layout::render(
-            &mut v,
+        let v = layout::render(
             &layout,
             &page, &sidebar, &settings,
             self.shared.css_file_extension.is_some(),
             &themes,
             self.shared.generate_search_filter,
         );
-        self.shared.fs.write(&settings_file, v.into_inner().as_bytes())?;
+        self.shared.fs.write(&settings_file, v.as_bytes())?;
 
         Ok(())
     }
 
     fn render_item(&self,
-                   writer: &mut Buffer,
                    it: &clean::Item,
-                   pushname: bool) {
+                   pushname: bool) -> String {
         // A little unfortunate that this is done like this, but it sure
         // does make formatting *a lot* nicer.
         CURRENT_DEPTH.with(|slot| {
@@ -2022,12 +2017,12 @@ impl Context {
         }
 
         if !self.render_redirect_pages {
-            layout::render(writer, &self.shared.layout, &page,
+            layout::render(&self.shared.layout, &page,
                            &Sidebar{ cx: self, item: it },
                            &Item{ cx: self, item: it },
                            self.shared.css_file_extension.is_some(),
                            &self.shared.themes,
-                           self.shared.generate_search_filter);
+                           self.shared.generate_search_filter)
         } else {
             let mut url = self.root_path();
             if let Some(&(ref names, ty)) = cache().paths.get(&it.def_id) {
@@ -2036,7 +2031,9 @@ impl Context {
                     url.push_str("/");
                 }
                 url.push_str(&item_path(ty, names.last().unwrap()));
-                layout::redirect(writer, &url);
+                layout::redirect(&url)
+            } else {
+                String::new()
             }
         }
     }
@@ -2074,13 +2071,12 @@ impl Context {
 
             info!("Recursing into {}", self.dst.display());
 
-            let mut buf = Buffer::html();
-            self.render_item(&mut buf, &item, false);
+            let buf = self.render_item(&item, false);
             // buf will be empty if the module is stripped and there is no redirect for it
             if !buf.is_empty() {
                 self.shared.ensure_dir(&self.dst)?;
                 let joint_dst = self.dst.join("index.html");
-                scx.fs.write(&joint_dst, buf.into_inner().as_bytes())?;
+                scx.fs.write(&joint_dst, buf.as_bytes())?;
             }
 
             let m = match item.inner {
@@ -2109,8 +2105,7 @@ impl Context {
             self.dst = prev;
             self.current.pop().unwrap();
         } else if item.name.is_some() {
-            let mut buf = Buffer::html();
-            self.render_item(&mut buf, &item, true);
+            let buf = self.render_item(&item, true);
             // buf will be empty if the item is stripped and there is no redirect for it
             if !buf.is_empty() {
                 let name = item.name.as_ref().unwrap();
@@ -2118,7 +2113,7 @@ impl Context {
                 let file_name = &item_path(item_type, name);
                 self.shared.ensure_dir(&self.dst)?;
                 let joint_dst = self.dst.join(file_name);
-                self.shared.fs.write(&joint_dst, buf.into_inner().as_bytes())?;
+                self.shared.fs.write(&joint_dst, buf.as_bytes())?;
 
                 if !self.render_redirect_pages {
                     all.append(full_path(self, &item), &item_type);
@@ -2128,18 +2123,16 @@ impl Context {
                     // URL for the page.
                     let redir_name = format!("{}.{}.html", name, item_type.name_space());
                     let redir_dst = self.dst.join(redir_name);
-                    let mut v = Buffer::html();
-                    layout::redirect(&mut v, file_name);
-                    self.shared.fs.write(&redir_dst, v.into_inner().as_bytes())?;
+                    let v = layout::redirect(file_name);
+                    self.shared.fs.write(&redir_dst, v.as_bytes())?;
                 }
                 // If the item is a macro, redirect from the old macro URL (with !)
                 // to the new one (without).
                 if item_type == ItemType::Macro {
                     let redir_name = format!("{}.{}!.html", item_type, name);
                     let redir_dst = self.dst.join(redir_name);
-                    let mut v = Buffer::html();
-                    layout::redirect(&mut v, file_name);
-                    self.shared.fs.write(&redir_dst, v.into_inner().as_bytes())?;
+                    let v = layout::redirect(file_name);
+                    self.shared.fs.write(&redir_dst, v.as_bytes())?;
                 }
             }
         }
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index a2a35b94c4fe7..d3e006447415b 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -4,7 +4,6 @@ use crate::fold::DocFolder;
 use crate::html::layout;
 use crate::html::render::{Error, SharedContext, BASIC_KEYWORDS};
 use crate::html::highlight;
-use crate::html::format::Buffer;
 use std::ffi::OsStr;
 use std::fs;
 use std::path::{Component, Path, PathBuf};
@@ -106,7 +105,6 @@ impl<'a> SourceCollector<'a> {
         cur.push(&fname);
         href.push_str(&fname.to_string_lossy());
 
-        let mut v = Buffer::html();
         let title = format!("{} -- source", cur.file_name().expect("failed to get file name")
                                                .to_string_lossy());
         let desc = format!("Source to the Rust file `{}`.", filename);
@@ -121,12 +119,12 @@ impl<'a> SourceCollector<'a> {
             extra_scripts: &[&format!("source-files{}", self.scx.resource_suffix)],
             static_extra_scripts: &[&format!("source-script{}", self.scx.resource_suffix)],
         };
-        layout::render(&mut v, &self.scx.layout,
+        let v = layout::render(&self.scx.layout,
                        &page, &(""), &Source(contents),
                        self.scx.css_file_extension.is_some(),
                        &self.scx.themes,
                        self.scx.generate_search_filter);
-        self.scx.fs.write(&cur, v.into_inner().as_bytes())?;
+        self.scx.fs.write(&cur, v.as_bytes())?;
         self.scx.local_sources.insert(p.clone(), href);
         Ok(())
     }

From 3657bfc040d1240ed0f84a15d96432f7d60b8d3f Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Fri, 30 Aug 2019 10:41:56 -0400
Subject: [PATCH 593/943] Remove needless clone of layout

---
 src/librustdoc/html/render.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 7ac606f89d2b9..c9483088b7b1b 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1955,9 +1955,8 @@ impl Context {
         let mut themes = self.shared.themes.clone();
         let sidebar = "<p class='location'>Settings</p><div class='sidebar-elems'></div>";
         themes.push(PathBuf::from("settings.css"));
-        let layout = self.shared.layout.clone();
         let v = layout::render(
-            &layout,
+            &self.shared.layout,
             &page, &sidebar, &settings,
             self.shared.css_file_extension.is_some(),
             &themes,

From 57243b74b136c26ffa20d0802ce2777b5bf1f3f0 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Fri, 30 Aug 2019 10:51:13 -0400
Subject: [PATCH 594/943] Move constant parameters to render to Layout struct

---
 src/librustdoc/html/layout.rs  | 12 ++++++++----
 src/librustdoc/html/render.rs  | 29 +++++++----------------------
 src/librustdoc/html/sources.rs |  4 +---
 3 files changed, 16 insertions(+), 29 deletions(-)

diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 3b6d4f3b92d50..cf55b9ad34308 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -11,6 +11,12 @@ pub struct Layout {
     pub favicon: String,
     pub external_html: ExternalHtml,
     pub krate: String,
+    /// The given user css file which allow to customize the generated
+    /// documentation theme.
+    pub css_file_extension: Option<PathBuf>,
+    /// If false, the `select` element to have search filtering by crates on rendered docs
+    /// won't be generated.
+    pub generate_search_filter: bool,
 }
 
 pub struct Page<'a> {
@@ -30,9 +36,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
     page: &Page<'_>,
     sidebar: &S,
     t: &T,
-    css_file_extension: bool,
     themes: &[PathBuf],
-    generate_search_filter: bool,
 ) -> String {
     let mut dst = Buffer::html();
     let static_root_path = page.static_root_path.unwrap_or(page.root_path);
@@ -164,7 +168,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
     <script defer src=\"{root_path}search-index{suffix}.js\"></script>\
 </body>\
 </html>",
-    css_extension = if css_file_extension {
+    css_extension = if layout.css_file_extension.is_some() {
         format!("<link rel=\"stylesheet\" \
                        type=\"text/css\" \
                        href=\"{static_root_path}theme{suffix}.css\">",
@@ -228,7 +232,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
                 root_path=page.root_path,
                 extra_script=e)
     }).collect::<String>(),
-    filter_crates=if generate_search_filter {
+    filter_crates=if layout.generate_search_filter {
         "<select id=\"crate-search\">\
             <option value=\"All crates\">All crates</option>\
         </select>"
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c9483088b7b1b..1da862315bc98 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -192,9 +192,6 @@ crate struct SharedContext {
     /// The base-URL of the issue tracker for when an item has been tagged with
     /// an issue number.
     pub issue_tracker_base_url: Option<String>,
-    /// The given user css file which allow to customize the generated
-    /// documentation theme.
-    pub css_file_extension: Option<PathBuf>,
     /// The directories that have already been created in this doc run. Used to reduce the number
     /// of spurious `create_dir_all` calls.
     pub created_dirs: RefCell<FxHashSet<PathBuf>>,
@@ -209,9 +206,6 @@ crate struct SharedContext {
     /// Optional path string to be used to load static files on output pages. If not set, uses
     /// combinations of `../` to reach the documentation root.
     pub static_root_path: Option<String>,
-    /// If false, the `select` element to have search filtering by crates on rendered docs
-    /// won't be generated.
-    pub generate_search_filter: bool,
     /// Option disabled by default to generate files used by RLS and some other tools.
     pub generate_redirect_pages: bool,
     /// The fs handle we are working with.
@@ -545,14 +539,14 @@ pub fn run(mut krate: clean::Crate,
             favicon: String::new(),
             external_html,
             krate: krate.name.clone(),
+            css_file_extension: extension_css,
+            generate_search_filter,
         },
-        css_file_extension: extension_css,
         created_dirs: Default::default(),
         sort_modules_alphabetically,
         themes,
         resource_suffix,
         static_root_path,
-        generate_search_filter,
         generate_redirect_pages,
         fs: DocFS::new(&errors),
     };
@@ -932,7 +926,7 @@ themePicker.onblur = handleThemeButtonsBlur;
             options.enable_minification)?;
     }
 
-    if let Some(ref css) = cx.shared.css_file_extension {
+    if let Some(ref css) = cx.shared.layout.css_file_extension {
         let out = cx.dst.join(&format!("theme{}.css", cx.shared.resource_suffix));
         let buffer = try_err!(fs::read_to_string(css), css);
         if !options.enable_minification {
@@ -1187,9 +1181,7 @@ themePicker.onblur = handleThemeButtonsBlur;
                                     .collect::<String>());
             let v = layout::render(&cx.shared.layout,
                            &page, &(""), &content,
-                           cx.shared.css_file_extension.is_some(),
-                           &cx.shared.themes,
-                           cx.shared.generate_search_filter);
+                           &cx.shared.themes);
             cx.shared.fs.write(&dst, v.as_bytes())?;
         }
     }
@@ -1940,9 +1932,7 @@ impl Context {
         };
         let v = layout::render(&self.shared.layout,
                        &page, &sidebar, &all,
-                       self.shared.css_file_extension.is_some(),
-                       &self.shared.themes,
-                       self.shared.generate_search_filter);
+                       &self.shared.themes);
         self.shared.fs.write(&final_file, v.as_bytes())?;
 
         // Generating settings page.
@@ -1958,10 +1948,7 @@ impl Context {
         let v = layout::render(
             &self.shared.layout,
             &page, &sidebar, &settings,
-            self.shared.css_file_extension.is_some(),
-            &themes,
-            self.shared.generate_search_filter,
-        );
+            &themes);
         self.shared.fs.write(&settings_file, v.as_bytes())?;
 
         Ok(())
@@ -2019,9 +2006,7 @@ impl Context {
             layout::render(&self.shared.layout, &page,
                            &Sidebar{ cx: self, item: it },
                            &Item{ cx: self, item: it },
-                           self.shared.css_file_extension.is_some(),
-                           &self.shared.themes,
-                           self.shared.generate_search_filter)
+                           &self.shared.themes)
         } else {
             let mut url = self.root_path();
             if let Some(&(ref names, ty)) = cache().paths.get(&it.def_id) {
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index d3e006447415b..018db3f9363cb 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -121,9 +121,7 @@ impl<'a> SourceCollector<'a> {
         };
         let v = layout::render(&self.scx.layout,
                        &page, &(""), &Source(contents),
-                       self.scx.css_file_extension.is_some(),
-                       &self.scx.themes,
-                       self.scx.generate_search_filter);
+                       &self.scx.themes);
         self.scx.fs.write(&cur, v.as_bytes())?;
         self.scx.local_sources.insert(p.clone(), href);
         Ok(())

From 75528f266fc5b3b3f7acc8fbd3c51ce78ccd7dcd Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 08:45:44 -0400
Subject: [PATCH 595/943] Replace writeln!/write! with push_str

---
 src/librustdoc/html/render.rs | 150 ++++++++++++++++------------------
 1 file changed, 69 insertions(+), 81 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 1da862315bc98..09c2e31b4ed6b 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -65,7 +65,7 @@ use crate::docfs::{DocFS, ErrorStorage, PathError};
 use crate::doctree;
 use crate::fold::DocFolder;
 use crate::html::escape::Escape;
-use crate::html::format::{AsyncSpace, ConstnessSpace};
+use crate::html::format::{Buffer, AsyncSpace, ConstnessSpace};
 use crate::html::format::{GenericBounds, WhereClause, href, AbiSpace, DefaultSpace};
 use crate::html::format::{VisSpace, Function, UnsafetySpace, MutableSpace};
 use crate::html::format::fmt_impl_for_trait_page;
@@ -1025,12 +1025,12 @@ themePicker.onblur = handleThemeButtonsBlur;
         }
         all_aliases.push(format!("ALIASES[\"{}\"] = {{{}}};", krate.name, output));
         all_aliases.sort();
-        let mut v = Vec::new();
-        try_err!(writeln!(&mut v, "var ALIASES = {{}};"), &dst);
+        let mut v = Buffer::html();
+        writeln!(&mut v, "var ALIASES = {{}};");
         for aliases in &all_aliases {
-            try_err!(writeln!(&mut v, "{}", aliases), &dst);
+            writeln!(&mut v, "{}", aliases);
         }
-        cx.shared.fs.write(&dst, &v)?;
+        cx.shared.fs.write(&dst, v.into_inner().into_bytes())?;
     }
 
     use std::ffi::OsString;
@@ -1114,12 +1114,9 @@ themePicker.onblur = handleThemeButtonsBlur;
                                  &krate.name,
                                  hierarchy.to_json_string()));
         all_sources.sort();
-        let mut v = Vec::new();
-        try_err!(writeln!(&mut v,
-                          "var N = null;var sourcesIndex = {{}};\n{}\ncreateSourceSidebar();",
-                          all_sources.join("\n")),
-                 &dst);
-        cx.shared.fs.write(&dst, &v)?;
+        let v = format!("var N = null;var sourcesIndex = {{}};\n{}\ncreateSourceSidebar();\n",
+                          all_sources.join("\n"));
+        cx.shared.fs.write(&dst, v.as_bytes())?;
     }
 
     // Update the search index
@@ -1134,14 +1131,11 @@ themePicker.onblur = handleThemeButtonsBlur;
     // with rustdoc running in parallel.
     all_indexes.sort();
     {
-        let mut v = Vec::new();
-        try_err!(writeln!(&mut v, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst);
-        try_err!(write_minify_replacer(
-            &mut v,
+        let mut v = String::from("var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={};\n");
+        v.push_str(&minify_replacer(
             &format!("{}\n{}", variables.join(""), all_indexes.join("\n")),
-            options.enable_minification),
-            &dst);
-        try_err!(write!(&mut v, "initSearch(searchIndex);addSearchOptions(searchIndex);"), &dst);
+            options.enable_minification));
+        v.push_str("initSearch(searchIndex);addSearchOptions(searchIndex);");
         cx.shared.fs.write(&dst, &v)?;
     }
     if options.enable_index_page {
@@ -1247,19 +1241,18 @@ themePicker.onblur = handleThemeButtonsBlur;
         // identically even with rustdoc running in parallel.
         all_implementors.sort();
 
-        let mut v = Vec::new();
-        try_err!(writeln!(&mut v, "(function() {{var implementors = {{}};"), &mydst);
+        let mut v = String::from("(function() {var implementors = {}};\n");
         for implementor in &all_implementors {
-            try_err!(writeln!(&mut v, "{}", *implementor), &mydst);
+            v.push_str(&format!("{}", *implementor));
         }
-        try_err!(writeln!(&mut v, "{}", r"
+        v.push_str(r"
             if (window.register_implementors) {
                 window.register_implementors(implementors);
             } else {
                 window.pending_implementors = implementors;
             }
-        "), &mydst);
-        try_err!(writeln!(&mut v, r"}})()"), &mydst);
+        \n");
+        v.push_str("})()");
         cx.shared.fs.write(&mydst, &v)?;
     }
     Ok(())
@@ -1279,68 +1272,65 @@ fn write_minify(fs:&DocFS, dst: PathBuf, contents: &str, enable_minification: bo
     }
 }
 
-fn write_minify_replacer<W: Write>(
-    dst: &mut W,
+fn minify_replacer(
     contents: &str,
     enable_minification: bool,
-) -> io::Result<()> {
+) -> String {
     use minifier::js::{simple_minify, Keyword, ReservedChar, Token, Tokens};
 
     if enable_minification {
-        writeln!(dst, "{}",
-                 {
-                    let tokens: Tokens<'_> = simple_minify(contents)
-                        .into_iter()
-                        .filter(|(f, next)| {
-                            // We keep backlines.
-                            minifier::js::clean_token_except(f, next, &|c: &Token<'_>| {
-                                c.get_char() != Some(ReservedChar::Backline)
-                            })
-                        })
-                        .map(|(f, _)| {
-                            minifier::js::replace_token_with(f, &|t: &Token<'_>| {
-                                match *t {
-                                    Token::Keyword(Keyword::Null) => Some(Token::Other("N")),
-                                    Token::String(s) => {
-                                        let s = &s[1..s.len() -1]; // The quotes are included
-                                        if s.is_empty() {
-                                            Some(Token::Other("E"))
-                                        } else if s == "t" {
-                                            Some(Token::Other("T"))
-                                        } else if s == "u" {
-                                            Some(Token::Other("U"))
-                                        } else {
-                                            None
-                                        }
-                                    }
-                                    _ => None,
-                                }
-                            })
-                        })
-                        .collect::<Vec<_>>()
-                        .into();
-                    tokens.apply(|f| {
-                        // We add a backline after the newly created variables.
-                        minifier::js::aggregate_strings_into_array_with_separation_filter(
-                            f,
-                            "R",
-                            Token::Char(ReservedChar::Backline),
-                            // This closure prevents crates' names from being aggregated.
-                            //
-                            // The point here is to check if the string is preceded by '[' and
-                            // "searchIndex". If so, it means this is a crate name and that it
-                            // shouldn't be aggregated.
-                            |tokens, pos| {
-                                pos < 2 ||
-                                !tokens[pos - 1].eq_char(ReservedChar::OpenBracket) ||
-                                tokens[pos - 2].get_other() != Some("searchIndex")
+        let tokens: Tokens<'_> = simple_minify(contents)
+            .into_iter()
+            .filter(|(f, next)| {
+                // We keep backlines.
+                minifier::js::clean_token_except(f, next, &|c: &Token<'_>| {
+                    c.get_char() != Some(ReservedChar::Backline)
+                })
+            })
+            .map(|(f, _)| {
+                minifier::js::replace_token_with(f, &|t: &Token<'_>| {
+                    match *t {
+                        Token::Keyword(Keyword::Null) => Some(Token::Other("N")),
+                        Token::String(s) => {
+                            let s = &s[1..s.len() -1]; // The quotes are included
+                            if s.is_empty() {
+                                Some(Token::Other("E"))
+                            } else if s == "t" {
+                                Some(Token::Other("T"))
+                            } else if s == "u" {
+                                Some(Token::Other("U"))
+                            } else {
+                                None
                             }
-                        )
-                    })
-                    .to_string()
+                        }
+                        _ => None,
+                    }
                 })
+            })
+            .collect::<Vec<_>>()
+            .into();
+        let o = tokens.apply(|f| {
+            // We add a backline after the newly created variables.
+            minifier::js::aggregate_strings_into_array_with_separation_filter(
+                f,
+                "R",
+                Token::Char(ReservedChar::Backline),
+                // This closure prevents crates' names from being aggregated.
+                //
+                // The point here is to check if the string is preceded by '[' and
+                // "searchIndex". If so, it means this is a crate name and that it
+                // shouldn't be aggregated.
+                |tokens, pos| {
+                    pos < 2 ||
+                    !tokens[pos - 1].eq_char(ReservedChar::OpenBracket) ||
+                    tokens[pos - 2].get_other() != Some("searchIndex")
+                }
+            )
+        })
+        .to_string();
+        format!("{}\n", o)
     } else {
-        writeln!(dst, "{}", contents)
+        format!("{}\n", contents)
     }
 }
 
@@ -2073,9 +2063,7 @@ impl Context {
             if !self.render_redirect_pages {
                 let items = self.build_sidebar_items(&m);
                 let js_dst = self.dst.join("sidebar-items.js");
-                let mut v = Vec::new();
-                try_err!(write!(&mut v, "initSidebarItems({});",
-                                as_json(&items)), &js_dst);
+                let v = format!("initSidebarItems({});", as_json(&items));
                 scx.fs.write(&js_dst, &v)?;
             }
 

From 04dc72eeef1ecea0833ce022dde0fd45c4744757 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 08:52:04 -0400
Subject: [PATCH 596/943] Remove unnecessary Buffer in layout::render

---
 src/librustdoc/html/layout.rs | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index cf55b9ad34308..c7b6684fd3110 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -3,7 +3,6 @@ use std::path::PathBuf;
 
 use crate::externalfiles::ExternalHtml;
 use crate::html::render::SlashChecker;
-use crate::html::format::Buffer;
 
 #[derive(Clone)]
 pub struct Layout {
@@ -38,10 +37,8 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
     t: &T,
     themes: &[PathBuf],
 ) -> String {
-    let mut dst = Buffer::html();
     let static_root_path = page.static_root_path.unwrap_or(page.root_path);
-    write!(dst,
-"<!DOCTYPE html>\
+    format!("<!DOCTYPE html>\
 <html lang=\"en\">\
 <head>\
     <meta charset=\"utf-8\">\
@@ -239,8 +236,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
     } else {
         ""
     },
-    );
-    dst.into_inner()
+    )
 }
 
 pub fn redirect(url: &str) -> String {

From f8bccb1658dce1b70e08c7c8f438b65f6f9bc139 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 09:07:29 -0400
Subject: [PATCH 597/943] Move sidebar to Buffer-printing

---
 src/librustdoc/html/format.rs |  23 ++++++++
 src/librustdoc/html/layout.rs |   5 +-
 src/librustdoc/html/render.rs | 104 ++++++++++++++--------------------
 3 files changed, 70 insertions(+), 62 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 941d2c4acb1a8..99ddbcd7170d7 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -22,6 +22,24 @@ pub trait Print {
     fn print(&self, buffer: &mut Buffer);
 }
 
+impl<T: ?Sized + Print> Print for &'_ T {
+    fn print(&self, buffer: &mut Buffer) {
+        (&**self).print(buffer)
+    }
+}
+
+impl Print for String {
+    fn print(&self, buffer: &mut Buffer) {
+        buffer.write_str(self);
+    }
+}
+
+impl Print for str {
+    fn print(&self, buffer: &mut Buffer) {
+        buffer.write_str(self);
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct Buffer {
     for_html: bool,
@@ -74,6 +92,11 @@ impl Buffer {
         self.buffer.write_fmt(v).unwrap();
     }
 
+    crate fn to_display<T: ?Sized + Print>(mut self, t: &T) -> String {
+        t.print(&mut self);
+        self.into_inner()
+    }
+
     crate fn display<T: fmt::Display>(&mut self, t: T) {
         if self.for_html {
             write!(self, "{}", t);
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index c7b6684fd3110..38dcfbfcec49c 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -3,6 +3,7 @@ use std::path::PathBuf;
 
 use crate::externalfiles::ExternalHtml;
 use crate::html::render::SlashChecker;
+use crate::html::format::{Buffer, Print};
 
 #[derive(Clone)]
 pub struct Layout {
@@ -30,7 +31,7 @@ pub struct Page<'a> {
     pub static_extra_scripts: &'a [&'a str],
 }
 
-pub fn render<T: fmt::Display, S: fmt::Display>(
+pub fn render<T: fmt::Display, S: Print>(
     layout: &Layout,
     page: &Page<'_>,
     sidebar: &S,
@@ -208,7 +209,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
     in_header = layout.external_html.in_header,
     before_content = layout.external_html.before_content,
     after_content = layout.external_html.after_content,
-    sidebar   = *sidebar,
+    sidebar   = Buffer::html().to_display(sidebar),
     krate     = layout.krate,
     themes = themes.iter()
                    .filter_map(|t| t.file_stem())
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 09c2e31b4ed6b..40e7081c57c72 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -65,7 +65,7 @@ use crate::docfs::{DocFS, ErrorStorage, PathError};
 use crate::doctree;
 use crate::fold::DocFolder;
 use crate::html::escape::Escape;
-use crate::html::format::{Buffer, AsyncSpace, ConstnessSpace};
+use crate::html::format::{Print, Buffer, AsyncSpace, ConstnessSpace};
 use crate::html::format::{GenericBounds, WhereClause, href, AbiSpace, DefaultSpace};
 use crate::html::format::{VisSpace, Function, UnsafetySpace, MutableSpace};
 use crate::html::format::fmt_impl_for_trait_page;
@@ -4266,15 +4266,15 @@ fn item_foreign_type(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item)
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
 
-impl<'a> fmt::Display for Sidebar<'a> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+impl Print for Sidebar<'_> {
+    fn print(&self, buffer: &mut Buffer) {
         let cx = self.cx;
         let it = self.item;
         let parentlen = cx.current.len() - if it.is_mod() {1} else {0};
 
         if it.is_struct() || it.is_trait() || it.is_primitive() || it.is_union()
             || it.is_enum() || it.is_mod() || it.is_typedef() {
-            write!(fmt, "<p class='location'>{}{}</p>",
+            write!(buffer, "<p class='location'>{}{}</p>",
                 match it.inner {
                     clean::StructItem(..) => "Struct ",
                     clean::TraitItem(..) => "Trait ",
@@ -4290,33 +4290,33 @@ impl<'a> fmt::Display for Sidebar<'a> {
                     },
                     _ => "",
                 },
-                it.name.as_ref().unwrap())?;
+                it.name.as_ref().unwrap());
         }
 
         if it.is_crate() {
             if let Some(ref version) = cache().crate_version {
-                write!(fmt,
+                write!(buffer,
                        "<div class='block version'>\
                         <p>Version {}</p>\
                         </div>",
-                       version)?;
+                       version);
             }
         }
 
-        write!(fmt, "<div class=\"sidebar-elems\">")?;
+        write!(buffer, "<div class=\"sidebar-elems\">");
         if it.is_crate() {
-            write!(fmt, "<a id='all-types' href='all.html'><p>See all {}'s items</p></a>",
-                   it.name.as_ref().expect("crates always have a name"))?;
+            write!(buffer, "<a id='all-types' href='all.html'><p>See all {}'s items</p></a>",
+                   it.name.as_ref().expect("crates always have a name"));
         }
         match it.inner {
-            clean::StructItem(ref s) => sidebar_struct(fmt, it, s)?,
-            clean::TraitItem(ref t) => sidebar_trait(fmt, it, t)?,
-            clean::PrimitiveItem(ref p) => sidebar_primitive(fmt, it, p)?,
-            clean::UnionItem(ref u) => sidebar_union(fmt, it, u)?,
-            clean::EnumItem(ref e) => sidebar_enum(fmt, it, e)?,
-            clean::TypedefItem(ref t, _) => sidebar_typedef(fmt, it, t)?,
-            clean::ModuleItem(ref m) => sidebar_module(fmt, it, &m.items)?,
-            clean::ForeignTypeItem => sidebar_foreign_type(fmt, it)?,
+            clean::StructItem(ref s) => sidebar_struct(buffer, it, s),
+            clean::TraitItem(ref t) => sidebar_trait(buffer, it, t),
+            clean::PrimitiveItem(ref p) => sidebar_primitive(buffer, it, p),
+            clean::UnionItem(ref u) => sidebar_union(buffer, it, u),
+            clean::EnumItem(ref e) => sidebar_enum(buffer, it, e),
+            clean::TypedefItem(ref t, _) => sidebar_typedef(buffer, it, t),
+            clean::ModuleItem(ref m) => sidebar_module(buffer, it, &m.items),
+            clean::ForeignTypeItem => sidebar_foreign_type(buffer, it),
             _ => (),
         }
 
@@ -4328,20 +4328,20 @@ impl<'a> fmt::Display for Sidebar<'a> {
         // as much HTML as possible in order to allow non-JS-enabled browsers
         // to navigate the documentation (though slightly inefficiently).
 
-        write!(fmt, "<p class='location'>")?;
+        write!(buffer, "<p class='location'>");
         for (i, name) in cx.current.iter().take(parentlen).enumerate() {
             if i > 0 {
-                write!(fmt, "::<wbr>")?;
+                write!(buffer, "::<wbr>");
             }
-            write!(fmt, "<a href='{}index.html'>{}</a>",
+            write!(buffer, "<a href='{}index.html'>{}</a>",
                    &cx.root_path()[..(cx.current.len() - i - 1) * 3],
-                   *name)?;
+                   *name);
         }
-        write!(fmt, "</p>")?;
+        write!(buffer, "</p>");
 
         // Sidebar refers to the enclosing module, not this module.
         let relpath = if it.is_mod() { "../" } else { "" };
-        write!(fmt,
+        write!(buffer,
                "<script>window.sidebarCurrent = {{\
                    name: '{name}', \
                    ty: '{ty}', \
@@ -4349,18 +4349,16 @@ impl<'a> fmt::Display for Sidebar<'a> {
                 }};</script>",
                name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""),
                ty = it.type_().css_class(),
-               path = relpath)?;
+               path = relpath);
         if parentlen == 0 {
             // There is no sidebar-items.js beyond the crate root path
             // FIXME maybe dynamic crate loading can be merged here
         } else {
-            write!(fmt, "<script defer src=\"{path}sidebar-items.js\"></script>",
-                   path = relpath)?;
+            write!(buffer, "<script defer src=\"{path}sidebar-items.js\"></script>",
+                   path = relpath);
         }
         // Closes sidebar-elems div.
-        write!(fmt, "</div>")?;
-
-        Ok(())
+        write!(buffer, "</div>");
     }
 }
 
@@ -4534,8 +4532,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
     out
 }
 
-fn sidebar_struct(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
-                  s: &clean::Struct) -> fmt::Result {
+fn sidebar_struct(buf: &mut Buffer, it: &clean::Item, s: &clean::Struct) {
     let mut sidebar = String::new();
     let fields = get_struct_fields_name(&s.fields);
 
@@ -4549,9 +4546,8 @@ fn sidebar_struct(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
     sidebar.push_str(&sidebar_assoc_items(it));
 
     if !sidebar.is_empty() {
-        write!(fmt, "<div class=\"block items\">{}</div>", sidebar)?;
+        write!(buf, "<div class=\"block items\">{}</div>", sidebar);
     }
-    Ok(())
 }
 
 fn get_id_for_impl_on_foreign_type(for_: &clean::Type, trait_: &clean::Type) -> String {
@@ -4575,8 +4571,7 @@ fn is_negative_impl(i: &clean::Impl) -> bool {
     i.polarity == Some(clean::ImplPolarity::Negative)
 }
 
-fn sidebar_trait(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
-                 t: &clean::Trait) -> fmt::Result {
+fn sidebar_trait(buf: &mut Buffer, it: &clean::Item, t: &clean::Trait) {
     let mut sidebar = String::new();
 
     let types = t.items
@@ -4684,27 +4679,23 @@ fn sidebar_trait(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
 
     sidebar.push_str(&sidebar_assoc_items(it));
 
-    write!(fmt, "<div class=\"block items\">{}</div>", sidebar)
+    write!(buf, "<div class=\"block items\">{}</div>", sidebar)
 }
 
-fn sidebar_primitive(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
-                     _p: &clean::PrimitiveType) -> fmt::Result {
+fn sidebar_primitive(buf: &mut Buffer, it: &clean::Item, _p: &clean::PrimitiveType) {
     let sidebar = sidebar_assoc_items(it);
 
     if !sidebar.is_empty() {
-        write!(fmt, "<div class=\"block items\">{}</div>", sidebar)?;
+        write!(buf, "<div class=\"block items\">{}</div>", sidebar);
     }
-    Ok(())
 }
 
-fn sidebar_typedef(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
-                   _t: &clean::Typedef) -> fmt::Result {
+fn sidebar_typedef(buf: &mut Buffer, it: &clean::Item, _t: &clean::Typedef) {
     let sidebar = sidebar_assoc_items(it);
 
     if !sidebar.is_empty() {
-        write!(fmt, "<div class=\"block items\">{}</div>", sidebar)?;
+        write!(buf, "<div class=\"block items\">{}</div>", sidebar);
     }
-    Ok(())
 }
 
 fn get_struct_fields_name(fields: &[clean::Item]) -> String {
@@ -4722,8 +4713,7 @@ fn get_struct_fields_name(fields: &[clean::Item]) -> String {
           .collect()
 }
 
-fn sidebar_union(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
-                 u: &clean::Union) -> fmt::Result {
+fn sidebar_union(buf: &mut Buffer, it: &clean::Item, u: &clean::Union) {
     let mut sidebar = String::new();
     let fields = get_struct_fields_name(&u.fields);
 
@@ -4735,13 +4725,11 @@ fn sidebar_union(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
     sidebar.push_str(&sidebar_assoc_items(it));
 
     if !sidebar.is_empty() {
-        write!(fmt, "<div class=\"block items\">{}</div>", sidebar)?;
+        write!(buf, "<div class=\"block items\">{}</div>", sidebar);
     }
-    Ok(())
 }
 
-fn sidebar_enum(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
-                e: &clean::Enum) -> fmt::Result {
+fn sidebar_enum(buf: &mut Buffer, it: &clean::Item, e: &clean::Enum) {
     let mut sidebar = String::new();
 
     let variants = e.variants.iter()
@@ -4759,9 +4747,8 @@ fn sidebar_enum(fmt: &mut fmt::Formatter<'_>, it: &clean::Item,
     sidebar.push_str(&sidebar_assoc_items(it));
 
     if !sidebar.is_empty() {
-        write!(fmt, "<div class=\"block items\">{}</div>", sidebar)?;
+        write!(buf, "<div class=\"block items\">{}</div>", sidebar);
     }
-    Ok(())
 }
 
 fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) {
@@ -4795,8 +4782,7 @@ fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) {
     }
 }
 
-fn sidebar_module(fmt: &mut fmt::Formatter<'_>, _it: &clean::Item,
-                  items: &[clean::Item]) -> fmt::Result {
+fn sidebar_module(buf: &mut Buffer, _it: &clean::Item, items: &[clean::Item]) {
     let mut sidebar = String::new();
 
     if items.iter().any(|it| it.type_() == ItemType::ExternCrate ||
@@ -4823,17 +4809,15 @@ fn sidebar_module(fmt: &mut fmt::Formatter<'_>, _it: &clean::Item,
     }
 
     if !sidebar.is_empty() {
-        write!(fmt, "<div class=\"block items\"><ul>{}</ul></div>", sidebar)?;
+        write!(buf, "<div class=\"block items\"><ul>{}</ul></div>", sidebar);
     }
-    Ok(())
 }
 
-fn sidebar_foreign_type(fmt: &mut fmt::Formatter<'_>, it: &clean::Item) -> fmt::Result {
+fn sidebar_foreign_type(buf: &mut Buffer, it: &clean::Item) {
     let sidebar = sidebar_assoc_items(it);
     if !sidebar.is_empty() {
-        write!(fmt, "<div class=\"block items\">{}</div>", sidebar)?;
+        write!(buf, "<div class=\"block items\">{}</div>", sidebar);
     }
-    Ok(())
 }
 
 fn item_macro(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,

From f4a15ae3b248bf91f10f6e5d031ca84dc1942e19 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 11:22:51 -0400
Subject: [PATCH 598/943] Implement Print for FnOnce(&mut Buffer)

This means that callers can pass in a closure like
`|buf| some_function(..., &mut buf)` and pass in arbitrary arguments to
that function without complicating the trait definition. We also keep
the impl for str and String, since it's useful to be able to just pass
in "" or format!("{}"...) results in some cases.

This changes Print's definition to take self, instead of &self, because
otherwise FnOnce cannot be called directly. We could instead take FnMut
or even Fn, but that seems like it'd merely complicate matters -- most
of the time, the FnOnce does not constrain us at all anyway. If it does,
a custom Print impl for &'_ SomeStruct is not all that painful.
---
 src/librustdoc/html/format.rs  | 20 +++++++++++---------
 src/librustdoc/html/layout.rs  |  2 +-
 src/librustdoc/html/render.rs  | 10 +++++-----
 src/librustdoc/html/sources.rs |  2 +-
 4 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 99ddbcd7170d7..5d86f0566111f 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -19,23 +19,25 @@ use crate::html::item_type::ItemType;
 use crate::html::render::{self, cache, CURRENT_DEPTH};
 
 pub trait Print {
-    fn print(&self, buffer: &mut Buffer);
+    fn print(self, buffer: &mut Buffer);
 }
 
-impl<T: ?Sized + Print> Print for &'_ T {
-    fn print(&self, buffer: &mut Buffer) {
-        (&**self).print(buffer)
+impl<F> Print for F
+    where F: FnOnce(&mut Buffer),
+{
+    fn print(self, buffer: &mut Buffer) {
+        (self)(buffer)
     }
 }
 
 impl Print for String {
-    fn print(&self, buffer: &mut Buffer) {
-        buffer.write_str(self);
+    fn print(self, buffer: &mut Buffer) {
+        buffer.write_str(&self);
     }
 }
 
-impl Print for str {
-    fn print(&self, buffer: &mut Buffer) {
+impl Print for &'_ str {
+    fn print(self, buffer: &mut Buffer) {
         buffer.write_str(self);
     }
 }
@@ -92,7 +94,7 @@ impl Buffer {
         self.buffer.write_fmt(v).unwrap();
     }
 
-    crate fn to_display<T: ?Sized + Print>(mut self, t: &T) -> String {
+    crate fn to_display<T: Print>(mut self, t: T) -> String {
         t.print(&mut self);
         self.into_inner()
     }
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 38dcfbfcec49c..1202f411f912c 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -34,7 +34,7 @@ pub struct Page<'a> {
 pub fn render<T: fmt::Display, S: Print>(
     layout: &Layout,
     page: &Page<'_>,
-    sidebar: &S,
+    sidebar: S,
     t: &T,
     themes: &[PathBuf],
 ) -> String {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 40e7081c57c72..fc7038f8bda96 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1174,7 +1174,7 @@ themePicker.onblur = handleThemeButtonsBlur;
                                     })
                                     .collect::<String>());
             let v = layout::render(&cx.shared.layout,
-                           &page, &(""), &content,
+                           &page, "", &content,
                            &cx.shared.themes);
             cx.shared.fs.write(&dst, v.as_bytes())?;
         }
@@ -1921,7 +1921,7 @@ impl Context {
             String::new()
         };
         let v = layout::render(&self.shared.layout,
-                       &page, &sidebar, &all,
+                       &page, sidebar, &all,
                        &self.shared.themes);
         self.shared.fs.write(&final_file, v.as_bytes())?;
 
@@ -1937,7 +1937,7 @@ impl Context {
         themes.push(PathBuf::from("settings.css"));
         let v = layout::render(
             &self.shared.layout,
-            &page, &sidebar, &settings,
+            &page, sidebar, &settings,
             &themes);
         self.shared.fs.write(&settings_file, v.as_bytes())?;
 
@@ -1994,7 +1994,7 @@ impl Context {
 
         if !self.render_redirect_pages {
             layout::render(&self.shared.layout, &page,
-                           &Sidebar{ cx: self, item: it },
+                           Sidebar{ cx: self, item: it },
                            &Item{ cx: self, item: it },
                            &self.shared.themes)
         } else {
@@ -4267,7 +4267,7 @@ fn item_foreign_type(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item)
 }
 
 impl Print for Sidebar<'_> {
-    fn print(&self, buffer: &mut Buffer) {
+    fn print(self, buffer: &mut Buffer) {
         let cx = self.cx;
         let it = self.item;
         let parentlen = cx.current.len() - if it.is_mod() {1} else {0};
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 018db3f9363cb..94ae14226097f 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -120,7 +120,7 @@ impl<'a> SourceCollector<'a> {
             static_extra_scripts: &[&format!("source-script{}", self.scx.resource_suffix)],
         };
         let v = layout::render(&self.scx.layout,
-                       &page, &(""), &Source(contents),
+                       &page, "", &Source(contents),
                        &self.scx.themes);
         self.scx.fs.write(&cur, v.as_bytes())?;
         self.scx.local_sources.insert(p.clone(), href);

From eefaee1af4cc3df09d2588638c2bb250fe6a30e6 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 11:32:47 -0400
Subject: [PATCH 599/943] Delete Sidebar struct in favor of FnOnce impl

---
 src/librustdoc/html/render.rs | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index fc7038f8bda96..3dec5c2a20e8e 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -387,8 +387,6 @@ struct Item<'a> {
     item: &'a clean::Item,
 }
 
-struct Sidebar<'a> { cx: &'a Context, item: &'a clean::Item, }
-
 /// Struct representing one entry in the JS search index. These are all emitted
 /// by hand to a large JS file at the end of cache-creation.
 #[derive(Debug)]
@@ -1994,7 +1992,7 @@ impl Context {
 
         if !self.render_redirect_pages {
             layout::render(&self.shared.layout, &page,
-                           Sidebar{ cx: self, item: it },
+                           |buf: &mut _| print_sidebar(self, it, buf),
                            &Item{ cx: self, item: it },
                            &self.shared.themes)
         } else {
@@ -4266,10 +4264,7 @@ fn item_foreign_type(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item)
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
 
-impl Print for Sidebar<'_> {
-    fn print(self, buffer: &mut Buffer) {
-        let cx = self.cx;
-        let it = self.item;
+    fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) {
         let parentlen = cx.current.len() - if it.is_mod() {1} else {0};
 
         if it.is_struct() || it.is_trait() || it.is_primitive() || it.is_union()
@@ -4360,7 +4355,6 @@ impl Print for Sidebar<'_> {
         // Closes sidebar-elems div.
         write!(buffer, "</div>");
     }
-}
 
 fn get_next_url(used_links: &mut FxHashSet<String>, url: String) -> String {
     if used_links.insert(url.clone()) {

From d5f147086bbc70eb248804d3a16c643979fd1f2b Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 11:34:37 -0400
Subject: [PATCH 600/943] De-indent all fmt::Display impls for later
 replacement to functions

---
 src/librustdoc/html/format.rs  |  10 +-
 src/librustdoc/html/render.rs  | 466 ++++++++++++++++-----------------
 src/librustdoc/html/sources.rs |  34 +--
 3 files changed, 255 insertions(+), 255 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 5d86f0566111f..f3c40c8568bb6 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -290,11 +290,11 @@ impl<'a> fmt::Display for WhereClause<'a> {
                 }
                 &clean::WherePredicate::RegionPredicate { ref lifetime, ref bounds } => {
                     clause.push_str(&format!("{}: {}",
-                                             lifetime,
-                                             bounds.iter()
-                                                   .map(|b| b.to_string())
-                                                   .collect::<Vec<_>>()
-                                                   .join(" + ")));
+                                                lifetime,
+                                                bounds.iter()
+                                                    .map(|b| b.to_string())
+                                                    .collect::<Vec<_>>()
+                                                    .join(" + ")));
                 }
                 &clean::WherePredicate::EqPredicate { ref lhs, ref rhs } => {
                     if f.alternate() {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 3dec5c2a20e8e..1d1e54fc9eaba 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1772,33 +1772,33 @@ fn print_entries(f: &mut fmt::Formatter<'_>, e: &FxHashSet<ItemEntry>, title: &s
 }
 
 impl fmt::Display for AllTypes {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f,
+fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+    write!(f,
 "<h1 class='fqn'>\
-     <span class='out-of-band'>\
-         <span id='render-detail'>\
-             <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" title=\"collapse all docs\">\
-                 [<span class='inner'>&#x2212;</span>]\
-             </a>\
-         </span>
-     </span>
-     <span class='in-band'>List of all items</span>\
+    <span class='out-of-band'>\
+        <span id='render-detail'>\
+            <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" title=\"collapse all docs\">\
+                [<span class='inner'>&#x2212;</span>]\
+            </a>\
+        </span>
+    </span>
+    <span class='in-band'>List of all items</span>\
 </h1>")?;
-        print_entries(f, &self.structs, "Structs", "structs")?;
-        print_entries(f, &self.enums, "Enums", "enums")?;
-        print_entries(f, &self.unions, "Unions", "unions")?;
-        print_entries(f, &self.primitives, "Primitives", "primitives")?;
-        print_entries(f, &self.traits, "Traits", "traits")?;
-        print_entries(f, &self.macros, "Macros", "macros")?;
-        print_entries(f, &self.attributes, "Attribute Macros", "attributes")?;
-        print_entries(f, &self.derives, "Derive Macros", "derives")?;
-        print_entries(f, &self.functions, "Functions", "functions")?;
-        print_entries(f, &self.typedefs, "Typedefs", "typedefs")?;
-        print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-aliases")?;
-        print_entries(f, &self.opaque_tys, "Opaque Types", "opaque-types")?;
-        print_entries(f, &self.statics, "Statics", "statics")?;
-        print_entries(f, &self.constants, "Constants", "constants")
-    }
+    print_entries(f, &self.structs, "Structs", "structs")?;
+    print_entries(f, &self.enums, "Enums", "enums")?;
+    print_entries(f, &self.unions, "Unions", "unions")?;
+    print_entries(f, &self.primitives, "Primitives", "primitives")?;
+    print_entries(f, &self.traits, "Traits", "traits")?;
+    print_entries(f, &self.macros, "Macros", "macros")?;
+    print_entries(f, &self.attributes, "Attribute Macros", "attributes")?;
+    print_entries(f, &self.derives, "Derive Macros", "derives")?;
+    print_entries(f, &self.functions, "Functions", "functions")?;
+    print_entries(f, &self.typedefs, "Typedefs", "typedefs")?;
+    print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-aliases")?;
+    print_entries(f, &self.opaque_tys, "Opaque Types", "opaque-types")?;
+    print_entries(f, &self.statics, "Statics", "statics")?;
+    print_entries(f, &self.constants, "Constants", "constants")
+}
 }
 
 #[derive(Debug)]
@@ -1829,27 +1829,27 @@ impl<'a> Settings<'a> {
 }
 
 impl<'a> fmt::Display for Settings<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f,
+fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+    write!(f,
 "<h1 class='fqn'>\
-     <span class='in-band'>Rustdoc settings</span>\
+    <span class='in-band'>Rustdoc settings</span>\
 </h1>\
 <div class='settings'>{}</div>\
 <script src='{}settings{}.js'></script>",
-               self.settings.iter()
-                            .map(|(id, text, enabled)| {
-                                format!("<div class='setting-line'>\
-                                             <label class='toggle'>\
-                                                <input type='checkbox' id='{}' {}>\
-                                                <span class='slider'></span>\
-                                             </label>\
-                                             <div>{}</div>\
-                                         </div>", id, if *enabled { " checked" } else { "" }, text)
-                            })
-                            .collect::<String>(),
-               self.root_path,
-               self.suffix)
-    }
+            self.settings.iter()
+                        .map(|(id, text, enabled)| {
+                            format!("<div class='setting-line'>\
+                                            <label class='toggle'>\
+                                            <input type='checkbox' id='{}' {}>\
+                                            <span class='slider'></span>\
+                                            </label>\
+                                            <div>{}</div>\
+                                        </div>", id, if *enabled { " checked" } else { "" }, text)
+                        })
+                        .collect::<String>(),
+            self.root_path,
+            self.suffix)
+}
 }
 
 impl Context {
@@ -2205,108 +2205,108 @@ where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result {
 }
 
 impl<'a> fmt::Display for Item<'a> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        debug_assert!(!self.item.is_stripped());
-        // Write the breadcrumb trail header for the top
-        write!(fmt, "<h1 class='fqn'><span class='out-of-band'>")?;
-        if let Some(version) = self.item.stable_since() {
-            write!(fmt, "<span class='since' title='Stable since Rust version {0}'>{0}</span>",
-                   version)?;
-        }
-        write!(fmt,
-               "<span id='render-detail'>\
-                   <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \
-                      title=\"collapse all docs\">\
-                       [<span class='inner'>&#x2212;</span>]\
-                   </a>\
-               </span>")?;
-
-        // Write `src` tag
-        //
-        // When this item is part of a `pub use` in a downstream crate, the
-        // [src] link in the downstream documentation will actually come back to
-        // this page, and this link will be auto-clicked. The `id` attribute is
-        // used to find the link to auto-click.
-        if self.cx.shared.include_sources && !self.item.is_primitive() {
-            if let Some(l) = self.src_href() {
-                write!(fmt, "<a class='srclink' href='{}' title='{}'>[src]</a>",
-                       l, "goto source code")?;
-            }
-        }
-
-        write!(fmt, "</span>")?; // out-of-band
-        write!(fmt, "<span class='in-band'>")?;
-        match self.item.inner {
-            clean::ModuleItem(ref m) => if m.is_crate {
-                    write!(fmt, "Crate ")?;
-                } else {
-                    write!(fmt, "Module ")?;
-                },
-            clean::FunctionItem(..) | clean::ForeignFunctionItem(..) => write!(fmt, "Function ")?,
-            clean::TraitItem(..) => write!(fmt, "Trait ")?,
-            clean::StructItem(..) => write!(fmt, "Struct ")?,
-            clean::UnionItem(..) => write!(fmt, "Union ")?,
-            clean::EnumItem(..) => write!(fmt, "Enum ")?,
-            clean::TypedefItem(..) => write!(fmt, "Type Definition ")?,
-            clean::MacroItem(..) => write!(fmt, "Macro ")?,
-            clean::ProcMacroItem(ref mac) => match mac.kind {
-                MacroKind::Bang => write!(fmt, "Macro ")?,
-                MacroKind::Attr => write!(fmt, "Attribute Macro ")?,
-                MacroKind::Derive => write!(fmt, "Derive Macro ")?,
-            }
-            clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?,
-            clean::StaticItem(..) | clean::ForeignStaticItem(..) => write!(fmt, "Static ")?,
-            clean::ConstantItem(..) => write!(fmt, "Constant ")?,
-            clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?,
-            clean::KeywordItem(..) => write!(fmt, "Keyword ")?,
-            clean::OpaqueTyItem(..) => write!(fmt, "Opaque Type ")?,
-            clean::TraitAliasItem(..) => write!(fmt, "Trait Alias ")?,
-            _ => {
-                // We don't generate pages for any other type.
-                unreachable!();
-            }
-        }
-        if !self.item.is_primitive() && !self.item.is_keyword() {
-            let cur = &self.cx.current;
-            let amt = if self.item.is_mod() { cur.len() - 1 } else { cur.len() };
-            for (i, component) in cur.iter().enumerate().take(amt) {
-                write!(fmt, "<a href='{}index.html'>{}</a>::<wbr>",
-                       "../".repeat(cur.len() - i - 1),
-                       component)?;
-            }
-        }
-        write!(fmt, "<a class=\"{}\" href=''>{}</a>",
-               self.item.type_(), self.item.name.as_ref().unwrap())?;
-
-        write!(fmt, "</span></h1>")?; // in-band
-
-        match self.item.inner {
-            clean::ModuleItem(ref m) =>
-                item_module(fmt, self.cx, self.item, &m.items),
-            clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) =>
-                item_function(fmt, self.cx, self.item, f),
-            clean::TraitItem(ref t) => item_trait(fmt, self.cx, self.item, t),
-            clean::StructItem(ref s) => item_struct(fmt, self.cx, self.item, s),
-            clean::UnionItem(ref s) => item_union(fmt, self.cx, self.item, s),
-            clean::EnumItem(ref e) => item_enum(fmt, self.cx, self.item, e),
-            clean::TypedefItem(ref t, _) => item_typedef(fmt, self.cx, self.item, t),
-            clean::MacroItem(ref m) => item_macro(fmt, self.cx, self.item, m),
-            clean::ProcMacroItem(ref m) => item_proc_macro(fmt, self.cx, self.item, m),
-            clean::PrimitiveItem(ref p) => item_primitive(fmt, self.cx, self.item, p),
-            clean::StaticItem(ref i) | clean::ForeignStaticItem(ref i) =>
-                item_static(fmt, self.cx, self.item, i),
-            clean::ConstantItem(ref c) => item_constant(fmt, self.cx, self.item, c),
-            clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item),
-            clean::KeywordItem(ref k) => item_keyword(fmt, self.cx, self.item, k),
-            clean::OpaqueTyItem(ref e, _) => item_opaque_ty(fmt, self.cx, self.item, e),
-            clean::TraitAliasItem(ref ta) => item_trait_alias(fmt, self.cx, self.item, ta),
-            _ => {
-                // We don't generate pages for any other type.
-                unreachable!();
-            }
+fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+    debug_assert!(!self.item.is_stripped());
+    // Write the breadcrumb trail header for the top
+    write!(fmt, "<h1 class='fqn'><span class='out-of-band'>")?;
+    if let Some(version) = self.item.stable_since() {
+        write!(fmt, "<span class='since' title='Stable since Rust version {0}'>{0}</span>",
+                version)?;
+    }
+    write!(fmt,
+            "<span id='render-detail'>\
+                <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \
+                    title=\"collapse all docs\">\
+                    [<span class='inner'>&#x2212;</span>]\
+                </a>\
+            </span>")?;
+
+    // Write `src` tag
+    //
+    // When this item is part of a `pub use` in a downstream crate, the
+    // [src] link in the downstream documentation will actually come back to
+    // this page, and this link will be auto-clicked. The `id` attribute is
+    // used to find the link to auto-click.
+    if self.cx.shared.include_sources && !self.item.is_primitive() {
+        if let Some(l) = self.src_href() {
+            write!(fmt, "<a class='srclink' href='{}' title='{}'>[src]</a>",
+                    l, "goto source code")?;
+        }
+    }
+
+    write!(fmt, "</span>")?; // out-of-band
+    write!(fmt, "<span class='in-band'>")?;
+    match self.item.inner {
+        clean::ModuleItem(ref m) => if m.is_crate {
+                write!(fmt, "Crate ")?;
+            } else {
+                write!(fmt, "Module ")?;
+            },
+        clean::FunctionItem(..) | clean::ForeignFunctionItem(..) => write!(fmt, "Function ")?,
+        clean::TraitItem(..) => write!(fmt, "Trait ")?,
+        clean::StructItem(..) => write!(fmt, "Struct ")?,
+        clean::UnionItem(..) => write!(fmt, "Union ")?,
+        clean::EnumItem(..) => write!(fmt, "Enum ")?,
+        clean::TypedefItem(..) => write!(fmt, "Type Definition ")?,
+        clean::MacroItem(..) => write!(fmt, "Macro ")?,
+        clean::ProcMacroItem(ref mac) => match mac.kind {
+            MacroKind::Bang => write!(fmt, "Macro ")?,
+            MacroKind::Attr => write!(fmt, "Attribute Macro ")?,
+            MacroKind::Derive => write!(fmt, "Derive Macro ")?,
+        }
+        clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?,
+        clean::StaticItem(..) | clean::ForeignStaticItem(..) => write!(fmt, "Static ")?,
+        clean::ConstantItem(..) => write!(fmt, "Constant ")?,
+        clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?,
+        clean::KeywordItem(..) => write!(fmt, "Keyword ")?,
+        clean::OpaqueTyItem(..) => write!(fmt, "Opaque Type ")?,
+        clean::TraitAliasItem(..) => write!(fmt, "Trait Alias ")?,
+        _ => {
+            // We don't generate pages for any other type.
+            unreachable!();
+        }
+    }
+    if !self.item.is_primitive() && !self.item.is_keyword() {
+        let cur = &self.cx.current;
+        let amt = if self.item.is_mod() { cur.len() - 1 } else { cur.len() };
+        for (i, component) in cur.iter().enumerate().take(amt) {
+            write!(fmt, "<a href='{}index.html'>{}</a>::<wbr>",
+                    "../".repeat(cur.len() - i - 1),
+                    component)?;
+        }
+    }
+    write!(fmt, "<a class=\"{}\" href=''>{}</a>",
+            self.item.type_(), self.item.name.as_ref().unwrap())?;
+
+    write!(fmt, "</span></h1>")?; // in-band
+
+    match self.item.inner {
+        clean::ModuleItem(ref m) =>
+            item_module(fmt, self.cx, self.item, &m.items),
+        clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) =>
+            item_function(fmt, self.cx, self.item, f),
+        clean::TraitItem(ref t) => item_trait(fmt, self.cx, self.item, t),
+        clean::StructItem(ref s) => item_struct(fmt, self.cx, self.item, s),
+        clean::UnionItem(ref s) => item_union(fmt, self.cx, self.item, s),
+        clean::EnumItem(ref e) => item_enum(fmt, self.cx, self.item, e),
+        clean::TypedefItem(ref t, _) => item_typedef(fmt, self.cx, self.item, t),
+        clean::MacroItem(ref m) => item_macro(fmt, self.cx, self.item, m),
+        clean::ProcMacroItem(ref m) => item_proc_macro(fmt, self.cx, self.item, m),
+        clean::PrimitiveItem(ref p) => item_primitive(fmt, self.cx, self.item, p),
+        clean::StaticItem(ref i) | clean::ForeignStaticItem(ref i) =>
+            item_static(fmt, self.cx, self.item, i),
+        clean::ConstantItem(ref c) => item_constant(fmt, self.cx, self.item, c),
+        clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item),
+        clean::KeywordItem(ref k) => item_keyword(fmt, self.cx, self.item, k),
+        clean::OpaqueTyItem(ref e, _) => item_opaque_ty(fmt, self.cx, self.item, e),
+        clean::TraitAliasItem(ref ta) => item_trait_alias(fmt, self.cx, self.item, ta),
+        _ => {
+            // We don't generate pages for any other type.
+            unreachable!();
         }
     }
 }
+}
 
 fn item_path(ty: ItemType, name: &str) -> String {
     match ty {
@@ -3834,9 +3834,9 @@ fn render_assoc_items(w: &mut fmt::Formatter<'_>,
         struct RendererStruct<'a, 'b, 'c>(&'a Context, Vec<&'b &'b Impl>, &'c clean::Item);
 
         impl<'a, 'b, 'c> fmt::Display for RendererStruct<'a, 'b, 'c> {
-            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-                render_impls(self.0, fmt, &self.1, self.2)
-            }
+        fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+            render_impls(self.0, fmt, &self.1, self.2)
+        }
         }
 
         let impls = RendererStruct(cx, concrete, containing_item).to_string();
@@ -4264,97 +4264,97 @@ fn item_foreign_type(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item)
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
 
-    fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) {
-        let parentlen = cx.current.len() - if it.is_mod() {1} else {0};
-
-        if it.is_struct() || it.is_trait() || it.is_primitive() || it.is_union()
-            || it.is_enum() || it.is_mod() || it.is_typedef() {
-            write!(buffer, "<p class='location'>{}{}</p>",
-                match it.inner {
-                    clean::StructItem(..) => "Struct ",
-                    clean::TraitItem(..) => "Trait ",
-                    clean::PrimitiveItem(..) => "Primitive Type ",
-                    clean::UnionItem(..) => "Union ",
-                    clean::EnumItem(..) => "Enum ",
-                    clean::TypedefItem(..) => "Type Definition ",
-                    clean::ForeignTypeItem => "Foreign Type ",
-                    clean::ModuleItem(..) => if it.is_crate() {
-                        "Crate "
-                    } else {
-                        "Module "
-                    },
-                    _ => "",
+fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) {
+    let parentlen = cx.current.len() - if it.is_mod() {1} else {0};
+
+    if it.is_struct() || it.is_trait() || it.is_primitive() || it.is_union()
+        || it.is_enum() || it.is_mod() || it.is_typedef() {
+        write!(buffer, "<p class='location'>{}{}</p>",
+            match it.inner {
+                clean::StructItem(..) => "Struct ",
+                clean::TraitItem(..) => "Trait ",
+                clean::PrimitiveItem(..) => "Primitive Type ",
+                clean::UnionItem(..) => "Union ",
+                clean::EnumItem(..) => "Enum ",
+                clean::TypedefItem(..) => "Type Definition ",
+                clean::ForeignTypeItem => "Foreign Type ",
+                clean::ModuleItem(..) => if it.is_crate() {
+                    "Crate "
+                } else {
+                    "Module "
                 },
-                it.name.as_ref().unwrap());
-        }
-
-        if it.is_crate() {
-            if let Some(ref version) = cache().crate_version {
-                write!(buffer,
-                       "<div class='block version'>\
-                        <p>Version {}</p>\
-                        </div>",
-                       version);
-            }
-        }
-
-        write!(buffer, "<div class=\"sidebar-elems\">");
-        if it.is_crate() {
-            write!(buffer, "<a id='all-types' href='all.html'><p>See all {}'s items</p></a>",
-                   it.name.as_ref().expect("crates always have a name"));
-        }
-        match it.inner {
-            clean::StructItem(ref s) => sidebar_struct(buffer, it, s),
-            clean::TraitItem(ref t) => sidebar_trait(buffer, it, t),
-            clean::PrimitiveItem(ref p) => sidebar_primitive(buffer, it, p),
-            clean::UnionItem(ref u) => sidebar_union(buffer, it, u),
-            clean::EnumItem(ref e) => sidebar_enum(buffer, it, e),
-            clean::TypedefItem(ref t, _) => sidebar_typedef(buffer, it, t),
-            clean::ModuleItem(ref m) => sidebar_module(buffer, it, &m.items),
-            clean::ForeignTypeItem => sidebar_foreign_type(buffer, it),
-            _ => (),
-        }
-
-        // The sidebar is designed to display sibling functions, modules and
-        // other miscellaneous information. since there are lots of sibling
-        // items (and that causes quadratic growth in large modules),
-        // we refactor common parts into a shared JavaScript file per module.
-        // still, we don't move everything into JS because we want to preserve
-        // as much HTML as possible in order to allow non-JS-enabled browsers
-        // to navigate the documentation (though slightly inefficiently).
-
-        write!(buffer, "<p class='location'>");
-        for (i, name) in cx.current.iter().take(parentlen).enumerate() {
-            if i > 0 {
-                write!(buffer, "::<wbr>");
-            }
-            write!(buffer, "<a href='{}index.html'>{}</a>",
-                   &cx.root_path()[..(cx.current.len() - i - 1) * 3],
-                   *name);
-        }
-        write!(buffer, "</p>");
-
-        // Sidebar refers to the enclosing module, not this module.
-        let relpath = if it.is_mod() { "../" } else { "" };
-        write!(buffer,
-               "<script>window.sidebarCurrent = {{\
-                   name: '{name}', \
-                   ty: '{ty}', \
-                   relpath: '{path}'\
-                }};</script>",
-               name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""),
-               ty = it.type_().css_class(),
-               path = relpath);
-        if parentlen == 0 {
-            // There is no sidebar-items.js beyond the crate root path
-            // FIXME maybe dynamic crate loading can be merged here
-        } else {
-            write!(buffer, "<script defer src=\"{path}sidebar-items.js\"></script>",
-                   path = relpath);
-        }
-        // Closes sidebar-elems div.
-        write!(buffer, "</div>");
+                _ => "",
+            },
+            it.name.as_ref().unwrap());
+    }
+
+    if it.is_crate() {
+        if let Some(ref version) = cache().crate_version {
+            write!(buffer,
+                    "<div class='block version'>\
+                    <p>Version {}</p>\
+                    </div>",
+                    version);
+        }
+    }
+
+    write!(buffer, "<div class=\"sidebar-elems\">");
+    if it.is_crate() {
+        write!(buffer, "<a id='all-types' href='all.html'><p>See all {}'s items</p></a>",
+                it.name.as_ref().expect("crates always have a name"));
+    }
+    match it.inner {
+        clean::StructItem(ref s) => sidebar_struct(buffer, it, s),
+        clean::TraitItem(ref t) => sidebar_trait(buffer, it, t),
+        clean::PrimitiveItem(ref p) => sidebar_primitive(buffer, it, p),
+        clean::UnionItem(ref u) => sidebar_union(buffer, it, u),
+        clean::EnumItem(ref e) => sidebar_enum(buffer, it, e),
+        clean::TypedefItem(ref t, _) => sidebar_typedef(buffer, it, t),
+        clean::ModuleItem(ref m) => sidebar_module(buffer, it, &m.items),
+        clean::ForeignTypeItem => sidebar_foreign_type(buffer, it),
+        _ => (),
+    }
+
+    // The sidebar is designed to display sibling functions, modules and
+    // other miscellaneous information. since there are lots of sibling
+    // items (and that causes quadratic growth in large modules),
+    // we refactor common parts into a shared JavaScript file per module.
+    // still, we don't move everything into JS because we want to preserve
+    // as much HTML as possible in order to allow non-JS-enabled browsers
+    // to navigate the documentation (though slightly inefficiently).
+
+    write!(buffer, "<p class='location'>");
+    for (i, name) in cx.current.iter().take(parentlen).enumerate() {
+        if i > 0 {
+            write!(buffer, "::<wbr>");
+        }
+        write!(buffer, "<a href='{}index.html'>{}</a>",
+                &cx.root_path()[..(cx.current.len() - i - 1) * 3],
+                *name);
+    }
+    write!(buffer, "</p>");
+
+    // Sidebar refers to the enclosing module, not this module.
+    let relpath = if it.is_mod() { "../" } else { "" };
+    write!(buffer,
+            "<script>window.sidebarCurrent = {{\
+                name: '{name}', \
+                ty: '{ty}', \
+                relpath: '{path}'\
+            }};</script>",
+            name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""),
+            ty = it.type_().css_class(),
+            path = relpath);
+    if parentlen == 0 {
+        // There is no sidebar-items.js beyond the crate root path
+        // FIXME maybe dynamic crate loading can be merged here
+    } else {
+        write!(buffer, "<script defer src=\"{path}sidebar-items.js\"></script>",
+                path = relpath);
     }
+    // Closes sidebar-elems div.
+    write!(buffer, "</div>");
+}
 
 fn get_next_url(used_links: &mut FxHashSet<String>, url: String) -> String {
     if used_links.insert(url.clone()) {
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 94ae14226097f..6dccfdadf0fb8 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -160,22 +160,22 @@ where
 struct Source<'a>(&'a str);
 
 impl<'a> fmt::Display for Source<'a> {
-    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let Source(s) = *self;
-        let lines = s.lines().count();
-        let mut cols = 0;
-        let mut tmp = lines;
-        while tmp > 0 {
-            cols += 1;
-            tmp /= 10;
-        }
-        write!(fmt, "<pre class=\"line-numbers\">")?;
-        for i in 1..=lines {
-            write!(fmt, "<span id=\"{0}\">{0:1$}</span>\n", i, cols)?;
-        }
-        write!(fmt, "</pre>")?;
-        write!(fmt, "{}",
-               highlight::render_with_highlighting(s, None, None, None))?;
-        Ok(())
+fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+    let Source(s) = *self;
+    let lines = s.lines().count();
+    let mut cols = 0;
+    let mut tmp = lines;
+    while tmp > 0 {
+        cols += 1;
+        tmp /= 10;
     }
+    write!(fmt, "<pre class=\"line-numbers\">")?;
+    for i in 1..=lines {
+        write!(fmt, "<span id=\"{0}\">{0:1$}</span>\n", i, cols)?;
+    }
+    write!(fmt, "</pre>")?;
+    write!(fmt, "{}",
+            highlight::render_with_highlighting(s, None, None, None))?;
+    Ok(())
+}
 }

From 3f0e77f19c16eb3cd46390ab0082ad749cb1c5b5 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 12:18:25 -0400
Subject: [PATCH 601/943] layout::render takes Print instead of fmt::Display

---
 src/librustdoc/html/format.rs  |  6 +++++-
 src/librustdoc/html/layout.rs  |  7 +++----
 src/librustdoc/html/render.rs  | 10 +++++-----
 src/librustdoc/html/sources.rs |  3 ++-
 4 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index f3c40c8568bb6..80f34fb17d2e8 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -99,7 +99,11 @@ impl Buffer {
         self.into_inner()
     }
 
-    crate fn display<T: fmt::Display>(&mut self, t: T) {
+    crate fn with_formatter<T: FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result>(&mut self, t: T) {
+        self.from_display(display_fn(move |f| (t)(f)));
+    }
+
+    crate fn from_display<T: std::fmt::Display>(&mut self, t: T) {
         if self.for_html {
             write!(self, "{}", t);
         } else {
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 1202f411f912c..56074f4ab1192 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -1,4 +1,3 @@
-use std::fmt;
 use std::path::PathBuf;
 
 use crate::externalfiles::ExternalHtml;
@@ -31,11 +30,11 @@ pub struct Page<'a> {
     pub static_extra_scripts: &'a [&'a str],
 }
 
-pub fn render<T: fmt::Display, S: Print>(
+pub fn render<T: Print, S: Print>(
     layout: &Layout,
     page: &Page<'_>,
     sidebar: S,
-    t: &T,
+    t: T,
     themes: &[PathBuf],
 ) -> String {
     let static_root_path = page.static_root_path.unwrap_or(page.root_path);
@@ -175,7 +174,7 @@ pub fn render<T: fmt::Display, S: Print>(
     } else {
         String::new()
     },
-    content   = *t,
+    content   = Buffer::html().to_display(t),
     static_root_path = static_root_path,
     root_path = page.root_path,
     css_class = page.css_class,
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 1d1e54fc9eaba..4514a540f543a 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -65,7 +65,7 @@ use crate::docfs::{DocFS, ErrorStorage, PathError};
 use crate::doctree;
 use crate::fold::DocFolder;
 use crate::html::escape::Escape;
-use crate::html::format::{Print, Buffer, AsyncSpace, ConstnessSpace};
+use crate::html::format::{Buffer, AsyncSpace, ConstnessSpace};
 use crate::html::format::{GenericBounds, WhereClause, href, AbiSpace, DefaultSpace};
 use crate::html::format::{VisSpace, Function, UnsafetySpace, MutableSpace};
 use crate::html::format::fmt_impl_for_trait_page;
@@ -1172,7 +1172,7 @@ themePicker.onblur = handleThemeButtonsBlur;
                                     })
                                     .collect::<String>());
             let v = layout::render(&cx.shared.layout,
-                           &page, "", &content,
+                           &page, "", content,
                            &cx.shared.themes);
             cx.shared.fs.write(&dst, v.as_bytes())?;
         }
@@ -1919,7 +1919,7 @@ impl Context {
             String::new()
         };
         let v = layout::render(&self.shared.layout,
-                       &page, sidebar, &all,
+                       &page, sidebar, |buf: &mut Buffer| buf.from_display(all),
                        &self.shared.themes);
         self.shared.fs.write(&final_file, v.as_bytes())?;
 
@@ -1935,7 +1935,7 @@ impl Context {
         themes.push(PathBuf::from("settings.css"));
         let v = layout::render(
             &self.shared.layout,
-            &page, sidebar, &settings,
+            &page, sidebar, |buf: &mut Buffer| buf.from_display(settings),
             &themes);
         self.shared.fs.write(&settings_file, v.as_bytes())?;
 
@@ -1993,7 +1993,7 @@ impl Context {
         if !self.render_redirect_pages {
             layout::render(&self.shared.layout, &page,
                            |buf: &mut _| print_sidebar(self, it, buf),
-                           &Item{ cx: self, item: it },
+                           |buf: &mut Buffer| buf.from_display(Item { cx: self, item: it }),
                            &self.shared.themes)
         } else {
             let mut url = self.root_path();
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 6dccfdadf0fb8..e94ae1d968ef5 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -4,6 +4,7 @@ use crate::fold::DocFolder;
 use crate::html::layout;
 use crate::html::render::{Error, SharedContext, BASIC_KEYWORDS};
 use crate::html::highlight;
+use crate::html::format::Buffer;
 use std::ffi::OsStr;
 use std::fs;
 use std::path::{Component, Path, PathBuf};
@@ -120,7 +121,7 @@ impl<'a> SourceCollector<'a> {
             static_extra_scripts: &[&format!("source-script{}", self.scx.resource_suffix)],
         };
         let v = layout::render(&self.scx.layout,
-                       &page, "", &Source(contents),
+                       &page, "", |buf: &mut Buffer| buf.from_display(Source(&contents)),
                        &self.scx.themes);
         self.scx.fs.write(&cur, v.as_bytes())?;
         self.scx.local_sources.insert(p.clone(), href);

From bb40d5fa498603f041dcf1092099c0b93928e442 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 12:20:56 -0400
Subject: [PATCH 602/943] Move Source to Buffer

---
 src/librustdoc/html/sources.rs | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index e94ae1d968ef5..d840683a7af87 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -8,7 +8,6 @@ use crate::html::format::Buffer;
 use std::ffi::OsStr;
 use std::fs;
 use std::path::{Component, Path, PathBuf};
-use std::fmt;
 use syntax::source_map::FileName;
 
 crate fn render(dst: &Path, scx: &mut SharedContext,
@@ -121,7 +120,7 @@ impl<'a> SourceCollector<'a> {
             static_extra_scripts: &[&format!("source-script{}", self.scx.resource_suffix)],
         };
         let v = layout::render(&self.scx.layout,
-                       &page, "", |buf: &mut Buffer| buf.from_display(Source(&contents)),
+                       &page, "", |buf: &mut _| print_src(buf, &contents),
                        &self.scx.themes);
         self.scx.fs.write(&cur, v.as_bytes())?;
         self.scx.local_sources.insert(p.clone(), href);
@@ -158,11 +157,7 @@ where
 
 /// Wrapper struct to render the source code of a file. This will do things like
 /// adding line numbers to the left-hand side.
-struct Source<'a>(&'a str);
-
-impl<'a> fmt::Display for Source<'a> {
-fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-    let Source(s) = *self;
+fn print_src(buf: &mut Buffer, s: &str) {
     let lines = s.lines().count();
     let mut cols = 0;
     let mut tmp = lines;
@@ -170,13 +165,11 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
         cols += 1;
         tmp /= 10;
     }
-    write!(fmt, "<pre class=\"line-numbers\">")?;
+    write!(buf, "<pre class=\"line-numbers\">");
     for i in 1..=lines {
-        write!(fmt, "<span id=\"{0}\">{0:1$}</span>\n", i, cols)?;
+        write!(buf, "<span id=\"{0}\">{0:1$}</span>\n", i, cols);
     }
-    write!(fmt, "</pre>")?;
-    write!(fmt, "{}",
-            highlight::render_with_highlighting(s, None, None, None))?;
-    Ok(())
-}
+    write!(buf, "</pre>");
+    write!(buf, "{}",
+            highlight::render_with_highlighting(s, None, None, None));
 }

From 17bef30d0b1cc3851fb76fdd84b4d15bb629dc39 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 12:27:27 -0400
Subject: [PATCH 603/943] Settings to function

---
 src/librustdoc/html/render.rs | 55 ++++++++++++-----------------------
 1 file changed, 19 insertions(+), 36 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 4514a540f543a..2eb2ba4e2b201 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1801,42 +1801,25 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 }
 }
 
-#[derive(Debug)]
-struct Settings<'a> {
+fn settings(root_path: &str, suffix: &str) -> String {
     // (id, explanation, default value)
-    settings: Vec<(&'static str, &'static str, bool)>,
-    root_path: &'a str,
-    suffix: &'a str,
-}
-
-impl<'a> Settings<'a> {
-    pub fn new(root_path: &'a str, suffix: &'a str) -> Settings<'a> {
-        Settings {
-            settings: vec![
-                ("item-declarations", "Auto-hide item declarations.", true),
-                ("item-attributes", "Auto-hide item attributes.", true),
-                ("trait-implementations", "Auto-hide trait implementations documentation",
-                 true),
-                ("method-docs", "Auto-hide item methods' documentation", false),
-                ("go-to-only-result", "Directly go to item in search if there is only one result",
-                 false),
-                ("line-numbers", "Show line numbers on code examples", false),
-            ],
-            root_path,
-            suffix,
-        }
-    }
-}
-
-impl<'a> fmt::Display for Settings<'a> {
-fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    write!(f,
+    let settings = [
+        ("item-declarations", "Auto-hide item declarations.", true),
+        ("item-attributes", "Auto-hide item attributes.", true),
+        ("trait-implementations", "Auto-hide trait implementations documentation",
+            true),
+        ("method-docs", "Auto-hide item methods' documentation", false),
+        ("go-to-only-result", "Directly go to item in search if there is only one result",
+            false),
+        ("line-numbers", "Show line numbers on code examples", false),
+    ];
+    format!(
 "<h1 class='fqn'>\
     <span class='in-band'>Rustdoc settings</span>\
 </h1>\
 <div class='settings'>{}</div>\
 <script src='{}settings{}.js'></script>",
-            self.settings.iter()
+            settings.iter()
                         .map(|(id, text, enabled)| {
                             format!("<div class='setting-line'>\
                                             <label class='toggle'>\
@@ -1847,9 +1830,8 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                                         </div>", id, if *enabled { " checked" } else { "" }, text)
                         })
                         .collect::<String>(),
-            self.root_path,
-            self.suffix)
-}
+            root_path,
+            suffix)
 }
 
 impl Context {
@@ -1924,8 +1906,6 @@ impl Context {
         self.shared.fs.write(&final_file, v.as_bytes())?;
 
         // Generating settings page.
-        let settings = Settings::new(self.shared.static_root_path.as_deref().unwrap_or("./"),
-                                     &self.shared.resource_suffix);
         page.title = "Rustdoc settings";
         page.description = "Settings of Rustdoc";
         page.root_path = "./";
@@ -1935,7 +1915,10 @@ impl Context {
         themes.push(PathBuf::from("settings.css"));
         let v = layout::render(
             &self.shared.layout,
-            &page, sidebar, |buf: &mut Buffer| buf.from_display(settings),
+            &page, sidebar, settings(
+                self.shared.static_root_path.as_deref().unwrap_or("./"),
+                &self.shared.resource_suffix
+            ),
             &themes);
         self.shared.fs.write(&settings_file, v.as_bytes())?;
 

From a502e856034bcd4bc38152b3bd74cad792b62c63 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 12:31:55 -0400
Subject: [PATCH 604/943] AllTypes to function

---
 src/librustdoc/html/render.rs | 62 +++++++++++++++++------------------
 1 file changed, 30 insertions(+), 32 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 2eb2ba4e2b201..ee7981aba013a 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1757,8 +1757,7 @@ impl AllTypes {
     }
 }
 
-fn print_entries(f: &mut fmt::Formatter<'_>, e: &FxHashSet<ItemEntry>, title: &str,
-                 class: &str) -> fmt::Result {
+fn print_entries(f: &mut Buffer, e: &FxHashSet<ItemEntry>, title: &str, class: &str) {
     if !e.is_empty() {
         let mut e: Vec<&ItemEntry> = e.iter().collect();
         e.sort();
@@ -1766,39 +1765,38 @@ fn print_entries(f: &mut fmt::Formatter<'_>, e: &FxHashSet<ItemEntry>, title: &s
                title,
                Escape(title),
                class,
-               e.iter().map(|s| format!("<li>{}</li>", s)).collect::<String>())?;
+               e.iter().map(|s| format!("<li>{}</li>", s)).collect::<String>());
     }
-    Ok(())
 }
 
-impl fmt::Display for AllTypes {
-fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-    write!(f,
-"<h1 class='fqn'>\
-    <span class='out-of-band'>\
-        <span id='render-detail'>\
-            <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" title=\"collapse all docs\">\
-                [<span class='inner'>&#x2212;</span>]\
-            </a>\
+impl AllTypes {
+    fn print(self, f: &mut Buffer) {
+        write!(f,
+    "<h1 class='fqn'>\
+        <span class='out-of-band'>\
+            <span id='render-detail'>\
+                <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" title=\"collapse all docs\">\
+                    [<span class='inner'>&#x2212;</span>]\
+                </a>\
+            </span>
         </span>
-    </span>
-    <span class='in-band'>List of all items</span>\
-</h1>")?;
-    print_entries(f, &self.structs, "Structs", "structs")?;
-    print_entries(f, &self.enums, "Enums", "enums")?;
-    print_entries(f, &self.unions, "Unions", "unions")?;
-    print_entries(f, &self.primitives, "Primitives", "primitives")?;
-    print_entries(f, &self.traits, "Traits", "traits")?;
-    print_entries(f, &self.macros, "Macros", "macros")?;
-    print_entries(f, &self.attributes, "Attribute Macros", "attributes")?;
-    print_entries(f, &self.derives, "Derive Macros", "derives")?;
-    print_entries(f, &self.functions, "Functions", "functions")?;
-    print_entries(f, &self.typedefs, "Typedefs", "typedefs")?;
-    print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-aliases")?;
-    print_entries(f, &self.opaque_tys, "Opaque Types", "opaque-types")?;
-    print_entries(f, &self.statics, "Statics", "statics")?;
-    print_entries(f, &self.constants, "Constants", "constants")
-}
+        <span class='in-band'>List of all items</span>\
+    </h1>");
+        print_entries(f, &self.structs, "Structs", "structs");
+        print_entries(f, &self.enums, "Enums", "enums");
+        print_entries(f, &self.unions, "Unions", "unions");
+        print_entries(f, &self.primitives, "Primitives", "primitives");
+        print_entries(f, &self.traits, "Traits", "traits");
+        print_entries(f, &self.macros, "Macros", "macros");
+        print_entries(f, &self.attributes, "Attribute Macros", "attributes");
+        print_entries(f, &self.derives, "Derive Macros", "derives");
+        print_entries(f, &self.functions, "Functions", "functions");
+        print_entries(f, &self.typedefs, "Typedefs", "typedefs");
+        print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-aliases");
+        print_entries(f, &self.opaque_tys, "Opaque Types", "opaque-types");
+        print_entries(f, &self.statics, "Statics", "statics");
+        print_entries(f, &self.constants, "Constants", "constants")
+    }
 }
 
 fn settings(root_path: &str, suffix: &str) -> String {
@@ -1901,7 +1899,7 @@ impl Context {
             String::new()
         };
         let v = layout::render(&self.shared.layout,
-                       &page, sidebar, |buf: &mut Buffer| buf.from_display(all),
+                       &page, sidebar, |buf: &mut Buffer| all.print(buf),
                        &self.shared.themes);
         self.shared.fs.write(&final_file, v.as_bytes())?;
 

From c1c1e86d5a03796ec4442372b185fb1e20d81124 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 13:29:31 -0400
Subject: [PATCH 605/943] Item to function

---
 src/librustdoc/html/render.rs | 163 ++++++++++++++++------------------
 1 file changed, 79 insertions(+), 84 deletions(-)

diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index ee7981aba013a..fc23ffe2b8ca7 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -381,12 +381,6 @@ pub struct RenderInfo {
 // Helper structs for rendering items/sidebars and carrying along contextual
 // information
 
-#[derive(Copy, Clone)]
-struct Item<'a> {
-    cx: &'a Context,
-    item: &'a clean::Item,
-}
-
 /// Struct representing one entry in the JS search index. These are all emitted
 /// by hand to a large JS file at the end of cache-creation.
 #[derive(Debug)]
@@ -1974,7 +1968,7 @@ impl Context {
         if !self.render_redirect_pages {
             layout::render(&self.shared.layout, &page,
                            |buf: &mut _| print_sidebar(self, it, buf),
-                           |buf: &mut Buffer| buf.from_display(Item { cx: self, item: it }),
+                           |buf: &mut _| print_item(self, it, buf),
                            &self.shared.themes)
         } else {
             let mut url = self.root_path();
@@ -2115,7 +2109,7 @@ impl Context {
     }
 }
 
-impl<'a> Item<'a> {
+impl Context {
     /// Generates a url appropriate for an `href` attribute back to the source of
     /// this item.
     ///
@@ -2125,26 +2119,26 @@ impl<'a> Item<'a> {
     /// If `None` is returned, then a source link couldn't be generated. This
     /// may happen, for example, with externally inlined items where the source
     /// of their crate documentation isn't known.
-    fn src_href(&self) -> Option<String> {
-        let mut root = self.cx.root_path();
+    fn src_href(&self, item: &clean::Item) -> Option<String> {
+        let mut root = self.root_path();
 
         let cache = cache();
         let mut path = String::new();
 
         // We can safely ignore macros from other libraries
-        let file = match self.item.source.filename {
+        let file = match item.source.filename {
             FileName::Real(ref path) => path,
             _ => return None,
         };
 
-        let (krate, path) = if self.item.def_id.is_local() {
-            if let Some(path) = self.cx.shared.local_sources.get(file) {
-                (&self.cx.shared.layout.krate, path)
+        let (krate, path) = if item.def_id.is_local() {
+            if let Some(path) = self.shared.local_sources.get(file) {
+                (&self.shared.layout.krate, path)
             } else {
                 return None;
             }
         } else {
-            let (krate, src_root) = match *cache.extern_locations.get(&self.item.def_id.krate)? {
+            let (krate, src_root) = match *cache.extern_locations.get(&item.def_id.krate)? {
                 (ref name, ref src, Local) => (name, src),
                 (ref name, ref src, Remote(ref s)) => {
                     root = s.to_string();
@@ -2164,10 +2158,10 @@ impl<'a> Item<'a> {
             (krate, &path)
         };
 
-        let lines = if self.item.source.loline == self.item.source.hiline {
-            self.item.source.loline.to_string()
+        let lines = if item.source.loline == item.source.hiline {
+            item.source.loline.to_string()
         } else {
-            format!("{}-{}", self.item.source.loline, self.item.source.hiline)
+            format!("{}-{}", item.source.loline, item.source.hiline)
         };
         Some(format!("{root}src/{krate}/{path}#{lines}",
                      root = Escape(&root),
@@ -2185,22 +2179,21 @@ where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result {
     write!(w, "</div>")
 }
 
-impl<'a> fmt::Display for Item<'a> {
-fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-    debug_assert!(!self.item.is_stripped());
+fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer) {
+    debug_assert!(!item.is_stripped());
     // Write the breadcrumb trail header for the top
-    write!(fmt, "<h1 class='fqn'><span class='out-of-band'>")?;
-    if let Some(version) = self.item.stable_since() {
-        write!(fmt, "<span class='since' title='Stable since Rust version {0}'>{0}</span>",
-                version)?;
+    write!(buf, "<h1 class='fqn'><span class='out-of-band'>");
+    if let Some(version) = item.stable_since() {
+        write!(buf, "<span class='since' title='Stable since Rust version {0}'>{0}</span>",
+                version);
     }
-    write!(fmt,
+    write!(buf,
             "<span id='render-detail'>\
                 <a id=\"toggle-all-docs\" href=\"javascript:void(0)\" \
                     title=\"collapse all docs\">\
                     [<span class='inner'>&#x2212;</span>]\
                 </a>\
-            </span>")?;
+            </span>");
 
     // Write `src` tag
     //
@@ -2208,85 +2201,87 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
     // [src] link in the downstream documentation will actually come back to
     // this page, and this link will be auto-clicked. The `id` attribute is
     // used to find the link to auto-click.
-    if self.cx.shared.include_sources && !self.item.is_primitive() {
-        if let Some(l) = self.src_href() {
-            write!(fmt, "<a class='srclink' href='{}' title='{}'>[src]</a>",
-                    l, "goto source code")?;
+    if cx.shared.include_sources && !item.is_primitive() {
+        if let Some(l) = cx.src_href(item) {
+            write!(buf, "<a class='srclink' href='{}' title='{}'>[src]</a>",
+                    l, "goto source code");
         }
     }
 
-    write!(fmt, "</span>")?; // out-of-band
-    write!(fmt, "<span class='in-band'>")?;
-    match self.item.inner {
+    write!(buf, "</span>"); // out-of-band
+    write!(buf, "<span class='in-band'>");
+    let name = match item.inner {
         clean::ModuleItem(ref m) => if m.is_crate {
-                write!(fmt, "Crate ")?;
+                "Crate "
             } else {
-                write!(fmt, "Module ")?;
+                "Module "
             },
-        clean::FunctionItem(..) | clean::ForeignFunctionItem(..) => write!(fmt, "Function ")?,
-        clean::TraitItem(..) => write!(fmt, "Trait ")?,
-        clean::StructItem(..) => write!(fmt, "Struct ")?,
-        clean::UnionItem(..) => write!(fmt, "Union ")?,
-        clean::EnumItem(..) => write!(fmt, "Enum ")?,
-        clean::TypedefItem(..) => write!(fmt, "Type Definition ")?,
-        clean::MacroItem(..) => write!(fmt, "Macro ")?,
+        clean::FunctionItem(..) | clean::ForeignFunctionItem(..) => "Function ",
+        clean::TraitItem(..) => "Trait ",
+        clean::StructItem(..) => "Struct ",
+        clean::UnionItem(..) => "Union ",
+        clean::EnumItem(..) => "Enum ",
+        clean::TypedefItem(..) => "Type Definition ",
+        clean::MacroItem(..) => "Macro ",
         clean::ProcMacroItem(ref mac) => match mac.kind {
-            MacroKind::Bang => write!(fmt, "Macro ")?,
-            MacroKind::Attr => write!(fmt, "Attribute Macro ")?,
-            MacroKind::Derive => write!(fmt, "Derive Macro ")?,
-        }
-        clean::PrimitiveItem(..) => write!(fmt, "Primitive Type ")?,
-        clean::StaticItem(..) | clean::ForeignStaticItem(..) => write!(fmt, "Static ")?,
-        clean::ConstantItem(..) => write!(fmt, "Constant ")?,
-        clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?,
-        clean::KeywordItem(..) => write!(fmt, "Keyword ")?,
-        clean::OpaqueTyItem(..) => write!(fmt, "Opaque Type ")?,
-        clean::TraitAliasItem(..) => write!(fmt, "Trait Alias ")?,
+            MacroKind::Bang => "Macro ",
+            MacroKind::Attr => "Attribute Macro ",
+            MacroKind::Derive => "Derive Macro ",
+        }
+        clean::PrimitiveItem(..) => "Primitive Type ",
+        clean::StaticItem(..) | clean::ForeignStaticItem(..) => "Static ",
+        clean::ConstantItem(..) => "Constant ",
+        clean::ForeignTypeItem => "Foreign Type ",
+        clean::KeywordItem(..) => "Keyword ",
+        clean::OpaqueTyItem(..) => "Opaque Type ",
+        clean::TraitAliasItem(..) => "Trait Alias ",
         _ => {
             // We don't generate pages for any other type.
             unreachable!();
         }
-    }
-    if !self.item.is_primitive() && !self.item.is_keyword() {
-        let cur = &self.cx.current;
-        let amt = if self.item.is_mod() { cur.len() - 1 } else { cur.len() };
+    };
+    buf.write_str(name);
+    if !item.is_primitive() && !item.is_keyword() {
+        let cur = &cx.current;
+        let amt = if item.is_mod() { cur.len() - 1 } else { cur.len() };
         for (i, component) in cur.iter().enumerate().take(amt) {
-            write!(fmt, "<a href='{}index.html'>{}</a>::<wbr>",
+            write!(buf, "<a href='{}index.html'>{}</a>::<wbr>",
                     "../".repeat(cur.len() - i - 1),
-                    component)?;
+                    component);
         }
     }
-    write!(fmt, "<a class=\"{}\" href=''>{}</a>",
-            self.item.type_(), self.item.name.as_ref().unwrap())?;
+    write!(buf, "<a class=\"{}\" href=''>{}</a>",
+            item.type_(), item.name.as_ref().unwrap());
 
-    write!(fmt, "</span></h1>")?; // in-band
+    write!(buf, "</span></h1>"); // in-band
 
-    match self.item.inner {
+    buf.with_formatter(|fmt| {
+    match item.inner {
         clean::ModuleItem(ref m) =>
-            item_module(fmt, self.cx, self.item, &m.items),
+            item_module(fmt, cx, item, &m.items),
         clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) =>
-            item_function(fmt, self.cx, self.item, f),
-        clean::TraitItem(ref t) => item_trait(fmt, self.cx, self.item, t),
-        clean::StructItem(ref s) => item_struct(fmt, self.cx, self.item, s),
-        clean::UnionItem(ref s) => item_union(fmt, self.cx, self.item, s),
-        clean::EnumItem(ref e) => item_enum(fmt, self.cx, self.item, e),
-        clean::TypedefItem(ref t, _) => item_typedef(fmt, self.cx, self.item, t),
-        clean::MacroItem(ref m) => item_macro(fmt, self.cx, self.item, m),
-        clean::ProcMacroItem(ref m) => item_proc_macro(fmt, self.cx, self.item, m),
-        clean::PrimitiveItem(ref p) => item_primitive(fmt, self.cx, self.item, p),
+            item_function(fmt, cx, item, f),
+        clean::TraitItem(ref t) => item_trait(fmt, cx, item, t),
+        clean::StructItem(ref s) => item_struct(fmt, cx, item, s),
+        clean::UnionItem(ref s) => item_union(fmt, cx, item, s),
+        clean::EnumItem(ref e) => item_enum(fmt, cx, item, e),
+        clean::TypedefItem(ref t, _) => item_typedef(fmt, cx, item, t),
+        clean::MacroItem(ref m) => item_macro(fmt, cx, item, m),
+        clean::ProcMacroItem(ref m) => item_proc_macro(fmt, cx, item, m),
+        clean::PrimitiveItem(ref p) => item_primitive(fmt, cx, item, p),
         clean::StaticItem(ref i) | clean::ForeignStaticItem(ref i) =>
-            item_static(fmt, self.cx, self.item, i),
-        clean::ConstantItem(ref c) => item_constant(fmt, self.cx, self.item, c),
-        clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item),
-        clean::KeywordItem(ref k) => item_keyword(fmt, self.cx, self.item, k),
-        clean::OpaqueTyItem(ref e, _) => item_opaque_ty(fmt, self.cx, self.item, e),
-        clean::TraitAliasItem(ref ta) => item_trait_alias(fmt, self.cx, self.item, ta),
+            item_static(fmt, cx, item, i),
+        clean::ConstantItem(ref c) => item_constant(fmt, cx, item, c),
+        clean::ForeignTypeItem => item_foreign_type(fmt, cx, item),
+        clean::KeywordItem(ref k) => item_keyword(fmt, cx, item, k),
+        clean::OpaqueTyItem(ref e, _) => item_opaque_ty(fmt, cx, item, e),
+        clean::TraitAliasItem(ref ta) => item_trait_alias(fmt, cx, item, ta),
         _ => {
             // We don't generate pages for any other type.
             unreachable!();
         }
     }
-}
+    })
 }
 
 fn item_path(ty: ItemType, name: &str) -> String {
@@ -4004,7 +3999,7 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
         write!(w, "<a href='#{}' class='anchor'></a>", id)?;
         let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]);
         render_stability_since_raw(w, since, outer_version)?;
-        if let Some(l) = (Item { item: &i.impl_item, cx: cx }).src_href() {
+        if let Some(l) = cx.src_href(&i.impl_item) {
             write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
                    l, "goto source code")?;
         }
@@ -4050,7 +4045,7 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
                     render_assoc_item(w, item, link.anchor(&id), ItemType::Impl)?;
                     write!(w, "</code>")?;
                     render_stability_since_raw(w, item.stable_since(), outer_version)?;
-                    if let Some(l) = (Item { cx, item }).src_href() {
+                    if let Some(l) = cx.src_href(item) {
                         write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
                                l, "goto source code")?;
                     }
@@ -4073,7 +4068,7 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
                 assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "")?;
                 write!(w, "</code>")?;
                 render_stability_since_raw(w, item.stable_since(), outer_version)?;
-                if let Some(l) = (Item { cx, item }).src_href() {
+                if let Some(l) = cx.src_href(item) {
                     write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
                             l, "goto source code")?;
                 }

From 02c5c5cb597c873dd152f3ec8a6b74b5f28ccf36 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 31 Aug 2019 15:47:55 -0400
Subject: [PATCH 606/943] Move to buffers throughout print_item

---
 src/librustdoc/html/format.rs |   6 +-
 src/librustdoc/html/render.rs | 797 ++++++++++++++++------------------
 2 files changed, 375 insertions(+), 428 deletions(-)

diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 80f34fb17d2e8..dcd32192ff384 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -872,9 +872,9 @@ impl fmt::Display for clean::Impl {
 
 // The difference from above is that trait is not hyperlinked.
 pub fn fmt_impl_for_trait_page(i: &clean::Impl,
-                               f: &mut fmt::Formatter<'_>,
-                               use_absolute: bool) -> fmt::Result {
-    fmt_impl(i, f, false, use_absolute)
+                               f: &mut Buffer,
+                               use_absolute: bool) {
+    f.with_formatter(|f| fmt_impl(i, f, false, use_absolute))
 }
 
 impl fmt::Display for clean::Arguments {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index fc23ffe2b8ca7..9846073cad4bc 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1233,9 +1233,9 @@ themePicker.onblur = handleThemeButtonsBlur;
         // identically even with rustdoc running in parallel.
         all_implementors.sort();
 
-        let mut v = String::from("(function() {var implementors = {}};\n");
+        let mut v = String::from("(function() {var implementors = {};\n");
         for implementor in &all_implementors {
-            v.push_str(&format!("{}", *implementor));
+            writeln!(v, "{}", *implementor).unwrap();
         }
         v.push_str(r"
             if (window.register_implementors) {
@@ -1243,7 +1243,7 @@ themePicker.onblur = handleThemeButtonsBlur;
             } else {
                 window.pending_implementors = implementors;
             }
-        \n");
+        ");
         v.push_str("})()");
         cx.shared.fs.write(&mydst, &v)?;
     }
@@ -2171,11 +2171,11 @@ impl Context {
     }
 }
 
-fn wrap_into_docblock<F>(w: &mut fmt::Formatter<'_>,
-                         f: F) -> fmt::Result
-where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result {
-    write!(w, "<div class=\"docblock type-decl hidden-by-usual-hider\">")?;
-    f(w)?;
+fn wrap_into_docblock<F>(w: &mut Buffer, f: F)
+    where F: FnOnce(&mut Buffer)
+{
+    write!(w, "<div class=\"docblock type-decl hidden-by-usual-hider\">");
+    f(w);
     write!(w, "</div>")
 }
 
@@ -2255,33 +2255,31 @@ fn print_item(cx: &Context, item: &clean::Item, buf: &mut Buffer) {
 
     write!(buf, "</span></h1>"); // in-band
 
-    buf.with_formatter(|fmt| {
     match item.inner {
         clean::ModuleItem(ref m) =>
-            item_module(fmt, cx, item, &m.items),
+            item_module(buf, cx, item, &m.items),
         clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) =>
-            item_function(fmt, cx, item, f),
-        clean::TraitItem(ref t) => item_trait(fmt, cx, item, t),
-        clean::StructItem(ref s) => item_struct(fmt, cx, item, s),
-        clean::UnionItem(ref s) => item_union(fmt, cx, item, s),
-        clean::EnumItem(ref e) => item_enum(fmt, cx, item, e),
-        clean::TypedefItem(ref t, _) => item_typedef(fmt, cx, item, t),
-        clean::MacroItem(ref m) => item_macro(fmt, cx, item, m),
-        clean::ProcMacroItem(ref m) => item_proc_macro(fmt, cx, item, m),
-        clean::PrimitiveItem(ref p) => item_primitive(fmt, cx, item, p),
+            item_function(buf, cx, item, f),
+        clean::TraitItem(ref t) => item_trait(buf, cx, item, t),
+        clean::StructItem(ref s) => item_struct(buf, cx, item, s),
+        clean::UnionItem(ref s) => item_union(buf, cx, item, s),
+        clean::EnumItem(ref e) => item_enum(buf, cx, item, e),
+        clean::TypedefItem(ref t, _) => item_typedef(buf, cx, item, t),
+        clean::MacroItem(ref m) => item_macro(buf, cx, item, m),
+        clean::ProcMacroItem(ref m) => item_proc_macro(buf, cx, item, m),
+        clean::PrimitiveItem(ref p) => item_primitive(buf, cx, item, p),
         clean::StaticItem(ref i) | clean::ForeignStaticItem(ref i) =>
-            item_static(fmt, cx, item, i),
-        clean::ConstantItem(ref c) => item_constant(fmt, cx, item, c),
-        clean::ForeignTypeItem => item_foreign_type(fmt, cx, item),
-        clean::KeywordItem(ref k) => item_keyword(fmt, cx, item, k),
-        clean::OpaqueTyItem(ref e, _) => item_opaque_ty(fmt, cx, item, e),
-        clean::TraitAliasItem(ref ta) => item_trait_alias(fmt, cx, item, ta),
+            item_static(buf, cx, item, i),
+        clean::ConstantItem(ref c) => item_constant(buf, cx, item, c),
+        clean::ForeignTypeItem => item_foreign_type(buf, cx, item),
+        clean::KeywordItem(ref k) => item_keyword(buf, cx, item, k),
+        clean::OpaqueTyItem(ref e, _) => item_opaque_ty(buf, cx, item, e),
+        clean::TraitAliasItem(ref ta) => item_trait_alias(buf, cx, item, ta),
         _ => {
             // We don't generate pages for any other type.
             unreachable!();
         }
     }
-    })
 }
 
 fn item_path(ty: ItemType, name: &str) -> String {
@@ -2333,24 +2331,23 @@ fn shorten(s: String) -> String {
     }
 }
 
-fn document(w: &mut fmt::Formatter<'_>, cx: &Context, item: &clean::Item) -> fmt::Result {
+fn document(w: &mut Buffer, cx: &Context, item: &clean::Item) {
     if let Some(ref name) = item.name {
         info!("Documenting {}", name);
     }
-    document_stability(w, cx, item, false)?;
-    document_full(w, item, cx, "", false)?;
-    Ok(())
+    document_stability(w, cx, item, false);
+    document_full(w, item, cx, "", false);
 }
 
 /// Render md_text as markdown.
 fn render_markdown(
-    w: &mut fmt::Formatter<'_>,
+    w: &mut Buffer,
     cx: &Context,
     md_text: &str,
     links: Vec<(String, String)>,
     prefix: &str,
     is_hidden: bool,
-) -> fmt::Result {
+) {
     let mut ids = cx.id_map.borrow_mut();
     write!(w, "<div class='docblock{}'>{}{}</div>",
            if is_hidden { " hidden" } else { "" },
@@ -2360,13 +2357,13 @@ fn render_markdown(
 }
 
 fn document_short(
-    w: &mut fmt::Formatter<'_>,
+    w: &mut Buffer,
     cx: &Context,
     item: &clean::Item,
     link: AssocItemLink<'_>,
     prefix: &str,
     is_hidden: bool,
-) -> fmt::Result {
+) {
     if let Some(s) = item.doc_value() {
         let markdown = if s.contains('\n') {
             format!("{} [Read more]({})",
@@ -2374,46 +2371,41 @@ fn document_short(
         } else {
             plain_summary_line(Some(s))
         };
-        render_markdown(w, cx, &markdown, item.links(), prefix, is_hidden)?;
+        render_markdown(w, cx, &markdown, item.links(), prefix, is_hidden);
     } else if !prefix.is_empty() {
         write!(w, "<div class='docblock{}'>{}</div>",
                if is_hidden { " hidden" } else { "" },
-               prefix)?;
+               prefix);
     }
-    Ok(())
 }
 
-fn document_full(w: &mut fmt::Formatter<'_>, item: &clean::Item,
-                 cx: &Context, prefix: &str, is_hidden: bool) -> fmt::Result {
+fn document_full(w: &mut Buffer, item: &clean::Item, cx: &Context, prefix: &str, is_hidden: bool) {
     if let Some(s) = cx.shared.maybe_collapsed_doc_value(item) {
         debug!("Doc block: =====\n{}\n=====", s);
-        render_markdown(w, cx, &*s, item.links(), prefix, is_hidden)?;
+        render_markdown(w, cx, &*s, item.links(), prefix, is_hidden);
     } else if !prefix.is_empty() {
         write!(w, "<div class='docblock{}'>{}</div>",
                if is_hidden { " hidden" } else { "" },
-               prefix)?;
+               prefix);
     }
-    Ok(())
 }
 
-fn document_stability(w: &mut fmt::Formatter<'_>, cx: &Context, item: &clean::Item,
-                      is_hidden: bool) -> fmt::Result {
+fn document_stability(w: &mut Buffer, cx: &Context, item: &clean::Item, is_hidden: bool) {
     let stabilities = short_stability(item, cx);
     if !stabilities.is_empty() {
-        write!(w, "<div class='stability{}'>", if is_hidden { " hidden" } else { "" })?;
+        write!(w, "<div class='stability{}'>", if is_hidden { " hidden" } else { "" });
         for stability in stabilities {
-            write!(w, "{}", stability)?;
+            write!(w, "{}", stability);
         }
-        write!(w, "</div>")?;
+        write!(w, "</div>");
     }
-    Ok(())
 }
 
 fn document_non_exhaustive_header(item: &clean::Item) -> &str {
     if item.is_non_exhaustive() { " (Non-exhaustive)" } else { "" }
 }
 
-fn document_non_exhaustive(w: &mut fmt::Formatter<'_>, item: &clean::Item) -> fmt::Result {
+fn document_non_exhaustive(w: &mut Buffer, item: &clean::Item) {
     if item.is_non_exhaustive() {
         write!(w, "<div class='docblock non-exhaustive non-exhaustive-{}'>", {
             if item.is_struct() {
@@ -2425,31 +2417,29 @@ fn document_non_exhaustive(w: &mut fmt::Formatter<'_>, item: &clean::Item) -> fm
             } else {
                 "type"
             }
-        })?;
+        });
 
         if item.is_struct() {
             write!(w, "Non-exhaustive structs could have additional fields added in future. \
                        Therefore, non-exhaustive structs cannot be constructed in external crates \
                        using the traditional <code>Struct {{ .. }}</code> syntax; cannot be \
                        matched against without a wildcard <code>..</code>; and \
-                       struct update syntax will not work.")?;
+                       struct update syntax will not work.");
         } else if item.is_enum() {
             write!(w, "Non-exhaustive enums could have additional variants added in future. \
                        Therefore, when matching against variants of non-exhaustive enums, an \
-                       extra wildcard arm must be added to account for any future variants.")?;
+                       extra wildcard arm must be added to account for any future variants.");
         } else if item.is_variant() {
             write!(w, "Non-exhaustive enum variants could have additional fields added in future. \
                        Therefore, non-exhaustive enum variants cannot be constructed in external \
-                       crates and cannot be matched against.")?;
+                       crates and cannot be matched against.");
         } else {
             write!(w, "This type will require a wildcard arm in any match statements or \
-                       constructors.")?;
+                       constructors.");
         }
 
-        write!(w, "</div>")?;
+        write!(w, "</div>");
     }
-
-    Ok(())
 }
 
 fn name_key(name: &str) -> (&str, u64, usize) {
@@ -2473,9 +2463,8 @@ fn name_key(name: &str) -> (&str, u64, usize) {
     }
 }
 
-fn item_module(w: &mut fmt::Formatter<'_>, cx: &Context,
-               item: &clean::Item, items: &[clean::Item]) -> fmt::Result {
-    document(w, cx, item)?;
+fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean::Item]) {
+    document(w, cx, item);
 
     let mut indices = (0..items.len()).filter(|i| !items[*i].is_stripped()).collect::<Vec<usize>>();
 
@@ -2566,13 +2555,13 @@ fn item_module(w: &mut fmt::Formatter<'_>, cx: &Context,
             curty = myty;
         } else if myty != curty {
             if curty.is_some() {
-                write!(w, "</table>")?;
+                write!(w, "</table>");
             }
             curty = myty;
             let (short, name) = item_ty_to_strs(&myty.unwrap());
             write!(w, "<h2 id='{id}' class='section-header'>\
                        <a href=\"#{id}\">{name}</a></h2>\n<table>",
-                   id = cx.derive_id(short.to_owned()), name = name)?;
+                   id = cx.derive_id(short.to_owned()), name = name);
         }
 
         match myitem.inner {
@@ -2584,20 +2573,20 @@ fn item_module(w: &mut fmt::Formatter<'_>, cx: &Context,
                         write!(w, "<tr><td><code>{}extern crate {} as {};",
                                VisSpace(&myitem.visibility),
                                anchor(myitem.def_id, src),
-                               name)?
+                               name)
                     }
                     None => {
                         write!(w, "<tr><td><code>{}extern crate {};",
                                VisSpace(&myitem.visibility),
-                               anchor(myitem.def_id, name))?
+                               anchor(myitem.def_id, name))
                     }
                 }
-                write!(w, "</code></td></tr>")?;
+                write!(w, "</code></td></tr>");
             }
 
             clean::ImportItem(ref import) => {
                 write!(w, "<tr><td><code>{}{}</code></td></tr>",
-                       VisSpace(&myitem.visibility), *import)?;
+                       VisSpace(&myitem.visibility), *import);
             }
 
             _ => {
@@ -2642,15 +2631,14 @@ fn item_module(w: &mut fmt::Formatter<'_>, cx: &Context,
                                 })
                                 .collect::<Vec<_>>()
                                 .join(" "),
-                      )?;
+                      );
             }
         }
     }
 
     if curty.is_some() {
-        write!(w, "</table>")?;
+        write!(w, "</table>");
     }
-    Ok(())
 }
 
 /// Render the stability and deprecation tags that are displayed in the item's summary at the
@@ -2799,33 +2787,30 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
     stability
 }
 
-fn item_constant(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
-                 c: &clean::Constant) -> fmt::Result {
-    write!(w, "<pre class='rust const'>")?;
-    render_attributes(w, it, false)?;
+fn item_constant(w: &mut Buffer, cx: &Context, it: &clean::Item, c: &clean::Constant) {
+    write!(w, "<pre class='rust const'>");
+    render_attributes(w, it, false);
     write!(w, "{vis}const \
                {name}: {typ}</pre>",
            vis = VisSpace(&it.visibility),
            name = it.name.as_ref().unwrap(),
-           typ = c.type_)?;
+           typ = c.type_);
     document(w, cx, it)
 }
 
-fn item_static(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
-               s: &clean::Static) -> fmt::Result {
-    write!(w, "<pre class='rust static'>")?;
-    render_attributes(w, it, false)?;
+fn item_static(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Static) {
+    write!(w, "<pre class='rust static'>");
+    render_attributes(w, it, false);
     write!(w, "{vis}static {mutability}\
                {name}: {typ}</pre>",
            vis = VisSpace(&it.visibility),
            mutability = MutableSpace(s.mutability),
            name = it.name.as_ref().unwrap(),
-           typ = s.type_)?;
+           typ = s.type_);
     document(w, cx, it)
 }
 
-fn item_function(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
-                 f: &clean::Function) -> fmt::Result {
+fn item_function(w: &mut Buffer, cx: &Context, it: &clean::Item, f: &clean::Function) {
     let header_len = format!(
         "{}{}{}{}{:#}fn {}{:#}",
         VisSpace(&it.visibility),
@@ -2836,8 +2821,8 @@ fn item_function(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
         it.name.as_ref().unwrap(),
         f.generics
     ).len();
-    write!(w, "{}<pre class='rust fn'>", render_spotlight_traits(it)?)?;
-    render_attributes(w, it, false)?;
+    write!(w, "{}<pre class='rust fn'>", render_spotlight_traits(it));
+    render_attributes(w, it, false);
     write!(w,
            "{vis}{constness}{unsafety}{asyncness}{abi}fn \
            {name}{generics}{decl}{where_clause}</pre>",
@@ -2854,12 +2839,12 @@ fn item_function(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
               header_len,
               indent: 0,
               asyncness: f.header.asyncness,
-           })?;
+           });
     document(w, cx, it)
 }
 
-fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter<'_>,
-                      implementor_dups: &FxHashMap<&str, (DefId, bool)>) -> fmt::Result {
+fn render_implementor(cx: &Context, implementor: &Impl, w: &mut Buffer,
+                      implementor_dups: &FxHashMap<&str, (DefId, bool)>) {
     // If there's already another implementor that has the same abbridged name, use the
     // full path, for example in `std::iter::ExactSizeIterator`
     let use_absolute = match implementor.inner_impl().for_ {
@@ -2871,20 +2856,18 @@ fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter<'
         _ => false,
     };
     render_impl(w, cx, implementor, AssocItemLink::Anchor(None), RenderMode::Normal,
-                implementor.impl_item.stable_since(), false, Some(use_absolute), false, false)?;
-    Ok(())
+                implementor.impl_item.stable_since(), false, Some(use_absolute), false, false);
 }
 
-fn render_impls(cx: &Context, w: &mut fmt::Formatter<'_>,
+fn render_impls(cx: &Context, w: &mut Buffer,
                 traits: &[&&Impl],
-                containing_item: &clean::Item) -> fmt::Result {
+                containing_item: &clean::Item) {
     for i in traits {
         let did = i.trait_did().unwrap();
         let assoc_link = AssocItemLink::GotoSource(did, &i.inner_impl().provided_trait_methods);
         render_impl(w, cx, i, assoc_link,
-                    RenderMode::Normal, containing_item.stable_since(), true, None, false, true)?;
+                    RenderMode::Normal, containing_item.stable_since(), true, None, false, true);
     }
-    Ok(())
 }
 
 fn bounds(t_bounds: &[clean::GenericBound], trait_alias: bool) -> String {
@@ -2912,11 +2895,11 @@ fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl) -> Ordering {
 }
 
 fn item_trait(
-    w: &mut fmt::Formatter<'_>,
+    w: &mut Buffer,
     cx: &Context,
     it: &clean::Item,
     t: &clean::Trait,
-) -> fmt::Result {
+) {
     let bounds = bounds(&t.bounds, false);
     let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>();
     let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>();
@@ -2925,146 +2908,144 @@ fn item_trait(
 
     // Output the trait definition
     wrap_into_docblock(w, |w| {
-        write!(w, "<pre class='rust trait'>")?;
-        render_attributes(w, it, true)?;
+        write!(w, "<pre class='rust trait'>");
+        render_attributes(w, it, true);
         write!(w, "{}{}{}trait {}{}{}",
                VisSpace(&it.visibility),
                UnsafetySpace(t.unsafety),
                if t.is_auto { "auto " } else { "" },
                it.name.as_ref().unwrap(),
                t.generics,
-               bounds)?;
+               bounds);
 
         if !t.generics.where_predicates.is_empty() {
-            write!(w, "{}", WhereClause { gens: &t.generics, indent: 0, end_newline: true })?;
+            write!(w, "{}", WhereClause { gens: &t.generics, indent: 0, end_newline: true });
         } else {
-            write!(w, " ")?;
+            write!(w, " ");
         }
 
         if t.items.is_empty() {
-            write!(w, "{{ }}")?;
+            write!(w, "{{ }}");
         } else {
             // FIXME: we should be using a derived_id for the Anchors here
-            write!(w, "{{\n")?;
+            write!(w, "{{\n");
             for t in &types {
-                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?;
-                write!(w, ";\n")?;
+                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait);
+                write!(w, ";\n");
             }
             if !types.is_empty() && !consts.is_empty() {
-                w.write_str("\n")?;
+                w.write_str("\n");
             }
             for t in &consts {
-                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait)?;
-                write!(w, ";\n")?;
+                render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait);
+                write!(w, ";\n");
             }
             if !consts.is_empty() && !required.is_empty() {
-                w.write_str("\n")?;
+                w.write_str("\n");
             }
             for (pos, m) in required.iter().enumerate() {
-                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?;
-                write!(w, ";\n")?;
+                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait);
+                write!(w, ";\n");
 
                 if pos < required.len() - 1 {
-                   write!(w, "<div class='item-spacer'></div>")?;
+                   write!(w, "<div class='item-spacer'></div>");
                 }
             }
             if !required.is_empty() && !provided.is_empty() {
-                w.write_str("\n")?;
+                w.write_str("\n");
             }
             for (pos, m) in provided.iter().enumerate() {
-                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait)?;
+                render_assoc_item(w, m, AssocItemLink::Anchor(None), ItemType::Trait);
                 match m.inner {
                     clean::MethodItem(ref inner) if !inner.generics.where_predicates.is_empty() => {
-                        write!(w, ",\n    {{ ... }}\n")?;
+                        write!(w, ",\n    {{ ... }}\n");
                     },
                     _ => {
-                        write!(w, " {{ ... }}\n")?;
+                        write!(w, " {{ ... }}\n");
                     },
                 }
                 if pos < provided.len() - 1 {
-                   write!(w, "<div class='item-spacer'></div>")?;
+                   write!(w, "<div class='item-spacer'></div>");
                 }
             }
-            write!(w, "}}")?;
+            write!(w, "}}");
         }
         write!(w, "</pre>")
-    })?;
+    });
 
     // Trait documentation
-    document(w, cx, it)?;
+    document(w, cx, it);
 
     fn write_small_section_header(
-        w: &mut fmt::Formatter<'_>,
+        w: &mut Buffer,
         id: &str,
         title: &str,
         extra_content: &str,
-    ) -> fmt::Result {
+    ) {
         write!(w, "
             <h2 id='{0}' class='small-section-header'>\
               {1}<a href='#{0}' class='anchor'></a>\
             </h2>{2}", id, title, extra_content)
     }
 
-    fn write_loading_content(w: &mut fmt::Formatter<'_>, extra_content: &str) -> fmt::Result {
+    fn write_loading_content(w: &mut Buffer, extra_content: &str) {
         write!(w, "{}<span class='loading-content'>Loading content...</span>", extra_content)
     }
 
-    fn trait_item(w: &mut fmt::Formatter<'_>, cx: &Context, m: &clean::Item, t: &clean::Item)
-                  -> fmt::Result {
+    fn trait_item(w: &mut Buffer, cx: &Context, m: &clean::Item, t: &clean::Item) {
         let name = m.name.as_ref().unwrap();
         let item_type = m.type_();
         let id = cx.derive_id(format!("{}.{}", item_type, name));
         let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
         write!(w, "<h3 id='{id}' class='method'>{extra}<code id='{ns_id}'>",
-               extra = render_spotlight_traits(m)?,
+               extra = render_spotlight_traits(m),
                id = id,
-               ns_id = ns_id)?;
-        render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl)?;
-        write!(w, "</code>")?;
-        render_stability_since(w, m, t)?;
-        write!(w, "</h3>")?;
-        document(w, cx, m)?;
-        Ok(())
+               ns_id = ns_id);
+        render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl);
+        write!(w, "</code>");
+        render_stability_since(w, m, t);
+        write!(w, "</h3>");
+        document(w, cx, m);
     }
 
     if !types.is_empty() {
         write_small_section_header(w, "associated-types", "Associated Types",
-                                   "<div class='methods'>")?;
+                                   "<div class='methods'>");
         for t in &types {
-            trait_item(w, cx, *t, it)?;
+            trait_item(w, cx, *t, it);
         }
-        write_loading_content(w, "</div>")?;
+        write_loading_content(w, "</div>");
     }
 
     if !consts.is_empty() {
         write_small_section_header(w, "associated-const", "Associated Constants",
-                                   "<div class='methods'>")?;
+                                   "<div class='methods'>");
         for t in &consts {
-            trait_item(w, cx, *t, it)?;
+            trait_item(w, cx, *t, it);
         }
-        write_loading_content(w, "</div>")?;
+        write_loading_content(w, "</div>");
     }
 
     // Output the documentation for each function individually
     if !required.is_empty() {
         write_small_section_header(w, "required-methods", "Required methods",
-                                   "<div class='methods'>")?;
+                                   "<div class='methods'>");
         for m in &required {
-            trait_item(w, cx, *m, it)?;
+            trait_item(w, cx, *m, it);
         }
-        write_loading_content(w, "</div>")?;
+        write_loading_content(w, "</div>");
     }
     if !provided.is_empty() {
         write_small_section_header(w, "provided-methods", "Provided methods",
-                                   "<div class='methods'>")?;
+                                   "<div class='methods'>");
         for m in &provided {
-            trait_item(w, cx, *m, it)?;
+            trait_item(w, cx, *m, it);
         }
-        write_loading_content(w, "</div>")?;
+        write_loading_content(w, "</div>");
     }
 
     // If there are methods directly on this trait object, render them here.
-    render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)?;
+    render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All);
 
     let cache = cache();
 
@@ -3103,7 +3084,7 @@ fn item_trait(
         concrete.sort_by(compare_impl);
 
         if !foreign.is_empty() {
-            write_small_section_header(w, "foreign-impls", "Implementations on Foreign Types", "")?;
+            write_small_section_header(w, "foreign-impls", "Implementations on Foreign Types", "");
 
             for implementor in foreign {
                 let assoc_link = AssocItemLink::GotoSource(
@@ -3112,44 +3093,44 @@ fn item_trait(
                 );
                 render_impl(w, cx, &implementor, assoc_link,
                             RenderMode::Normal, implementor.impl_item.stable_since(), false,
-                            None, true, false)?;
+                            None, true, false);
             }
-            write_loading_content(w, "")?;
+            write_loading_content(w, "");
         }
 
         write_small_section_header(w, "implementors", "Implementors",
-                                   "<div class='item-list' id='implementors-list'>")?;
+                                   "<div class='item-list' id='implementors-list'>");
         for implementor in concrete {
-            render_implementor(cx, implementor, w, &implementor_dups)?;
+            render_implementor(cx, implementor, w, &implementor_dups);
         }
-        write_loading_content(w, "</div>")?;
+        write_loading_content(w, "</div>");
 
         if t.auto {
             write_small_section_header(w, "synthetic-implementors", "Auto implementors",
-                                       "<div class='item-list' id='synthetic-implementors-list'>")?;
+                                       "<div class='item-list' id='synthetic-implementors-list'>");
             for implementor in synthetic {
                 synthetic_types.extend(
                     collect_paths_for_type(implementor.inner_impl().for_.clone())
                 );
-                render_implementor(cx, implementor, w, &implementor_dups)?;
+                render_implementor(cx, implementor, w, &implementor_dups);
             }
-            write_loading_content(w, "</div>")?;
+            write_loading_content(w, "</div>");
         }
     } else {
         // even without any implementations to write in, we still want the heading and list, so the
         // implementors javascript file pulled in below has somewhere to write the impls into
         write_small_section_header(w, "implementors", "Implementors",
-                                   "<div class='item-list' id='implementors-list'>")?;
-        write_loading_content(w, "</div>")?;
+                                   "<div class='item-list' id='implementors-list'>");
+        write_loading_content(w, "</div>");
 
         if t.auto {
             write_small_section_header(w, "synthetic-implementors", "Auto implementors",
-                                       "<div class='item-list' id='synthetic-implementors-list'>")?;
-            write_loading_content(w, "</div>")?;
+                                       "<div class='item-list' id='synthetic-implementors-list'>");
+            write_loading_content(w, "</div>");
         }
     }
     write!(w, r#"<script type="text/javascript">window.inlined_types=new Set({});</script>"#,
-           as_json(&synthetic_types))?;
+           as_json(&synthetic_types));
 
     write!(w, r#"<script type="text/javascript" async
                          src="{root_path}/implementors/{path}/{ty}.{name}.js">
@@ -3162,8 +3143,7 @@ fn item_trait(
                path[..path.len() - 1].join("/")
            },
            ty = it.type_().css_class(),
-           name = *it.name.as_ref().unwrap())?;
-    Ok(())
+           name = *it.name.as_ref().unwrap());
 }
 
 fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>) -> String {
@@ -3185,70 +3165,60 @@ fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>) -> String {
     }
 }
 
-fn assoc_const(w: &mut fmt::Formatter<'_>,
+fn assoc_const(w: &mut Buffer,
                it: &clean::Item,
                ty: &clean::Type,
                _default: Option<&String>,
                link: AssocItemLink<'_>,
-               extra: &str) -> fmt::Result {
+               extra: &str) {
     write!(w, "{}{}const <a href='{}' class=\"constant\"><b>{}</b></a>: {}",
            extra,
            VisSpace(&it.visibility),
            naive_assoc_href(it, link),
            it.name.as_ref().unwrap(),
-           ty)?;
-    Ok(())
+           ty);
 }
 
-fn assoc_type<W: fmt::Write>(w: &mut W, it: &clean::Item,
-                             bounds: &[clean::GenericBound],
-                             default: Option<&clean::Type>,
-                             link: AssocItemLink<'_>,
-                             extra: &str) -> fmt::Result {
+fn assoc_type(w: &mut Buffer, it: &clean::Item,
+              bounds: &[clean::GenericBound],
+              default: Option<&clean::Type>,
+              link: AssocItemLink<'_>,
+              extra: &str) {
     write!(w, "{}type <a href='{}' class=\"type\">{}</a>",
            extra,
            naive_assoc_href(it, link),
-           it.name.as_ref().unwrap())?;
+           it.name.as_ref().unwrap());
     if !bounds.is_empty() {
-        write!(w, ": {}", GenericBounds(bounds))?
+        write!(w, ": {}", GenericBounds(bounds))
     }
     if let Some(default) = default {
-        write!(w, " = {}", default)?;
+        write!(w, " = {}", default)
     }
-    Ok(())
 }
 
-fn render_stability_since_raw<'a, T: fmt::Write>(
-    w: &mut T,
-    ver: Option<&'a str>,
-    containing_ver: Option<&'a str>,
-) -> fmt::Result {
+fn render_stability_since_raw(w: &mut Buffer, ver: Option<&str>, containing_ver: Option<&str>) {
     if let Some(v) = ver {
         if containing_ver != ver && v.len() > 0 {
-            write!(w, "<span class='since' title='Stable since Rust version {0}'>{0}</span>", v)?
+            write!(w, "<span class='since' title='Stable since Rust version {0}'>{0}</span>", v)
         }
     }
-    Ok(())
 }
 
-fn render_stability_since(w: &mut fmt::Formatter<'_>,
-                          item: &clean::Item,
-                          containing_item: &clean::Item) -> fmt::Result {
+fn render_stability_since(w: &mut Buffer, item: &clean::Item, containing_item: &clean::Item) {
     render_stability_since_raw(w, item.stable_since(), containing_item.stable_since())
 }
 
-fn render_assoc_item(w: &mut fmt::Formatter<'_>,
+fn render_assoc_item(w: &mut Buffer,
                      item: &clean::Item,
                      link: AssocItemLink<'_>,
-                     parent: ItemType) -> fmt::Result {
-    fn method(w: &mut fmt::Formatter<'_>,
+                     parent: ItemType) {
+    fn method(w: &mut Buffer,
               meth: &clean::Item,
               header: hir::FnHeader,
               g: &clean::Generics,
               d: &clean::FnDecl,
               link: AssocItemLink<'_>,
-              parent: ItemType)
-              -> fmt::Result {
+              parent: ItemType) {
         let name = meth.name.as_ref().unwrap();
         let anchor = format!("#{}.{}", meth.type_(), name);
         let href = match link {
@@ -3283,7 +3253,7 @@ fn render_assoc_item(w: &mut fmt::Formatter<'_>,
         } else {
             (0, true)
         };
-        render_attributes(w, meth, false)?;
+        render_attributes(w, meth, false);
         write!(w, "{}{}{}{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
                    {generics}{decl}{where_clause}",
                if parent == ItemType::Trait { "    " } else { "" },
@@ -3309,7 +3279,7 @@ fn render_assoc_item(w: &mut fmt::Formatter<'_>,
                })
     }
     match item.inner {
-        clean::StrippedItem(..) => Ok(()),
+        clean::StrippedItem(..) => {},
         clean::TyMethodItem(ref m) => {
             method(w, item, m.header, &m.generics, &m.decl, link, parent)
         }
@@ -3328,22 +3298,21 @@ fn render_assoc_item(w: &mut fmt::Formatter<'_>,
     }
 }
 
-fn item_struct(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
-               s: &clean::Struct) -> fmt::Result {
+fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct) {
     wrap_into_docblock(w, |w| {
-        write!(w, "<pre class='rust struct'>")?;
-        render_attributes(w, it, true)?;
+        write!(w, "<pre class='rust struct'>");
+        render_attributes(w, it, true);
         render_struct(w,
                       it,
                       Some(&s.generics),
                       s.struct_type,
                       &s.fields,
                       "",
-                      true)?;
+                      true);
         write!(w, "</pre>")
-    })?;
+    });
 
-    document(w, cx, it)?;
+    document(w, cx, it);
     let mut fields = s.fields.iter().filter_map(|f| {
         match f.inner {
             clean::StructFieldItem(ref ty) => Some((f, ty)),
@@ -3354,8 +3323,8 @@ fn item_struct(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
         if fields.peek().is_some() {
             write!(w, "<h2 id='fields' class='fields small-section-header'>
                        Fields{}<a href='#fields' class='anchor'></a></h2>",
-                       document_non_exhaustive_header(it))?;
-            document_non_exhaustive(w, it)?;
+                       document_non_exhaustive_header(it));
+            document_non_exhaustive(w, it);
             for (field, ty) in fields {
                 let id = cx.derive_id(format!("{}.{}",
                                            ItemType::StructField,
@@ -3371,29 +3340,28 @@ fn item_struct(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                        id = id,
                        ns_id = ns_id,
                        name = field.name.as_ref().unwrap(),
-                       ty = ty)?;
-                document(w, cx, field)?;
+                       ty = ty);
+                document(w, cx, field);
             }
         }
     }
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
 
-fn item_union(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
-               s: &clean::Union) -> fmt::Result {
+fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) {
     wrap_into_docblock(w, |w| {
-        write!(w, "<pre class='rust union'>")?;
-        render_attributes(w, it, true)?;
+        write!(w, "<pre class='rust union'>");
+        render_attributes(w, it, true);
         render_union(w,
                      it,
                      Some(&s.generics),
                      &s.fields,
                      "",
-                     true)?;
+                     true);
         write!(w, "</pre>")
-    })?;
+    });
 
-    document(w, cx, it)?;
+    document(w, cx, it);
     let mut fields = s.fields.iter().filter_map(|f| {
         match f.inner {
             clean::StructFieldItem(ref ty) => Some((f, ty)),
@@ -3402,7 +3370,7 @@ fn item_union(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
     }).peekable();
     if fields.peek().is_some() {
         write!(w, "<h2 id='fields' class='fields small-section-header'>
-                   Fields<a href='#fields' class='anchor'></a></h2>")?;
+                   Fields<a href='#fields' class='anchor'></a></h2>");
         for (field, ty) in fields {
             let name = field.name.as_ref().expect("union field name");
             let id = format!("{}.{}", ItemType::StructField, name);
@@ -3413,47 +3381,46 @@ fn item_union(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                    id = id,
                    name = name,
                    shortty = ItemType::StructField,
-                   ty = ty)?;
+                   ty = ty);
             if let Some(stability_class) = field.stability_class() {
                 write!(w, "<span class='stab {stab}'></span>",
-                    stab = stability_class)?;
+                    stab = stability_class);
             }
-            document(w, cx, field)?;
+            document(w, cx, field);
         }
     }
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
 
-fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
-             e: &clean::Enum) -> fmt::Result {
+fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) {
     wrap_into_docblock(w, |w| {
-        write!(w, "<pre class='rust enum'>")?;
-        render_attributes(w, it, true)?;
+        write!(w, "<pre class='rust enum'>");
+        render_attributes(w, it, true);
         write!(w, "{}enum {}{}{}",
                VisSpace(&it.visibility),
                it.name.as_ref().unwrap(),
                e.generics,
-               WhereClause { gens: &e.generics, indent: 0, end_newline: true })?;
+               WhereClause { gens: &e.generics, indent: 0, end_newline: true });
         if e.variants.is_empty() && !e.variants_stripped {
-            write!(w, " {{}}")?;
+            write!(w, " {{}}");
         } else {
-            write!(w, " {{\n")?;
+            write!(w, " {{\n");
             for v in &e.variants {
-                write!(w, "    ")?;
+                write!(w, "    ");
                 let name = v.name.as_ref().unwrap();
                 match v.inner {
                     clean::VariantItem(ref var) => {
                         match var.kind {
-                            clean::VariantKind::CLike => write!(w, "{}", name)?,
+                            clean::VariantKind::CLike => write!(w, "{}", name),
                             clean::VariantKind::Tuple(ref tys) => {
-                                write!(w, "{}(", name)?;
+                                write!(w, "{}(", name);
                                 for (i, ty) in tys.iter().enumerate() {
                                     if i > 0 {
-                                        write!(w, ",&nbsp;")?
+                                        write!(w, ",&nbsp;")
                                     }
-                                    write!(w, "{}", *ty)?;
+                                    write!(w, "{}", *ty);
                                 }
-                                write!(w, ")")?;
+                                write!(w, ")");
                             }
                             clean::VariantKind::Struct(ref s) => {
                                 render_struct(w,
@@ -3462,29 +3429,29 @@ fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                                               s.struct_type,
                                               &s.fields,
                                               "    ",
-                                              false)?;
+                                              false);
                             }
                         }
                     }
                     _ => unreachable!()
                 }
-                write!(w, ",\n")?;
+                write!(w, ",\n");
             }
 
             if e.variants_stripped {
-                write!(w, "    // some variants omitted\n")?;
+                write!(w, "    // some variants omitted\n");
             }
-            write!(w, "}}")?;
+            write!(w, "}}");
         }
         write!(w, "</pre>")
-    })?;
+    });
 
-    document(w, cx, it)?;
+    document(w, cx, it);
     if !e.variants.is_empty() {
         write!(w, "<h2 id='variants' class='variants small-section-header'>
                    Variants{}<a href='#variants' class='anchor'></a></h2>\n",
-                   document_non_exhaustive_header(it))?;
-        document_non_exhaustive(w, it)?;
+                   document_non_exhaustive_header(it));
+        document_non_exhaustive(w, it);
         for variant in &e.variants {
             let id = cx.derive_id(format!("{}.{}",
                                        ItemType::Variant,
@@ -3497,22 +3464,22 @@ fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                        <code id='{ns_id}'>{name}",
                    id = id,
                    ns_id = ns_id,
-                   name = variant.name.as_ref().unwrap())?;
+                   name = variant.name.as_ref().unwrap());
             if let clean::VariantItem(ref var) = variant.inner {
                 if let clean::VariantKind::Tuple(ref tys) = var.kind {
-                    write!(w, "(")?;
+                    write!(w, "(");
                     for (i, ty) in tys.iter().enumerate() {
                         if i > 0 {
-                            write!(w, ",&nbsp;")?;
+                            write!(w, ",&nbsp;");
                         }
-                        write!(w, "{}", *ty)?;
+                        write!(w, "{}", *ty);
                     }
-                    write!(w, ")")?;
+                    write!(w, ")");
                 }
             }
-            write!(w, "</code></div>")?;
-            document(w, cx, variant)?;
-            document_non_exhaustive(w, variant)?;
+            write!(w, "</code></div>");
+            document(w, cx, variant);
+            document_non_exhaustive(w, variant);
 
             use crate::clean::{Variant, VariantKind};
             if let clean::VariantItem(Variant {
@@ -3522,9 +3489,9 @@ fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                                                    ItemType::Variant,
                                                    variant.name.as_ref().unwrap()));
                 write!(w, "<div class='autohide sub-variant' id='{id}'>",
-                       id = variant_id)?;
+                       id = variant_id);
                 write!(w, "<h3>Fields of <b>{name}</b></h3><div>",
-                       name = variant.name.as_ref().unwrap())?;
+                       name = variant.name.as_ref().unwrap());
                 for field in &s.fields {
                     use crate::clean::StructFieldItem;
                     if let StructFieldItem(ref ty) = field.inner {
@@ -3543,17 +3510,16 @@ fn item_enum(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
                                id = id,
                                ns_id = ns_id,
                                f = field.name.as_ref().unwrap(),
-                               t = *ty)?;
-                        document(w, cx, field)?;
+                               t = *ty);
+                        document(w, cx, field);
                     }
                 }
-                write!(w, "</div></div>")?;
+                write!(w, "</div></div>");
             }
-            render_stability_since(w, variant, it)?;
+            render_stability_since(w, variant, it);
         }
     }
-    render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)?;
-    Ok(())
+    render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
 
 fn render_attribute(attr: &ast::MetaItem) -> Option<String> {
@@ -3596,7 +3562,7 @@ const ATTRIBUTE_WHITELIST: &'static [Symbol] = &[
 //     #[bar] <---- not "top" attribute
 //     bar: usize,
 // }
-fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item, top: bool) -> fmt::Result {
+fn render_attributes(w: &mut Buffer, it: &clean::Item, top: bool) {
     let mut attrs = String::new();
 
     for attr in &it.attrs.other_attrs {
@@ -3609,117 +3575,114 @@ fn render_attributes(w: &mut dyn fmt::Write, it: &clean::Item, top: bool) -> fmt
     }
     if attrs.len() > 0 {
         write!(w, "<span class=\"docblock attributes{}\">{}</span>",
-               if top { " top-attr" } else { "" }, &attrs)?;
+               if top { " top-attr" } else { "" }, &attrs);
     }
-    Ok(())
 }
 
-fn render_struct(w: &mut fmt::Formatter<'_>, it: &clean::Item,
+fn render_struct(w: &mut Buffer, it: &clean::Item,
                  g: Option<&clean::Generics>,
                  ty: doctree::StructType,
                  fields: &[clean::Item],
                  tab: &str,
-                 structhead: bool) -> fmt::Result {
+                 structhead: bool) {
     write!(w, "{}{}{}",
            VisSpace(&it.visibility),
            if structhead {"struct "} else {""},
-           it.name.as_ref().unwrap())?;
+           it.name.as_ref().unwrap());
     if let Some(g) = g {
-        write!(w, "{}", g)?
+        write!(w, "{}", g)
     }
     match ty {
         doctree::Plain => {
             if let Some(g) = g {
-                write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: true })?
+                write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: true })
             }
             let mut has_visible_fields = false;
-            write!(w, " {{")?;
+            write!(w, " {{");
             for field in fields {
                 if let clean::StructFieldItem(ref ty) = field.inner {
                     write!(w, "\n{}    {}{}: {},",
                            tab,
                            VisSpace(&field.visibility),
                            field.name.as_ref().unwrap(),
-                           *ty)?;
+                           *ty);
                     has_visible_fields = true;
                 }
             }
 
             if has_visible_fields {
                 if it.has_stripped_fields().unwrap() {
-                    write!(w, "\n{}    // some fields omitted", tab)?;
+                    write!(w, "\n{}    // some fields omitted", tab);
                 }
-                write!(w, "\n{}", tab)?;
+                write!(w, "\n{}", tab);
             } else if it.has_stripped_fields().unwrap() {
                 // If there are no visible fields we can just display
                 // `{ /* fields omitted */ }` to save space.
-                write!(w, " /* fields omitted */ ")?;
+                write!(w, " /* fields omitted */ ");
             }
-            write!(w, "}}")?;
+            write!(w, "}}");
         }
         doctree::Tuple => {
-            write!(w, "(")?;
+            write!(w, "(");
             for (i, field) in fields.iter().enumerate() {
                 if i > 0 {
-                    write!(w, ", ")?;
+                    write!(w, ", ");
                 }
                 match field.inner {
                     clean::StrippedItem(box clean::StructFieldItem(..)) => {
-                        write!(w, "_")?
+                        write!(w, "_")
                     }
                     clean::StructFieldItem(ref ty) => {
-                        write!(w, "{}{}", VisSpace(&field.visibility), *ty)?
+                        write!(w, "{}{}", VisSpace(&field.visibility), *ty)
                     }
                     _ => unreachable!()
                 }
             }
-            write!(w, ")")?;
+            write!(w, ")");
             if let Some(g) = g {
-                write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: false })?
+                write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: false })
             }
-            write!(w, ";")?;
+            write!(w, ";");
         }
         doctree::Unit => {
             // Needed for PhantomData.
             if let Some(g) = g {
-                write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: false })?
+                write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: false })
             }
-            write!(w, ";")?;
+            write!(w, ";");
         }
     }
-    Ok(())
 }
 
-fn render_union(w: &mut fmt::Formatter<'_>, it: &clean::Item,
+fn render_union(w: &mut Buffer, it: &clean::Item,
                 g: Option<&clean::Generics>,
                 fields: &[clean::Item],
                 tab: &str,
-                structhead: bool) -> fmt::Result {
+                structhead: bool) {
     write!(w, "{}{}{}",
            VisSpace(&it.visibility),
            if structhead {"union "} else {""},
-           it.name.as_ref().unwrap())?;
+           it.name.as_ref().unwrap());
     if let Some(g) = g {
-        write!(w, "{}", g)?;
-        write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: true })?;
+        write!(w, "{}", g);
+        write!(w, "{}", WhereClause { gens: g, indent: 0, end_newline: true });
     }
 
-    write!(w, " {{\n{}", tab)?;
+    write!(w, " {{\n{}", tab);
     for field in fields {
         if let clean::StructFieldItem(ref ty) = field.inner {
             write!(w, "    {}{}: {},\n{}",
                    VisSpace(&field.visibility),
                    field.name.as_ref().unwrap(),
                    *ty,
-                   tab)?;
+                   tab);
         }
     }
 
     if it.has_stripped_fields().unwrap() {
-        write!(w, "    // some fields omitted\n{}", tab)?;
+        write!(w, "    // some fields omitted\n{}", tab);
     }
-    write!(w, "}}")?;
-    Ok(())
+    write!(w, "}}");
 }
 
 #[derive(Copy, Clone)]
@@ -3748,15 +3711,15 @@ enum RenderMode {
     ForDeref { mut_: bool },
 }
 
-fn render_assoc_items(w: &mut fmt::Formatter<'_>,
+fn render_assoc_items(w: &mut Buffer,
                       cx: &Context,
                       containing_item: &clean::Item,
                       it: DefId,
-                      what: AssocItemRender<'_>) -> fmt::Result {
+                      what: AssocItemRender<'_>) {
     let c = cache();
     let v = match c.impls.get(&it) {
         Some(v) => v,
-        None => return Ok(()),
+        None => return,
     };
     let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| {
         i.inner_impl().trait_.is_none()
@@ -3768,7 +3731,7 @@ fn render_assoc_items(w: &mut fmt::Formatter<'_>,
                     <h2 id='methods' class='small-section-header'>\
                       Methods<a href='#methods' class='anchor'></a>\
                     </h2>\
-                ")?;
+                ");
                 RenderMode::Normal
             }
             AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
@@ -3777,17 +3740,17 @@ fn render_assoc_items(w: &mut fmt::Formatter<'_>,
                       Methods from {}&lt;Target = {}&gt;\
                       <a href='#deref-methods' class='anchor'></a>\
                     </h2>\
-                ", trait_, type_)?;
+                ", trait_, type_);
                 RenderMode::ForDeref { mut_: deref_mut_ }
             }
         };
         for i in &non_trait {
             render_impl(w, cx, i, AssocItemLink::Anchor(None), render_mode,
-                        containing_item.stable_since(), true, None, false, true)?;
+                        containing_item.stable_since(), true, None, false, true);
         }
     }
     if let AssocItemRender::DerefFor { .. } = what {
-        return Ok(());
+        return;
     }
     if !traits.is_empty() {
         let deref_impl = traits.iter().find(|t| {
@@ -3797,31 +3760,25 @@ fn render_assoc_items(w: &mut fmt::Formatter<'_>,
             let has_deref_mut = traits.iter().find(|t| {
                 t.inner_impl().trait_.def_id() == c.deref_mut_trait_did
             }).is_some();
-            render_deref_methods(w, cx, impl_, containing_item, has_deref_mut)?;
+            render_deref_methods(w, cx, impl_, containing_item, has_deref_mut);
         }
 
         let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = traits
             .iter()
             .partition(|t| t.inner_impl().synthetic);
-        let (blanket_impl, concrete) = concrete
+        let (blanket_impl, concrete): (Vec<&&Impl>, _) = concrete
             .into_iter()
             .partition(|t| t.inner_impl().blanket_impl.is_some());
 
-        struct RendererStruct<'a, 'b, 'c>(&'a Context, Vec<&'b &'b Impl>, &'c clean::Item);
-
-        impl<'a, 'b, 'c> fmt::Display for RendererStruct<'a, 'b, 'c> {
-        fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-            render_impls(self.0, fmt, &self.1, self.2)
-        }
-        }
-
-        let impls = RendererStruct(cx, concrete, containing_item).to_string();
+        let mut impls = Buffer::empty_from(&w);
+        render_impls(cx, &mut impls, &concrete, containing_item);
+        let impls = impls.into_inner();
         if !impls.is_empty() {
             write!(w, "\
                 <h2 id='implementations' class='small-section-header'>\
                   Trait Implementations<a href='#implementations' class='anchor'></a>\
                 </h2>\
-                <div id='implementations-list'>{}</div>", impls)?;
+                <div id='implementations-list'>{}</div>", impls);
         }
 
         if !synthetic.is_empty() {
@@ -3831,9 +3788,9 @@ fn render_assoc_items(w: &mut fmt::Formatter<'_>,
                   <a href='#synthetic-implementations' class='anchor'></a>\
                 </h2>\
                 <div id='synthetic-implementations-list'>\
-            ")?;
-            render_impls(cx, w, &synthetic, containing_item)?;
-            write!(w, "</div>")?;
+            ");
+            render_impls(cx, w, &synthetic, containing_item);
+            write!(w, "</div>");
         }
 
         if !blanket_impl.is_empty() {
@@ -3843,16 +3800,15 @@ fn render_assoc_items(w: &mut fmt::Formatter<'_>,
                   <a href='#blanket-implementations' class='anchor'></a>\
                 </h2>\
                 <div id='blanket-implementations-list'>\
-            ")?;
-            render_impls(cx, w, &blanket_impl, containing_item)?;
-            write!(w, "</div>")?;
+            ");
+            render_impls(cx, w, &blanket_impl, containing_item);
+            write!(w, "</div>");
         }
     }
-    Ok(())
 }
 
-fn render_deref_methods(w: &mut fmt::Formatter<'_>, cx: &Context, impl_: &Impl,
-                        container_item: &clean::Item, deref_mut: bool) -> fmt::Result {
+fn render_deref_methods(w: &mut Buffer, cx: &Context, impl_: &Impl,
+                        container_item: &clean::Item, deref_mut: bool) {
     let deref_type = impl_.inner_impl().trait_.as_ref().unwrap();
     let target = impl_.inner_impl().items.iter().filter_map(|item| {
         match item.inner {
@@ -3867,10 +3823,9 @@ fn render_deref_methods(w: &mut fmt::Formatter<'_>, cx: &Context, impl_: &Impl,
     } else {
         if let Some(prim) = target.primitive_type() {
             if let Some(&did) = cache().primitive_locations.get(&prim) {
-                render_assoc_items(w, cx, container_item, did, what)?;
+                render_assoc_items(w, cx, container_item, did, what);
             }
         }
-        Ok(())
     }
 }
 
@@ -3900,7 +3855,7 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool) -> bool {
     }
 }
 
-fn render_spotlight_traits(item: &clean::Item) -> Result<String, fmt::Error> {
+fn render_spotlight_traits(item: &clean::Item) -> String {
     let mut out = String::new();
 
     match item.inner {
@@ -3908,16 +3863,16 @@ fn render_spotlight_traits(item: &clean::Item) -> Result<String, fmt::Error> {
         clean::TyMethodItem(clean::TyMethod { ref decl, .. }) |
         clean::MethodItem(clean::Method { ref decl, .. }) |
         clean::ForeignFunctionItem(clean::Function { ref decl, .. }) => {
-            out = spotlight_decl(decl)?;
+            out = spotlight_decl(decl);
         }
         _ => {}
     }
 
-    Ok(out)
+    out
 }
 
-fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> {
-    let mut out = String::new();
+fn spotlight_decl(decl: &clean::FnDecl) -> String {
+    let mut out = Buffer::html();
     let mut trait_ = String::new();
 
     if let Some(did) = decl.output.def_id() {
@@ -3943,7 +3898,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> {
                             assoc_type(&mut out, it, &[],
                                        Some(&tydef.type_),
                                        AssocItemLink::GotoSource(t_did, &FxHashSet::default()),
-                                       "")?;
+                                       "");
                             out.push_str(";</span>");
                         }
                     }
@@ -3960,13 +3915,13 @@ fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> {
         out.push_str("</code></div></div>");
     }
 
-    Ok(out)
+    out.into_inner()
 }
 
-fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocItemLink<'_>,
+fn render_impl(w: &mut Buffer, cx: &Context, i: &Impl, link: AssocItemLink<'_>,
                render_mode: RenderMode, outer_version: Option<&str>, show_def_docs: bool,
                use_absolute: Option<bool>, is_on_foreign_type: bool,
-               show_default_items: bool) -> fmt::Result {
+               show_default_items: bool) {
     if render_mode == RenderMode::Normal {
         let id = cx.derive_id(match i.inner_impl().trait_ {
             Some(ref t) => if is_on_foreign_type {
@@ -3977,45 +3932,45 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
             None => "impl".to_string(),
         });
         if let Some(use_absolute) = use_absolute {
-            write!(w, "<h3 id='{}' class='impl'><code class='in-band'>", id)?;
-            fmt_impl_for_trait_page(&i.inner_impl(), w, use_absolute)?;
+            write!(w, "<h3 id='{}' class='impl'><code class='in-band'>", id);
+            fmt_impl_for_trait_page(&i.inner_impl(), w, use_absolute);
             if show_def_docs {
                 for it in &i.inner_impl().items {
                     if let clean::TypedefItem(ref tydef, _) = it.inner {
-                        write!(w, "<span class=\"where fmt-newline\">  ")?;
+                        write!(w, "<span class=\"where fmt-newline\">  ");
                         assoc_type(w, it, &vec![], Some(&tydef.type_),
                                    AssocItemLink::Anchor(None),
-                                   "")?;
-                        write!(w, ";</span>")?;
+                                   "");
+                        write!(w, ";</span>");
                     }
                 }
             }
-            write!(w, "</code>")?;
+            write!(w, "</code>");
         } else {
             write!(w, "<h3 id='{}' class='impl'><code class='in-band'>{}</code>",
                 id, i.inner_impl()
-            )?;
+            );
         }
-        write!(w, "<a href='#{}' class='anchor'></a>", id)?;
+        write!(w, "<a href='#{}' class='anchor'></a>", id);
         let since = i.impl_item.stability.as_ref().map(|s| &s.since[..]);
-        render_stability_since_raw(w, since, outer_version)?;
+        render_stability_since_raw(w, since, outer_version);
         if let Some(l) = cx.src_href(&i.impl_item) {
             write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
-                   l, "goto source code")?;
+                   l, "goto source code");
         }
-        write!(w, "</h3>")?;
+        write!(w, "</h3>");
         if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
             let mut ids = cx.id_map.borrow_mut();
             write!(w, "<div class='docblock'>{}</div>",
                    Markdown(&*dox, &i.impl_item.links(), &mut ids,
-                            cx.codes, cx.edition, &cx.playground).to_string())?;
+                            cx.codes, cx.edition, &cx.playground).to_string());
         }
     }
 
-    fn doc_impl_item(w: &mut fmt::Formatter<'_>, cx: &Context, item: &clean::Item,
+    fn doc_impl_item(w: &mut Buffer, cx: &Context, item: &clean::Item,
                      link: AssocItemLink<'_>, render_mode: RenderMode,
                      is_default_item: bool, outer_version: Option<&str>,
-                     trait_: Option<&clean::Trait>, show_def_docs: bool) -> fmt::Result {
+                     trait_: Option<&clean::Trait>, show_def_docs: bool) {
         let item_type = item.type_();
         let name = item.name.as_ref().unwrap();
 
@@ -4039,50 +3994,50 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
                 if render_method_item {
                     let id = cx.derive_id(format!("{}.{}", item_type, name));
                     let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-                    write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
-                    write!(w, "{}", spotlight_decl(decl)?)?;
-                    write!(w, "<code id='{}'>", ns_id)?;
-                    render_assoc_item(w, item, link.anchor(&id), ItemType::Impl)?;
-                    write!(w, "</code>")?;
-                    render_stability_since_raw(w, item.stable_since(), outer_version)?;
+                    write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class);
+                    write!(w, "{}", spotlight_decl(decl));
+                    write!(w, "<code id='{}'>", ns_id);
+                    render_assoc_item(w, item, link.anchor(&id), ItemType::Impl);
+                    write!(w, "</code>");
+                    render_stability_since_raw(w, item.stable_since(), outer_version);
                     if let Some(l) = cx.src_href(item) {
                         write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
-                               l, "goto source code")?;
+                               l, "goto source code");
                     }
-                    write!(w, "</h4>")?;
+                    write!(w, "</h4>");
                 }
             }
             clean::TypedefItem(ref tydef, _) => {
                 let id = cx.derive_id(format!("{}.{}", ItemType::AssocType, name));
                 let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-                write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
-                write!(w, "<code id='{}'>", ns_id)?;
-                assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id), "")?;
-                write!(w, "</code></h4>")?;
+                write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class);
+                write!(w, "<code id='{}'>", ns_id);
+                assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id), "");
+                write!(w, "</code></h4>");
             }
             clean::AssocConstItem(ref ty, ref default) => {
                 let id = cx.derive_id(format!("{}.{}", item_type, name));
                 let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-                write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
-                write!(w, "<code id='{}'>", ns_id)?;
-                assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "")?;
-                write!(w, "</code>")?;
-                render_stability_since_raw(w, item.stable_since(), outer_version)?;
+                write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class);
+                write!(w, "<code id='{}'>", ns_id);
+                assoc_const(w, item, ty, default.as_ref(), link.anchor(&id), "");
+                write!(w, "</code>");
+                render_stability_since_raw(w, item.stable_since(), outer_version);
                 if let Some(l) = cx.src_href(item) {
                     write!(w, "<a class='srclink' href='{}' title='{}'>[src]</a>",
-                            l, "goto source code")?;
+                            l, "goto source code");
                 }
-                write!(w, "</h4>")?;
+                write!(w, "</h4>");
             }
             clean::AssocTypeItem(ref bounds, ref default) => {
                 let id = cx.derive_id(format!("{}.{}", item_type, name));
                 let ns_id = cx.derive_id(format!("{}.{}", name, item_type.name_space()));
-                write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class)?;
-                write!(w, "<code id='{}'>", ns_id)?;
-                assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id), "")?;
-                write!(w, "</code></h4>")?;
+                write!(w, "<h4 id='{}' class=\"{}{}\">", id, item_type, extra_class);
+                write!(w, "<code id='{}'>", ns_id);
+                assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id), "");
+                write!(w, "</code></h4>");
             }
-            clean::StrippedItem(..) => return Ok(()),
+            clean::StrippedItem(..) => return,
             _ => panic!("can't make docs for trait item with name {:?}", item.name)
         }
 
@@ -4094,47 +4049,46 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
                     if let Some(it) = t.items.iter().find(|i| i.name == item.name) {
                         // We need the stability of the item from the trait
                         // because impls can't have a stability.
-                        document_stability(w, cx, it, is_hidden)?;
+                        document_stability(w, cx, it, is_hidden);
                         if item.doc_value().is_some() {
-                            document_full(w, item, cx, "", is_hidden)?;
+                            document_full(w, item, cx, "", is_hidden);
                         } else if show_def_docs {
                             // In case the item isn't documented,
                             // provide short documentation from the trait.
-                            document_short(w, cx, it, link, "", is_hidden)?;
+                            document_short(w, cx, it, link, "", is_hidden);
                         }
                     }
                 } else {
-                    document_stability(w, cx, item, is_hidden)?;
+                    document_stability(w, cx, item, is_hidden);
                     if show_def_docs {
-                        document_full(w, item, cx, "", is_hidden)?;
+                        document_full(w, item, cx, "", is_hidden);
                     }
                 }
             } else {
-                document_stability(w, cx, item, is_hidden)?;
+                document_stability(w, cx, item, is_hidden);
                 if show_def_docs {
-                    document_short(w, cx, item, link, "", is_hidden)?;
+                    document_short(w, cx, item, link, "", is_hidden);
                 }
             }
         }
-        Ok(())
     }
 
     let traits = &cache().traits;
     let trait_ = i.trait_did().map(|did| &traits[&did]);
 
-    write!(w, "<div class='impl-items'>")?;
+    write!(w, "<div class='impl-items'>");
     for trait_item in &i.inner_impl().items {
         doc_impl_item(w, cx, trait_item, link, render_mode,
-                      false, outer_version, trait_, show_def_docs)?;
+                      false, outer_version, trait_, show_def_docs);
     }
 
-    fn render_default_items(w: &mut fmt::Formatter<'_>,
+    fn render_default_items(w: &mut Buffer,
                             cx: &Context,
                             t: &clean::Trait,
                             i: &clean::Impl,
                             render_mode: RenderMode,
                             outer_version: Option<&str>,
-                            show_def_docs: bool) -> fmt::Result {
+                            show_def_docs: bool) {
         for trait_item in &t.items {
             let n = trait_item.name.clone();
             if i.items.iter().find(|m| m.name == n).is_some() {
@@ -4144,9 +4098,8 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
             let assoc_link = AssocItemLink::GotoSource(did, &i.provided_trait_methods);
 
             doc_impl_item(w, cx, trait_item, assoc_link, render_mode, true,
-                          outer_version, None, show_def_docs)?;
+                          outer_version, None, show_def_docs);
         }
-        Ok(())
     }
 
     // If we've implemented a trait, then also emit documentation for all
@@ -4156,29 +4109,27 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
     if show_default_items {
         if let Some(t) = trait_ {
             render_default_items(w, cx, t, &i.inner_impl(),
-                                render_mode, outer_version, show_def_docs)?;
+                                render_mode, outer_version, show_def_docs);
         }
     }
-    write!(w, "</div>")?;
-
-    Ok(())
+    write!(w, "</div>");
 }
 
 fn item_opaque_ty(
-    w: &mut fmt::Formatter<'_>,
+    w: &mut Buffer,
     cx: &Context,
     it: &clean::Item,
     t: &clean::OpaqueTy,
-) -> fmt::Result {
-    write!(w, "<pre class='rust opaque'>")?;
-    render_attributes(w, it, false)?;
+) {
+    write!(w, "<pre class='rust opaque'>");
+    render_attributes(w, it, false);
     write!(w, "type {}{}{where_clause} = impl {bounds};</pre>",
            it.name.as_ref().unwrap(),
            t.generics,
            where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true },
-           bounds = bounds(&t.bounds, false))?;
+           bounds = bounds(&t.bounds, false));
 
-    document(w, cx, it)?;
+    document(w, cx, it);
 
     // Render any items associated directly to this alias, as otherwise they
     // won't be visible anywhere in the docs. It would be nice to also show
@@ -4187,17 +4138,17 @@ fn item_opaque_ty(
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
 
-fn item_trait_alias(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
-                    t: &clean::TraitAlias) -> fmt::Result {
-    write!(w, "<pre class='rust trait-alias'>")?;
-    render_attributes(w, it, false)?;
+fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item,
+                    t: &clean::TraitAlias) {
+    write!(w, "<pre class='rust trait-alias'>");
+    render_attributes(w, it, false);
     write!(w, "trait {}{}{} = {};</pre>",
            it.name.as_ref().unwrap(),
            t.generics,
            WhereClause { gens: &t.generics, indent: 0, end_newline: true },
-           bounds(&t.bounds, true))?;
+           bounds(&t.bounds, true));
 
-    document(w, cx, it)?;
+    document(w, cx, it);
 
     // Render any items associated directly to this alias, as otherwise they
     // won't be visible anywhere in the docs. It would be nice to also show
@@ -4206,17 +4157,16 @@ fn item_trait_alias(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
 
-fn item_typedef(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
-                t: &clean::Typedef) -> fmt::Result {
-    write!(w, "<pre class='rust typedef'>")?;
-    render_attributes(w, it, false)?;
+fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef) {
+    write!(w, "<pre class='rust typedef'>");
+    render_attributes(w, it, false);
     write!(w, "type {}{}{where_clause} = {type_};</pre>",
            it.name.as_ref().unwrap(),
            t.generics,
            where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true },
-           type_ = t.type_)?;
+           type_ = t.type_);
 
-    document(w, cx, it)?;
+    document(w, cx, it);
 
     // Render any items associated directly to this alias, as otherwise they
     // won't be visible anywhere in the docs. It would be nice to also show
@@ -4225,17 +4175,17 @@ fn item_typedef(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
 
-fn item_foreign_type(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item) -> fmt::Result {
-    writeln!(w, "<pre class='rust foreigntype'>extern {{")?;
-    render_attributes(w, it, false)?;
+fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) {
+    writeln!(w, "<pre class='rust foreigntype'>extern {{");
+    render_attributes(w, it, false);
     write!(
         w,
         "    {}type {};\n}}</pre>",
         VisSpace(&it.visibility),
         it.name.as_ref().unwrap(),
-    )?;
+    );
 
-    document(w, cx, it)?;
+    document(w, cx, it);
 
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
@@ -4790,59 +4740,56 @@ fn sidebar_foreign_type(buf: &mut Buffer, it: &clean::Item) {
     }
 }
 
-fn item_macro(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item,
-              t: &clean::Macro) -> fmt::Result {
+fn item_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Macro) {
     wrap_into_docblock(w, |w| {
         w.write_str(&highlight::render_with_highlighting(&t.source,
                                                          Some("macro"),
                                                          None,
                                                          None))
-    })?;
+    });
     document(w, cx, it)
 }
 
-fn item_proc_macro(w: &mut fmt::Formatter<'_>, cx: &Context, it: &clean::Item, m: &clean::ProcMacro)
-    -> fmt::Result
-{
+fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::ProcMacro) {
     let name = it.name.as_ref().expect("proc-macros always have names");
     match m.kind {
         MacroKind::Bang => {
-            write!(w, "<pre class='rust macro'>")?;
-            write!(w, "{}!() {{ /* proc-macro */ }}", name)?;
-            write!(w, "</pre>")?;
+            write!(w, "<pre class='rust macro'>");
+            write!(w, "{}!() {{ /* proc-macro */ }}", name);
+            write!(w, "</pre>");
         }
         MacroKind::Attr => {
-            write!(w, "<pre class='rust attr'>")?;
-            write!(w, "#[{}]", name)?;
-            write!(w, "</pre>")?;
+            write!(w, "<pre class='rust attr'>");
+            write!(w, "#[{}]", name);
+            write!(w, "</pre>");
         }
         MacroKind::Derive => {
-            write!(w, "<pre class='rust derive'>")?;
-            write!(w, "#[derive({})]", name)?;
+            write!(w, "<pre class='rust derive'>");
+            write!(w, "#[derive({})]", name);
             if !m.helpers.is_empty() {
-                writeln!(w, "\n{{")?;
-                writeln!(w, "    // Attributes available to this derive:")?;
+                writeln!(w, "\n{{");
+                writeln!(w, "    // Attributes available to this derive:");
                 for attr in &m.helpers {
-                    writeln!(w, "    #[{}]", attr)?;
+                    writeln!(w, "    #[{}]", attr);
                 }
-                write!(w, "}}")?;
+                write!(w, "}}");
             }
-            write!(w, "</pre>")?;
+            write!(w, "</pre>");
         }
     }
     document(w, cx, it)
 }
 
-fn item_primitive(w: &mut fmt::Formatter<'_>, cx: &Context,
+fn item_primitive(w: &mut Buffer, cx: &Context,
                   it: &clean::Item,
-                  _p: &clean::PrimitiveType) -> fmt::Result {
-    document(w, cx, it)?;
+                  _p: &clean::PrimitiveType) {
+    document(w, cx, it);
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
 }
 
-fn item_keyword(w: &mut fmt::Formatter<'_>, cx: &Context,
+fn item_keyword(w: &mut Buffer, cx: &Context,
                 it: &clean::Item,
-                _p: &str) -> fmt::Result {
+                _p: &str) {
     document(w, cx, it)
 }
 

From 642993e6dca427ce3cc5ca97bccaf6f6c872eb16 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 30 Jul 2019 01:25:30 +0200
Subject: [PATCH 607/943] Update tests wrt. bind_by_by_move_pattern_guards
 stabilization.

---
 src/librustc_mir/error_codes.rs               |  1 -
 src/test/mir-opt/match-arm-scopes.rs          |  2 -
 .../ui/bind-by-move/bind-by-move-no-guards.rs | 13 ------
 .../bind-by-move-no-guards.stderr             | 11 -----
 .../ui/borrowck/borrowck-mutate-in-guard.rs   |  7 +---
 .../borrowck/borrowck-mutate-in-guard.stderr  | 27 ++-----------
 src/test/ui/error-codes/E0008.rs              |  7 ----
 src/test/ui/error-codes/E0008.stderr          | 11 -----
 src/test/ui/error-codes/E0301.rs              |  2 +-
 src/test/ui/error-codes/E0301.stderr          | 13 +-----
 src/test/ui/error-codes/E0302.rs              |  2 +-
 src/test/ui/error-codes/E0302.stderr          |  9 +----
 ...535-allow-mutable-borrow-in-match-guard.rs |  2 -
 .../issue-27282-reborrow-ref-mut-in-guard.rs  |  2 -
 ...sue-27282-reborrow-ref-mut-in-guard.stderr |  2 +-
 src/test/ui/match/match-ref-mut-stability.rs  |  2 -
 src/test/ui/nll/match-cfg-fake-edges.rs       |  2 -
 src/test/ui/nll/match-cfg-fake-edges.stderr   |  4 +-
 .../ui/nll/match-guards-partially-borrow.rs   |  2 -
 .../nll/match-guards-partially-borrow.stderr  | 18 ++++-----
 .../bind-by-move-no-guards.rs                 |  2 -
 .../feature-gate.gate_and_2015.stderr         | 10 -----
 .../feature-gate.gate_and_2018.stderr         | 10 -----
 .../feature-gate.gate_and_feature_nll.stderr  | 10 -----
 .../feature-gate.gate_and_znll.stderr         | 10 -----
 .../feature-gate.no_gate.stderr               | 11 -----
 .../feature-gate.rs                           | 40 -------------------
 .../former-E0008-now-pass.rs                  | 11 +++++
 .../rfc-basic-examples.rs                     |  2 -
 .../rfc-reject-double-move-across-arms.rs     |  2 -
 .../rfc-reject-double-move-across-arms.stderr |  2 +-
 .../rfc-reject-double-move-in-first-arm.rs    |  2 -
 ...rfc-reject-double-move-in-first-arm.stderr |  2 +-
 33 files changed, 35 insertions(+), 218 deletions(-)
 delete mode 100644 src/test/ui/bind-by-move/bind-by-move-no-guards.rs
 delete mode 100644 src/test/ui/bind-by-move/bind-by-move-no-guards.stderr
 delete mode 100644 src/test/ui/error-codes/E0008.rs
 delete mode 100644 src/test/ui/error-codes/E0008.stderr
 delete mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr
 delete mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr
 delete mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_feature_nll.stderr
 delete mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_znll.stderr
 delete mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr
 delete mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs
 create mode 100644 src/test/ui/rfc-0107-bind-by-move-pattern-guards/former-E0008-now-pass.rs

diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs
index d80449ac23724..844711acbf875 100644
--- a/src/librustc_mir/error_codes.rs
+++ b/src/librustc_mir/error_codes.rs
@@ -1989,7 +1989,6 @@ When matching on a variable it cannot be mutated in the match guards, as this
 could cause the match to be non-exhaustive:
 
 ```compile_fail,E0510
-#![feature(bind_by_move_pattern_guards)]
 let mut x = Some(0);
 match x {
     None => (),
diff --git a/src/test/mir-opt/match-arm-scopes.rs b/src/test/mir-opt/match-arm-scopes.rs
index 18e0642eb3427..c898d3a6f168c 100644
--- a/src/test/mir-opt/match-arm-scopes.rs
+++ b/src/test/mir-opt/match-arm-scopes.rs
@@ -8,8 +8,6 @@
 //   all of the bindings for that scope.
 // * No drop flags are used.
 
-#![feature(nll, bind_by_move_pattern_guards)]
-
 fn complicated_match(cond: bool, items: (bool, bool, String)) -> i32 {
     match items {
         (false, a, s) | (a, false, s) if if cond { return 3 } else { a } => 1,
diff --git a/src/test/ui/bind-by-move/bind-by-move-no-guards.rs b/src/test/ui/bind-by-move/bind-by-move-no-guards.rs
deleted file mode 100644
index bc9b3a8de4ef5..0000000000000
--- a/src/test/ui/bind-by-move/bind-by-move-no-guards.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-use std::sync::mpsc::channel;
-
-fn main() {
-    let (tx, rx) = channel();
-    let x = Some(rx);
-    tx.send(false);
-    match x {
-        Some(z) if z.recv().unwrap() => { panic!() },
-            //~^ ERROR cannot bind by-move into a pattern guard
-        Some(z) => { assert!(!z.recv().unwrap()); },
-        None => panic!()
-    }
-}
diff --git a/src/test/ui/bind-by-move/bind-by-move-no-guards.stderr b/src/test/ui/bind-by-move/bind-by-move-no-guards.stderr
deleted file mode 100644
index c5f0256c2c92f..0000000000000
--- a/src/test/ui/bind-by-move/bind-by-move-no-guards.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0008]: cannot bind by-move into a pattern guard
-  --> $DIR/bind-by-move-no-guards.rs:8:14
-   |
-LL |         Some(z) if z.recv().unwrap() => { panic!() },
-   |              ^ moves value into pattern guard
-   |
-   = help: add `#![feature(bind_by_move_pattern_guards)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0008`.
diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.rs b/src/test/ui/borrowck/borrowck-mutate-in-guard.rs
index 5b6aa7a979be5..9cbceeb945ccc 100644
--- a/src/test/ui/borrowck/borrowck-mutate-in-guard.rs
+++ b/src/test/ui/borrowck/borrowck-mutate-in-guard.rs
@@ -8,12 +8,9 @@ fn foo() -> isize {
     let mut x = Enum::A(&mut n);
     match x {
         Enum::A(_) if { x = Enum::B(false); false } => 1,
-        //~^ ERROR cannot assign in a pattern guard
-        //~| ERROR cannot assign `x` in match guard
+        //~^ ERROR cannot assign `x` in match guard
         Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
-        //~^ ERROR cannot mutably borrow in a pattern guard
-        //~| ERROR cannot assign in a pattern guard
-        //~| ERROR cannot mutably borrow `x` in match guard
+        //~^ ERROR cannot mutably borrow `x` in match guard
         Enum::A(p) => *p,
         Enum::B(_) => 2,
     }
diff --git a/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr b/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr
index 674f137dbb043..6d05e97252d92 100644
--- a/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr
+++ b/src/test/ui/borrowck/borrowck-mutate-in-guard.stderr
@@ -1,23 +1,3 @@
-error[E0302]: cannot assign in a pattern guard
-  --> $DIR/borrowck-mutate-in-guard.rs:10:25
-   |
-LL |         Enum::A(_) if { x = Enum::B(false); false } => 1,
-   |                         ^^^^^^^^^^^^^^^^^^ assignment in pattern guard
-
-error[E0301]: cannot mutably borrow in a pattern guard
-  --> $DIR/borrowck-mutate-in-guard.rs:13:38
-   |
-LL |         Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
-   |                                      ^ borrowed mutably in pattern guard
-   |
-   = help: add `#![feature(bind_by_move_pattern_guards)]` to the crate attributes to enable
-
-error[E0302]: cannot assign in a pattern guard
-  --> $DIR/borrowck-mutate-in-guard.rs:13:41
-   |
-LL |         Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
-   |                                         ^^^^^^^^^^^^^^^^^^^ assignment in pattern guard
-
 error[E0510]: cannot assign `x` in match guard
   --> $DIR/borrowck-mutate-in-guard.rs:10:25
    |
@@ -27,7 +7,7 @@ LL |         Enum::A(_) if { x = Enum::B(false); false } => 1,
    |                         ^^^^^^^^^^^^^^^^^^ cannot assign
 
 error[E0510]: cannot mutably borrow `x` in match guard
-  --> $DIR/borrowck-mutate-in-guard.rs:13:33
+  --> $DIR/borrowck-mutate-in-guard.rs:12:33
    |
 LL |     match x {
    |           - value is immutable in match guard
@@ -35,7 +15,6 @@ LL |     match x {
 LL |         Enum::A(_) if { let y = &mut x; *y = Enum::B(false); false } => 1,
    |                                 ^^^^^^ cannot mutably borrow
 
-error: aborting due to 5 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0301, E0302, E0510.
-For more information about an error, try `rustc --explain E0301`.
+For more information about this error, try `rustc --explain E0510`.
diff --git a/src/test/ui/error-codes/E0008.rs b/src/test/ui/error-codes/E0008.rs
deleted file mode 100644
index c87ef4cb8541f..0000000000000
--- a/src/test/ui/error-codes/E0008.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-fn main() {
-    match Some("hi".to_string()) {
-        Some(s) if s.len() == 0 => {},
-        //~^ ERROR E0008
-        _ => {},
-    }
-}
diff --git a/src/test/ui/error-codes/E0008.stderr b/src/test/ui/error-codes/E0008.stderr
deleted file mode 100644
index 6b45439c4b587..0000000000000
--- a/src/test/ui/error-codes/E0008.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0008]: cannot bind by-move into a pattern guard
-  --> $DIR/E0008.rs:3:14
-   |
-LL |         Some(s) if s.len() == 0 => {},
-   |              ^ moves value into pattern guard
-   |
-   = help: add `#![feature(bind_by_move_pattern_guards)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0008`.
diff --git a/src/test/ui/error-codes/E0301.rs b/src/test/ui/error-codes/E0301.rs
index 3b451801c99df..0df04036bb767 100644
--- a/src/test/ui/error-codes/E0301.rs
+++ b/src/test/ui/error-codes/E0301.rs
@@ -1,7 +1,7 @@
 fn main() {
     match Some(()) {
         None => { },
-        option if option.take().is_none() => {}, //~ ERROR E0301
+        option if option.take().is_none() => {},
         Some(_) => { } //~^ ERROR E0596
     }
 }
diff --git a/src/test/ui/error-codes/E0301.stderr b/src/test/ui/error-codes/E0301.stderr
index 4f12fd3850e33..661b86e389485 100644
--- a/src/test/ui/error-codes/E0301.stderr
+++ b/src/test/ui/error-codes/E0301.stderr
@@ -1,11 +1,3 @@
-error[E0301]: cannot mutably borrow in a pattern guard
-  --> $DIR/E0301.rs:4:19
-   |
-LL |         option if option.take().is_none() => {},
-   |                   ^^^^^^ borrowed mutably in pattern guard
-   |
-   = help: add `#![feature(bind_by_move_pattern_guards)]` to the crate attributes to enable
-
 error[E0596]: cannot borrow `option` as mutable, as it is immutable for the pattern guard
   --> $DIR/E0301.rs:4:19
    |
@@ -14,7 +6,6 @@ LL |         option if option.take().is_none() => {},
    |
    = note: variables bound in patterns are immutable until the end of the pattern guard
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0301, E0596.
-For more information about an error, try `rustc --explain E0301`.
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/error-codes/E0302.rs b/src/test/ui/error-codes/E0302.rs
index 69f5953deb223..28a1bc31bea7b 100644
--- a/src/test/ui/error-codes/E0302.rs
+++ b/src/test/ui/error-codes/E0302.rs
@@ -1,7 +1,7 @@
 fn main() {
     match Some(()) {
         None => { },
-        option if { option = None; false } => { }, //~ ERROR E0302
+        option if { option = None; false } => { },
         //~^ ERROR cannot assign to `option`, as it is immutable for the pattern guard
         Some(_) => { }
     }
diff --git a/src/test/ui/error-codes/E0302.stderr b/src/test/ui/error-codes/E0302.stderr
index a077fcaea4101..5854772f1d34a 100644
--- a/src/test/ui/error-codes/E0302.stderr
+++ b/src/test/ui/error-codes/E0302.stderr
@@ -1,9 +1,3 @@
-error[E0302]: cannot assign in a pattern guard
-  --> $DIR/E0302.rs:4:21
-   |
-LL |         option if { option = None; false } => { },
-   |                     ^^^^^^^^^^^^^ assignment in pattern guard
-
 error[E0594]: cannot assign to `option`, as it is immutable for the pattern guard
   --> $DIR/E0302.rs:4:21
    |
@@ -12,6 +6,5 @@ LL |         option if { option = None; false } => { },
    |
    = note: variables bound in patterns are immutable until the end of the pattern guard
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0302`.
diff --git a/src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs b/src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs
index 48362d0bb6282..7253d35ed2d4f 100644
--- a/src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs
+++ b/src/test/ui/issues/issue-24535-allow-mutable-borrow-in-match-guard.rs
@@ -5,8 +5,6 @@
 // See further discussion on rust-lang/rust#24535,
 // rust-lang/rfcs#1006, and rust-lang/rfcs#107
 
-#![feature(bind_by_move_pattern_guards)]
-
 fn main() {
     rust_issue_24535();
     rfcs_issue_1006_1();
diff --git a/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs b/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs
index 1ffb7f6fd4acd..82d8b9e9ed977 100644
--- a/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs
+++ b/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.rs
@@ -5,8 +5,6 @@
 // reject it. But I want to make sure that we continue to reject it
 // (under NLL) even when that conservaive check goes away.
 
-#![feature(bind_by_move_pattern_guards)]
-
 fn main() {
     let mut b = &mut true;
     match b {
diff --git a/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.stderr b/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.stderr
index a8eb78b7cc007..f0264b56ea569 100644
--- a/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.stderr
+++ b/src/test/ui/issues/issue-27282-reborrow-ref-mut-in-guard.stderr
@@ -1,5 +1,5 @@
 error[E0596]: cannot borrow `r` as mutable, as it is immutable for the pattern guard
-  --> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:14:25
+  --> $DIR/issue-27282-reborrow-ref-mut-in-guard.rs:12:25
    |
 LL |         ref mut r if { (|| { let bar = &mut *r; **bar = false; })();
    |                         ^^                   - mutable borrow occurs due to use of `r` in closure
diff --git a/src/test/ui/match/match-ref-mut-stability.rs b/src/test/ui/match/match-ref-mut-stability.rs
index 49e0dfaa3eb84..52120360be71e 100644
--- a/src/test/ui/match/match-ref-mut-stability.rs
+++ b/src/test/ui/match/match-ref-mut-stability.rs
@@ -3,8 +3,6 @@
 
 // run-pass
 
-#![feature(bind_by_move_pattern_guards)]
-
 // Test that z always point to the same temporary.
 fn referent_stability() {
     let p;
diff --git a/src/test/ui/nll/match-cfg-fake-edges.rs b/src/test/ui/nll/match-cfg-fake-edges.rs
index 5fc9966cdf807..2e6d675fb641e 100644
--- a/src/test/ui/nll/match-cfg-fake-edges.rs
+++ b/src/test/ui/nll/match-cfg-fake-edges.rs
@@ -1,8 +1,6 @@
 // Test that we have enough false edges to avoid exposing the exact matching
 // algorithm in borrow checking.
 
-#![feature(bind_by_move_pattern_guards)]
-
 fn guard_always_precedes_arm(y: i32) {
     let mut x;
     // x should always be initialized, as the only way to reach the arm is
diff --git a/src/test/ui/nll/match-cfg-fake-edges.stderr b/src/test/ui/nll/match-cfg-fake-edges.stderr
index 3d9037bbe7bf8..06fe564ac69e3 100644
--- a/src/test/ui/nll/match-cfg-fake-edges.stderr
+++ b/src/test/ui/nll/match-cfg-fake-edges.stderr
@@ -1,11 +1,11 @@
 error[E0381]: use of possibly-uninitialized variable: `x`
-  --> $DIR/match-cfg-fake-edges.rs:23:13
+  --> $DIR/match-cfg-fake-edges.rs:21:13
    |
 LL |             x;
    |             ^ use of possibly-uninitialized `x`
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/match-cfg-fake-edges.rs:37:13
+  --> $DIR/match-cfg-fake-edges.rs:35:13
    |
 LL |     let x = String::new();
    |         - move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait
diff --git a/src/test/ui/nll/match-guards-partially-borrow.rs b/src/test/ui/nll/match-guards-partially-borrow.rs
index 601c46ff86cc7..81ae19ebf8a72 100644
--- a/src/test/ui/nll/match-guards-partially-borrow.rs
+++ b/src/test/ui/nll/match-guards-partially-borrow.rs
@@ -5,8 +5,6 @@
 // Test that we don't allow mutating the value being matched on in a way that
 // changes which patterns it matches, until we have chosen an arm.
 
-#![feature(bind_by_move_pattern_guards)]
-
 fn ok_mutation_in_guard(mut q: i32) {
     match q {
         // OK, mutation doesn't change which patterns g matches
diff --git a/src/test/ui/nll/match-guards-partially-borrow.stderr b/src/test/ui/nll/match-guards-partially-borrow.stderr
index b2951fd339da4..48e3a7c699318 100644
--- a/src/test/ui/nll/match-guards-partially-borrow.stderr
+++ b/src/test/ui/nll/match-guards-partially-borrow.stderr
@@ -1,5 +1,5 @@
 error[E0510]: cannot assign `q` in match guard
-  --> $DIR/match-guards-partially-borrow.rs:57:13
+  --> $DIR/match-guards-partially-borrow.rs:55:13
    |
 LL |     match q {
    |           - value is immutable in match guard
@@ -8,7 +8,7 @@ LL |             q = true;
    |             ^^^^^^^^ cannot assign
 
 error[E0510]: cannot assign `r` in match guard
-  --> $DIR/match-guards-partially-borrow.rs:69:13
+  --> $DIR/match-guards-partially-borrow.rs:67:13
    |
 LL |     match r {
    |           - value is immutable in match guard
@@ -17,7 +17,7 @@ LL |             r = true;
    |             ^^^^^^^^ cannot assign
 
 error[E0510]: cannot assign `t` in match guard
-  --> $DIR/match-guards-partially-borrow.rs:93:13
+  --> $DIR/match-guards-partially-borrow.rs:91:13
    |
 LL |     match t {
    |           - value is immutable in match guard
@@ -26,7 +26,7 @@ LL |             t = true;
    |             ^^^^^^^^ cannot assign
 
 error[E0510]: cannot mutably borrow `x.0` in match guard
-  --> $DIR/match-guards-partially-borrow.rs:107:22
+  --> $DIR/match-guards-partially-borrow.rs:105:22
    |
 LL |     match x {
    |           - value is immutable in match guard
@@ -35,7 +35,7 @@ LL |                 Some(ref mut r) => *r = None,
    |                      ^^^^^^^^^ cannot mutably borrow
 
 error[E0506]: cannot assign to `t` because it is borrowed
-  --> $DIR/match-guards-partially-borrow.rs:119:13
+  --> $DIR/match-guards-partially-borrow.rs:117:13
    |
 LL |         s if {
    |         - borrow of `t` occurs here
@@ -46,7 +46,7 @@ LL |         } => (), // What value should `s` have in the arm?
    |         - borrow later used here
 
 error[E0510]: cannot assign `y` in match guard
-  --> $DIR/match-guards-partially-borrow.rs:130:13
+  --> $DIR/match-guards-partially-borrow.rs:128:13
    |
 LL |     match *y {
    |           -- value is immutable in match guard
@@ -55,7 +55,7 @@ LL |             y = &true;
    |             ^^^^^^^^^ cannot assign
 
 error[E0510]: cannot assign `z` in match guard
-  --> $DIR/match-guards-partially-borrow.rs:141:13
+  --> $DIR/match-guards-partially-borrow.rs:139:13
    |
 LL |     match z {
    |           - value is immutable in match guard
@@ -64,7 +64,7 @@ LL |             z = &true;
    |             ^^^^^^^^^ cannot assign
 
 error[E0510]: cannot assign `a` in match guard
-  --> $DIR/match-guards-partially-borrow.rs:153:13
+  --> $DIR/match-guards-partially-borrow.rs:151:13
    |
 LL |     match a {
    |           - value is immutable in match guard
@@ -73,7 +73,7 @@ LL |             a = &true;
    |             ^^^^^^^^^ cannot assign
 
 error[E0510]: cannot assign `b` in match guard
-  --> $DIR/match-guards-partially-borrow.rs:164:13
+  --> $DIR/match-guards-partially-borrow.rs:162:13
    |
 LL |     match b {
    |           - value is immutable in match guard
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs
index e43c8541e6d6d..40a47ce45fbb5 100644
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs
@@ -4,8 +4,6 @@
 
 // run-pass
 
-#![feature(bind_by_move_pattern_guards)]
-
 use std::sync::mpsc::channel;
 
 fn main() {
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr
deleted file mode 100644
index fe1f699074735..0000000000000
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2015.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: compilation successful
-  --> $DIR/feature-gate.rs:36:1
-   |
-LL | / fn main() {
-LL | |     foo(107)
-LL | | }
-   | |_^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr
deleted file mode 100644
index fe1f699074735..0000000000000
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_2018.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: compilation successful
-  --> $DIR/feature-gate.rs:36:1
-   |
-LL | / fn main() {
-LL | |     foo(107)
-LL | | }
-   | |_^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_feature_nll.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_feature_nll.stderr
deleted file mode 100644
index 34e8b0e14399e..0000000000000
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_feature_nll.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: compilation successful
-  --> $DIR/feature-gate.rs:41:1
-   |
-LL | / fn main() {
-LL | |     foo(107)
-LL | | }
-   | |_^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_znll.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_znll.stderr
deleted file mode 100644
index 34e8b0e14399e..0000000000000
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.gate_and_znll.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: compilation successful
-  --> $DIR/feature-gate.rs:41:1
-   |
-LL | / fn main() {
-LL | |     foo(107)
-LL | | }
-   | |_^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr
deleted file mode 100644
index 7a7b1c253528f..0000000000000
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.no_gate.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0008]: cannot bind by-move into a pattern guard
-  --> $DIR/feature-gate.rs:28:16
-   |
-LL |         A { a: v } if *v == 42 => v,
-   |                ^ moves value into pattern guard
-   |
-   = help: add `#![feature(bind_by_move_pattern_guards)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0008`.
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs
deleted file mode 100644
index 69fce0bc775f7..0000000000000
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/feature-gate.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Check that pattern-guards with move-bound variables is only allowed
-// with the appropriate set of feature gates. (Note that we require
-// the code to opt into MIR-borrowck in *some* way before the feature
-// will work; we use the revision system here to enumerate a number of
-// ways that opt-in could occur.)
-
-// gate-test-bind_by_move_pattern_guards
-
-// revisions: no_gate gate_and_2015 gate_and_2018
-
-// (We're already testing NLL behavior quite explicitly, no need for compare-mode=nll.)
-// ignore-compare-mode-nll
-
-#![feature(rustc_attrs)]
-
-#![cfg_attr(gate_and_2015, feature(bind_by_move_pattern_guards))]
-#![cfg_attr(gate_and_2018, feature(bind_by_move_pattern_guards))]
-
-//[gate_and_2015] edition:2015
-//[gate_and_2018] edition:2018
-
-struct A { a: Box<i32> }
-
-fn foo(n: i32) {
-    let x = A { a: Box::new(n) };
-    let _y = match x {
-
-        A { a: v } if *v == 42 => v,
-        //[no_gate]~^ ERROR cannot bind by-move into a pattern guard
-
-        _ => Box::new(0)
-    };
-}
-
-#[rustc_error]
-fn main() {
-    foo(107)
-}
-//[gate_and_2015]~^^^ ERROR compilation successful
-//[gate_and_2018]~^^^^ ERROR compilation successful
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/former-E0008-now-pass.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/former-E0008-now-pass.rs
new file mode 100644
index 0000000000000..3161d6fbbe647
--- /dev/null
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/former-E0008-now-pass.rs
@@ -0,0 +1,11 @@
+// This test used to emit E0008 but now passed since `bind_by_move_pattern_guards`
+// have been stabilized.
+
+// check-pass
+
+fn main() {
+    match Some("hi".to_string()) {
+        Some(s) if s.len() == 0 => {},
+        _ => {},
+    }
+}
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs
index eccb4e417b694..b716fc870e071 100644
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-basic-examples.rs
@@ -1,5 +1,3 @@
-#![feature(bind_by_move_pattern_guards)]
-
 // run-pass
 
 struct A { a: Box<i32> }
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs
index 602a8e15cb180..d1f685f3e7a6d 100644
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.rs
@@ -1,5 +1,3 @@
-#![feature(bind_by_move_pattern_guards)]
-
 enum VecWrapper { A(Vec<i32>) }
 
 fn foo(x: VecWrapper) -> usize {
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr
index c9e8fc8ee532b..7becd013249d4 100644
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-across-arms.stderr
@@ -1,5 +1,5 @@
 error[E0507]: cannot move out of `v` in pattern guard
-  --> $DIR/rfc-reject-double-move-across-arms.rs:7:36
+  --> $DIR/rfc-reject-double-move-across-arms.rs:5:36
    |
 LL |         VecWrapper::A(v) if { drop(v); false } => 1,
    |                                    ^ move occurs because `v` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs
index 77252a1ce1569..571f51c900120 100644
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.rs
@@ -1,5 +1,3 @@
-#![feature(bind_by_move_pattern_guards)]
-
 struct A { a: Box<i32> }
 
 fn foo(n: i32) {
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr
index a345022cee7c5..b93e72190680d 100644
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/rfc-reject-double-move-in-first-arm.stderr
@@ -1,5 +1,5 @@
 error[E0507]: cannot move out of `v` in pattern guard
-  --> $DIR/rfc-reject-double-move-in-first-arm.rs:8:30
+  --> $DIR/rfc-reject-double-move-in-first-arm.rs:6:30
    |
 LL |         A { a: v } if { drop(v); true } => v,
    |                              ^ move occurs because `v` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait

From c6bfb1e9fdce7b94b4258d20d7402d551b30096c Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 30 Jul 2019 05:56:02 +0200
Subject: [PATCH 608/943] Tests: No longer emitting 0008, E0301, E0302.

---
 src/librustc_mir/error_codes.rs      | 83 ++--------------------------
 src/test/ui/error-codes/E0301.rs     |  7 ---
 src/test/ui/error-codes/E0301.stderr | 11 ----
 src/test/ui/error-codes/E0302.rs     |  8 ---
 src/test/ui/error-codes/E0302.stderr | 10 ----
 5 files changed, 6 insertions(+), 113 deletions(-)
 delete mode 100644 src/test/ui/error-codes/E0301.rs
 delete mode 100644 src/test/ui/error-codes/E0301.stderr
 delete mode 100644 src/test/ui/error-codes/E0302.rs
 delete mode 100644 src/test/ui/error-codes/E0302.stderr

diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs
index 844711acbf875..a10af7e2aceab 100644
--- a/src/librustc_mir/error_codes.rs
+++ b/src/librustc_mir/error_codes.rs
@@ -157,81 +157,6 @@ match x {
 See also the error E0303.
 "##,
 
-E0008: r##"
-Names bound in match arms retain their type in pattern guards. As such, if a
-name is bound by move in a pattern, it should also be moved to wherever it is
-referenced in the pattern guard code. Doing so however would prevent the name
-from being available in the body of the match arm. Consider the following:
-
-```compile_fail,E0008
-match Some("hi".to_string()) {
-    Some(s) if s.len() == 0 => {}, // use s.
-    _ => {},
-}
-```
-
-The variable `s` has type `String`, and its use in the guard is as a variable of
-type `String`. The guard code effectively executes in a separate scope to the
-body of the arm, so the value would be moved into this anonymous scope and
-therefore becomes unavailable in the body of the arm.
-
-The problem above can be solved by using the `ref` keyword.
-
-```
-match Some("hi".to_string()) {
-    Some(ref s) if s.len() == 0 => {},
-    _ => {},
-}
-```
-
-Though this example seems innocuous and easy to solve, the problem becomes clear
-when it encounters functions which consume the value:
-
-```compile_fail,E0008
-struct A{}
-
-impl A {
-    fn consume(self) -> usize {
-        0
-    }
-}
-
-fn main() {
-    let a = Some(A{});
-    match a {
-        Some(y) if y.consume() > 0 => {}
-        _ => {}
-    }
-}
-```
-
-In this situation, even the `ref` keyword cannot solve it, since borrowed
-content cannot be moved. This problem cannot be solved generally. If the value
-can be cloned, here is a not-so-specific solution:
-
-```
-#[derive(Clone)]
-struct A{}
-
-impl A {
-    fn consume(self) -> usize {
-        0
-    }
-}
-
-fn main() {
-    let a = Some(A{});
-    match a{
-        Some(ref y) if y.clone().consume() > 0 => {}
-        _ => {}
-    }
-}
-```
-
-If the value will be consumed in the pattern guard, using its clone will not
-move its ownership, so the code works.
-"##,
-
 E0009: r##"
 In a pattern, all values that don't implement the `Copy` trait have to be bound
 the same way. The goal here is to avoid binding simultaneously by-move and
@@ -475,13 +400,15 @@ for item in xs {
 "##,
 
 E0301: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
 Mutable borrows are not allowed in pattern guards, because matching cannot have
 side effects. Side effects could alter the matched object or the environment
 on which the match depends in such a way, that the match would not be
 exhaustive. For instance, the following would not match any arm if mutable
 borrows were allowed:
 
-```compile_fail,E0301
+```compile_fail,E0596
 match Some(()) {
     None => { },
     option if option.take().is_none() => {
@@ -493,13 +420,15 @@ match Some(()) {
 "##,
 
 E0302: r##"
+#### Note: this error code is no longer emitted by the compiler.
+
 Assignments are not allowed in pattern guards, because matching cannot have
 side effects. Side effects could alter the matched object or the environment
 on which the match depends in such a way, that the match would not be
 exhaustive. For instance, the following would not match any arm if assignments
 were allowed:
 
-```compile_fail,E0302
+```compile_fail,E0594
 match Some(()) {
     None => { },
     option if { option = None; false } => { },
diff --git a/src/test/ui/error-codes/E0301.rs b/src/test/ui/error-codes/E0301.rs
deleted file mode 100644
index 0df04036bb767..0000000000000
--- a/src/test/ui/error-codes/E0301.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-fn main() {
-    match Some(()) {
-        None => { },
-        option if option.take().is_none() => {},
-        Some(_) => { } //~^ ERROR E0596
-    }
-}
diff --git a/src/test/ui/error-codes/E0301.stderr b/src/test/ui/error-codes/E0301.stderr
deleted file mode 100644
index 661b86e389485..0000000000000
--- a/src/test/ui/error-codes/E0301.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0596]: cannot borrow `option` as mutable, as it is immutable for the pattern guard
-  --> $DIR/E0301.rs:4:19
-   |
-LL |         option if option.take().is_none() => {},
-   |                   ^^^^^^ cannot borrow as mutable
-   |
-   = note: variables bound in patterns are immutable until the end of the pattern guard
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/error-codes/E0302.rs b/src/test/ui/error-codes/E0302.rs
deleted file mode 100644
index 28a1bc31bea7b..0000000000000
--- a/src/test/ui/error-codes/E0302.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-fn main() {
-    match Some(()) {
-        None => { },
-        option if { option = None; false } => { },
-        //~^ ERROR cannot assign to `option`, as it is immutable for the pattern guard
-        Some(_) => { }
-    }
-}
diff --git a/src/test/ui/error-codes/E0302.stderr b/src/test/ui/error-codes/E0302.stderr
deleted file mode 100644
index 5854772f1d34a..0000000000000
--- a/src/test/ui/error-codes/E0302.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error[E0594]: cannot assign to `option`, as it is immutable for the pattern guard
-  --> $DIR/E0302.rs:4:21
-   |
-LL |         option if { option = None; false } => { },
-   |                     ^^^^^^^^^^^^^ cannot assign
-   |
-   = note: variables bound in patterns are immutable until the end of the pattern guard
-
-error: aborting due to previous error
-

From e362ff9febb7df9a2e82cd238775b4e32e755ade Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 20 Aug 2019 05:03:58 +0200
Subject: [PATCH 609/943] bootstrap -> boostrap_stdarch_ignore_this

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

diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 0b4b6322534f2..7fb8b4dbb3366 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -87,7 +87,7 @@
 #![feature(link_llvm_intrinsics)]
 #![feature(never_type)]
 #![feature(nll)]
-#![cfg_attr(bootstrap, feature(bind_by_move_pattern_guards))]
+#![cfg_attr(boostrap_stdarch_ignore_this, feature(bind_by_move_pattern_guards))]
 #![feature(exhaustive_patterns)]
 #![feature(no_core)]
 #![feature(on_unimplemented)]

From aaa9762651c15ee16ae210b18c843bceab7bf454 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 5 Sep 2019 19:37:38 +0200
Subject: [PATCH 610/943] bind-by-move: add E0008 commented out to
 error_codes.rs

---
 src/librustc_mir/error_codes.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs
index a10af7e2aceab..908dd601df3d0 100644
--- a/src/librustc_mir/error_codes.rs
+++ b/src/librustc_mir/error_codes.rs
@@ -2379,6 +2379,7 @@ There are some known bugs that trigger this message.
 
 ;
 
+//  E0008, // cannot bind by-move into a pattern guard
 //  E0298, // cannot compare constants
 //  E0299, // mismatched types between arms
 //  E0471, // constant evaluation error (in pattern)

From 8acab6bc566df9adbd74ab39181b7333cff26e26 Mon Sep 17 00:00:00 2001
From: Charles Lew <crlf0710@gmail.com>
Date: Sun, 8 Sep 2019 09:34:24 +0800
Subject: [PATCH 611/943] Improve wording.

---
 src/librustc_metadata/native_libs.rs                          | 4 ++--
 src/test/ui/attributes/obsolete-attr.rs                       | 2 +-
 src/test/ui/attributes/unknown-attr.rs                        | 2 +-
 src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs    | 2 +-
 .../ui/feature-gate/feature-gate-static-nobundle-2.stderr     | 2 +-
 src/test/ui/feature-gates/feature-gate-is_sorted.rs           | 4 ++--
 src/test/ui/feature-gates/feature-gate-link_cfg.rs            | 2 +-
 src/test/ui/feature-gates/feature-gate-link_cfg.stderr        | 2 +-
 src/test/ui/feature-gates/feature-gate-static-nobundle.rs     | 2 +-
 src/test/ui/feature-gates/feature-gate-static-nobundle.stderr | 2 +-
 src/test/ui/feature-gates/feature-gate-type_ascription.rs     | 2 +-
 src/test/ui/proc-macro/resolve-error.rs                       | 4 ++--
 src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs    | 2 +-
 13 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index 66971bb6f8b1c..66d676b7747d0 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -159,7 +159,7 @@ impl Collector<'tcx> {
                                            sym::link_cfg,
                                            span.unwrap(),
                                            GateIssue::Language,
-                                           "is feature gated");
+                                           "is unstable");
         }
         if lib.kind == cstore::NativeStaticNobundle &&
            !self.tcx.features().static_nobundle {
@@ -167,7 +167,7 @@ impl Collector<'tcx> {
                                            sym::static_nobundle,
                                            span.unwrap_or_else(|| syntax_pos::DUMMY_SP),
                                            GateIssue::Language,
-                                           "kind=\"static-nobundle\" is feature gated");
+                                           "kind=\"static-nobundle\" is unstable");
         }
         self.libs.push(lib);
     }
diff --git a/src/test/ui/attributes/obsolete-attr.rs b/src/test/ui/attributes/obsolete-attr.rs
index 8759344e6f820..cf6dd338552b8 100644
--- a/src/test/ui/attributes/obsolete-attr.rs
+++ b/src/test/ui/attributes/obsolete-attr.rs
@@ -1,4 +1,4 @@
-// Obsolete attributes fall back to feature gated custom attributes.
+// Obsolete attributes fall back to unstable custom attributes.
 
 #[ab_isize="stdcall"] extern {}
 //~^ ERROR cannot find attribute macro `ab_isize` in this scope
diff --git a/src/test/ui/attributes/unknown-attr.rs b/src/test/ui/attributes/unknown-attr.rs
index 140a1fc3f93e5..544a6e2a7e78a 100644
--- a/src/test/ui/attributes/unknown-attr.rs
+++ b/src/test/ui/attributes/unknown-attr.rs
@@ -1,4 +1,4 @@
-// Unknown attributes fall back to feature gated custom attributes.
+// Unknown attributes fall back to unstable custom attributes.
 
 #![feature(custom_inner_attributes)]
 
diff --git a/src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs
index 92844f9306d28..b6c8648a7d03d 100644
--- a/src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs
+++ b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.rs
@@ -1,4 +1,4 @@
-//~ ERROR kind="static-nobundle" is feature gated
+//~ ERROR kind="static-nobundle" is unstable
 // Test the behavior of rustc when non-existent library is statically linked
 
 // compile-flags: -l static-nobundle=nonexistent
diff --git a/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr
index 059559dd92831..cfff4c36a6d7b 100644
--- a/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr
+++ b/src/test/ui/feature-gate/feature-gate-static-nobundle-2.stderr
@@ -1,4 +1,4 @@
-error[E0658]: kind="static-nobundle" is feature gated
+error[E0658]: kind="static-nobundle" is unstable
    |
    = note: for more information, see https://github.com/rust-lang/rust/issues/37403
    = help: add `#![feature(static_nobundle)]` to the crate attributes to enable
diff --git a/src/test/ui/feature-gates/feature-gate-is_sorted.rs b/src/test/ui/feature-gates/feature-gate-is_sorted.rs
index 078ecc577610b..359ed835bcbb2 100644
--- a/src/test/ui/feature-gates/feature-gate-is_sorted.rs
+++ b/src/test/ui/feature-gates/feature-gate-is_sorted.rs
@@ -1,11 +1,11 @@
 fn main() {
-    // Assert `Iterator` methods are feature gated
+    // Assert `Iterator` methods are unstable
     assert!([1, 2, 2, 9].iter().is_sorted());
     //~^ ERROR: use of unstable library feature 'is_sorted': new API
     assert!(![-2i32, -1, 0, 3].iter().is_sorted_by_key(|n| n.abs()));
     //~^ ERROR: use of unstable library feature 'is_sorted': new API
 
-    // Assert `[T]` methods are feature gated
+    // Assert `[T]` methods are unstable
     assert!([1, 2, 2, 9].is_sorted());
     //~^ ERROR: use of unstable library feature 'is_sorted': new API
     assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
diff --git a/src/test/ui/feature-gates/feature-gate-link_cfg.rs b/src/test/ui/feature-gates/feature-gate-link_cfg.rs
index 1905346e2b5d7..27ec2e98eb68b 100644
--- a/src/test/ui/feature-gates/feature-gate-link_cfg.rs
+++ b/src/test/ui/feature-gates/feature-gate-link_cfg.rs
@@ -1,5 +1,5 @@
 #[link(name = "foo", cfg(foo))]
-//~^ ERROR: is feature gated
+//~^ ERROR: is unstable
 extern {}
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-link_cfg.stderr b/src/test/ui/feature-gates/feature-gate-link_cfg.stderr
index 58aa4ed7497ce..f6c5061546438 100644
--- a/src/test/ui/feature-gates/feature-gate-link_cfg.stderr
+++ b/src/test/ui/feature-gates/feature-gate-link_cfg.stderr
@@ -1,4 +1,4 @@
-error[E0658]: is feature gated
+error[E0658]: is unstable
   --> $DIR/feature-gate-link_cfg.rs:1:1
    |
 LL | #[link(name = "foo", cfg(foo))]
diff --git a/src/test/ui/feature-gates/feature-gate-static-nobundle.rs b/src/test/ui/feature-gates/feature-gate-static-nobundle.rs
index 1ce6c54aa4dc2..644b1f964a059 100644
--- a/src/test/ui/feature-gates/feature-gate-static-nobundle.rs
+++ b/src/test/ui/feature-gates/feature-gate-static-nobundle.rs
@@ -1,5 +1,5 @@
 #[link(name="foo", kind="static-nobundle")]
-//~^ ERROR: kind="static-nobundle" is feature gated
+//~^ ERROR: kind="static-nobundle" is unstable
 extern {}
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr b/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr
index f2e29cf0678ae..cc0d426d6cf9a 100644
--- a/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr
+++ b/src/test/ui/feature-gates/feature-gate-static-nobundle.stderr
@@ -1,4 +1,4 @@
-error[E0658]: kind="static-nobundle" is feature gated
+error[E0658]: kind="static-nobundle" is unstable
   --> $DIR/feature-gate-static-nobundle.rs:1:1
    |
 LL | #[link(name="foo", kind="static-nobundle")]
diff --git a/src/test/ui/feature-gates/feature-gate-type_ascription.rs b/src/test/ui/feature-gates/feature-gate-type_ascription.rs
index e42e340550681..7a597157300ed 100644
--- a/src/test/ui/feature-gates/feature-gate-type_ascription.rs
+++ b/src/test/ui/feature-gates/feature-gate-type_ascription.rs
@@ -1,4 +1,4 @@
-// Type ascription is feature gated
+// Type ascription is unstable
 
 fn main() {
     let a = 10: u8; //~ ERROR type ascription is experimental
diff --git a/src/test/ui/proc-macro/resolve-error.rs b/src/test/ui/proc-macro/resolve-error.rs
index 0a7861aba6ebb..088f39c6665ff 100644
--- a/src/test/ui/proc-macro/resolve-error.rs
+++ b/src/test/ui/proc-macro/resolve-error.rs
@@ -23,11 +23,11 @@ macro_rules! attr_proc_mac {
 //~^ ERROR cannot find
 struct Foo;
 
-// Interpreted as a feature gated custom attribute
+// Interpreted as an unstable custom attribute
 #[attr_proc_macra] //~ ERROR cannot find attribute macro `attr_proc_macra` in this scope
 struct Bar;
 
-// Interpreted as a feature gated custom attribute
+// Interpreted as an unstable custom attribute
 #[FooWithLongNan] //~ ERROR cannot find attribute macro `FooWithLongNan` in this scope
 struct Asdf;
 
diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs
index 8c62b34bd9ea5..c07da4345f7d9 100644
--- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs
+++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs
@@ -4,7 +4,7 @@ type B = rustfmt::skip; //~ ERROR expected type, found tool attribute `rustfmt::
 #[derive(rustfmt)] //~ ERROR cannot find derive macro `rustfmt` in this scope
 struct S;
 
-// Interpreted as a feature gated custom attribute
+// Interpreted as an unstable custom attribute
 #[rustfmt] //~ ERROR cannot find attribute macro `rustfmt` in this scope
 fn check() {}
 

From 995d9857bdae6da200703e3aefbc39f5eded299b Mon Sep 17 00:00:00 2001
From: Aleksi Juvani <aleksi@aleksijuvani.com>
Date: Sat, 7 Sep 2019 21:02:27 +0300
Subject: [PATCH 612/943] Fix cross-compilation to macOS

---
 src/librustc_target/spec/apple_base.rs        | 55 ++++++++++++-------
 src/librustc_target/spec/apple_ios_base.rs    | 21 ++++---
 src/librustc_target/spec/i686_apple_darwin.rs | 18 +++---
 .../spec/x86_64_apple_darwin.rs               | 18 +++---
 4 files changed, 62 insertions(+), 50 deletions(-)

diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs
index 297e64d4aebaa..a8d6290aa433b 100644
--- a/src/librustc_target/spec/apple_base.rs
+++ b/src/librustc_target/spec/apple_base.rs
@@ -1,4 +1,4 @@
-use std::{env, io, path::Path, process::Command};
+use std::{env, path::Path};
 
 use crate::spec::{LinkArgs, TargetOptions};
 
@@ -52,18 +52,19 @@ pub fn macos_llvm_target(arch: &str) -> String {
     format!("{}-apple-macosx{}.{}.0", arch, major, minor)
 }
 
-pub fn sysroot(sdk: &str) -> Result<String, String> {
-    let actual_sdk_path = sdk_path(sdk)?;
+#[cfg(target_os = "macos")]
+pub fn sysroot(sdk: &str) -> Result<Option<String>, String> {
     // Like Clang, allow the `SDKROOT` environment variable used by Xcode to define the sysroot.
     if let Some(sdk_root) = env::var("SDKROOT").ok() {
+        let actual_sdk_path = sdk_path(sdk)?;
         let sdk_root_p = Path::new(&sdk_root);
         // Ignore `SDKROOT` if it's not a valid path.
         if !sdk_root_p.is_absolute() || sdk_root_p == Path::new("/") || !sdk_root_p.exists() {
-            return Ok(actual_sdk_path);
+            return Ok(Some(actual_sdk_path));
         }
         // Ignore `SDKROOT` if it's clearly set for the wrong platform, which may occur when we're
         // compiling a custom build script while targeting iOS for example.
-        return Ok(match sdk {
+        return Ok(Some(match sdk {
             "iphoneos" if sdk_root.contains("iPhoneSimulator.platform")
                 || sdk_root.contains("MacOSX.platform") => actual_sdk_path,
             "iphonesimulator" if sdk_root.contains("iPhoneOS.platform")
@@ -71,24 +72,40 @@ pub fn sysroot(sdk: &str) -> Result<String, String> {
             "macosx" | "macosx10.15" if sdk_root.contains("iPhoneOS.platform")
                 || sdk_root.contains("iPhoneSimulator.platform") => actual_sdk_path,
             _ => sdk_root,
-        })
+        }))
     }
-    Ok(actual_sdk_path)
+    Ok(None)
 }
 
+// `xcrun` is only available on macOS.
+#[cfg(not(target_os = "macos"))]
+pub fn sysroot(_sdk: &str) -> Result<Option<String>, String> {
+    if let Some(sdk_root) = env::var("SDKROOT").ok() {
+        let sdk_root_p = Path::new(&sdk_root);
+        // Use `SDKROOT` only if it's a valid path.
+        if sdk_root_p.is_absolute() && sdk_root_p != Path::new("/") && sdk_root_p.exists() {
+            return Ok(Some(sdk_root));
+        }
+    }
+    Ok(None)
+}
+
+#[cfg(target_os = "macos")]
 fn sdk_path(sdk_name: &str) -> Result<String, String> {
-    let res =
-        Command::new("xcrun").arg("--show-sdk-path").arg("-sdk").arg(sdk_name).output().and_then(
-            |output| {
-                if output.status.success() {
-                    Ok(String::from_utf8(output.stdout).unwrap())
-                } else {
-                    let error = String::from_utf8(output.stderr);
-                    let error = format!("process exit with error: {}", error.unwrap());
-                    Err(io::Error::new(io::ErrorKind::Other, &error[..]))
-                }
-            },
-        );
+    let res = std::process::Command::new("xcrun")
+        .arg("--show-sdk-path")
+        .arg("-sdk")
+        .arg(sdk_name)
+        .output()
+        .and_then(|output| {
+            if output.status.success() {
+                Ok(String::from_utf8(output.stdout).unwrap())
+            } else {
+                let error = String::from_utf8(output.stderr);
+                let error = format!("process exit with error: {}", error.unwrap());
+                Err(std::io::Error::new(std::io::ErrorKind::Other, &error[..]))
+            }
+        });
     match res {
         Ok(output) => Ok(output.trim().to_string()),
         Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs
index db4a818083183..801736944f4f8 100644
--- a/src/librustc_target/spec/apple_ios_base.rs
+++ b/src/librustc_target/spec/apple_ios_base.rs
@@ -35,16 +35,19 @@ fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> {
 
     let arch_name = arch.to_string();
 
-    let sdk_root = super::apple_base::sysroot(sdk_name)?;
-
     let mut args = LinkArgs::new();
-    args.insert(LinkerFlavor::Gcc,
-                vec!["-arch".to_string(),
-                     arch_name.to_string(),
-                     "-isysroot".to_string(),
-                     sdk_root.clone(),
-                     "-Wl,-syslibroot".to_string(),
-                     sdk_root]);
+    args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), arch_name.to_string()]);
+    if let Some(sdk_root) = super::apple_base::sysroot(sdk_name)? {
+        args.insert(
+            LinkerFlavor::Gcc,
+            vec![
+                "-isysroot".to_string(),
+                sdk_root.clone(),
+                "-Wl,-syslibroot".to_string(),
+                sdk_root
+            ],
+        );
+    }
 
     Ok(args)
 }
diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs
index a60c007212474..b08ed56025208 100644
--- a/src/librustc_target/spec/i686_apple_darwin.rs
+++ b/src/librustc_target/spec/i686_apple_darwin.rs
@@ -1,20 +1,16 @@
 use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
-    let sysroot = super::apple_base::sysroot("macosx")?;
     let mut base = super::apple_base::opts();
     base.cpu = "yonah".to_string();
     base.max_atomic_width = Some(64);
-    base.pre_link_args.insert(
-        LinkerFlavor::Gcc,
-        vec![
-            "-m32".to_string(),
-            "-isysroot".to_string(),
-            sysroot.clone(),
-            "-Wl,-syslibroot".to_string(),
-            sysroot,
-        ],
-    );
+    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
+    if let Some(sysroot) = super::apple_base::sysroot("macosx")? {
+        base.pre_link_args.insert(
+            LinkerFlavor::Gcc,
+            vec!["-isysroot".to_string(), sysroot.clone(), "-Wl,-syslibroot".to_string(), sysroot],
+        );
+    }
     base.stack_probes = true;
     base.eliminate_frame_pointer = false;
 
diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs
index b72d037565b5b..f299c27e7e1ef 100644
--- a/src/librustc_target/spec/x86_64_apple_darwin.rs
+++ b/src/librustc_target/spec/x86_64_apple_darwin.rs
@@ -1,21 +1,17 @@
 use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
-    let sysroot = super::apple_base::sysroot("macosx")?;
     let mut base = super::apple_base::opts();
     base.cpu = "core2".to_string();
     base.max_atomic_width = Some(128); // core2 support cmpxchg16b
     base.eliminate_frame_pointer = false;
-    base.pre_link_args.insert(
-        LinkerFlavor::Gcc,
-        vec![
-            "-m64".to_string(),
-            "-isysroot".to_string(),
-            sysroot.clone(),
-            "-Wl,-syslibroot".to_string(),
-            sysroot,
-        ],
-    );
+    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
+    if let Some(sysroot) = super::apple_base::sysroot("macosx")? {
+        base.pre_link_args.insert(
+            LinkerFlavor::Gcc,
+            vec!["-isysroot".to_string(), sysroot.clone(), "-Wl,-syslibroot".to_string(), sysroot],
+        );
+    }
     base.stack_probes = true;
 
     // Clang automatically chooses a more specific target based on

From 38ab20dbf7469aa5a3cb0d7bfd3700281aa46467 Mon Sep 17 00:00:00 2001
From: V1shvesh <22243137+V1shvesh@users.noreply.github.com>
Date: Sun, 8 Sep 2019 14:57:03 +0530
Subject: [PATCH 613/943] Add pluralise macro

Adress issue #64238. Create a macro to be used for pluralisation check
throughout rustc codebase.
---
 src/librustc_errors/lib.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 6585633e00af8..b5341a2b727a5 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -845,3 +845,11 @@ impl Level {
         }
     }
 }
+
+#[macro_export]
+macro_rules! pluralise {
+            ($x:expr) => {
+                if $x != 1 { "s" } else { "" }
+            };
+}
+

From c2552065819288a91a7e2646d95bf53765304b4f Mon Sep 17 00:00:00 2001
From: V1shvesh <22243137+V1shvesh@users.noreply.github.com>
Date: Sun, 8 Sep 2019 15:00:08 +0530
Subject: [PATCH 614/943] Refactor Pluralisation

Modify files performing pluralisation checks to incorporate the
dedicated macro located in `syntax::errors`.
---
 src/librustc/ty/error.rs                    | 7 +------
 src/librustc_typeck/astconv.rs              | 3 ++-
 src/librustc_typeck/check/compare_method.rs | 9 +++++----
 3 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index f67526ea4a1d9..62910ec320494 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -4,6 +4,7 @@ use std::borrow::Cow;
 use std::fmt;
 use rustc_target::spec::abi;
 use syntax::ast;
+use syntax::errors::pluralise;
 use errors::{Applicability, DiagnosticBuilder};
 use syntax_pos::Span;
 
@@ -82,12 +83,6 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
             }
         };
 
-        macro_rules! pluralise {
-            ($x:expr) => {
-                if $x != 1 { "s" } else { "" }
-            };
-        }
-
         match *self {
             CyclicTy(_) => write!(f, "cyclic type of infinite size"),
             Mismatch => write!(f, "types differ"),
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 9e52eae88ef45..e9ca0f3d978ca 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -23,6 +23,7 @@ use rustc_target::spec::abi;
 use crate::require_c_abi_if_c_variadic;
 use smallvec::SmallVec;
 use syntax::ast;
+use syntax::errors::pluralise;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax::util::lev_distance::find_best_match_for_name;
 use syntax::symbol::sym;
@@ -377,7 +378,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     quantifier,
                     bound,
                     kind,
-                    if bound != 1 { "s" } else { "" },
+                    pluralise!(bound),
                 ))
             };
 
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 8e187b7e05b51..f22499f547272 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -10,6 +10,7 @@ use rustc::util::common::ErrorReported;
 use errors::{Applicability, DiagnosticId};
 
 use syntax_pos::Span;
+use syntax::errors::pluralise;
 
 use super::{Inherited, FnCtxt, potentially_plural_count};
 
@@ -648,9 +649,9 @@ fn compare_number_of_generics<'tcx>(
                      declaration has {} {kind} parameter{}",
                     trait_.ident,
                     impl_count,
-                    if impl_count != 1 { "s" } else { "" },
+                    pluralise!(impl_count),
                     trait_count,
-                    if trait_count != 1 { "s" } else { "" },
+                    pluralise!(trait_count),
                     kind = kind,
                 ),
                 DiagnosticId::Error("E0049".into()),
@@ -665,7 +666,7 @@ fn compare_number_of_generics<'tcx>(
                         "expected {} {} parameter{}",
                         trait_count,
                         kind,
-                        if trait_count != 1 { "s" } else { "" },
+                        pluralise!(trait_count),
                     ));
                 }
                 for span in spans {
@@ -680,7 +681,7 @@ fn compare_number_of_generics<'tcx>(
                     "found {} {} parameter{}{}",
                     impl_count,
                     kind,
-                    if impl_count != 1 { "s" } else { "" },
+                    pluralise!(impl_count),
                     suffix.unwrap_or_else(|| String::new()),
                 ));
             }

From 6fdbece55f7ccba7ac16808bd62ead27d6da9500 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sun, 1 Sep 2019 17:30:19 -0400
Subject: [PATCH 615/943] Update test stderr with results of enabling unused
 lints

---
 .../bounds-on-assoc-in-trait.rs                  |  2 +-
 src/test/ui/associated-type-bounds/fn-apit.rs    |  1 +
 .../ui/associated-type-bounds/fn-dyn-apit.rs     |  1 +
 src/test/ui/associated-type-bounds/fn-inline.rs  |  1 +
 src/test/ui/associated-type-bounds/fn-where.rs   |  1 +
 .../ui/associated-type-bounds/fn-wrap-apit.rs    |  1 +
 .../ui/associated-type-bounds/struct-bounds.rs   |  1 +
 src/test/ui/async-await/argument-patterns.rs     |  3 +--
 src/test/ui/async-await/async-await.rs           |  2 ++
 .../drop-order-for-locals-when-cancelled.rs      |  6 ++++--
 .../drop-order/drop-order-when-cancelled.rs      |  4 +++-
 .../issues/issue-54752-async-block.stderr        |  8 ++++++++
 src/test/ui/async-await/issues/issue-59972.rs    |  2 +-
 .../ui/async-await/multiple-lifetimes/hrtb.rs    |  2 +-
 src/test/ui/borrowck/borrowck-migrate-to-nll.rs  |  2 +-
 src/test/ui/borrowck/issue-10876.rs              |  2 +-
 .../borrowck/two-phase-multiple-activations.rs   |  4 ++--
 .../ui/const-generics/apit-with-const-param.rs   |  2 +-
 .../const-generics/array-wrapper-struct-ctor.rs  |  2 ++
 src/test/ui/const-generics/const-types.rs        |  2 +-
 src/test/ui/const-generics/issue-61422.rs        |  4 ++--
 src/test/ui/const-generics/unused-const-param.rs |  2 +-
 src/test/ui/consts/const-eval/const_transmute.rs |  1 +
 src/test/ui/consts/const-labeled-break.rs        |  2 +-
 src/test/ui/consts/packed_pattern.stderr         |  8 ++++++++
 src/test/ui/consts/packed_pattern2.stderr        |  8 ++++++++
 src/test/ui/deprecation/deprecation-in-future.rs |  2 +-
 src/test/ui/drop/dynamic-drop-async.rs           |  1 +
 src/test/ui/hrtb/issue-57639.rs                  |  2 +-
 src/test/ui/if-ret.stderr                        |  8 ++++++++
 .../ui/impl-trait/closure-calling-parent-fn.rs   |  2 +-
 src/test/ui/impl-trait/issues/issue-53457.rs     |  4 ++--
 .../multiple-lifetimes/inverse-bounds.rs         |  2 +-
 .../ui/impl-trait/needs_least_region_or_bound.rs |  4 +---
 src/test/ui/issues/issue-26448-2.rs              |  2 +-
 src/test/ui/issues/issue-26448-3.rs              |  2 +-
 src/test/ui/issues/issue-27697.rs                |  2 +-
 src/test/ui/issues/issue-38591.rs                |  2 +-
 src/test/ui/issues/issue-43806.rs                |  2 +-
 src/test/ui/issues/issue-48132.rs                |  2 ++
 src/test/ui/issues/issue-48179.rs                |  2 +-
 .../issue-61711-once-caused-rustc-inf-loop.rs    |  2 +-
 src/test/ui/lint/empty-lint-attributes.rs        |  2 +-
 src/test/ui/nll/issue-55288.rs                   |  2 +-
 src/test/ui/nll/issue-57960.rs                   |  1 -
 src/test/ui/nll/normalization-bounds.rs          |  2 +-
 .../promotable-mutable-zst-doesnt-conflict.rs    |  4 ++--
 src/test/ui/nll/user-annotations/issue-55219.rs  |  2 +-
 .../ui/nll/user-annotations/normalize-self-ty.rs |  4 ++--
 .../bind-by-move-no-guards.rs                    |  4 ++--
 .../variants_same_crate.rs                       |  6 +++---
 .../protect-precedences.rs                       |  2 --
 .../protect-precedences.stderr                   |  8 ++++++++
 .../traits/trait-alias/trait-alias-object-wf.rs  |  2 +-
 .../enum-variant-generic-args-pass.rs            | 16 ++++++++--------
 src/test/ui/while-let.rs                         |  7 ++++---
 src/test/ui/while-let.stderr                     | 12 ++++++------
 57 files changed, 121 insertions(+), 68 deletions(-)
 create mode 100644 src/test/ui/async-await/issues/issue-54752-async-block.stderr
 create mode 100644 src/test/ui/consts/packed_pattern.stderr
 create mode 100644 src/test/ui/consts/packed_pattern2.stderr
 create mode 100644 src/test/ui/if-ret.stderr
 create mode 100644 src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr

diff --git a/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs b/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs
index 9db5233e21e57..ceca54b7cd75f 100644
--- a/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs
+++ b/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(associated_type_bounds)]
 
diff --git a/src/test/ui/associated-type-bounds/fn-apit.rs b/src/test/ui/associated-type-bounds/fn-apit.rs
index 7e208b4e70d81..3c9f511338f69 100644
--- a/src/test/ui/associated-type-bounds/fn-apit.rs
+++ b/src/test/ui/associated-type-bounds/fn-apit.rs
@@ -1,6 +1,7 @@
 // run-pass
 // aux-build:fn-aux.rs
 
+#![allow(unused)]
 #![feature(associated_type_bounds)]
 
 extern crate fn_aux;
diff --git a/src/test/ui/associated-type-bounds/fn-dyn-apit.rs b/src/test/ui/associated-type-bounds/fn-dyn-apit.rs
index 9ff4a50e1e6e4..c4e8092c211d6 100644
--- a/src/test/ui/associated-type-bounds/fn-dyn-apit.rs
+++ b/src/test/ui/associated-type-bounds/fn-dyn-apit.rs
@@ -1,6 +1,7 @@
 // run-pass
 // aux-build:fn-dyn-aux.rs
 
+#![allow(unused)]
 #![feature(associated_type_bounds)]
 
 extern crate fn_dyn_aux;
diff --git a/src/test/ui/associated-type-bounds/fn-inline.rs b/src/test/ui/associated-type-bounds/fn-inline.rs
index 7b188763b7a5e..8fa7212d6275b 100644
--- a/src/test/ui/associated-type-bounds/fn-inline.rs
+++ b/src/test/ui/associated-type-bounds/fn-inline.rs
@@ -1,6 +1,7 @@
 // run-pass
 // aux-build:fn-aux.rs
 
+#![allow(unused)]
 #![feature(associated_type_bounds)]
 
 extern crate fn_aux;
diff --git a/src/test/ui/associated-type-bounds/fn-where.rs b/src/test/ui/associated-type-bounds/fn-where.rs
index 60d7149a56f25..9c4f82ac991c8 100644
--- a/src/test/ui/associated-type-bounds/fn-where.rs
+++ b/src/test/ui/associated-type-bounds/fn-where.rs
@@ -1,6 +1,7 @@
 // run-pass
 // aux-build:fn-aux.rs
 
+#![allow(unused)]
 #![feature(associated_type_bounds)]
 
 extern crate fn_aux;
diff --git a/src/test/ui/associated-type-bounds/fn-wrap-apit.rs b/src/test/ui/associated-type-bounds/fn-wrap-apit.rs
index 23790d416e1f7..96df13e372a24 100644
--- a/src/test/ui/associated-type-bounds/fn-wrap-apit.rs
+++ b/src/test/ui/associated-type-bounds/fn-wrap-apit.rs
@@ -2,6 +2,7 @@
 // aux-build:fn-aux.rs
 
 #![feature(associated_type_bounds)]
+#![allow(dead_code)]
 
 extern crate fn_aux;
 
diff --git a/src/test/ui/associated-type-bounds/struct-bounds.rs b/src/test/ui/associated-type-bounds/struct-bounds.rs
index 2d189cd66724a..2c1ce1c3785ae 100644
--- a/src/test/ui/associated-type-bounds/struct-bounds.rs
+++ b/src/test/ui/associated-type-bounds/struct-bounds.rs
@@ -1,5 +1,6 @@
 // run-pass
 
+#![allow(unused)]
 #![feature(associated_type_bounds)]
 
 trait Tr1 { type As1; }
diff --git a/src/test/ui/async-await/argument-patterns.rs b/src/test/ui/async-await/argument-patterns.rs
index 0e42f48b8351e..b9fc1a88cee13 100644
--- a/src/test/ui/async-await/argument-patterns.rs
+++ b/src/test/ui/async-await/argument-patterns.rs
@@ -1,7 +1,6 @@
 // edition:2018
-// run-pass
+// check-pass
 
-#![allow(unused_variables)]
 #![deny(unused_mut)]
 
 type A = Vec<u32>;
diff --git a/src/test/ui/async-await/async-await.rs b/src/test/ui/async-await/async-await.rs
index bf8bf0bcce0fe..1dc7315e88c11 100644
--- a/src/test/ui/async-await/async-await.rs
+++ b/src/test/ui/async-await/async-await.rs
@@ -1,5 +1,7 @@
 // run-pass
 
+#![allow(unused)]
+
 // edition:2018
 // aux-build:arc_wake.rs
 
diff --git a/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs b/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs
index 5d020c9a52601..15cc9fbc81fb7 100644
--- a/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs
+++ b/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs
@@ -3,6 +3,9 @@
 // run-pass
 
 #![deny(dead_code)]
+#![allow(unused_variables)]
+#![allow(unused_must_use)]
+#![allow(path_statements)]
 
 // Test that the drop order for locals in a fn and async fn matches up.
 extern crate arc_wake;
@@ -10,7 +13,6 @@ extern crate arc_wake;
 use arc_wake::ArcWake;
 use std::cell::RefCell;
 use std::future::Future;
-use std::marker::PhantomData;
 use std::pin::Pin;
 use std::rc::Rc;
 use std::sync::Arc;
@@ -42,7 +44,7 @@ struct NeverReady;
 
 impl Future for NeverReady {
     type Output = ();
-    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
+    fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
         Poll::Pending
     }
 }
diff --git a/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs b/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs
index 84fe79348c601..9e8304935bffc 100644
--- a/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs
+++ b/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs
@@ -6,6 +6,8 @@
 // parameters (used or unused) are not dropped until the async fn is cancelled.
 // This file is mostly copy-pasted from drop-order-for-async-fn-parameters.rs
 
+#![allow(unused_variables)]
+
 extern crate arc_wake;
 
 use arc_wake::ArcWake;
@@ -43,7 +45,7 @@ struct NeverReady;
 
 impl Future for NeverReady {
     type Output = ();
-    fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
+    fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
         Poll::Pending
     }
 }
diff --git a/src/test/ui/async-await/issues/issue-54752-async-block.stderr b/src/test/ui/async-await/issues/issue-54752-async-block.stderr
new file mode 100644
index 0000000000000..c3b3392cfc495
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-54752-async-block.stderr
@@ -0,0 +1,8 @@
+warning: unnecessary parentheses around assigned value
+  --> $DIR/issue-54752-async-block.rs:6:22
+   |
+LL | fn main() { let _a = (async  { }); }
+   |                      ^^^^^^^^^^^^ help: remove these parentheses
+   |
+   = note: `#[warn(unused_parens)]` on by default
+
diff --git a/src/test/ui/async-await/issues/issue-59972.rs b/src/test/ui/async-await/issues/issue-59972.rs
index 154226e8bb88f..c2e24a96b1d93 100644
--- a/src/test/ui/async-await/issues/issue-59972.rs
+++ b/src/test/ui/async-await/issues/issue-59972.rs
@@ -4,7 +4,7 @@
 
 // run-pass
 
-// compile-flags: --edition=2018
+// compile-flags: --edition=2018 -Aunused
 
 pub enum Uninhabited { }
 
diff --git a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs
index 31d0736ba63c8..e788ca5ff49c3 100644
--- a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs
+++ b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs
@@ -1,5 +1,5 @@
 // edition:2018
-// run-pass
+// check-pass
 
 // Test that we can use async fns with multiple arbitrary lifetimes.
 
diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs
index 98fd5682277b3..6587dfdbc03f3 100644
--- a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs
+++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs
@@ -17,7 +17,7 @@
 // revisions: zflag edition
 //[zflag]compile-flags: -Z borrowck=migrate
 //[edition]edition:2018
-//[zflag] run-pass
+//[zflag] check-pass
 
 pub struct Block<'a> {
     current: &'a u8,
diff --git a/src/test/ui/borrowck/issue-10876.rs b/src/test/ui/borrowck/issue-10876.rs
index 20ab905fec46e..22eaa119f2467 100644
--- a/src/test/ui/borrowck/issue-10876.rs
+++ b/src/test/ui/borrowck/issue-10876.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 enum Nat {
     S(Box<Nat>),
diff --git a/src/test/ui/borrowck/two-phase-multiple-activations.rs b/src/test/ui/borrowck/two-phase-multiple-activations.rs
index a7fa7fac13e73..599138a9ce0f1 100644
--- a/src/test/ui/borrowck/two-phase-multiple-activations.rs
+++ b/src/test/ui/borrowck/two-phase-multiple-activations.rs
@@ -11,7 +11,7 @@ pub trait FakeRead {
 }
 
 impl FakeRead for Foo {
-    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
+    fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> Result<usize> {
         Ok(4)
     }
 }
@@ -19,5 +19,5 @@ impl FakeRead for Foo {
 fn main() {
     let mut a = Foo {};
     let mut v = Vec::new();
-    a.read_to_end(&mut v);
+    a.read_to_end(&mut v).unwrap();
 }
diff --git a/src/test/ui/const-generics/apit-with-const-param.rs b/src/test/ui/const-generics/apit-with-const-param.rs
index 70e718d889029..7acc50819a6ad 100644
--- a/src/test/ui/const-generics/apit-with-const-param.rs
+++ b/src/test/ui/const-generics/apit-with-const-param.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
diff --git a/src/test/ui/const-generics/array-wrapper-struct-ctor.rs b/src/test/ui/const-generics/array-wrapper-struct-ctor.rs
index d83846fcf88d4..2d1a405ebdd80 100644
--- a/src/test/ui/const-generics/array-wrapper-struct-ctor.rs
+++ b/src/test/ui/const-generics/array-wrapper-struct-ctor.rs
@@ -3,6 +3,8 @@
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
 
+#![allow(dead_code)]
+
 struct ArrayStruct<T, const N: usize> {
     data: [T; N],
 }
diff --git a/src/test/ui/const-generics/const-types.rs b/src/test/ui/const-generics/const-types.rs
index 11757cd588dab..bc5188133d7f1 100644
--- a/src/test/ui/const-generics/const-types.rs
+++ b/src/test/ui/const-generics/const-types.rs
@@ -3,7 +3,7 @@
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
 
-#[allow(dead_code)]
+#![allow(dead_code, unused_variables)]
 
 struct ConstArray<T, const LEN: usize> {
     array: [T; LEN],
diff --git a/src/test/ui/const-generics/issue-61422.rs b/src/test/ui/const-generics/issue-61422.rs
index 68e5a52e0ac5c..45d37b6a2f3c5 100644
--- a/src/test/ui/const-generics/issue-61422.rs
+++ b/src/test/ui/const-generics/issue-61422.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
@@ -8,7 +8,7 @@ use std::mem;
 fn foo<const SIZE: usize>() {
     let arr: [u8; SIZE] = unsafe {
         #[allow(deprecated)]
-        let mut array: [u8; SIZE] = mem::uninitialized();
+        let array: [u8; SIZE] = mem::uninitialized();
         array
     };
 }
diff --git a/src/test/ui/const-generics/unused-const-param.rs b/src/test/ui/const-generics/unused-const-param.rs
index ee98e5eb4a01f..8025b3af8f1bf 100644
--- a/src/test/ui/const-generics/unused-const-param.rs
+++ b/src/test/ui/const-generics/unused-const-param.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(const_generics)]
 //~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
diff --git a/src/test/ui/consts/const-eval/const_transmute.rs b/src/test/ui/consts/const-eval/const_transmute.rs
index 4a7d8490ef25f..f0e1d8263022b 100644
--- a/src/test/ui/consts/const-eval/const_transmute.rs
+++ b/src/test/ui/consts/const-eval/const_transmute.rs
@@ -1,6 +1,7 @@
 // run-pass
 
 #![feature(const_fn_union)]
+#![allow(dead_code)]
 
 #[repr(C)]
 union Transmute<T: Copy, U: Copy> {
diff --git a/src/test/ui/consts/const-labeled-break.rs b/src/test/ui/consts/const-labeled-break.rs
index 36e308ade9c54..7cdbb22f92459 100644
--- a/src/test/ui/consts/const-labeled-break.rs
+++ b/src/test/ui/consts/const-labeled-break.rs
@@ -1,4 +1,4 @@
-// run-pass
+// build-pass
 
 // Using labeled break in a while loop has caused an illegal instruction being
 // generated, and an ICE later.
diff --git a/src/test/ui/consts/packed_pattern.stderr b/src/test/ui/consts/packed_pattern.stderr
new file mode 100644
index 0000000000000..9b7daf2e674fb
--- /dev/null
+++ b/src/test/ui/consts/packed_pattern.stderr
@@ -0,0 +1,8 @@
+warning: unreachable pattern
+  --> $DIR/packed_pattern.rs:16:9
+   |
+LL |         FOO => unreachable!(),
+   |         ^^^
+   |
+   = note: `#[warn(unreachable_patterns)]` on by default
+
diff --git a/src/test/ui/consts/packed_pattern2.stderr b/src/test/ui/consts/packed_pattern2.stderr
new file mode 100644
index 0000000000000..6cc0225d3043d
--- /dev/null
+++ b/src/test/ui/consts/packed_pattern2.stderr
@@ -0,0 +1,8 @@
+warning: unreachable pattern
+  --> $DIR/packed_pattern2.rs:24:9
+   |
+LL |         FOO => unreachable!(),
+   |         ^^^
+   |
+   = note: `#[warn(unreachable_patterns)]` on by default
+
diff --git a/src/test/ui/deprecation/deprecation-in-future.rs b/src/test/ui/deprecation/deprecation-in-future.rs
index c4f9fdce74907..464ddcc4cdb94 100644
--- a/src/test/ui/deprecation/deprecation-in-future.rs
+++ b/src/test/ui/deprecation/deprecation-in-future.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![deny(deprecated_in_future)]
 
diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs
index 79d09d1817601..91063edf0f6c4 100644
--- a/src/test/ui/drop/dynamic-drop-async.rs
+++ b/src/test/ui/drop/dynamic-drop-async.rs
@@ -8,6 +8,7 @@
 // ignore-wasm32-bare compiled with panic=abort by default
 
 #![feature(slice_patterns)]
+#![allow(unused)]
 
 use std::{
     cell::{Cell, RefCell},
diff --git a/src/test/ui/hrtb/issue-57639.rs b/src/test/ui/hrtb/issue-57639.rs
index 4bcaef3616bd5..392e7233b567a 100644
--- a/src/test/ui/hrtb/issue-57639.rs
+++ b/src/test/ui/hrtb/issue-57639.rs
@@ -10,7 +10,7 @@
 //
 // See [this comment on GitHub][c] for more details.
 //
-// run-pass
+// check-pass
 //
 // [c]: https://github.com/rust-lang/rust/issues/57639#issuecomment-455685861
 
diff --git a/src/test/ui/if-ret.stderr b/src/test/ui/if-ret.stderr
new file mode 100644
index 0000000000000..73402e55a4fd8
--- /dev/null
+++ b/src/test/ui/if-ret.stderr
@@ -0,0 +1,8 @@
+warning: unreachable block in `if` expression
+  --> $DIR/if-ret.rs:6:24
+   |
+LL | fn foo() { if (return) { } }
+   |                        ^^^
+   |
+   = note: `#[warn(unreachable_code)]` on by default
+
diff --git a/src/test/ui/impl-trait/closure-calling-parent-fn.rs b/src/test/ui/impl-trait/closure-calling-parent-fn.rs
index 58d7875ccd034..9dab334a217c2 100644
--- a/src/test/ui/impl-trait/closure-calling-parent-fn.rs
+++ b/src/test/ui/impl-trait/closure-calling-parent-fn.rs
@@ -5,7 +5,7 @@
 // `foo` and hence is treated opaquely within the closure body.  This
 // resulted in a failed subtype relationship.
 //
-// run-pass
+// check-pass
 
 fn foo() -> impl Copy { || foo(); }
 fn bar() -> impl Copy { || bar(); }
diff --git a/src/test/ui/impl-trait/issues/issue-53457.rs b/src/test/ui/impl-trait/issues/issue-53457.rs
index de8c579743fc0..3f97502492506 100644
--- a/src/test/ui/impl-trait/issues/issue-53457.rs
+++ b/src/test/ui/impl-trait/issues/issue-53457.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(type_alias_impl_trait)]
 
@@ -9,7 +9,7 @@ fn bar<F: Fn(&i32) + Clone>(f: F) -> F {
 }
 
 fn foo() -> X {
-    bar(|x| ())
+    bar(|_| ())
 }
 
 fn main() {}
diff --git a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs
index 2da3886bb552b..3911769b0c63d 100644
--- a/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs
+++ b/src/test/ui/impl-trait/multiple-lifetimes/inverse-bounds.rs
@@ -1,5 +1,5 @@
 // edition:2018
-// run-pass
+// check-pass
 // revisions: migrate mir
 //[mir]compile-flags: -Z borrowck=mir
 
diff --git a/src/test/ui/impl-trait/needs_least_region_or_bound.rs b/src/test/ui/impl-trait/needs_least_region_or_bound.rs
index 52475f65a8353..3c8682bb62aa5 100644
--- a/src/test/ui/impl-trait/needs_least_region_or_bound.rs
+++ b/src/test/ui/impl-trait/needs_least_region_or_bound.rs
@@ -1,9 +1,7 @@
-// run-pass
+// check-pass
 
 #![feature(member_constraints)]
 
-use std::fmt::Debug;
-
 trait MultiRegionTrait<'a, 'b> {}
 impl<'a, 'b> MultiRegionTrait<'a, 'b> for (&'a u32, &'b u32) {}
 
diff --git a/src/test/ui/issues/issue-26448-2.rs b/src/test/ui/issues/issue-26448-2.rs
index 17e7c1f977a6d..c60e06c3ceb35 100644
--- a/src/test/ui/issues/issue-26448-2.rs
+++ b/src/test/ui/issues/issue-26448-2.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 pub struct Bar<T> {
     items: Vec<&'static str>,
diff --git a/src/test/ui/issues/issue-26448-3.rs b/src/test/ui/issues/issue-26448-3.rs
index e57352e57f4fc..d48022c09fee3 100644
--- a/src/test/ui/issues/issue-26448-3.rs
+++ b/src/test/ui/issues/issue-26448-3.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 pub struct Item {
     _inner: &'static str,
diff --git a/src/test/ui/issues/issue-27697.rs b/src/test/ui/issues/issue-27697.rs
index 83070012f5f04..12af8a8e875af 100644
--- a/src/test/ui/issues/issue-27697.rs
+++ b/src/test/ui/issues/issue-27697.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 use std::ops::Deref;
 
diff --git a/src/test/ui/issues/issue-38591.rs b/src/test/ui/issues/issue-38591.rs
index 7aa71f8b9eb9b..2f594b48e697f 100644
--- a/src/test/ui/issues/issue-38591.rs
+++ b/src/test/ui/issues/issue-38591.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 struct S<T> {
     t : T,
diff --git a/src/test/ui/issues/issue-43806.rs b/src/test/ui/issues/issue-43806.rs
index cbfbfa35afbd9..8c8cccfb2bb82 100644
--- a/src/test/ui/issues/issue-43806.rs
+++ b/src/test/ui/issues/issue-43806.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![deny(unused_results)]
 
diff --git a/src/test/ui/issues/issue-48132.rs b/src/test/ui/issues/issue-48132.rs
index ea325ea695f66..f564aefe78ced 100644
--- a/src/test/ui/issues/issue-48132.rs
+++ b/src/test/ui/issues/issue-48132.rs
@@ -3,6 +3,8 @@
 
 // run-pass
 
+#![allow(dead_code)]
+
 struct Inner<I, V> {
     iterator: I,
     item: V,
diff --git a/src/test/ui/issues/issue-48179.rs b/src/test/ui/issues/issue-48179.rs
index 90e9858d74197..f81203dc41299 100644
--- a/src/test/ui/issues/issue-48179.rs
+++ b/src/test/ui/issues/issue-48179.rs
@@ -1,7 +1,7 @@
 // Regression test for #48132. This was failing due to problems around
 // the projection caching and dropck type enumeration.
 
-// run-pass
+// check-pass
 
 pub struct Container<T: Iterator> {
     value: Option<T::Item>,
diff --git a/src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs b/src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs
index 8fc09c89f786b..de7d6a0d80c9e 100644
--- a/src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs
+++ b/src/test/ui/issues/issue-61711-once-caused-rustc-inf-loop.rs
@@ -5,7 +5,7 @@
 // aux-build:xcrate-issue-61711-b.rs
 // compile-flags:--extern xcrate_issue_61711_b
 
-// run-pass
+// build-pass
 
 fn f<F: Fn(xcrate_issue_61711_b::Struct)>(_: F) { }
 fn main() { }
diff --git a/src/test/ui/lint/empty-lint-attributes.rs b/src/test/ui/lint/empty-lint-attributes.rs
index 1f0a9538d88b1..9a0ec253322e4 100644
--- a/src/test/ui/lint/empty-lint-attributes.rs
+++ b/src/test/ui/lint/empty-lint-attributes.rs
@@ -1,6 +1,6 @@
 #![feature(lint_reasons)]
 
-// run-pass
+// check-pass
 
 // Empty (and reason-only) lint attributes are legal—although we may want to
 // lint them in the future (Issue #55112).
diff --git a/src/test/ui/nll/issue-55288.rs b/src/test/ui/nll/issue-55288.rs
index c7b6ac5924837..aab2dc267d594 100644
--- a/src/test/ui/nll/issue-55288.rs
+++ b/src/test/ui/nll/issue-55288.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 struct Slice(&'static [&'static [u8]]);
 
diff --git a/src/test/ui/nll/issue-57960.rs b/src/test/ui/nll/issue-57960.rs
index 1399694a79b6a..32e45184a9195 100644
--- a/src/test/ui/nll/issue-57960.rs
+++ b/src/test/ui/nll/issue-57960.rs
@@ -30,7 +30,6 @@ fn digits(x: u8) -> u32 {
         OneDigit::FIRST..=OneDigit::LAST => 1,
         TwoDigits::FIRST..=TwoDigits::LAST => 2,
         ThreeDigits::FIRST..=ThreeDigits::LAST => 3,
-        _ => unreachable!(),
     }
 }
 
diff --git a/src/test/ui/nll/normalization-bounds.rs b/src/test/ui/nll/normalization-bounds.rs
index 5d2825ef2d670..bb6d981e0133f 100644
--- a/src/test/ui/nll/normalization-bounds.rs
+++ b/src/test/ui/nll/normalization-bounds.rs
@@ -1,6 +1,6 @@
 // Check that lifetime bounds get checked the right way around with NLL enabled.
 
-//run-pass
+// check-pass
 
 trait Visitor<'d> {
     type Value;
diff --git a/src/test/ui/nll/promotable-mutable-zst-doesnt-conflict.rs b/src/test/ui/nll/promotable-mutable-zst-doesnt-conflict.rs
index 6d5bdfa4da2f0..3b06b0db37065 100644
--- a/src/test/ui/nll/promotable-mutable-zst-doesnt-conflict.rs
+++ b/src/test/ui/nll/promotable-mutable-zst-doesnt-conflict.rs
@@ -1,11 +1,11 @@
 // Check that mutable promoted length zero arrays don't check for conflicting
 // access
 
-// run-pass
+// check-pass
 
 pub fn main() {
     let mut x: Vec<&[i32; 0]> = Vec::new();
-    for i in 0..10 {
+    for _ in 0..10 {
         x.push(&[]);
     }
 }
diff --git a/src/test/ui/nll/user-annotations/issue-55219.rs b/src/test/ui/nll/user-annotations/issue-55219.rs
index 4d18e96cc1543..147413663897d 100644
--- a/src/test/ui/nll/user-annotations/issue-55219.rs
+++ b/src/test/ui/nll/user-annotations/issue-55219.rs
@@ -3,7 +3,7 @@
 // The `Self::HASH_LEN` here expands to a "self-type" where `T` is not
 // known. This unbound inference variable was causing an ICE.
 //
-// run-pass
+// check-pass
 
 pub struct Foo<T>(T);
 
diff --git a/src/test/ui/nll/user-annotations/normalize-self-ty.rs b/src/test/ui/nll/user-annotations/normalize-self-ty.rs
index a06229a02032a..df905c8786a18 100644
--- a/src/test/ui/nll/user-annotations/normalize-self-ty.rs
+++ b/src/test/ui/nll/user-annotations/normalize-self-ty.rs
@@ -2,7 +2,7 @@
 // the inherent impl requires normalization to be equal to the
 // user-provided type.
 //
-// run-pass
+// check-pass
 
 trait Mirror {
     type Me;
@@ -15,7 +15,7 @@ impl<T> Mirror for T {
 struct Foo<A, B>(A, B);
 
 impl<A> Foo<A, <A as Mirror>::Me> {
-    fn m(b: A) { }
+    fn m(_: A) { }
 }
 
 fn main() {
diff --git a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs
index e43c8541e6d6d..041e410df85c9 100644
--- a/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs
+++ b/src/test/ui/rfc-0107-bind-by-move-pattern-guards/bind-by-move-no-guards.rs
@@ -11,8 +11,8 @@ use std::sync::mpsc::channel;
 fn main() {
     let (tx, rx) = channel();
     let x = Some(rx);
-    tx.send(false);
-    tx.send(false);
+    tx.send(false).unwrap();
+    tx.send(false).unwrap();
     match x {
         Some(z) if z.recv().unwrap() => { panic!() },
         Some(z) => { assert!(!z.recv().unwrap()); },
diff --git a/src/test/ui/rfc-2008-non-exhaustive/variants_same_crate.rs b/src/test/ui/rfc-2008-non-exhaustive/variants_same_crate.rs
index 470a5ea9833ad..fe7df44590b8d 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/variants_same_crate.rs
+++ b/src/test/ui/rfc-2008-non-exhaustive/variants_same_crate.rs
@@ -10,11 +10,11 @@ pub enum NonExhaustiveVariants {
 
 fn main() {
     let variant_tuple = NonExhaustiveVariants::Tuple(340);
-    let variant_struct = NonExhaustiveVariants::Struct { field: 340 };
+    let _variant_struct = NonExhaustiveVariants::Struct { field: 340 };
 
     match variant_tuple {
         NonExhaustiveVariants::Unit => "",
-        NonExhaustiveVariants::Tuple(fe_tpl) => "",
-        NonExhaustiveVariants::Struct { field } => ""
+        NonExhaustiveVariants::Tuple(_fe_tpl) => "",
+        NonExhaustiveVariants::Struct { field: _ } => ""
     };
 }
diff --git a/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs
index 1de4e5bcebee9..b95105b59eddb 100644
--- a/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.rs
@@ -2,8 +2,6 @@
 
 #![allow(irrefutable_let_patterns)]
 
-use std::ops::Range;
-
 fn main() {
     let x: bool;
     // This should associate as: `(x = (true && false));`.
diff --git a/src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr
new file mode 100644
index 0000000000000..be7ef658411e1
--- /dev/null
+++ b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr
@@ -0,0 +1,8 @@
+warning: unreachable block in `if` expression
+  --> $DIR/protect-precedences.rs:13:41
+   |
+LL |         if let _ = return true && false {};
+   |                                         ^^
+   |
+   = note: `#[warn(unreachable_code)]` on by default
+
diff --git a/src/test/ui/traits/trait-alias/trait-alias-object-wf.rs b/src/test/ui/traits/trait-alias/trait-alias-object-wf.rs
index fb26b7e2df7cb..1440f02df1df8 100644
--- a/src/test/ui/traits/trait-alias/trait-alias-object-wf.rs
+++ b/src/test/ui/traits/trait-alias/trait-alias-object-wf.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 // This test checks that trait objects involving trait aliases are well-formed.
 
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs
index 0c212096f9234..19fcc78721ab1 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args-pass.rs
@@ -9,13 +9,13 @@
 
 #![allow(irrefutable_let_patterns)]
 
-enum Enum<T> { TSVariant(T), SVariant { v: T }, UVariant }
+enum Enum<T> { TSVariant(T), SVariant { _v: T }, UVariant }
 type Alias<T> = Enum<T>;
 type AliasFixed = Enum<()>;
 
 macro_rules! is_variant {
     (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr));
-    (SVariant, $expr:expr) => (is_variant!(@check SVariant, { v: _ }, $expr));
+    (SVariant, $expr:expr) => (is_variant!(@check SVariant, { _v: _ }, $expr));
     (UVariant, $expr:expr) => (is_variant!(@check UVariant, {}, $expr));
     (@check $variant:ident, $matcher:tt, $expr:expr) => (
         assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false },
@@ -37,14 +37,14 @@ fn main() {
 
     // Struct variant
 
-    is_variant!(SVariant, Enum::SVariant { v: () });
-    is_variant!(SVariant, Enum::SVariant::<()> { v: () });
-    is_variant!(SVariant, Enum::<()>::SVariant { v: () });
+    is_variant!(SVariant, Enum::SVariant { _v: () });
+    is_variant!(SVariant, Enum::SVariant::<()> { _v: () });
+    is_variant!(SVariant, Enum::<()>::SVariant { _v: () });
 
-    is_variant!(SVariant, Alias::SVariant { v: () });
-    is_variant!(SVariant, Alias::<()>::SVariant { v: () });
+    is_variant!(SVariant, Alias::SVariant { _v: () });
+    is_variant!(SVariant, Alias::<()>::SVariant { _v: () });
 
-    is_variant!(SVariant, AliasFixed::SVariant { v: () });
+    is_variant!(SVariant, AliasFixed::SVariant { _v: () });
 
     // Unit variant
 
diff --git a/src/test/ui/while-let.rs b/src/test/ui/while-let.rs
index 69f9de9497740..53babefae81c0 100644
--- a/src/test/ui/while-let.rs
+++ b/src/test/ui/while-let.rs
@@ -1,5 +1,6 @@
 // run-pass
 
+#[allow(dead_code)]
 fn macros() {
     macro_rules! foo{
         ($p:pat, $e:expr, $b:block) => {{
@@ -12,16 +13,16 @@ fn macros() {
         }}
     }
 
-    foo!(a, 1, { //~ WARN irrefutable while-let
+    foo!(_a, 1, { //~ WARN irrefutable while-let
         println!("irrefutable pattern");
     });
-    bar!(a, 1, { //~ WARN irrefutable while-let
+    bar!(_a, 1, { //~ WARN irrefutable while-let
         println!("irrefutable pattern");
     });
 }
 
 pub fn main() {
-    while let a = 1 { //~ WARN irrefutable while-let
+    while let _a = 1 { //~ WARN irrefutable while-let
         println!("irrefutable pattern");
         break;
     }
diff --git a/src/test/ui/while-let.stderr b/src/test/ui/while-let.stderr
index 348925aa9702c..30307ecaeadf2 100644
--- a/src/test/ui/while-let.stderr
+++ b/src/test/ui/while-let.stderr
@@ -1,10 +1,10 @@
 warning: irrefutable while-let pattern
-  --> $DIR/while-let.rs:6:13
+  --> $DIR/while-let.rs:7:13
    |
 LL |               while let $p = $e $b
    |               ^^^^^
 ...
-LL | /     foo!(a, 1, {
+LL | /     foo!(_a, 1, {
 LL | |         println!("irrefutable pattern");
 LL | |     });
    | |_______- in this macro invocation
@@ -12,20 +12,20 @@ LL | |     });
    = note: `#[warn(irrefutable_let_patterns)]` on by default
 
 warning: irrefutable while-let pattern
-  --> $DIR/while-let.rs:6:13
+  --> $DIR/while-let.rs:7:13
    |
 LL |               while let $p = $e $b
    |               ^^^^^
 ...
-LL | /     bar!(a, 1, {
+LL | /     bar!(_a, 1, {
 LL | |         println!("irrefutable pattern");
 LL | |     });
    | |_______- in this macro invocation
 
 warning: irrefutable while-let pattern
-  --> $DIR/while-let.rs:24:5
+  --> $DIR/while-let.rs:25:5
    |
-LL | /     while let a = 1 {
+LL | /     while let _a = 1 {
 LL | |         println!("irrefutable pattern");
 LL | |         break;
 LL | |     }

From 85e09c6531e1d3920065310c275b573bfad412ac Mon Sep 17 00:00:00 2001
From: Guanqun Lu <guanqun.lu@gmail.com>
Date: Sun, 8 Sep 2019 16:26:06 +0800
Subject: [PATCH 616/943] use 'get_toml' instead of regular expression

---
 src/bootstrap/bootstrap.py | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index e0e4c076071b6..14bc90700b76e 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -523,6 +523,10 @@ def get_toml(self, key, section=None):
         'value2'
         >>> rb.get_toml('key', 'c') is None
         True
+
+        >>> rb.config_toml = 'key1 = true'
+        >>> rb.get_toml("key1")
+        'true'
         """
 
         cur_section = None
@@ -571,6 +575,12 @@ def get_string(line):
 
         >>> RustBuild.get_string('    "devel"   ')
         'devel'
+        >>> RustBuild.get_string("    'devel'   ")
+        'devel'
+        >>> RustBuild.get_string('devel') is None
+        True
+        >>> RustBuild.get_string('    "devel   ')
+        ''
         """
         start = line.find('"')
         if start != -1:
@@ -822,13 +832,13 @@ def bootstrap(help_triggered):
     except (OSError, IOError):
         pass
 
-    match = re.search(r'\nverbose = (\d+)', build.config_toml)
-    if match is not None:
-        build.verbose = max(build.verbose, int(match.group(1)))
+    config_verbose = build.get_toml('verbose', 'build')
+    if config_verbose is not None:
+        build.verbose = max(build.verbose, int(config_verbose))
 
-    build.use_vendored_sources = '\nvendor = true' in build.config_toml
+    build.use_vendored_sources = build.get_toml('vendor', 'build') == 'true'
 
-    build.use_locked_deps = '\nlocked-deps = true' in build.config_toml
+    build.use_locked_deps = build.get_toml('locked-deps', 'build') == 'true'
 
     build.check_vendored_status()
 

From fc4375a895c899e937892c5666372cf14d35c6df Mon Sep 17 00:00:00 2001
From: V1shvesh <22243137+V1shvesh@users.noreply.github.com>
Date: Sun, 8 Sep 2019 22:58:28 +0530
Subject: [PATCH 617/943] Remove extra trailing newline

---
 src/librustc_errors/lib.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index b5341a2b727a5..20338a33ef684 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -852,4 +852,3 @@ macro_rules! pluralise {
                 if $x != 1 { "s" } else { "" }
             };
 }
-

From 7457ef858026d1858e9a36c7fad7a95773d0632d Mon Sep 17 00:00:00 2001
From: V1shvesh <22243137+V1shvesh@users.noreply.github.com>
Date: Sun, 8 Sep 2019 23:01:43 +0530
Subject: [PATCH 618/943] Dedent macro definition

---
 src/librustc_errors/lib.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 20338a33ef684..c1fba416d6433 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -848,7 +848,7 @@ impl Level {
 
 #[macro_export]
 macro_rules! pluralise {
-            ($x:expr) => {
-                if $x != 1 { "s" } else { "" }
-            };
+    ($x:expr) => {
+        if $x != 1 { "s" } else { "" }
+    };
 }

From 9a561872c419d3bc0c8ac9d13942f73535df27c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 1 Sep 2019 00:01:25 -0700
Subject: [PATCH 619/943] Always emit unresolved import errors and hide unused
 import lint

---
 src/librustc_resolve/resolve_imports.rs       | 89 ++++++++++++-------
 src/test/ui/extenv/issue-55897.rs             |  2 +-
 src/test/ui/extenv/issue-55897.stderr         |  8 +-
 .../ui/imports/unresolved-imports-used.rs     |  8 +-
 .../ui/imports/unresolved-imports-used.stderr | 26 +++++-
 .../ui/rust-2018/uniform-paths/deadlock.rs    |  2 +-
 .../rust-2018/uniform-paths/deadlock.stderr   |  6 +-
 7 files changed, 96 insertions(+), 45 deletions(-)

diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 132690dcd7df2..eb509f1a01d67 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -71,7 +71,7 @@ pub enum ImportDirectiveSubclass<'a> {
 }
 
 /// One import directive.
-#[derive(Debug,Clone)]
+#[derive(Debug, Clone)]
 crate struct ImportDirective<'a> {
     /// The ID of the `extern crate`, `UseTree` etc that imported this `ImportDirective`.
     ///
@@ -447,12 +447,13 @@ impl<'a> Resolver<'a> {
     }
 
     // Define the name or return the existing binding if there is a collision.
-    pub fn try_define(&mut self,
-                      module: Module<'a>,
-                      ident: Ident,
-                      ns: Namespace,
-                      binding: &'a NameBinding<'a>)
-                      -> Result<(), &'a NameBinding<'a>> {
+    pub fn try_define(
+        &mut self,
+        module: Module<'a>,
+        ident: Ident,
+        ns: Namespace,
+        binding: &'a NameBinding<'a>,
+    ) -> Result<(), &'a NameBinding<'a>> {
         let res = binding.res();
         self.check_reserved_macro_name(ident, res);
         self.set_binding_parent_module(binding, module);
@@ -480,8 +481,11 @@ impl<'a> Resolver<'a> {
                         };
                         if glob_binding.res() != nonglob_binding.res() &&
                            ns == MacroNS && nonglob_binding.expansion != ExpnId::root() {
-                            resolution.binding = Some(this.ambiguity(AmbiguityKind::GlobVsExpanded,
-                                                                    nonglob_binding, glob_binding));
+                            resolution.binding = Some(this.ambiguity(
+                                AmbiguityKind::GlobVsExpanded,
+                                nonglob_binding,
+                                glob_binding,
+                            ));
                         } else {
                             resolution.binding = Some(nonglob_binding);
                         }
@@ -513,9 +517,11 @@ impl<'a> Resolver<'a> {
         })
     }
 
-    fn ambiguity(&self, kind: AmbiguityKind,
-                 primary_binding: &'a NameBinding<'a>, secondary_binding: &'a NameBinding<'a>)
-                 -> &'a NameBinding<'a> {
+    fn ambiguity(
+        &self, kind: AmbiguityKind,
+        primary_binding: &'a NameBinding<'a>,
+        secondary_binding: &'a NameBinding<'a>,
+    ) -> &'a NameBinding<'a> {
         self.arenas.alloc_name_binding(NameBinding {
             ambiguity: Some((secondary_binding, kind)),
             ..primary_binding.clone()
@@ -524,8 +530,12 @@ impl<'a> Resolver<'a> {
 
     // Use `f` to mutate the resolution of the name in the module.
     // If the resolution becomes a success, define it in the module's glob importers.
-    fn update_resolution<T, F>(&mut self, module: Module<'a>, ident: Ident, ns: Namespace, f: F)
-                               -> T
+    fn update_resolution<T, F>(
+        &mut self, module: Module<'a>,
+        ident: Ident,
+        ns: Namespace,
+        f: F,
+    ) -> T
         where F: FnOnce(&mut Resolver<'a>, &mut NameResolution<'a>) -> T
     {
         // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
@@ -627,14 +637,18 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
             self.finalize_resolutions_in(module);
         }
 
-        let mut has_errors = false;
         let mut seen_spans = FxHashSet::default();
         let mut errors = vec![];
         let mut prev_root_id: NodeId = NodeId::from_u32(0);
-        for i in 0 .. self.r.determined_imports.len() {
-            let import = self.r.determined_imports[i];
+        let determined_imports = mem::take(&mut self.r.determined_imports);
+        let indeterminate_imports = mem::take(&mut self.r.indeterminate_imports);
+
+        for (is_indeterminate, import) in determined_imports
+            .into_iter()
+            .map(|i| (false, i))
+            .chain(indeterminate_imports.into_iter().map(|i| (true, i)))
+        {
             if let Some(err) = self.finalize_import(import) {
-                has_errors = true;
 
                 if let SingleImport { source, ref source_bindings, .. } = import.subclass {
                     if source.name == kw::SelfLower {
@@ -666,25 +680,27 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                     errors.push((path, err));
                     prev_root_id = import.root_id;
                 }
+            } else if is_indeterminate {
+                // Consider erroneous imports used to avoid duplicate diagnostics.
+                self.r.used_imports.insert((import.id, TypeNS));
+                let path = import_path_to_string(
+                    &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
+                    &import.subclass,
+                    import.span,
+                );
+                let err = UnresolvedImportError {
+                    span: import.span,
+                    label: None,
+                    note: Vec::new(),
+                    suggestion: None,
+                };
+                errors.push((path, err));
             }
         }
 
         if !errors.is_empty() {
             self.throw_unresolved_import_error(errors.clone(), None);
         }
-
-        for import in &self.r.indeterminate_imports {
-            // Consider erroneous imports used to avoid duplicate diagnostics.
-            self.r.used_imports.insert((import.id, TypeNS));
-        }
-        // Report unresolved imports only if no hard error was already reported
-        // to avoid generating multiple errors on the same import.
-        if !has_errors {
-            for import in &self.r.indeterminate_imports {
-                self.throw_unresolved_import_error(errors, Some(MultiSpan::from(import.span)));
-                break;
-            }
-        }
     }
 
     fn throw_unresolved_import_error(
@@ -839,8 +855,14 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
     ) -> Option<UnresolvedImportError> {
         let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
         let prev_ambiguity_errors_len = self.r.ambiguity_errors.len();
-        let path_res = self.r.resolve_path(&directive.module_path, None, &directive.parent_scope,
-                                         true, directive.span, directive.crate_lint());
+        let path_res = self.r.resolve_path(
+            &directive.module_path,
+            None,
+            &directive.parent_scope,
+            true,
+            directive.span,
+            directive.crate_lint(),
+        );
         let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len;
         directive.vis.set(orig_vis);
         if let PathResult::Failed { .. } | PathResult::NonModule(..) = path_res {
@@ -903,7 +925,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
                             }
                         }
                     };
-
                     return Some(err);
                 }
                 return None;
diff --git a/src/test/ui/extenv/issue-55897.rs b/src/test/ui/extenv/issue-55897.rs
index c3975f6b9255e..64c4107e89875 100644
--- a/src/test/ui/extenv/issue-55897.rs
+++ b/src/test/ui/extenv/issue-55897.rs
@@ -1,7 +1,7 @@
 use prelude::*; //~ ERROR unresolved import `prelude`
 
 mod unresolved_env {
-    use env;
+    use env; //~ ERROR unresolved import `env`
 
     include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
     //~^ ERROR cannot determine resolution for the macro `env`
diff --git a/src/test/ui/extenv/issue-55897.stderr b/src/test/ui/extenv/issue-55897.stderr
index 9d68131beabd7..c57a467cdba56 100644
--- a/src/test/ui/extenv/issue-55897.stderr
+++ b/src/test/ui/extenv/issue-55897.stderr
@@ -19,6 +19,12 @@ LL | use prelude::*;
    |     unresolved import
    |     help: a similar path exists: `std::prelude`
 
+error[E0432]: unresolved import `env`
+  --> $DIR/issue-55897.rs:4:9
+   |
+LL |     use env;
+   |         ^^^ no `env` in the root
+
 error: cannot determine resolution for the macro `env`
   --> $DIR/issue-55897.rs:6:22
    |
@@ -27,6 +33,6 @@ LL |     include!(concat!(env!("NON_EXISTENT"), "/data.rs"));
    |
    = note: import resolution is stuck, try simplifying macro imports
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0432`.
diff --git a/src/test/ui/imports/unresolved-imports-used.rs b/src/test/ui/imports/unresolved-imports-used.rs
index 5398dd63c8929..75cf880192c8e 100644
--- a/src/test/ui/imports/unresolved-imports-used.rs
+++ b/src/test/ui/imports/unresolved-imports-used.rs
@@ -8,11 +8,11 @@ mod qux {
 
 use qux::quz;  //~ ERROR function `quz` is private
 use qux::bar;  //~ ERROR unresolved import `qux::bar`
-use foo::bar;
-use baz::*;
+use foo::bar;  //~ ERROR unresolved import `foo`
+use baz::*;    //~ ERROR unresolved import `baz`
 use qux::bar2; //~ ERROR unresolved import `qux::bar2`
-use foo2::bar2;
-use baz2::*;
+use foo2::bar2;//~ ERROR unresolved import `foo2`
+use baz2::*;   //~ ERROR unresolved import `baz2`
 use qux::quy;  //~ ERROR unused import
 
 fn main() {}
diff --git a/src/test/ui/imports/unresolved-imports-used.stderr b/src/test/ui/imports/unresolved-imports-used.stderr
index c9342d17a49d7..b341e8e059288 100644
--- a/src/test/ui/imports/unresolved-imports-used.stderr
+++ b/src/test/ui/imports/unresolved-imports-used.stderr
@@ -10,6 +10,30 @@ error[E0432]: unresolved import `qux::bar2`
 LL | use qux::bar2;
    |     ^^^^^^^^^ no `bar2` in `qux`
 
+error[E0432]: unresolved import `foo`
+  --> $DIR/unresolved-imports-used.rs:11:5
+   |
+LL | use foo::bar;
+   |     ^^^ maybe a missing crate `foo`?
+
+error[E0432]: unresolved import `baz`
+  --> $DIR/unresolved-imports-used.rs:12:5
+   |
+LL | use baz::*;
+   |     ^^^ maybe a missing crate `baz`?
+
+error[E0432]: unresolved import `foo2`
+  --> $DIR/unresolved-imports-used.rs:14:5
+   |
+LL | use foo2::bar2;
+   |     ^^^^ maybe a missing crate `foo2`?
+
+error[E0432]: unresolved import `baz2`
+  --> $DIR/unresolved-imports-used.rs:15:5
+   |
+LL | use baz2::*;
+   |     ^^^^ maybe a missing crate `baz2`?
+
 error[E0603]: function `quz` is private
   --> $DIR/unresolved-imports-used.rs:9:10
    |
@@ -28,7 +52,7 @@ note: lint level defined here
 LL | #![deny(unused_imports)]
    |         ^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 8 previous errors
 
 Some errors have detailed explanations: E0432, E0603.
 For more information about an error, try `rustc --explain E0432`.
diff --git a/src/test/ui/rust-2018/uniform-paths/deadlock.rs b/src/test/ui/rust-2018/uniform-paths/deadlock.rs
index 3228d799083fb..83ed70a0459a8 100644
--- a/src/test/ui/rust-2018/uniform-paths/deadlock.rs
+++ b/src/test/ui/rust-2018/uniform-paths/deadlock.rs
@@ -1,7 +1,7 @@
 // edition:2018
 // compile-flags:--extern foo --extern bar
 
-use foo::bar; //~ ERROR unresolved import
+use foo::bar; //~ ERROR can't find crate for `foo`
 use bar::foo;
 
 fn main() {}
diff --git a/src/test/ui/rust-2018/uniform-paths/deadlock.stderr b/src/test/ui/rust-2018/uniform-paths/deadlock.stderr
index b4ac15c588ebd..9336e90afb71d 100644
--- a/src/test/ui/rust-2018/uniform-paths/deadlock.stderr
+++ b/src/test/ui/rust-2018/uniform-paths/deadlock.stderr
@@ -1,9 +1,9 @@
-error[E0432]: unresolved import
+error[E0463]: can't find crate for `foo`
   --> $DIR/deadlock.rs:4:5
    |
 LL | use foo::bar;
-   |     ^^^^^^^^
+   |     ^^^ can't find crate
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0432`.
+For more information about this error, try `rustc --explain E0463`.

From 9bf577311473aa0accbf0d456cbd26b7530b200f Mon Sep 17 00:00:00 2001
From: William Chargin <wchargin@gmail.com>
Date: Sun, 8 Sep 2019 14:03:09 -0700
Subject: [PATCH 620/943] Fix `Stdio::piped` example code and lint

Summary:
Invoking `rev` does not add a trailing newline when none is present in
the input (at least on my Debian). Nearby examples use `echo` rather
than `rev`, which probably explains the source of the discrepancy.

Also, a `mut` qualifier is unused.

Test Plan:
Copy the code block into <https://play.rust-lang.org> with a `fn main`
wrapper, and run it. Note that it compiles and runs cleanly; prior to
this commit, it would emit an `unused_mut` warning and then panic.

wchargin-branch: stdio-piped-docs
---
 src/libstd/process.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 000f80f99e7a9..cecd9a5ab56b7 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -935,12 +935,12 @@ impl Stdio {
     ///     .expect("Failed to spawn child process");
     ///
     /// {
-    ///     let mut stdin = child.stdin.as_mut().expect("Failed to open stdin");
+    ///     let stdin = child.stdin.as_mut().expect("Failed to open stdin");
     ///     stdin.write_all("Hello, world!".as_bytes()).expect("Failed to write to stdin");
     /// }
     ///
     /// let output = child.wait_with_output().expect("Failed to read stdout");
-    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "!dlrow ,olleH\n");
+    /// assert_eq!(String::from_utf8_lossy(&output.stdout), "!dlrow ,olleH");
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn piped() -> Stdio { Stdio(imp::Stdio::MakePipe) }

From c36d7d48345b4748596e51994e1696abde912e44 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Thu, 5 Sep 2019 06:43:03 +1000
Subject: [PATCH 621/943] Use `sym::{all,any,main,not}` more.

---
 src/librustdoc/clean/cfg.rs | 8 ++++----
 src/librustdoc/test.rs      | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index b9b3e621bb740..c3092cea9833c 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -81,10 +81,10 @@ impl Cfg {
             },
             MetaItemKind::List(ref items) => {
                 let mut sub_cfgs = items.iter().map(Cfg::parse_nested);
-                match &*name.as_str() {
-                    "all" => sub_cfgs.fold(Ok(Cfg::True), |x, y| Ok(x? & y?)),
-                    "any" => sub_cfgs.fold(Ok(Cfg::False), |x, y| Ok(x? | y?)),
-                    "not" => if sub_cfgs.len() == 1 {
+                match name {
+                    sym::all => sub_cfgs.fold(Ok(Cfg::True), |x, y| Ok(x? & y?)),
+                    sym::any => sub_cfgs.fold(Ok(Cfg::False), |x, y| Ok(x? | y?)),
+                    sym::not => if sub_cfgs.len() == 1 {
                         Ok(!sub_cfgs.next().unwrap()?)
                     } else {
                         Err(InvalidCfgError {
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 000d2843adce3..fe2be682ec52f 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -407,7 +407,7 @@ pub fn make_test(s: &str,
                 Ok(Some(item)) => {
                     if !found_main {
                         if let ast::ItemKind::Fn(..) = item.node {
-                            if item.ident.as_str() == "main" {
+                            if item.ident.name == sym::main {
                                 found_main = true;
                             }
                         }

From 36b37e22de92b584b9cf4464ed1d4ad317b798be Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 9 Sep 2019 08:25:54 +1000
Subject: [PATCH 622/943] Remove two unnecessary `clone()` calls.

---
 src/librustc_typeck/check/closure.rs        | 6 +++---
 src/librustc_typeck/check/compare_method.rs | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index e9370429f3f55..d626bff150020 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -529,11 +529,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ); // recreated from (*) above
 
                 // Check that E' = S'.
-                let cause = &self.misc(hir_ty.span);
+                let cause = self.misc(hir_ty.span);
                 let InferOk {
                     value: (),
                     obligations,
-                } = self.at(cause, self.param_env)
+                } = self.at(&cause, self.param_env)
                     .eq(*expected_ty, supplied_ty)?;
                 all_obligations.extend(obligations);
 
@@ -549,7 +549,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 );
                 all_obligations.push(
                     Obligation::new(
-                        cause.clone(),
+                        cause,
                         self.param_env,
                         ty::Predicate::TypeOutlives(
                             ty::Binder::dummy(
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 8e187b7e05b51..74ea93fc44270 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -308,7 +308,7 @@ fn compare_predicate_entailment<'tcx>(
 
             let cause = ObligationCause {
                 span: impl_err_span,
-                ..cause.clone()
+                ..cause
             };
 
             let mut diag = struct_span_err!(tcx.sess,

From 19db48ae389ee523c971e52302189606aab45a9b Mon Sep 17 00:00:00 2001
From: Mark Mansi <markm@cs.wisc.edu>
Date: Thu, 5 Sep 2019 17:03:12 -0500
Subject: [PATCH 623/943] update rustc-guide

---
 src/doc/rustc-guide | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide
index 6e25a3d0d3573..a0c08c27e60e5 160000
--- a/src/doc/rustc-guide
+++ b/src/doc/rustc-guide
@@ -1 +1 @@
-Subproject commit 6e25a3d0d3573eb42b2e2339f1219e969d1b3dee
+Subproject commit a0c08c27e60e52b72244c5241ed494a197bebf28

From 7c2dad292e93fc9bbb16085e0dddc2c57d7db7aa Mon Sep 17 00:00:00 2001
From: mark <markm@cs.wisc.edu>
Date: Fri, 6 Sep 2019 16:01:46 -0500
Subject: [PATCH 624/943] update guide

---
 src/doc/rustc-guide | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide
index a0c08c27e60e5..941968db2fd9c 160000
--- a/src/doc/rustc-guide
+++ b/src/doc/rustc-guide
@@ -1 +1 @@
-Subproject commit a0c08c27e60e52b72244c5241ed494a197bebf28
+Subproject commit 941968db2fd9c85788a4f971c8e425d46b4cb734

From 5799fb419c96a9e6a170f7980f67fd9047fd6f96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 6 Sep 2019 12:00:07 -0700
Subject: [PATCH 625/943] Give method not found a primary span label

---
 src/librustc_typeck/check/method/suggest.rs   |  3 ++
 src/test/ui/auto-ref-slice-plus-ref.stderr    |  6 +--
 src/test/ui/class-cast-to-trait.stderr        |  2 +-
 .../coherence/coherence_inherent.old.stderr   |  2 +-
 .../ui/coherence/coherence_inherent.re.stderr |  2 +-
 .../coherence_inherent_cc.old.stderr          |  2 +-
 .../coherence/coherence_inherent_cc.re.stderr |  2 +-
 .../invalid-const-arg-for-type-param.stderr   |  2 +-
 src/test/ui/copy-a-resource.stderr            |  2 +-
 .../derives/derive-assoc-type-not-impl.stderr |  2 +-
 src/test/ui/error-festival.stderr             |  2 +-
 .../ui/hygiene/no_implicit_prelude.stderr     |  2 +-
 src/test/ui/hygiene/trait_items.stderr        |  2 +-
 src/test/ui/impl-trait/bindings-opaque.stderr |  6 +--
 ...e-21659-show-relevant-trait-impls-3.stderr |  2 +-
 .../method-suggestion-no-duplication.stderr   |  2 +-
 .../no-method-suggested-traits.stderr         | 48 +++++++++----------
 .../ui/infinite/infinite-autoderef.stderr     |  2 +-
 src/test/ui/issues/issue-10465.stderr         |  2 +-
 src/test/ui/issues/issue-13853.stderr         |  2 +-
 src/test/ui/issues/issue-15207.stderr         |  2 +-
 src/test/ui/issues/issue-1871.stderr          |  2 +-
 src/test/ui/issues/issue-19521.stderr         |  2 +-
 src/test/ui/issues/issue-19692.stderr         |  2 +-
 src/test/ui/issues/issue-2149.stderr          |  2 +-
 src/test/ui/issues/issue-21596.stderr         |  2 +-
 src/test/ui/issues/issue-25385.stderr         |  4 +-
 src/test/ui/issues/issue-2823.stderr          |  2 +-
 src/test/ui/issues/issue-29124.stderr         |  4 +-
 src/test/ui/issues/issue-29181.stderr         |  2 +-
 src/test/ui/issues/issue-31173.stderr         |  2 +-
 src/test/ui/issues/issue-34334.stderr         |  2 +-
 src/test/ui/issues/issue-35677.stderr         |  2 +-
 src/test/ui/issues/issue-39175.stderr         |  2 +-
 src/test/ui/issues/issue-41880.stderr         |  2 +-
 src/test/ui/issues/issue-43189.stderr         |  2 +-
 .../option-as_deref_mut.stderr                |  2 +-
 src/test/ui/issues/issue-5153.stderr          |  2 +-
 src/test/ui/issues/issue-54062.stderr         |  2 +-
 src/test/ui/issues/issue-57362-1.stderr       |  2 +-
 .../macro-backtrace-invalid-internals.stderr  |  4 +-
 .../ui/methods/method-call-err-msg.stderr     |  2 +-
 .../ui/mismatched_types/issue-36053-2.stderr  |  2 +-
 .../method-help-unsatisfied-bound.stderr      |  2 +-
 src/test/ui/non-copyable-void.stderr          |  2 +-
 src/test/ui/noncopyable-class.stderr          |  2 +-
 src/test/ui/object-pointer-types.stderr       |  6 +--
 .../rust-2018/trait-import-suggestions.stderr |  6 +--
 ...point-at-arbitrary-self-type-method.stderr |  2 +-
 ...at-arbitrary-self-type-trait-method.stderr |  2 +-
 .../ui/shadowed/shadowed-trait-methods.stderr |  2 +-
 ...pecialization-trait-not-implemented.stderr |  2 +-
 ...it-with-missing-trait-bounds-in-arg.stderr |  2 +-
 src/test/ui/suggestions/issue-21673.stderr    |  4 +-
 .../ui/suggestions/suggest-methods.stderr     |  2 +-
 src/test/ui/traits/trait-impl-1.stderr        |  2 +-
 src/test/ui/traits/trait-item-privacy.stderr  |  4 +-
 .../trivial-bounds/trivial-bounds-leak.stderr |  2 +-
 ...ed-closures-static-call-wrong-trait.stderr |  2 +-
 src/test/ui/underscore-imports/shadow.stderr  |  2 +-
 src/test/ui/union/union-derive-clone.stderr   |  2 +-
 src/test/ui/unique-object-noncopyable.stderr  |  2 +-
 src/test/ui/unique-pinned-nocopy.stderr       |  2 +-
 63 files changed, 101 insertions(+), 98 deletions(-)

diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 72e6f59715960..3e45b1e98d4ec 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -425,6 +425,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             "private field"
                         };
                         err.span_label(item_name.span, format!("{}, not a method", field_kind));
+                    } else if lev_candidate.is_none() && static_sources.is_empty() {
+                        err.span_label(span, format!("{} not found in `{}`", item_kind, ty_str));
+                        self.tcx.sess.trait_methods_not_found.borrow_mut().insert(orig_span);
                     }
                 } else {
                     err.span_label(span, format!("{} not found in `{}`", item_kind, ty_str));
diff --git a/src/test/ui/auto-ref-slice-plus-ref.stderr b/src/test/ui/auto-ref-slice-plus-ref.stderr
index f2e0d379d1b30..3e36f2402a990 100644
--- a/src/test/ui/auto-ref-slice-plus-ref.stderr
+++ b/src/test/ui/auto-ref-slice-plus-ref.stderr
@@ -12,7 +12,7 @@ error[E0599]: no method named `test` found for type `std::vec::Vec<{integer}>` i
   --> $DIR/auto-ref-slice-plus-ref.rs:8:7
    |
 LL |     a.test();
-   |       ^^^^
+   |       ^^^^ method not found in `std::vec::Vec<{integer}>`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `test`, perhaps you need to implement it:
@@ -22,7 +22,7 @@ error[E0599]: no method named `test` found for type `[{integer}; 1]` in the curr
   --> $DIR/auto-ref-slice-plus-ref.rs:10:11
    |
 LL |     ([1]).test();
-   |           ^^^^
+   |           ^^^^ method not found in `[{integer}; 1]`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `test`, perhaps you need to implement it:
@@ -32,7 +32,7 @@ error[E0599]: no method named `test` found for type `&[{integer}; 1]` in the cur
   --> $DIR/auto-ref-slice-plus-ref.rs:11:12
    |
 LL |     (&[1]).test();
-   |            ^^^^
+   |            ^^^^ method not found in `&[{integer}; 1]`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `test`, perhaps you need to implement it:
diff --git a/src/test/ui/class-cast-to-trait.stderr b/src/test/ui/class-cast-to-trait.stderr
index 39f308cdfd490..4cab52e3e974c 100644
--- a/src/test/ui/class-cast-to-trait.stderr
+++ b/src/test/ui/class-cast-to-trait.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `eat` found for type `std::boxed::Box<dyn Noisy>`
   --> $DIR/class-cast-to-trait.rs:53:8
    |
 LL |   nyan.eat();
-   |        ^^^
+   |        ^^^ method not found in `std::boxed::Box<dyn Noisy>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_inherent.old.stderr b/src/test/ui/coherence/coherence_inherent.old.stderr
index fa564459b2133..750d243480638 100644
--- a/src/test/ui/coherence/coherence_inherent.old.stderr
+++ b/src/test/ui/coherence/coherence_inherent.old.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `the_fn` found for type `&Lib::TheStruct` in the c
   --> $DIR/coherence_inherent.rs:35:11
    |
 LL |         s.the_fn();
-   |           ^^^^^^
+   |           ^^^^^^ method not found in `&Lib::TheStruct`
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/coherence/coherence_inherent.re.stderr b/src/test/ui/coherence/coherence_inherent.re.stderr
index fa564459b2133..750d243480638 100644
--- a/src/test/ui/coherence/coherence_inherent.re.stderr
+++ b/src/test/ui/coherence/coherence_inherent.re.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `the_fn` found for type `&Lib::TheStruct` in the c
   --> $DIR/coherence_inherent.rs:35:11
    |
 LL |         s.the_fn();
-   |           ^^^^^^
+   |           ^^^^^^ method not found in `&Lib::TheStruct`
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/coherence/coherence_inherent_cc.old.stderr b/src/test/ui/coherence/coherence_inherent_cc.old.stderr
index 4d93e699031f3..59166a4609406 100644
--- a/src/test/ui/coherence/coherence_inherent_cc.old.stderr
+++ b/src/test/ui/coherence/coherence_inherent_cc.old.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `the_fn` found for type `&coherence_inherent_cc_li
   --> $DIR/coherence_inherent_cc.rs:26:11
    |
 LL |         s.the_fn();
-   |           ^^^^^^
+   |           ^^^^^^ method not found in `&coherence_inherent_cc_lib::TheStruct`
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/coherence/coherence_inherent_cc.re.stderr b/src/test/ui/coherence/coherence_inherent_cc.re.stderr
index 4d93e699031f3..59166a4609406 100644
--- a/src/test/ui/coherence/coherence_inherent_cc.re.stderr
+++ b/src/test/ui/coherence/coherence_inherent_cc.re.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `the_fn` found for type `&coherence_inherent_cc_li
   --> $DIR/coherence_inherent_cc.rs:26:11
    |
 LL |         s.the_fn();
-   |           ^^^^^^
+   |           ^^^^^^ method not found in `&coherence_inherent_cc_lib::TheStruct`
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr b/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr
index 8f3f91651edfb..47b090cb88678 100644
--- a/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr
+++ b/src/test/ui/const-generics/invalid-const-arg-for-type-param.stderr
@@ -11,7 +11,7 @@ LL | struct S;
    | --------- method `f` not found for this
 ...
 LL |     S.f::<0>();
-   |       ^
+   |       ^ method not found in `S`
 
 error[E0107]: wrong number of const arguments: expected 0, found 1
   --> $DIR/invalid-const-arg-for-type-param.rs:8:9
diff --git a/src/test/ui/copy-a-resource.stderr b/src/test/ui/copy-a-resource.stderr
index cceb9e328b676..054bd0914d31c 100644
--- a/src/test/ui/copy-a-resource.stderr
+++ b/src/test/ui/copy-a-resource.stderr
@@ -5,7 +5,7 @@ LL | struct Foo {
    | ---------- method `clone` not found for this
 ...
 LL |     let _y = x.clone();
-   |                ^^^^^
+   |                ^^^^^ method not found in `Foo`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `clone`, perhaps you need to implement it:
diff --git a/src/test/ui/derives/derive-assoc-type-not-impl.stderr b/src/test/ui/derives/derive-assoc-type-not-impl.stderr
index b9e175e43d1cf..038de80508ac2 100644
--- a/src/test/ui/derives/derive-assoc-type-not-impl.stderr
+++ b/src/test/ui/derives/derive-assoc-type-not-impl.stderr
@@ -5,7 +5,7 @@ LL | struct Bar<T: Foo> {
    | ------------------ method `clone` not found for this
 ...
 LL |     Bar::<NotClone> { x: 1 }.clone();
-   |                              ^^^^^
+   |                              ^^^^^ method not found in `Bar<NotClone>`
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `Bar<NotClone> : std::clone::Clone`
diff --git a/src/test/ui/error-festival.stderr b/src/test/ui/error-festival.stderr
index 8808e95d81b18..73571a375b5f6 100644
--- a/src/test/ui/error-festival.stderr
+++ b/src/test/ui/error-festival.stderr
@@ -24,7 +24,7 @@ error[E0599]: no method named `z` found for type `&str` in the current scope
   --> $DIR/error-festival.rs:16:7
    |
 LL |     x.z();
-   |       ^
+   |       ^ method not found in `&str`
 
 error[E0600]: cannot apply unary operator `!` to type `Question`
   --> $DIR/error-festival.rs:19:5
diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr
index 643f803f62049..8fa55d05bddcb 100644
--- a/src/test/ui/hygiene/no_implicit_prelude.stderr
+++ b/src/test/ui/hygiene/no_implicit_prelude.stderr
@@ -22,7 +22,7 @@ LL |     fn f() { ::bar::m!(); }
    |              ------------ in this macro invocation
 ...
 LL |         ().clone()
-   |            ^^^^^
+   |            ^^^^^ method not found in `()`
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/hygiene/trait_items.stderr b/src/test/ui/hygiene/trait_items.stderr
index 4192b97e75069..39e32522c7a76 100644
--- a/src/test/ui/hygiene/trait_items.stderr
+++ b/src/test/ui/hygiene/trait_items.stderr
@@ -5,7 +5,7 @@ LL |     fn f() { ::baz::m!(); }
    |              ------------ in this macro invocation
 ...
 LL |     pub macro m() { ().f() }
-   |                        ^
+   |                        ^ method not found in `()`
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/impl-trait/bindings-opaque.stderr b/src/test/ui/impl-trait/bindings-opaque.stderr
index ad108173a7a1e..644d26b34060c 100644
--- a/src/test/ui/impl-trait/bindings-opaque.stderr
+++ b/src/test/ui/impl-trait/bindings-opaque.stderr
@@ -10,19 +10,19 @@ error[E0599]: no method named `count_ones` found for type `impl std::marker::Cop
   --> $DIR/bindings-opaque.rs:11:17
    |
 LL |     let _ = FOO.count_ones();
-   |                 ^^^^^^^^^^
+   |                 ^^^^^^^^^^ method not found in `impl std::marker::Copy`
 
 error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope
   --> $DIR/bindings-opaque.rs:13:17
    |
 LL |     let _ = BAR.count_ones();
-   |                 ^^^^^^^^^^
+   |                 ^^^^^^^^^^ method not found in `impl std::marker::Copy`
 
 error[E0599]: no method named `count_ones` found for type `impl std::marker::Copy` in the current scope
   --> $DIR/bindings-opaque.rs:15:17
    |
 LL |     let _ = foo.count_ones();
-   |                 ^^^^^^^^^^
+   |                 ^^^^^^^^^^ method not found in `impl std::marker::Copy`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr b/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr
index 666418f6ee2c1..441191beaf588 100644
--- a/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr
+++ b/src/test/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr
@@ -5,7 +5,7 @@ LL | struct Bar;
    | ----------- method `foo` not found for this
 ...
 LL |     f1.foo(1usize);
-   |        ^^^
+   |        ^^^ method not found in `Bar`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `foo`, perhaps you need to implement it:
diff --git a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr
index afb3376638a96..fb870d6c6f076 100644
--- a/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr
+++ b/src/test/ui/impl-trait/method-suggestion-no-duplication.stderr
@@ -5,7 +5,7 @@ LL | struct Foo;
    | ----------- method `is_empty` not found for this
 ...
 LL |     foo(|s| s.is_empty());
-   |               ^^^^^^^^
+   |               ^^^^^^^^ method not found in `Foo`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `is_empty`, perhaps you need to implement it:
diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
index 002b60f9f258d..be8f3ab1b72e8 100644
--- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr
+++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `method` found for type `u32` in the current scope
   --> $DIR/no-method-suggested-traits.rs:23:10
    |
 LL |     1u32.method();
-   |          ^^^^^^
+   |          ^^^^^^ method not found in `u32`
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following traits are implemented but not in scope, perhaps add a `use` for one of them:
@@ -20,7 +20,7 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box
   --> $DIR/no-method-suggested-traits.rs:26:44
    |
 LL |     std::rc::Rc::new(&mut Box::new(&1u32)).method();
-   |                                            ^^^^^^
+   |                                            ^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&u32>>`
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following traits are implemented but not in scope, perhaps add a `use` for one of them:
@@ -38,7 +38,7 @@ error[E0599]: no method named `method` found for type `char` in the current scop
   --> $DIR/no-method-suggested-traits.rs:30:9
    |
 LL |     'a'.method();
-   |         ^^^^^^
+   |         ^^^^^^ method not found in `char`
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope, perhaps add a `use` for it:
@@ -58,7 +58,7 @@ LL |         fn method(&self) {}
    |            the method is available for `std::rc::Rc<std::rc::Rc<&mut std::boxed::Box<&char>>>` here
 ...
 LL |     std::rc::Rc::new(&mut Box::new(&'a')).method();
-   |                                           ^^^^^^
+   |                                           ^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&char>>`
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope, perhaps add a `use` for it:
@@ -70,7 +70,7 @@ error[E0599]: no method named `method` found for type `i32` in the current scope
   --> $DIR/no-method-suggested-traits.rs:35:10
    |
 LL |     1i32.method();
-   |          ^^^^^^
+   |          ^^^^^^ method not found in `i32`
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope, perhaps add a `use` for it:
@@ -82,7 +82,7 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box
   --> $DIR/no-method-suggested-traits.rs:37:44
    |
 LL |     std::rc::Rc::new(&mut Box::new(&1i32)).method();
-   |                                            ^^^^^^
+   |                                            ^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&i32>>`
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope, perhaps add a `use` for it:
@@ -97,7 +97,7 @@ LL | struct Foo;
    | ----------- method `method` not found for this
 ...
 LL |     Foo.method();
-   |         ^^^^^^
+   |         ^^^^^^ method not found in `Foo`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following traits define an item `method`, perhaps you need to implement one of them:
@@ -110,7 +110,7 @@ error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::box
   --> $DIR/no-method-suggested-traits.rs:42:43
    |
 LL |     std::rc::Rc::new(&mut Box::new(&Foo)).method();
-   |                                           ^^^^^^
+   |                                           ^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&Foo>>`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following traits define an item `method`, perhaps you need to implement one of them:
@@ -123,7 +123,7 @@ error[E0599]: no method named `method2` found for type `u64` in the current scop
   --> $DIR/no-method-suggested-traits.rs:45:10
    |
 LL |     1u64.method2();
-   |          ^^^^^^^
+   |          ^^^^^^^ method not found in `u64`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `method2`, perhaps you need to implement it:
@@ -133,7 +133,7 @@ error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::bo
   --> $DIR/no-method-suggested-traits.rs:47:44
    |
 LL |     std::rc::Rc::new(&mut Box::new(&1u64)).method2();
-   |                                            ^^^^^^^
+   |                                            ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&u64>>`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `method2`, perhaps you need to implement it:
@@ -143,7 +143,7 @@ error[E0599]: no method named `method2` found for type `no_method_suggested_trai
   --> $DIR/no-method-suggested-traits.rs:50:37
    |
 LL |     no_method_suggested_traits::Foo.method2();
-   |                                     ^^^^^^^
+   |                                     ^^^^^^^ method not found in `no_method_suggested_traits::Foo`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `method2`, perhaps you need to implement it:
@@ -153,7 +153,7 @@ error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::bo
   --> $DIR/no-method-suggested-traits.rs:52:71
    |
 LL |     std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method2();
-   |                                                                       ^^^^^^^
+   |                                                                       ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `method2`, perhaps you need to implement it:
@@ -163,7 +163,7 @@ error[E0599]: no method named `method2` found for type `no_method_suggested_trai
   --> $DIR/no-method-suggested-traits.rs:54:40
    |
 LL |     no_method_suggested_traits::Bar::X.method2();
-   |                                        ^^^^^^^
+   |                                        ^^^^^^^ method not found in `no_method_suggested_traits::Bar`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `method2`, perhaps you need to implement it:
@@ -173,7 +173,7 @@ error[E0599]: no method named `method2` found for type `std::rc::Rc<&mut std::bo
   --> $DIR/no-method-suggested-traits.rs:56:74
    |
 LL |     std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method2();
-   |                                                                          ^^^^^^^
+   |                                                                          ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `method2`, perhaps you need to implement it:
@@ -186,7 +186,7 @@ LL | struct Foo;
    | ----------- method `method3` not found for this
 ...
 LL |     Foo.method3();
-   |         ^^^^^^^
+   |         ^^^^^^^ method not found in `Foo`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `method3`, perhaps you need to implement it:
@@ -196,7 +196,7 @@ error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::bo
   --> $DIR/no-method-suggested-traits.rs:61:43
    |
 LL |     std::rc::Rc::new(&mut Box::new(&Foo)).method3();
-   |                                           ^^^^^^^
+   |                                           ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&Foo>>`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `method3`, perhaps you need to implement it:
@@ -209,7 +209,7 @@ LL | enum Bar { X }
    | -------- method `method3` not found for this
 ...
 LL |     Bar::X.method3();
-   |            ^^^^^^^
+   |            ^^^^^^^ method not found in `Bar`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `method3`, perhaps you need to implement it:
@@ -219,7 +219,7 @@ error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::bo
   --> $DIR/no-method-suggested-traits.rs:65:46
    |
 LL |     std::rc::Rc::new(&mut Box::new(&Bar::X)).method3();
-   |                                              ^^^^^^^
+   |                                              ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&Bar>>`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `method3`, perhaps you need to implement it:
@@ -229,37 +229,37 @@ error[E0599]: no method named `method3` found for type `usize` in the current sc
   --> $DIR/no-method-suggested-traits.rs:69:13
    |
 LL |     1_usize.method3();
-   |             ^^^^^^^
+   |             ^^^^^^^ method not found in `usize`
 
 error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&usize>>` in the current scope
   --> $DIR/no-method-suggested-traits.rs:70:47
    |
 LL |     std::rc::Rc::new(&mut Box::new(&1_usize)).method3();
-   |                                               ^^^^^^^
+   |                                               ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&usize>>`
 
 error[E0599]: no method named `method3` found for type `no_method_suggested_traits::Foo` in the current scope
   --> $DIR/no-method-suggested-traits.rs:71:37
    |
 LL |     no_method_suggested_traits::Foo.method3();
-   |                                     ^^^^^^^
+   |                                     ^^^^^^^ method not found in `no_method_suggested_traits::Foo`
 
 error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>` in the current scope
   --> $DIR/no-method-suggested-traits.rs:72:71
    |
 LL |     std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Foo)).method3();
-   |                                                                       ^^^^^^^
+   |                                                                       ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Foo>>`
 
 error[E0599]: no method named `method3` found for type `no_method_suggested_traits::Bar` in the current scope
   --> $DIR/no-method-suggested-traits.rs:74:40
    |
 LL |     no_method_suggested_traits::Bar::X.method3();
-   |                                        ^^^^^^^
+   |                                        ^^^^^^^ method not found in `no_method_suggested_traits::Bar`
 
 error[E0599]: no method named `method3` found for type `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>` in the current scope
   --> $DIR/no-method-suggested-traits.rs:75:74
    |
 LL |     std::rc::Rc::new(&mut Box::new(&no_method_suggested_traits::Bar::X)).method3();
-   |                                                                          ^^^^^^^
+   |                                                                          ^^^^^^^ method not found in `std::rc::Rc<&mut std::boxed::Box<&no_method_suggested_traits::Bar>>`
 
 error: aborting due to 24 previous errors
 
diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr
index 3159a4b67dae5..a2ad58a7e46fc 100644
--- a/src/test/ui/infinite/infinite-autoderef.stderr
+++ b/src/test/ui/infinite/infinite-autoderef.stderr
@@ -44,7 +44,7 @@ LL | struct Foo;
    | ----------- method `bar` not found for this
 ...
 LL |     Foo.bar();
-   |         ^^^
+   |         ^^^ method not found in `Foo`
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/issues/issue-10465.stderr b/src/test/ui/issues/issue-10465.stderr
index 6efbd8e40ef64..413daa6db6787 100644
--- a/src/test/ui/issues/issue-10465.stderr
+++ b/src/test/ui/issues/issue-10465.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `foo` found for type `&b::B` in the current scope
   --> $DIR/issue-10465.rs:17:15
    |
 LL |             b.foo();
-   |               ^^^
+   |               ^^^ method not found in `&b::B`
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/issues/issue-13853.stderr b/src/test/ui/issues/issue-13853.stderr
index 9026845b4ed86..c57ca3e25d99f 100644
--- a/src/test/ui/issues/issue-13853.stderr
+++ b/src/test/ui/issues/issue-13853.stderr
@@ -14,7 +14,7 @@ error[E0599]: no method named `iter` found for type `&G` in the current scope
   --> $DIR/issue-13853.rs:27:23
    |
 LL |     for node in graph.iter() {
-   |                       ^^^^
+   |                       ^^^^ method not found in `&G`
 
 error[E0308]: mismatched types
   --> $DIR/issue-13853.rs:37:13
diff --git a/src/test/ui/issues/issue-15207.stderr b/src/test/ui/issues/issue-15207.stderr
index 2d90eb80fc54c..25ce7cb5cc069 100644
--- a/src/test/ui/issues/issue-15207.stderr
+++ b/src/test/ui/issues/issue-15207.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `push` found for type `!` in the current scope
   --> $DIR/issue-15207.rs:3:15
    |
 LL |         break.push(1)
-   |               ^^^^
+   |               ^^^^ method not found in `!`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-1871.stderr b/src/test/ui/issues/issue-1871.stderr
index fecd689251b32..b774ca22dd72a 100644
--- a/src/test/ui/issues/issue-1871.stderr
+++ b/src/test/ui/issues/issue-1871.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `honk` found for type `{integer}` in the current s
   --> $DIR/issue-1871.rs:7:9
    |
 LL |       f.honk()
-   |         ^^^^
+   |         ^^^^ method not found in `{integer}`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-19521.stderr b/src/test/ui/issues/issue-19521.stderr
index a43368be58339..c15c5392fac25 100644
--- a/src/test/ui/issues/issue-19521.stderr
+++ b/src/test/ui/issues/issue-19521.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `homura` found for type `&'static str` in the curr
   --> $DIR/issue-19521.rs:2:8
    |
 LL |     "".homura()();
-   |        ^^^^^^
+   |        ^^^^^^ method not found in `&'static str`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-19692.stderr b/src/test/ui/issues/issue-19692.stderr
index 5e576f11583eb..fe920c1693982 100644
--- a/src/test/ui/issues/issue-19692.stderr
+++ b/src/test/ui/issues/issue-19692.stderr
@@ -5,7 +5,7 @@ LL | struct Homura;
    | -------------- method `kaname` not found for this
 ...
 LL |     let Some(ref madoka) = Some(homura.kaname());
-   |                                        ^^^^^^
+   |                                        ^^^^^^ method not found in `Homura`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-2149.stderr b/src/test/ui/issues/issue-2149.stderr
index 1df32aafa79c8..8ce2ba033321e 100644
--- a/src/test/ui/issues/issue-2149.stderr
+++ b/src/test/ui/issues/issue-2149.stderr
@@ -10,7 +10,7 @@ error[E0599]: no method named `bind` found for type `[&str; 1]` in the current s
   --> $DIR/issue-2149.rs:13:12
    |
 LL |     ["hi"].bind(|x| [x] );
-   |            ^^^^
+   |            ^^^^ method not found in `[&str; 1]`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `bind`, perhaps you need to implement it:
diff --git a/src/test/ui/issues/issue-21596.stderr b/src/test/ui/issues/issue-21596.stderr
index 8e4e09b13a9bd..4e5cace525787 100644
--- a/src/test/ui/issues/issue-21596.stderr
+++ b/src/test/ui/issues/issue-21596.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `to_string` found for type `*const u8` in the curr
   --> $DIR/issue-21596.rs:4:22
    |
 LL |     println!("{}", z.to_string());
-   |                      ^^^^^^^^^
+   |                      ^^^^^^^^^ method not found in `*const u8`
    |
    = note: try using `<*const T>::as_ref()` to get a reference to the type behind the pointer: https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref
    = note: using `<*const T>::as_ref()` on a pointer which is unaligned or points to invalid or uninitialized memory is undefined behavior
diff --git a/src/test/ui/issues/issue-25385.stderr b/src/test/ui/issues/issue-25385.stderr
index e170a9d383b0e..ab4db7e42a4b9 100644
--- a/src/test/ui/issues/issue-25385.stderr
+++ b/src/test/ui/issues/issue-25385.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `foo` found for type `i32` in the current scope
   --> $DIR/issue-25385.rs:2:23
    |
 LL |     ($e:expr) => { $e.foo() }
-   |                       ^^^
+   |                       ^^^ method not found in `i32`
 ...
 LL |     foo!(a);
    |     -------- in this macro invocation
@@ -11,7 +11,7 @@ error[E0599]: no method named `foo` found for type `i32` in the current scope
   --> $DIR/issue-25385.rs:10:15
    |
 LL |     foo!(1i32.foo());
-   |               ^^^
+   |               ^^^ method not found in `i32`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-2823.stderr b/src/test/ui/issues/issue-2823.stderr
index 4c1dfb8501a91..c9ede03003434 100644
--- a/src/test/ui/issues/issue-2823.stderr
+++ b/src/test/ui/issues/issue-2823.stderr
@@ -5,7 +5,7 @@ LL | struct C {
    | -------- method `clone` not found for this
 ...
 LL |     let _d = c.clone();
-   |                ^^^^^
+   |                ^^^^^ method not found in `C`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `clone`, perhaps you need to implement it:
diff --git a/src/test/ui/issues/issue-29124.stderr b/src/test/ui/issues/issue-29124.stderr
index 3beb728978884..c537c6118f3a8 100644
--- a/src/test/ui/issues/issue-29124.stderr
+++ b/src/test/ui/issues/issue-29124.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `x` found for type `fn() -> Ret {Obj::func}` in th
   --> $DIR/issue-29124.rs:15:15
    |
 LL |     Obj::func.x();
-   |               ^
+   |               ^ method not found in `fn() -> Ret {Obj::func}`
    |
    = note: Obj::func is a function, perhaps you wish to call it
 
@@ -10,7 +10,7 @@ error[E0599]: no method named `x` found for type `fn() -> Ret {func}` in the cur
   --> $DIR/issue-29124.rs:17:10
    |
 LL |     func.x();
-   |          ^
+   |          ^ method not found in `fn() -> Ret {func}`
    |
    = note: func is a function, perhaps you wish to call it
 
diff --git a/src/test/ui/issues/issue-29181.stderr b/src/test/ui/issues/issue-29181.stderr
index 092014281546f..250b158ab8e33 100644
--- a/src/test/ui/issues/issue-29181.stderr
+++ b/src/test/ui/issues/issue-29181.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `homura` found for type `{integer}` in the current
   --> $DIR/issue-29181.rs:6:7
    |
 LL |     0.homura();
-   |       ^^^^^^
+   |       ^^^^^^ method not found in `{integer}`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-31173.stderr b/src/test/ui/issues/issue-31173.stderr
index 3ca8338882681..6d03b7810939a 100644
--- a/src/test/ui/issues/issue-31173.stderr
+++ b/src/test/ui/issues/issue-31173.stderr
@@ -11,7 +11,7 @@ error[E0599]: no method named `collect` found for type `std::iter::Cloned<std::i
   --> $DIR/issue-31173.rs:14:10
    |
 LL |         .collect();
-   |          ^^^^^^^
+   |          ^^^^^^^ method not found in `std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6 found_e:_]>>`
    |
    = note: the method `collect` exists but the following trait bounds were not satisfied:
            `&mut std::iter::Cloned<std::iter::TakeWhile<&mut std::vec::IntoIter<u8>, [closure@$DIR/issue-31173.rs:6:39: 9:6 found_e:_]>> : std::iter::Iterator`
diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr
index 7f89caf92abe1..8d52e08374ac7 100644
--- a/src/test/ui/issues/issue-34334.stderr
+++ b/src/test/ui/issues/issue-34334.stderr
@@ -45,7 +45,7 @@ error[E0599]: no method named `iter` found for type `()` in the current scope
   --> $DIR/issue-34334.rs:9:36
    |
 LL |     let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
-   |                                    ^^^^
+   |                                    ^^^^ method not found in `()`
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/issues/issue-35677.stderr b/src/test/ui/issues/issue-35677.stderr
index 99d99db93f3e3..b381203856e92 100644
--- a/src/test/ui/issues/issue-35677.stderr
+++ b/src/test/ui/issues/issue-35677.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `is_subset` found for type `&std::collections::Has
   --> $DIR/issue-35677.rs:4:10
    |
 LL |     this.is_subset(other)
-   |          ^^^^^^^^^
+   |          ^^^^^^^^^ method not found in `&std::collections::HashSet<T>`
    |
    = note: the method `is_subset` exists but the following trait bounds were not satisfied:
            `T : std::cmp::Eq`
diff --git a/src/test/ui/issues/issue-39175.stderr b/src/test/ui/issues/issue-39175.stderr
index 108c969cdadde..66680b9936e68 100644
--- a/src/test/ui/issues/issue-39175.stderr
+++ b/src/test/ui/issues/issue-39175.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `exec` found for type `&mut std::process::Command`
   --> $DIR/issue-39175.rs:15:39
    |
 LL |     Command::new("echo").arg("hello").exec();
-   |                                       ^^^^
+   |                                       ^^^^ method not found in `&mut std::process::Command`
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/issues/issue-41880.stderr b/src/test/ui/issues/issue-41880.stderr
index 359a2340240a7..0e1d55c339eb4 100644
--- a/src/test/ui/issues/issue-41880.stderr
+++ b/src/test/ui/issues/issue-41880.stderr
@@ -5,7 +5,7 @@ LL | pub struct Iterate<T, F> {
    | ------------------------ method `iter` not found for this
 ...
 LL |     println!("{:?}", a.iter().take(10).collect::<Vec<usize>>());
-   |                        ^^^^
+   |                        ^^^^ method not found in `Iterate<{integer}, [closure@$DIR/issue-41880.rs:26:24: 26:31]>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-43189.stderr b/src/test/ui/issues/issue-43189.stderr
index e364650da40a1..33c3f18650a80 100644
--- a/src/test/ui/issues/issue-43189.stderr
+++ b/src/test/ui/issues/issue-43189.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `a` found for type `()` in the current scope
   --> $DIR/issue-43189.rs:10:8
    |
 LL |     ().a();
-   |        ^
+   |        ^ method not found in `()`
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
index 2c3a18be67c8f..29fd15fb396e9 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `as_deref_mut` found for type `std::option::Option
   --> $DIR/option-as_deref_mut.rs:4:33
    |
 LL |     let _result = &mut Some(42).as_deref_mut();
-   |                                 ^^^^^^^^^^^^
+   |                                 ^^^^^^^^^^^^ method not found in `std::option::Option<{integer}>`
    |
    = note: the method `as_deref_mut` exists but the following trait bounds were not satisfied:
            `{integer} : std::ops::DerefMut`
diff --git a/src/test/ui/issues/issue-5153.stderr b/src/test/ui/issues/issue-5153.stderr
index 97214fbdc52d4..5034e6d538e3e 100644
--- a/src/test/ui/issues/issue-5153.stderr
+++ b/src/test/ui/issues/issue-5153.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `foo` found for type `&dyn Foo` in the current sco
   --> $DIR/issue-5153.rs:10:27
    |
 LL |     (&5isize as &dyn Foo).foo();
-   |                           ^^^
+   |                           ^^^ method not found in `&dyn Foo`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `foo`, perhaps you need to implement it:
diff --git a/src/test/ui/issues/issue-54062.stderr b/src/test/ui/issues/issue-54062.stderr
index 082ac91edb1c4..3830ad4b1e3ae 100644
--- a/src/test/ui/issues/issue-54062.stderr
+++ b/src/test/ui/issues/issue-54062.stderr
@@ -8,7 +8,7 @@ error[E0599]: no method named `unwrap` found for type `std::sys_common::mutex::M
   --> $DIR/issue-54062.rs:10:37
    |
 LL |     let _ = test.comps.inner.lock().unwrap();
-   |                                     ^^^^^^
+   |                                     ^^^^^^ method not found in `std::sys_common::mutex::MutexGuard<'_>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-57362-1.stderr b/src/test/ui/issues/issue-57362-1.stderr
index 1d2ff7669c093..c4000c8a9d41e 100644
--- a/src/test/ui/issues/issue-57362-1.stderr
+++ b/src/test/ui/issues/issue-57362-1.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `f` found for type `fn(&u8)` in the current scope
   --> $DIR/issue-57362-1.rs:20:7
    |
 LL |     a.f();
-   |       ^
+   |       ^ method not found in `fn(&u8)`
    |
    = note: a is a function, perhaps you wish to call it
    = help: items from traits can only be used if the trait is implemented and in scope
diff --git a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
index 015e05ed9bf61..96054de801c1f 100644
--- a/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
+++ b/src/test/ui/macros/macro-backtrace-invalid-internals.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `fake` found for type `{integer}` in the current s
   --> $DIR/macro-backtrace-invalid-internals.rs:5:13
    |
 LL |           1.fake()
-   |             ^^^^
+   |             ^^^^ method not found in `{integer}`
 ...
 LL |     fake_method_stmt!();
    |     -------------------- in this macro invocation
@@ -42,7 +42,7 @@ error[E0599]: no method named `fake` found for type `{integer}` in the current s
   --> $DIR/macro-backtrace-invalid-internals.rs:23:13
    |
 LL |           1.fake()
-   |             ^^^^
+   |             ^^^^ method not found in `{integer}`
 ...
 LL |     let _ = fake_method_expr!();
    |             ------------------- in this macro invocation
diff --git a/src/test/ui/methods/method-call-err-msg.stderr b/src/test/ui/methods/method-call-err-msg.stderr
index b8ae4c34dc155..94c27b7d17865 100644
--- a/src/test/ui/methods/method-call-err-msg.stderr
+++ b/src/test/ui/methods/method-call-err-msg.stderr
@@ -32,7 +32,7 @@ LL | pub struct Foo;
    | --------------- method `take` not found for this
 ...
 LL |      .take()
-   |       ^^^^
+   |       ^^^^ method not found in `Foo`
    |
    = note: the method `take` exists but the following trait bounds were not satisfied:
            `&mut Foo : std::iter::Iterator`
diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr
index 3f87ef74b8ea3..89c7b0981158a 100644
--- a/src/test/ui/mismatched_types/issue-36053-2.stderr
+++ b/src/test/ui/mismatched_types/issue-36053-2.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `count` found for type `std::iter::Filter<std::ite
   --> $DIR/issue-36053-2.rs:7:55
    |
 LL |     once::<&str>("str").fuse().filter(|a: &str| true).count();
-   |                                                       ^^^^^
+   |                                                       ^^^^^ method not found in `std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>`
    |
    = note: the method `count` exists but the following trait bounds were not satisfied:
            `&mut std::iter::Filter<std::iter::Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]> : std::iter::Iterator`
diff --git a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
index 9721dc8ba4e6c..865092e4e9ccc 100644
--- a/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
+++ b/src/test/ui/mismatched_types/method-help-unsatisfied-bound.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `unwrap` found for type `std::result::Result<(), F
   --> $DIR/method-help-unsatisfied-bound.rs:5:7
    |
 LL |     a.unwrap();
-   |       ^^^^^^
+   |       ^^^^^^ method not found in `std::result::Result<(), Foo>`
    |
    = note: the method `unwrap` exists but the following trait bounds were not satisfied:
            `Foo : std::fmt::Debug`
diff --git a/src/test/ui/non-copyable-void.stderr b/src/test/ui/non-copyable-void.stderr
index 4041e1935dcb7..b05c29c0d4036 100644
--- a/src/test/ui/non-copyable-void.stderr
+++ b/src/test/ui/non-copyable-void.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `clone` found for type `libc::c_void` in the curre
   --> $DIR/non-copyable-void.rs:11:23
    |
 LL |         let _z = (*y).clone();
-   |                       ^^^^^
+   |                       ^^^^^ method not found in `libc::c_void`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/noncopyable-class.stderr b/src/test/ui/noncopyable-class.stderr
index eb47a33a7292b..c1c5021138189 100644
--- a/src/test/ui/noncopyable-class.stderr
+++ b/src/test/ui/noncopyable-class.stderr
@@ -5,7 +5,7 @@ LL | struct Foo {
    | ---------- method `clone` not found for this
 ...
 LL |     let _y = x.clone();
-   |                ^^^^^
+   |                ^^^^^ method not found in `Foo`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `clone`, perhaps you need to implement it:
diff --git a/src/test/ui/object-pointer-types.stderr b/src/test/ui/object-pointer-types.stderr
index 0c7e4e991a51d..2df628ecf8e50 100644
--- a/src/test/ui/object-pointer-types.stderr
+++ b/src/test/ui/object-pointer-types.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `owned` found for type `&dyn Foo` in the current s
   --> $DIR/object-pointer-types.rs:11:7
    |
 LL |     x.owned();
-   |       ^^^^^
+   |       ^^^^^ method not found in `&dyn Foo`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `owned`, perhaps you need to implement it:
@@ -12,7 +12,7 @@ error[E0599]: no method named `owned` found for type `&mut dyn Foo` in the curre
   --> $DIR/object-pointer-types.rs:17:7
    |
 LL |     x.owned();
-   |       ^^^^^
+   |       ^^^^^ method not found in `&mut dyn Foo`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `owned`, perhaps you need to implement it:
@@ -22,7 +22,7 @@ error[E0599]: no method named `managed` found for type `std::boxed::Box<(dyn Foo
   --> $DIR/object-pointer-types.rs:23:7
    |
 LL |     x.managed();
-   |       ^^^^^^^
+   |       ^^^^^^^ method not found in `std::boxed::Box<(dyn Foo + 'static)>`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/rust-2018/trait-import-suggestions.stderr b/src/test/ui/rust-2018/trait-import-suggestions.stderr
index a81181228dfda..19f758fd8da77 100644
--- a/src/test/ui/rust-2018/trait-import-suggestions.stderr
+++ b/src/test/ui/rust-2018/trait-import-suggestions.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `foobar` found for type `u32` in the current scope
   --> $DIR/trait-import-suggestions.rs:22:11
    |
 LL |         x.foobar();
-   |           ^^^^^^
+   |           ^^^^^^ method not found in `u32`
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
@@ -12,7 +12,7 @@ error[E0599]: no method named `bar` found for type `u32` in the current scope
   --> $DIR/trait-import-suggestions.rs:28:7
    |
 LL |     x.bar();
-   |       ^^^
+   |       ^^^ method not found in `u32`
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope, perhaps add a `use` for it:
@@ -24,7 +24,7 @@ error[E0599]: no method named `baz` found for type `u32` in the current scope
   --> $DIR/trait-import-suggestions.rs:29:7
    |
 LL |     x.baz();
-   |       ^^^
+   |       ^^^ method not found in `u32`
 
 error[E0599]: no function or associated item named `from_str` found for type `u32` in the current scope
   --> $DIR/trait-import-suggestions.rs:30:18
diff --git a/src/test/ui/self/point-at-arbitrary-self-type-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr
index 06dad7caa6735..dec5809f1539b 100644
--- a/src/test/ui/self/point-at-arbitrary-self-type-method.stderr
+++ b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr
@@ -8,7 +8,7 @@ LL |     fn foo(self: Box<Self>) {}
    |        --- the method is available for `std::boxed::Box<A>` here
 ...
 LL |     A.foo();
-   |       ^^^
+   |       ^^^ method not found in `A`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr
index 90cd3b8074580..e93c4da9dfc85 100644
--- a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr
+++ b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr
@@ -7,7 +7,7 @@ LL | struct A;
    | --------- method `foo` not found for this
 ...
 LL |     A.foo()
-   |       ^^^
+   |       ^^^ method not found in `A`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `foo`, perhaps you need to implement it:
diff --git a/src/test/ui/shadowed/shadowed-trait-methods.stderr b/src/test/ui/shadowed/shadowed-trait-methods.stderr
index e05da17983f83..190159ec7b88d 100644
--- a/src/test/ui/shadowed/shadowed-trait-methods.stderr
+++ b/src/test/ui/shadowed/shadowed-trait-methods.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `f` found for type `()` in the current scope
   --> $DIR/shadowed-trait-methods.rs:13:8
    |
 LL |     ().f()
-   |        ^
+   |        ^ method not found in `()`
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
index c14fc04f631fc..bbfe4c3d59dcf 100644
--- a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
+++ b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr
@@ -5,7 +5,7 @@ LL | struct MyStruct;
    | ---------------- method `foo_one` not found for this
 ...
 LL |     println!("{}", MyStruct.foo_one());
-   |                             ^^^^^^^
+   |                             ^^^^^^^ method not found in `MyStruct`
    |
    = note: the method `foo_one` exists but the following trait bounds were not satisfied:
            `MyStruct : Foo`
diff --git a/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr
index 48c2503e8eb32..4aec72006eef0 100644
--- a/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr
+++ b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `hello` found for type `impl Foo` in the current s
   --> $DIR/impl-trait-with-missing-trait-bounds-in-arg.rs:15:9
    |
 LL |     foo.hello();
-   |         ^^^^^
+   |         ^^^^^ method not found in `impl Foo`
    |
    = help: items from traits can only be used if the type parameter is bounded by the trait
 help: the following trait defines an item `hello`, perhaps you need to restrict type parameter `impl Foo` with it:
diff --git a/src/test/ui/suggestions/issue-21673.stderr b/src/test/ui/suggestions/issue-21673.stderr
index 6cf71c8b7c53b..f2496f696d698 100644
--- a/src/test/ui/suggestions/issue-21673.stderr
+++ b/src/test/ui/suggestions/issue-21673.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `method` found for type `&T` in the current scope
   --> $DIR/issue-21673.rs:6:7
    |
 LL |     x.method()
-   |       ^^^^^^
+   |       ^^^^^^ method not found in `&T`
    |
    = help: items from traits can only be used if the type parameter is bounded by the trait
 help: the following trait defines an item `method`, perhaps you need to restrict type parameter `T` with it:
@@ -14,7 +14,7 @@ error[E0599]: no method named `method` found for type `T` in the current scope
   --> $DIR/issue-21673.rs:10:7
    |
 LL |     x.method()
-   |       ^^^^^^
+   |       ^^^^^^ method not found in `T`
    |
    = help: items from traits can only be used if the type parameter is bounded by the trait
 help: the following trait defines an item `method`, perhaps you need to restrict type parameter `T` with it:
diff --git a/src/test/ui/suggestions/suggest-methods.stderr b/src/test/ui/suggestions/suggest-methods.stderr
index ad4a4deb5a886..4678410eb4859 100644
--- a/src/test/ui/suggestions/suggest-methods.stderr
+++ b/src/test/ui/suggestions/suggest-methods.stderr
@@ -23,7 +23,7 @@ error[E0599]: no method named `count_o` found for type `u32` in the current scop
   --> $DIR/suggest-methods.rs:28:19
    |
 LL |     let _ = 63u32.count_o();
-   |                   ^^^^^^^
+   |                   ^^^^^^^ method not found in `u32`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/traits/trait-impl-1.stderr b/src/test/ui/traits/trait-impl-1.stderr
index 71d5cc26bf141..0d61c3ed00d90 100644
--- a/src/test/ui/traits/trait-impl-1.stderr
+++ b/src/test/ui/traits/trait-impl-1.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `foo` found for type `&i32` in the current scope
   --> $DIR/trait-impl-1.rs:15:7
    |
 LL |     x.foo();
-   |       ^^^
+   |       ^^^ method not found in `&i32`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr
index 16ea7bdb0807d..39cc66d275c24 100644
--- a/src/test/ui/traits/trait-item-privacy.stderr
+++ b/src/test/ui/traits/trait-item-privacy.stderr
@@ -5,7 +5,7 @@ LL | struct S;
    | --------- method `a` not found for this
 ...
 LL |     S.a();
-   |       ^
+   |       ^ method not found in `S`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `a`, perhaps you need to implement it:
@@ -25,7 +25,7 @@ LL |         fn b(&self) { }
    |            the method is available for `std::rc::Rc<S>` here
 ...
 LL |     S.b();
-   |       ^
+   |       ^ method not found in `S`
    |
    = help: items from traits can only be used if the trait is in scope
 help: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
index f0f048159ec73..d172d5ecc4b70 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
+++ b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
@@ -12,7 +12,7 @@ error[E0599]: no method named `test` found for type `i32` in the current scope
   --> $DIR/trivial-bounds-leak.rs:24:10
    |
 LL |     3i32.test();
-   |          ^^^^
+   |          ^^^^ method not found in `i32`
    |
    = help: items from traits can only be used if the trait is implemented and in scope
    = note: the following trait defines an item `test`, perhaps you need to implement it:
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr
index 2e1845888a2f7..18276d5710cf8 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `call` found for type `[closure@$DIR/unboxed-closu
   --> $DIR/unboxed-closures-static-call-wrong-trait.rs:7:10
    |
 LL |     mut_.call((0, ));
-   |          ^^^^
+   |          ^^^^ method not found in `[closure@$DIR/unboxed-closures-static-call-wrong-trait.rs:6:26: 6:31]`
    |
    = note: mut_ is a function, perhaps you wish to call it
 
diff --git a/src/test/ui/underscore-imports/shadow.stderr b/src/test/ui/underscore-imports/shadow.stderr
index 92adca2c70490..63262d0dc326d 100644
--- a/src/test/ui/underscore-imports/shadow.stderr
+++ b/src/test/ui/underscore-imports/shadow.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `deref` found for type `&()` in the current scope
   --> $DIR/shadow.rs:19:11
    |
 LL |         x.deref();
-   |           ^^^^^
+   |           ^^^^^ method not found in `&()`
    |
    = help: items from traits can only be used if the trait is in scope
    = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
diff --git a/src/test/ui/union/union-derive-clone.stderr b/src/test/ui/union/union-derive-clone.stderr
index 37a0093784048..4f4c779b12bb3 100644
--- a/src/test/ui/union/union-derive-clone.stderr
+++ b/src/test/ui/union/union-derive-clone.stderr
@@ -13,7 +13,7 @@ LL | union U4<T> {
    | ----------- method `clone` not found for this
 ...
 LL |     let w = u.clone();
-   |               ^^^^^
+   |               ^^^^^ method not found in `U4<CloneNoCopy>`
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `U4<CloneNoCopy> : std::clone::Clone`
diff --git a/src/test/ui/unique-object-noncopyable.stderr b/src/test/ui/unique-object-noncopyable.stderr
index 407905f52e750..cd46878c19be4 100644
--- a/src/test/ui/unique-object-noncopyable.stderr
+++ b/src/test/ui/unique-object-noncopyable.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `clone` found for type `std::boxed::Box<dyn Foo>`
   --> $DIR/unique-object-noncopyable.rs:24:16
    |
 LL |     let _z = y.clone();
-   |                ^^^^^
+   |                ^^^^^ method not found in `std::boxed::Box<dyn Foo>`
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `std::boxed::Box<dyn Foo> : std::clone::Clone`
diff --git a/src/test/ui/unique-pinned-nocopy.stderr b/src/test/ui/unique-pinned-nocopy.stderr
index 0f6ba90afacf4..19ef2b21c2685 100644
--- a/src/test/ui/unique-pinned-nocopy.stderr
+++ b/src/test/ui/unique-pinned-nocopy.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `clone` found for type `std::boxed::Box<R>` in the
   --> $DIR/unique-pinned-nocopy.rs:12:16
    |
 LL |     let _j = i.clone();
-   |                ^^^^^
+   |                ^^^^^ method not found in `std::boxed::Box<R>`
    |
    = note: the method `clone` exists but the following trait bounds were not satisfied:
            `std::boxed::Box<R> : std::clone::Clone`

From c1b9a46f60440e2207f458e276b38239b1651a22 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 9 Sep 2019 14:06:14 +1000
Subject: [PATCH 626/943] Add some assertions on obligation type sizes.

These are types that get memcpy'd a lot.
---
 src/librustc/traits/fulfill.rs | 4 ++++
 src/librustc/traits/mod.rs     | 8 ++++++++
 2 files changed, 12 insertions(+)

diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index c1de4939c1d91..a59ea19896364 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -68,6 +68,10 @@ pub struct PendingPredicateObligation<'tcx> {
     pub stalled_on: Vec<Ty<'tcx>>,
 }
 
+// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
+#[cfg(target_arch = "x86_64")]
+static_assert_size!(PendingPredicateObligation<'_>, 160);
+
 impl<'a, 'tcx> FulfillmentContext<'tcx> {
     /// Creates a new fulfillment context.
     pub fn new() -> FulfillmentContext<'tcx> {
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 1ca92d79fa5f6..f43fbbfee3e91 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -123,6 +123,10 @@ pub struct Obligation<'tcx, T> {
 pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
 pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
 
+// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
+#[cfg(target_arch = "x86_64")]
+static_assert_size!(PredicateObligation<'_>, 136);
+
 /// The reason why we incurred this obligation; used for error reporting.
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub struct ObligationCause<'tcx> {
@@ -269,6 +273,10 @@ pub enum ObligationCauseCode<'tcx> {
     TrivialBound,
 }
 
+// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
+#[cfg(target_arch = "x86_64")]
+static_assert_size!(ObligationCauseCode<'_>, 56);
+
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub struct DerivedObligationCause<'tcx> {
     /// The trait reference of the parent obligation that led to the

From b972ac818c98373b6d045956b049dc34932c41be Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Fri, 6 Sep 2019 16:55:19 +1000
Subject: [PATCH 627/943] Shrink `ObligationCauseCode` by boxing
 `MatchExpressionArm`.

The reduction in `memcpy` calls greatly outweighs the cost of the extra
allocations, for a net performance win.
---
 src/librustc/infer/error_reporting/mod.rs | 24 ++++++++++++-----------
 src/librustc/traits/fulfill.rs            |  2 +-
 src/librustc/traits/mod.rs                | 24 +++++++++++++----------
 src/librustc/traits/structural_impls.rs   |  8 ++++----
 src/librustc_typeck/check/_match.rs       | 18 +++++++++--------
 5 files changed, 42 insertions(+), 34 deletions(-)

diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 5883be6e26883..684e799b40319 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -55,7 +55,7 @@ use crate::hir::def_id::DefId;
 use crate::hir::Node;
 use crate::infer::opaque_types;
 use crate::middle::region;
-use crate::traits::{ObligationCause, ObligationCauseCode};
+use crate::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode};
 use crate::ty::error::TypeError;
 use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TypeFoldable};
 use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
@@ -624,13 +624,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     }
                 }
             }
-            ObligationCauseCode::MatchExpressionArm {
+            ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
                 source,
                 ref prior_arms,
                 last_ty,
                 discrim_hir_id,
                 ..
-            } => match source {
+            }) => match source {
                 hir::MatchSource::IfLetDesugar { .. } => {
                     let msg = "`if let` arms have incompatible types";
                     err.span_label(cause.span, msg);
@@ -1622,13 +1622,15 @@ impl<'tcx> ObligationCause<'tcx> {
         use crate::traits::ObligationCauseCode::*;
         match self.code {
             CompareImplMethodObligation { .. } => Error0308("method not compatible with trait"),
-            MatchExpressionArm { source, .. } => Error0308(match source {
-                hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have incompatible types",
-                hir::MatchSource::TryDesugar => {
-                    "try expression alternatives have incompatible types"
-                }
-                _ => "match arms have incompatible types",
-            }),
+            MatchExpressionArm(box MatchExpressionArmCause { source, .. }) =>
+                Error0308(match source {
+                    hir::MatchSource::IfLetDesugar { .. } =>
+                        "`if let` arms have incompatible types",
+                    hir::MatchSource::TryDesugar => {
+                        "try expression alternatives have incompatible types"
+                    }
+                    _ => "match arms have incompatible types",
+                }),
             IfExpression { .. } => Error0308("if and else have incompatible types"),
             IfExpressionWithNoElse => Error0317("if may be missing an else clause"),
             MainFunctionType => Error0580("main function has wrong type"),
@@ -1656,7 +1658,7 @@ impl<'tcx> ObligationCause<'tcx> {
         match self.code {
             CompareImplMethodObligation { .. } => "method type is compatible with trait",
             ExprAssignable => "expression is assignable",
-            MatchExpressionArm { source, .. } => match source {
+            MatchExpressionArm(box MatchExpressionArmCause { source, .. }) => match source {
                 hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types",
                 _ => "match arms have compatible types",
             },
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index a59ea19896364..0b8de1f13d384 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -70,7 +70,7 @@ pub struct PendingPredicateObligation<'tcx> {
 
 // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(PendingPredicateObligation<'_>, 160);
+static_assert_size!(PendingPredicateObligation<'_>, 144);
 
 impl<'a, 'tcx> FulfillmentContext<'tcx> {
     /// Creates a new fulfillment context.
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index f43fbbfee3e91..548fb55098af1 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -125,7 +125,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
 
 // `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(PredicateObligation<'_>, 136);
+static_assert_size!(PredicateObligation<'_>, 120);
 
 /// The reason why we incurred this obligation; used for error reporting.
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -151,7 +151,8 @@ impl<'tcx> ObligationCause<'tcx> {
             ObligationCauseCode::StartFunctionType => {
                 tcx.sess.source_map().def_span(self.span)
             }
-            ObligationCauseCode::MatchExpressionArm { arm_span, .. } => arm_span,
+            ObligationCauseCode::MatchExpressionArm(
+                box MatchExpressionArmCause { arm_span, .. }) => arm_span,
             _ => self.span,
         }
     }
@@ -227,13 +228,7 @@ pub enum ObligationCauseCode<'tcx> {
     ExprAssignable,
 
     /// Computing common supertype in the arms of a match expression
-    MatchExpressionArm {
-        arm_span: Span,
-        source: hir::MatchSource,
-        prior_arms: Vec<Span>,
-        last_ty: Ty<'tcx>,
-        discrim_hir_id: hir::HirId,
-    },
+    MatchExpressionArm(Box<MatchExpressionArmCause<'tcx>>),
 
     /// Computing common supertype in the pattern guard for the arms of a match expression
     MatchExpressionArmPattern { span: Span, ty: Ty<'tcx> },
@@ -275,7 +270,16 @@ pub enum ObligationCauseCode<'tcx> {
 
 // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(ObligationCauseCode<'_>, 56);
+static_assert_size!(ObligationCauseCode<'_>, 40);
+
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct MatchExpressionArmCause<'tcx> {
+    pub arm_span: Span,
+    pub source: hir::MatchSource,
+    pub prior_arms: Vec<Span>,
+    pub last_ty: Ty<'tcx>,
+    pub discrim_hir_id: hir::HirId,
+}
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub struct DerivedObligationCause<'tcx> {
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 05b698eb4c4ea..56324baffa038 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -508,21 +508,21 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
                 trait_item_def_id,
             }),
             super::ExprAssignable => Some(super::ExprAssignable),
-            super::MatchExpressionArm {
+            super::MatchExpressionArm(box super::MatchExpressionArmCause {
                 arm_span,
                 source,
                 ref prior_arms,
                 last_ty,
                 discrim_hir_id,
-            } => {
+            }) => {
                 tcx.lift(&last_ty).map(|last_ty| {
-                    super::MatchExpressionArm {
+                    super::MatchExpressionArm(box super::MatchExpressionArmCause {
                         arm_span,
                         source,
                         prior_arms: prior_arms.clone(),
                         last_ty,
                         discrim_hir_id,
-                    }
+                    })
                 })
             }
             super::MatchExpressionArmPattern { span, ty } => {
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 7427ae9ce8de3..8ce08f523a1b0 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -2,7 +2,7 @@ use crate::check::{FnCtxt, Expectation, Diverges, Needs};
 use crate::check::coercion::CoerceMany;
 use rustc::hir::{self, ExprKind};
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc::traits::{ObligationCause, ObligationCauseCode};
+use rustc::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode};
 use rustc::ty::Ty;
 use syntax_pos::Span;
 
@@ -146,13 +146,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // The reason for the first arm to fail is not that the match arms diverge,
                     // but rather that there's a prior obligation that doesn't hold.
                     0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)),
-                    _ => (expr.span, ObligationCauseCode::MatchExpressionArm {
-                        arm_span,
-                        source: match_src,
-                        prior_arms: other_arms.clone(),
-                        last_ty: prior_arm_ty.unwrap(),
-                        discrim_hir_id: discrim.hir_id,
-                    }),
+                    _ => (expr.span,
+                          ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
+                            arm_span,
+                            source: match_src,
+                            prior_arms: other_arms.clone(),
+                            last_ty: prior_arm_ty.unwrap(),
+                            discrim_hir_id: discrim.hir_id,
+                          })
+                         ),
                 };
                 let cause = self.cause(span, code);
                 coercion.coerce(self, &cause, &arm.body, arm_ty);

From 2e3b079836823446eb014c69866d6a0f8cca4ef2 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 9 Sep 2019 12:40:54 +1000
Subject: [PATCH 628/943] Shrink `ObligationCauseCode` by boxing
 `IfExpression`.

The reduction in `memcpy` calls outweighs the cost of the extra
allocations, for a net performance win.
---
 src/librustc/infer/error_reporting/mod.rs |  5 +++--
 src/librustc/traits/fulfill.rs            |  2 +-
 src/librustc/traits/mod.rs                | 17 ++++++++++-------
 src/librustc/traits/structural_impls.rs   | 12 +++++++-----
 src/librustc_typeck/check/_match.rs       |  7 ++++---
 5 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 684e799b40319..ab24b3f2f059f 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -55,7 +55,8 @@ use crate::hir::def_id::DefId;
 use crate::hir::Node;
 use crate::infer::opaque_types;
 use crate::middle::region;
-use crate::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode};
+use crate::traits::{IfExpressionCause, MatchExpressionArmCause, ObligationCause};
+use crate::traits::{ObligationCauseCode};
 use crate::ty::error::TypeError;
 use crate::ty::{self, subst::{Subst, SubstsRef}, Region, Ty, TyCtxt, TypeFoldable};
 use errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString};
@@ -681,7 +682,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     }
                 }
             },
-            ObligationCauseCode::IfExpression { then, outer, semicolon } => {
+            ObligationCauseCode::IfExpression(box IfExpressionCause { then, outer, semicolon }) => {
                 err.span_label(then, "expected because of this");
                 outer.map(|sp| err.span_label(sp, "if and else have incompatible types"));
                 if let Some(sp) = semicolon {
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 0b8de1f13d384..4494c034d51e2 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -70,7 +70,7 @@ pub struct PendingPredicateObligation<'tcx> {
 
 // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(PendingPredicateObligation<'_>, 144);
+static_assert_size!(PendingPredicateObligation<'_>, 136);
 
 impl<'a, 'tcx> FulfillmentContext<'tcx> {
     /// Creates a new fulfillment context.
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 548fb55098af1..d2683090add40 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -125,7 +125,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
 
 // `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(PredicateObligation<'_>, 120);
+static_assert_size!(PredicateObligation<'_>, 112);
 
 /// The reason why we incurred this obligation; used for error reporting.
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -234,11 +234,7 @@ pub enum ObligationCauseCode<'tcx> {
     MatchExpressionArmPattern { span: Span, ty: Ty<'tcx> },
 
     /// Computing common supertype in an if expression
-    IfExpression {
-        then: Span,
-        outer: Option<Span>,
-        semicolon: Option<Span>,
-    },
+    IfExpression(Box<IfExpressionCause>),
 
     /// Computing common supertype of an if expression with no else counter-part
     IfExpressionWithNoElse,
@@ -270,7 +266,7 @@ pub enum ObligationCauseCode<'tcx> {
 
 // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(ObligationCauseCode<'_>, 40);
+static_assert_size!(ObligationCauseCode<'_>, 32);
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub struct MatchExpressionArmCause<'tcx> {
@@ -281,6 +277,13 @@ pub struct MatchExpressionArmCause<'tcx> {
     pub discrim_hir_id: hir::HirId,
 }
 
+#[derive(Clone, Debug, PartialEq, Eq, Hash)]
+pub struct IfExpressionCause {
+    pub then: Span,
+    pub outer: Option<Span>,
+    pub semicolon: Option<Span>,
+}
+
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub struct DerivedObligationCause<'tcx> {
     /// The trait reference of the parent obligation that led to the
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 56324baffa038..6930c9368282b 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -528,11 +528,13 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
             super::MatchExpressionArmPattern { span, ty } => {
                 tcx.lift(&ty).map(|ty| super::MatchExpressionArmPattern { span, ty })
             }
-            super::IfExpression { then, outer, semicolon } => Some(super::IfExpression {
-                then,
-                outer,
-                semicolon,
-            }),
+            super::IfExpression(box super::IfExpressionCause { then, outer, semicolon }) => {
+                Some(super::IfExpression(box super::IfExpressionCause {
+                    then,
+                    outer,
+                    semicolon,
+                }))
+            }
             super::IfExpressionWithNoElse => Some(super::IfExpressionWithNoElse),
             super::MainFunctionType => Some(super::MainFunctionType),
             super::StartFunctionType => Some(super::StartFunctionType),
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 8ce08f523a1b0..308a3d8ebc2cf 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -2,7 +2,8 @@ use crate::check::{FnCtxt, Expectation, Diverges, Needs};
 use crate::check::coercion::CoerceMany;
 use rustc::hir::{self, ExprKind};
 use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode};
+use rustc::traits::{IfExpressionCause, MatchExpressionArmCause, ObligationCause};
+use rustc::traits::{ObligationCauseCode};
 use rustc::ty::Ty;
 use syntax_pos::Span;
 
@@ -347,11 +348,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         // Finally construct the cause:
-        self.cause(error_sp, ObligationCauseCode::IfExpression {
+        self.cause(error_sp, ObligationCauseCode::IfExpression(box IfExpressionCause {
             then: then_sp,
             outer: outer_sp,
             semicolon: remove_semicolon,
-        })
+        }))
     }
 
     fn demand_discriminant_type(

From cfcc5c296ed6fabcc8b9d380eaaea8a7352299fd Mon Sep 17 00:00:00 2001
From: Erin Power <xampprocky@gmail.com>
Date: Sun, 8 Sep 2019 13:52:29 +0200
Subject: [PATCH 629/943] Updated RELEASES.md for 1.38.0

---
 RELEASES.md | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 105 insertions(+)

diff --git a/RELEASES.md b/RELEASES.md
index f26f6e6c888ed..d634feba33ac5 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,108 @@
+Version 1.38.0 (2019-09-26)
+==========================
+
+Language
+--------
+- [The `#[global_allocator]` attribute can now be used in submodules.][62735]
+- [The `#[deprecated]` attribute can now be used on macros.][62042]
+
+Compiler
+--------
+- [Added pipelined compilation support to `rustc`.][62766] This will
+  improve compilation times in some cases. For further information please refer
+  to the [_"Evaluating pipelined rustc compilation"_][pipeline-internals] thread.
+- [Added tier 3\* support for the `aarch64-uwp-windows-msvc`, `i686-uwp-windows-gnu`,
+  `i686-uwp-windows-msvc`, `x86_64-uwp-windows-gnu`, and
+  `x86_64-uwp-windows-msvc` targets.][60260]
+- [Added tier 3 support for the `armv7-unknown-linux-gnueabi` and
+  `armv7-unknown-linux-musleabi` targets.][63107]
+- [Added tier 3 support for the `hexagon-unknown-linux-musl` target.][62814]
+- [Added tier 3 support for the `riscv32i-unknown-none-elf` target.][62784]
+
+\* Refer to Rust's [platform support page][forge-platform-support] for more
+information on Rust's tiered platform support.
+
+Libraries
+---------
+- [`ascii::EscapeDefault` now implements `Clone` and `Display`.][63421]
+- [Derive macros for prelude traits (e.g. `Clone`, `Debug`, `Hash`) are now
+  available at the same path as the trait.][63056] (e.g. The `Clone` derive macro
+  is available at `std::clone::Clone`). This also makes all built-in macros
+  available in `std`/`core` root. e.g. `std::include_bytes!`.
+- [`str::Chars` now implements `Debug`.][63000]
+- [`slice::{concat, connect, join}` now accepts `&[T]` in addition to `&T`.][62528]
+- [`*const T` and `*mut T` now implement `marker::Unpin`.][62583]
+- [`Arc<[T]>` and `Rc<[T]>` now implement `FromIterator<T>`.][61953]
+- [Added euclidean remainder and division operations (`div_euclid`,
+  `rem_euclid`) to all numeric primitives.][61884] Additionally `checked`,
+  `overflowing`, and `wrapping` versions are available for all
+  integer primitives.
+- [`thread::AccessError` now implements `Clone`, `Copy`, `Eq`, `Error`, and
+  `PartialEq`.][61491]
+- [`iter::{StepBy, Peekable, Take}` now implement `DoubleEndedIterator`.][61457]
+
+Stabilized APIs
+---------------
+- [`<*const T>::cast`]
+- [`<*mut T>::cast`]
+- [`Duration::as_secs_f32`]
+- [`Duration::as_secs_f64`]
+- [`Duration::div_duration_f32`]
+- [`Duration::div_duration_f64`]
+- [`Duration::div_f32`]
+- [`Duration::div_f64`]
+- [`Duration::from_secs_f32`]
+- [`Duration::from_secs_f64`]
+- [`Duration::mul_f32`]
+- [`Duration::mul_f64`]
+- [`any::type_name`]
+
+Cargo
+-----
+- [Added pipelined compilation support to `cargo`.][cargo/7143]
+- [You can now pass the `--features` option multiple times to enable
+  multiple features.][cargo/7084]
+
+Misc
+----
+- [`rustc` will now warn about some incorrect uses of
+  `mem::{uninitialized, zeroed}` that are known to cause undefined behaviour.][63346]
+
+[60260]: https://github.com/rust-lang/rust/pull/60260/
+[61457]: https://github.com/rust-lang/rust/pull/61457/
+[61491]: https://github.com/rust-lang/rust/pull/61491/
+[61884]: https://github.com/rust-lang/rust/pull/61884/
+[61953]: https://github.com/rust-lang/rust/pull/61953/
+[62042]: https://github.com/rust-lang/rust/pull/62042/
+[62528]: https://github.com/rust-lang/rust/pull/62528/
+[62583]: https://github.com/rust-lang/rust/pull/62583/
+[62735]: https://github.com/rust-lang/rust/pull/62735/
+[62766]: https://github.com/rust-lang/rust/pull/62766/
+[62784]: https://github.com/rust-lang/rust/pull/62784/
+[62814]: https://github.com/rust-lang/rust/pull/62814/
+[63000]: https://github.com/rust-lang/rust/pull/63000/
+[63056]: https://github.com/rust-lang/rust/pull/63056/
+[63107]: https://github.com/rust-lang/rust/pull/63107/
+[63346]: https://github.com/rust-lang/rust/pull/63346/
+[63421]: https://github.com/rust-lang/rust/pull/63421/
+[cargo/7084]: https://github.com/rust-lang/cargo/pull/7084/
+[cargo/7143]: https://github.com/rust-lang/cargo/pull/7143/
+[`<*const T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast
+[`<*mut T>::cast`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.cast
+[`Duration::as_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f32
+[`Duration::as_secs_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.as_secs_f64
+[`Duration::div_duration_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f32
+[`Duration::div_duration_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_duration_f64
+[`Duration::div_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f32
+[`Duration::div_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.div_f64
+[`Duration::from_secs_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_secs_f32
+[`Duration::from_secs_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.from_secs_f64
+[`Duration::mul_f32`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f32
+[`Duration::mul_f64`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.mul_f64
+[`any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html
+[forge-platform-support]: https://forge.rust-lang.org/platform-support.html
+[pipeline-internals]: https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199
+
 Version 1.37.0 (2019-08-15)
 ==========================
 

From 4c62950d4fb98f71dae08d724c45e55835b80b51 Mon Sep 17 00:00:00 2001
From: Lukas <lukas-code@outlook.com>
Date: Mon, 9 Sep 2019 12:18:07 +0000
Subject: [PATCH 630/943] Fix typo in config.toml.example

---
 config.toml.example | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/config.toml.example b/config.toml.example
index 30e2ee1b9babf..848147c2974c1 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -184,7 +184,7 @@
 # default.
 #extended = false
 
-# Installs chosen set of extended tools if enables. By default builds all.
+# Installs chosen set of extended tools if enabled. By default builds all.
 # If chosen tool failed to build the installation fails.
 #tools = ["cargo", "rls", "clippy", "rustfmt", "analysis", "src"]
 

From 63a5f399aef46f94a24e0d0a3b03eb7f66a33800 Mon Sep 17 00:00:00 2001
From: Caio <c410.f3r@gmail.com>
Date: Mon, 9 Sep 2019 09:26:25 -0300
Subject: [PATCH 631/943] Resolve attributes in several places

Arm, Field, FieldPat, GenericParam, Param, StructField and Variant
---
 src/librustc/hir/map/def_collector.rs         |  58 ++++-
 src/librustc_resolve/build_reduced_graph.rs   | 139 ++++++++----
 src/librustc_resolve/lib.rs                   |   5 +
 src/librustc_resolve/macros.rs                |  22 +-
 src/librustc_typeck/collect.rs                |   6 +-
 src/libsyntax/ast.rs                          |  10 +-
 src/libsyntax/ext/base.rs                     | 140 ++++++++++++
 src/libsyntax/ext/build.rs                    |   9 +-
 src/libsyntax/ext/expand.rs                   | 199 +++++++++++++++++-
 src/libsyntax/ext/placeholders.rs             | 145 +++++++++++++
 src/libsyntax/ext/proc_macro.rs               |   8 +
 src/libsyntax/mut_visit.rs                    |  13 +-
 src/libsyntax/parse/diagnostics.rs            |   9 +-
 src/libsyntax/parse/parser.rs                 |   9 +-
 src/libsyntax/parse/parser/expr.rs            |   6 +-
 src/libsyntax/parse/parser/generics.rs        |   7 +-
 src/libsyntax/parse/parser/item.rs            |   3 +
 src/libsyntax/parse/parser/pat.rs             |   1 +
 src/libsyntax/print/pprust/tests.rs           |   1 +
 src/libsyntax_ext/deriving/generic/mod.rs     |   1 +
 src/test/ui/attrs-resolution-errors.rs        |  40 ++++
 src/test/ui/attrs-resolution-errors.stderr    |  32 +++
 src/test/ui/attrs-resolution.rs               |  37 ++++
 .../cfg-generic-params.rs                     |  12 +-
 .../cfg-generic-params.stderr                 |  52 ++---
 .../feature-gate-custom_attribute2.rs         |  34 +--
 .../feature-gate-custom_attribute2.stderr     | 186 ++++++----------
 src/test/ui/issues/issue-49934-errors.rs      |  13 ++
 src/test/ui/issues/issue-49934-errors.stderr  |  26 +++
 src/test/ui/issues/issue-49934.rs             |   9 +-
 src/test/ui/issues/issue-49934.stderr         |  26 +--
 src/test/ui/proc-macro/proc-macro-gates2.rs   |   4 +-
 .../ui/proc-macro/proc-macro-gates2.stderr    |  11 +-
 .../param-attrs-builtin-attrs.rs              |  16 +-
 .../param-attrs-builtin-attrs.stderr          | 121 +++++------
 .../proc-macro-cannot-be-used.rs              |  50 ++---
 .../proc-macro-cannot-be-used.stderr          | 126 +++--------
 37 files changed, 1097 insertions(+), 489 deletions(-)
 create mode 100644 src/test/ui/attrs-resolution-errors.rs
 create mode 100644 src/test/ui/attrs-resolution-errors.stderr
 create mode 100644 src/test/ui/attrs-resolution.rs
 create mode 100644 src/test/ui/issues/issue-49934-errors.rs
 create mode 100644 src/test/ui/issues/issue-49934-errors.stderr

diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index 17bcb1d085968..bffb4df836e3b 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -155,6 +155,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
     }
 
     fn visit_variant(&mut self, v: &'a Variant) {
+        if v.is_placeholder {
+            return self.visit_macro_invoc(v.id);
+        }
         let def = self.create_def(v.id,
                                   DefPathData::TypeNs(v.ident.as_interned_str()),
                                   v.span);
@@ -168,16 +171,24 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
 
     fn visit_variant_data(&mut self, data: &'a VariantData) {
         for (index, field) in data.fields().iter().enumerate() {
+            if field.is_placeholder {
+                self.visit_macro_invoc(field.id);
+                continue;
+            }
             let name = field.ident.map(|ident| ident.name)
                 .unwrap_or_else(|| sym::integer(index));
             let def = self.create_def(field.id,
                                       DefPathData::ValueNs(name.as_interned_str()),
                                       field.span);
-            self.with_parent(def, |this| this.visit_struct_field(field));
+            self.with_parent(def, |this| visit::walk_struct_field(this, field));
         }
     }
 
     fn visit_generic_param(&mut self, param: &'a GenericParam) {
+        if param.is_placeholder {
+            self.visit_macro_invoc(param.id);
+            return;
+        }
         let name = param.ident.as_interned_str();
         let def_path_data = match param.kind {
             GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(name),
@@ -294,4 +305,49 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
             }
         }
     }
+
+    fn visit_arm(&mut self, arm: &'a Arm) {
+        if arm.is_placeholder {
+            self.visit_macro_invoc(arm.id)
+        } else {
+            visit::walk_arm(self, arm)
+        }
+    }
+
+    fn visit_field(&mut self, f: &'a Field) {
+        if f.is_placeholder {
+            self.visit_macro_invoc(f.id)
+        } else {
+            visit::walk_field(self, f)
+        }
+    }
+
+    fn visit_field_pattern(&mut self, fp: &'a FieldPat) {
+        if fp.is_placeholder {
+            self.visit_macro_invoc(fp.id)
+        } else {
+            visit::walk_field_pattern(self, fp)
+        }
+    }
+
+    fn visit_param(&mut self, p: &'a Param) {
+        if p.is_placeholder {
+            self.visit_macro_invoc(p.id)
+        } else {
+            visit::walk_param(self, p)
+        }
+    }
+
+    fn visit_struct_field(&mut self, sf: &'a StructField) {
+        if sf.is_placeholder {
+            self.visit_macro_invoc(sf.id)
+        } else {
+            let name = sf.ident.map(|ident| ident.name)
+                .unwrap_or_else(|| panic!("don't know the field number in this context"));
+            let def = self.create_def(sf.id,
+                                        DefPathData::ValueNs(name.as_interned_str()),
+                                        sf.span);
+            self.with_parent(def, |this| visit::walk_struct_field(this, sf));
+        }
+    }
 }
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 333509e18504d..11dcf5b4b0019 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -31,7 +31,7 @@ use syntax::ast::{Name, Ident};
 use syntax::attr;
 
 use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind, NodeId};
-use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind, Variant};
+use syntax::ast::{MetaItemKind, StmtKind, TraitItem, TraitItemKind};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
 use syntax::ext::expand::AstFragment;
 use syntax::ext::hygiene::ExpnId;
@@ -580,7 +580,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
     }
 
     /// Constructs the reduced graph for one item.
-    fn build_reduced_graph_for_item(&mut self, item: &Item) {
+    fn build_reduced_graph_for_item(&mut self, item: &'b Item) {
         let parent_scope = &self.parent_scope;
         let parent = parent_scope.module;
         let expansion = parent_scope.expansion;
@@ -716,12 +716,10 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                 self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
             }
 
-            ItemKind::Enum(ref enum_definition, _) => {
-                let module_kind = ModuleKind::Def(
-                    DefKind::Enum,
-                    self.r.definitions.local_def_id(item.id),
-                    ident.name,
-                );
+            ItemKind::Enum(_, _) => {
+                let def_id = self.r.definitions.local_def_id(item.id);
+                self.r.variant_vis.insert(def_id, vis);
+                let module_kind = ModuleKind::Def(DefKind::Enum, def_id, ident.name);
                 let module = self.r.new_module(parent,
                                              module_kind,
                                              parent.normal_ancestor_id,
@@ -729,10 +727,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
                                              item.span);
                 self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
                 self.parent_scope.module = module;
-
-                for variant in &(*enum_definition).variants {
-                    self.build_reduced_graph_for_variant(variant, vis);
-                }
             }
 
             ItemKind::TraitAlias(..) => {
@@ -817,38 +811,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
         }
     }
 
-    // Constructs the reduced graph for one variant. Variants exist in the
-    // type and value namespaces.
-    fn build_reduced_graph_for_variant(&mut self, variant: &Variant, vis: ty::Visibility) {
-        let parent = self.parent_scope.module;
-        let expn_id = self.parent_scope.expansion;
-        let ident = variant.ident;
-
-        // Define a name in the type namespace.
-        let def_id = self.r.definitions.local_def_id(variant.id);
-        let res = Res::Def(DefKind::Variant, def_id);
-        self.r.define(parent, ident, TypeNS, (res, vis, variant.span, expn_id));
-
-        // If the variant is marked as non_exhaustive then lower the visibility to within the
-        // crate.
-        let mut ctor_vis = vis;
-        let has_non_exhaustive = attr::contains_name(&variant.attrs, sym::non_exhaustive);
-        if has_non_exhaustive && vis == ty::Visibility::Public {
-            ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
-        }
-
-        // Define a constructor name in the value namespace.
-        // Braced variants, unlike structs, generate unusable names in
-        // value namespace, they are reserved for possible future use.
-        // It's ok to use the variant's id as a ctor id since an
-        // error will be reported on any use of such resolution anyway.
-        let ctor_node_id = variant.data.ctor_id().unwrap_or(variant.id);
-        let ctor_def_id = self.r.definitions.local_def_id(ctor_node_id);
-        let ctor_kind = CtorKind::from_ast(&variant.data);
-        let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
-        self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
-    }
-
     /// Constructs the reduced graph for one foreign item.
     fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem) {
         let (res, ns) = match item.node {
@@ -1188,7 +1150,6 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
             ItemKind::Mod(..) => self.contains_macro_use(&item.attrs),
             _ => false,
         };
-
         let orig_current_module = self.parent_scope.module;
         let orig_current_legacy_scope = self.parent_scope.legacy;
         self.build_reduced_graph_for_item(item);
@@ -1271,4 +1232,92 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
         }
         visit::walk_attribute(self, attr);
     }
+
+    fn visit_arm(&mut self, arm: &'b ast::Arm) {
+        if arm.is_placeholder {
+            self.visit_invoc(arm.id);
+        } else {
+            visit::walk_arm(self, arm);
+        }
+    }
+
+    fn visit_field(&mut self, f: &'b ast::Field) {
+        if f.is_placeholder {
+            self.visit_invoc(f.id);
+        } else {
+            visit::walk_field(self, f);
+        }
+    }
+
+    fn visit_field_pattern(&mut self, fp: &'b ast::FieldPat) {
+        if fp.is_placeholder {
+            self.visit_invoc(fp.id);
+        } else {
+            visit::walk_field_pattern(self, fp);
+        }
+    }
+
+    fn visit_generic_param(&mut self, param: &'b ast::GenericParam) {
+        if param.is_placeholder {
+            self.visit_invoc(param.id);
+        } else {
+            visit::walk_generic_param(self, param);
+        }
+    }
+
+    fn visit_param(&mut self, p: &'b ast::Param) {
+        if p.is_placeholder {
+            self.visit_invoc(p.id);
+        } else {
+            visit::walk_param(self, p);
+        }
+    }
+
+    fn visit_struct_field(&mut self, sf: &'b ast::StructField) {
+        if sf.is_placeholder {
+            self.visit_invoc(sf.id);
+        } else {
+            visit::walk_struct_field(self, sf);
+        }
+    }
+
+    // Constructs the reduced graph for one variant. Variants exist in the
+    // type and value namespaces.
+    fn visit_variant(&mut self, variant: &'b ast::Variant) {
+        if variant.is_placeholder {
+            self.visit_invoc(variant.id);
+            return;
+        }
+
+        let parent = self.parent_scope.module;
+        let vis = self.r.variant_vis[&parent.def_id().expect("enum without def-id")];
+        let expn_id = self.parent_scope.expansion;
+        let ident = variant.ident;
+
+        // Define a name in the type namespace.
+        let def_id = self.r.definitions.local_def_id(variant.id);
+        let res = Res::Def(DefKind::Variant, def_id);
+        self.r.define(parent, ident, TypeNS, (res, vis, variant.span, expn_id));
+
+        // If the variant is marked as non_exhaustive then lower the visibility to within the
+        // crate.
+        let mut ctor_vis = vis;
+        let has_non_exhaustive = attr::contains_name(&variant.attrs, sym::non_exhaustive);
+        if has_non_exhaustive && vis == ty::Visibility::Public {
+            ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
+        }
+
+        // Define a constructor name in the value namespace.
+        // Braced variants, unlike structs, generate unusable names in
+        // value namespace, they are reserved for possible future use.
+        // It's ok to use the variant's id as a ctor id since an
+        // error will be reported on any use of such resolution anyway.
+        let ctor_node_id = variant.data.ctor_id().unwrap_or(variant.id);
+        let ctor_def_id = self.r.definitions.local_def_id(ctor_node_id);
+        let ctor_kind = CtorKind::from_ast(&variant.data);
+        let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
+        self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
+
+        visit::walk_variant(self, variant);
+    }
 }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 6e131c04722a9..f97fcb0a035a2 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -952,6 +952,10 @@ pub struct Resolver<'a> {
 
     /// Features enabled for this crate.
     active_features: FxHashSet<Symbol>,
+
+    /// Stores enum visibilities to properly build a reduced graph
+    /// when visiting the correspondent variants.
+    variant_vis: DefIdMap<ty::Visibility>,
 }
 
 /// Nothing really interesting here; it just provides memory for the rest of the crate.
@@ -1214,6 +1218,7 @@ impl<'a> Resolver<'a> {
                 features.declared_lib_features.iter().map(|(feat, ..)| *feat)
                     .chain(features.declared_lang_features.iter().map(|(feat, ..)| *feat))
                     .collect(),
+            variant_vis: Default::default()
         }
     }
 
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 87439440463b3..bd8b5e13c6205 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -16,7 +16,7 @@ use syntax::attr::StabilityLevel;
 use syntax::edition::Edition;
 use syntax::ext::base::{self, InvocationRes, Indeterminate, SpecialDerives};
 use syntax::ext::base::{MacroKind, SyntaxExtension};
-use syntax::ext::expand::{AstFragment, Invocation, InvocationKind};
+use syntax::ext::expand::{AstFragment, AstFragmentKind, Invocation, InvocationKind};
 use syntax::ext::hygiene::{self, ExpnId, ExpnData, ExpnKind};
 use syntax::ext::tt::macro_rules;
 use syntax::feature_gate::{emit_feature_err, is_builtin_attr_name};
@@ -225,6 +225,26 @@ impl<'a> base::Resolver for Resolver<'a> {
             self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id);
         }
 
+        match invoc.fragment_kind {
+            AstFragmentKind::Arms
+                | AstFragmentKind::Fields
+                | AstFragmentKind::FieldPats
+                | AstFragmentKind::GenericParams
+                | AstFragmentKind::Params
+                | AstFragmentKind::StructFields
+                | AstFragmentKind::Variants =>
+            {
+                if let Res::Def(..) = res {
+                    self.session.span_err(
+                        span,
+                        "expected an inert attribute, found an attribute macro"
+                    );
+                    return Ok(InvocationRes::Single(self.dummy_ext(kind)));
+                }
+            },
+            _ => {}
+        }
+
         Ok(InvocationRes::Single(ext))
     }
 
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 312a598af02bf..d2e9203779cc8 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -519,15 +519,15 @@ fn convert_variant_ctor(tcx: TyCtxt<'_>, ctor_id: hir::HirId) {
     tcx.predicates_of(def_id);
 }
 
-fn convert_enum_variant_types<'tcx>(
-    tcx: TyCtxt<'tcx>,
+fn convert_enum_variant_types(
+    tcx: TyCtxt<'_>,
     def_id: DefId,
     variants: &[hir::Variant]
 ) {
     let def = tcx.adt_def(def_id);
     let repr_type = def.repr.discr_type();
     let initial = repr_type.initial_discriminant(tcx);
-    let mut prev_discr = None::<Discr<'tcx>>;
+    let mut prev_discr = None::<Discr<'_>>;
 
     // fill the discriminant values and field types
     for variant in variants {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index bfb2db9596363..bcbc0a19ce768 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -352,7 +352,7 @@ pub struct GenericParam {
     pub ident: Ident,
     pub attrs: ThinVec<Attribute>,
     pub bounds: GenericBounds,
-
+    pub is_placeholder: bool,
     pub kind: GenericParamKind,
 }
 
@@ -613,6 +613,7 @@ pub struct FieldPat {
     pub attrs: ThinVec<Attribute>,
     pub id: NodeId,
     pub span: Span,
+    pub is_placeholder: bool,
 }
 
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
@@ -935,6 +936,7 @@ pub struct Arm {
     pub body: P<Expr>,
     pub span: Span,
     pub id: NodeId,
+    pub is_placeholder: bool,
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@@ -945,6 +947,7 @@ pub struct Field {
     pub is_shorthand: bool,
     pub attrs: ThinVec<Attribute>,
     pub id: NodeId,
+    pub is_placeholder: bool,
 }
 
 #[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy)]
@@ -1798,6 +1801,7 @@ pub struct Param {
     pub pat: P<Pat>,
     pub id: NodeId,
     pub span: Span,
+    pub is_placeholder: bool,
 }
 
 /// Alternative representation for `Arg`s describing `self` parameter of methods.
@@ -1859,6 +1863,7 @@ impl Param {
             span,
             ty,
             id: DUMMY_NODE_ID,
+            is_placeholder: false
         };
         match eself.node {
             SelfKind::Explicit(ty, mutbl) => param(mutbl, ty),
@@ -2054,6 +2059,8 @@ pub struct Variant {
     pub disr_expr: Option<AnonConst>,
     /// Span
     pub span: Span,
+    /// Is a macro placeholder
+    pub is_placeholder: bool,
 }
 
 /// Part of `use` item to the right of its prefix.
@@ -2216,6 +2223,7 @@ pub struct StructField {
     pub id: NodeId,
     pub ty: P<Ty>,
     pub attrs: Vec<Attribute>,
+    pub is_placeholder: bool,
 }
 
 /// Fields and constructor ids of enum variants and structs.
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index c4569b3fba1be..7759a985d6134 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -35,6 +35,13 @@ pub enum Annotatable {
     ForeignItem(P<ast::ForeignItem>),
     Stmt(P<ast::Stmt>),
     Expr(P<ast::Expr>),
+    Arm(ast::Arm),
+    Field(ast::Field),
+    FieldPat(ast::FieldPat),
+    GenericParam(ast::GenericParam),
+    Param(ast::Param),
+    StructField(ast::StructField),
+    Variant(ast::Variant),
 }
 
 impl HasAttrs for Annotatable {
@@ -46,6 +53,13 @@ impl HasAttrs for Annotatable {
             Annotatable::ForeignItem(ref foreign_item) => &foreign_item.attrs,
             Annotatable::Stmt(ref stmt) => stmt.attrs(),
             Annotatable::Expr(ref expr) => &expr.attrs,
+            Annotatable::Arm(ref arm) => &arm.attrs,
+            Annotatable::Field(ref field) => &field.attrs,
+            Annotatable::FieldPat(ref fp) => &fp.attrs,
+            Annotatable::GenericParam(ref gp) => &gp.attrs,
+            Annotatable::Param(ref p) => &p.attrs,
+            Annotatable::StructField(ref sf) => &sf.attrs,
+            Annotatable::Variant(ref v) => &v.attrs(),
         }
     }
 
@@ -57,6 +71,13 @@ impl HasAttrs for Annotatable {
             Annotatable::ForeignItem(foreign_item) => foreign_item.visit_attrs(f),
             Annotatable::Stmt(stmt) => stmt.visit_attrs(f),
             Annotatable::Expr(expr) => expr.visit_attrs(f),
+            Annotatable::Arm(arm) => arm.visit_attrs(f),
+            Annotatable::Field(field) => field.visit_attrs(f),
+            Annotatable::FieldPat(fp) => fp.visit_attrs(f),
+            Annotatable::GenericParam(gp) => gp.visit_attrs(f),
+            Annotatable::Param(p) => p.visit_attrs(f),
+            Annotatable::StructField(sf) => sf.visit_attrs(f),
+            Annotatable::Variant(v) => v.visit_attrs(f),
         }
     }
 }
@@ -70,6 +91,13 @@ impl Annotatable {
             Annotatable::ForeignItem(ref foreign_item) => foreign_item.span,
             Annotatable::Stmt(ref stmt) => stmt.span,
             Annotatable::Expr(ref expr) => expr.span,
+            Annotatable::Arm(ref arm) => arm.span,
+            Annotatable::Field(ref field) => field.span,
+            Annotatable::FieldPat(ref fp) => fp.pat.span,
+            Annotatable::GenericParam(ref gp) => gp.ident.span,
+            Annotatable::Param(ref p) => p.span,
+            Annotatable::StructField(ref sf) => sf.span,
+            Annotatable::Variant(ref v) => v.span,
         }
     }
 
@@ -81,6 +109,13 @@ impl Annotatable {
             Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item),
             Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt),
             Annotatable::Expr(expr) => visitor.visit_expr(expr),
+            Annotatable::Arm(arm) => visitor.visit_arm(arm),
+            Annotatable::Field(field) => visitor.visit_field(field),
+            Annotatable::FieldPat(fp) => visitor.visit_field_pattern(fp),
+            Annotatable::GenericParam(gp) => visitor.visit_generic_param(gp),
+            Annotatable::Param(p) => visitor.visit_param(p),
+            Annotatable::StructField(sf) =>visitor.visit_struct_field(sf),
+            Annotatable::Variant(v) => visitor.visit_variant(v),
         }
     }
 
@@ -136,6 +171,55 @@ impl Annotatable {
         }
     }
 
+    pub fn expect_arm(self) -> ast::Arm {
+        match self {
+            Annotatable::Arm(arm) => arm,
+            _ => panic!("expected match arm")
+        }
+    }
+
+    pub fn expect_field(self) -> ast::Field {
+        match self {
+            Annotatable::Field(field) => field,
+            _ => panic!("expected field")
+        }
+    }
+
+    pub fn expect_field_pattern(self) -> ast::FieldPat {
+        match self {
+            Annotatable::FieldPat(fp) => fp,
+            _ => panic!("expected field pattern")
+        }
+    }
+
+    pub fn expect_generic_param(self) -> ast::GenericParam {
+        match self {
+            Annotatable::GenericParam(gp) => gp,
+            _ => panic!("expected generic parameter")
+        }
+    }
+
+    pub fn expect_param(self) -> ast::Param {
+        match self {
+            Annotatable::Param(param) => param,
+            _ => panic!("expected parameter")
+        }
+    }
+
+    pub fn expect_struct_field(self) -> ast::StructField {
+        match self {
+            Annotatable::StructField(sf) => sf,
+            _ => panic!("expected struct field")
+        }
+    }
+
+    pub fn expect_variant(self) -> ast::Variant {
+        match self {
+            Annotatable::Variant(v) => v,
+            _ => panic!("expected variant")
+        }
+    }
+
     pub fn derive_allowed(&self) -> bool {
         match *self {
             Annotatable::Item(ref item) => match item.node {
@@ -325,6 +409,34 @@ pub trait MacResult {
     fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
         None
     }
+
+    fn make_arms(self: Box<Self>) -> Option<SmallVec<[ast::Arm; 1]>> {
+        None
+    }
+
+    fn make_fields(self: Box<Self>) -> Option<SmallVec<[ast::Field; 1]>> {
+        None
+    }
+
+    fn make_field_patterns(self: Box<Self>) -> Option<SmallVec<[ast::FieldPat; 1]>> {
+        None
+    }
+
+    fn make_generic_params(self: Box<Self>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
+        None
+    }
+
+    fn make_params(self: Box<Self>) -> Option<SmallVec<[ast::Param; 1]>> {
+        None
+    }
+
+    fn make_struct_fields(self: Box<Self>) -> Option<SmallVec<[ast::StructField; 1]>> {
+        None
+    }
+
+    fn make_variants(self: Box<Self>) -> Option<SmallVec<[ast::Variant; 1]>> {
+        None
+    }
 }
 
 macro_rules! make_MacEager {
@@ -498,6 +610,34 @@ impl MacResult for DummyResult {
     fn make_ty(self: Box<DummyResult>) -> Option<P<ast::Ty>> {
         Some(DummyResult::raw_ty(self.span, self.is_error))
     }
+
+    fn make_arms(self: Box<DummyResult>) -> Option<SmallVec<[ast::Arm; 1]>> {
+       Some(SmallVec::new())
+    }
+
+    fn make_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::Field; 1]>> {
+        Some(SmallVec::new())
+    }
+
+    fn make_field_patterns(self: Box<DummyResult>) -> Option<SmallVec<[ast::FieldPat; 1]>> {
+        Some(SmallVec::new())
+    }
+
+    fn make_generic_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::GenericParam; 1]>> {
+        Some(SmallVec::new())
+    }
+
+    fn make_params(self: Box<DummyResult>) -> Option<SmallVec<[ast::Param; 1]>> {
+        Some(SmallVec::new())
+    }
+
+    fn make_struct_fields(self: Box<DummyResult>) -> Option<SmallVec<[ast::StructField; 1]>> {
+        Some(SmallVec::new())
+    }
+
+    fn make_variants(self: Box<DummyResult>) -> Option<SmallVec<[ast::Variant; 1]>> {
+        Some(SmallVec::new())
+    }
 }
 
 /// A syntax extension kind.
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index dc6cbfcf6ad5c..06a55316f31d6 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -166,7 +166,8 @@ impl<'a> ExtCtxt<'a> {
             bounds,
             kind: ast::GenericParamKind::Type {
                 default,
-            }
+            },
+            is_placeholder: false
         }
     }
 
@@ -207,6 +208,7 @@ impl<'a> ExtCtxt<'a> {
             attrs: attrs.into(),
             bounds,
             kind: ast::GenericParamKind::Lifetime,
+            is_placeholder: false
         }
     }
 
@@ -404,6 +406,7 @@ impl<'a> ExtCtxt<'a> {
             is_shorthand: false,
             attrs: ThinVec::new(),
             id: ast::DUMMY_NODE_ID,
+            is_placeholder: false,
         }
     }
     pub fn expr_struct(
@@ -614,6 +617,7 @@ impl<'a> ExtCtxt<'a> {
             body: expr,
             span,
             id: ast::DUMMY_NODE_ID,
+            is_placeholder: false,
         }
     }
 
@@ -701,6 +705,7 @@ impl<'a> ExtCtxt<'a> {
             pat: arg_pat,
             span,
             ty,
+            is_placeholder: false,
         }
     }
 
@@ -774,6 +779,7 @@ impl<'a> ExtCtxt<'a> {
                 vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited),
                 attrs: Vec::new(),
                 id: ast::DUMMY_NODE_ID,
+                is_placeholder: false,
             }
         }).collect();
 
@@ -790,6 +796,7 @@ impl<'a> ExtCtxt<'a> {
             id: ast::DUMMY_NODE_ID,
             ident,
             span,
+            is_placeholder: false,
         }
     }
 
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 4fd0c367288bf..87e2d721f89a0 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -141,7 +141,40 @@ ast_fragments! {
         "impl item"; many fn flat_map_impl_item; fn visit_impl_item; fn make_impl_items;
     }
     ForeignItems(SmallVec<[ast::ForeignItem; 1]>) {
-        "foreign item"; many fn flat_map_foreign_item; fn visit_foreign_item; fn make_foreign_items;
+        "foreign item";
+        many fn flat_map_foreign_item;
+        fn visit_foreign_item;
+        fn make_foreign_items;
+    }
+    Arms(SmallVec<[ast::Arm; 1]>) {
+        "match arm"; many fn flat_map_arm; fn visit_arm; fn make_arms;
+    }
+    Fields(SmallVec<[ast::Field; 1]>) {
+        "field expression"; many fn flat_map_field; fn visit_field; fn make_fields;
+    }
+    FieldPats(SmallVec<[ast::FieldPat; 1]>) {
+        "field pattern";
+        many fn flat_map_field_pattern;
+        fn visit_field_pattern;
+        fn make_field_patterns;
+    }
+    GenericParams(SmallVec<[ast::GenericParam; 1]>) {
+        "generic parameter";
+        many fn flat_map_generic_param;
+        fn visit_generic_param;
+        fn make_generic_params;
+    }
+    Params(SmallVec<[ast::Param; 1]>) {
+        "function parameter"; many fn flat_map_param; fn visit_param; fn make_params;
+    }
+    StructFields(SmallVec<[ast::StructField; 1]>) {
+        "field";
+        many fn flat_map_struct_field;
+        fn visit_struct_field;
+        fn make_struct_fields;
+    }
+    Variants(SmallVec<[ast::Variant; 1]>) {
+        "variant"; many fn flat_map_variant; fn visit_variant; fn make_variants;
     }
 }
 
@@ -154,6 +187,21 @@ impl AstFragmentKind {
                                                                      -> AstFragment {
         let mut items = items.into_iter();
         match self {
+            AstFragmentKind::Arms =>
+                AstFragment::Arms(items.map(Annotatable::expect_arm).collect()),
+            AstFragmentKind::Fields =>
+                AstFragment::Fields(items.map(Annotatable::expect_field).collect()),
+            AstFragmentKind::FieldPats =>
+                AstFragment::FieldPats(items.map(Annotatable::expect_field_pattern).collect()),
+            AstFragmentKind::GenericParams =>
+                AstFragment::GenericParams(items.map(Annotatable::expect_generic_param).collect()),
+            AstFragmentKind::Params =>
+                AstFragment::Params(items.map(Annotatable::expect_param).collect()),
+            AstFragmentKind::StructFields => AstFragment::StructFields(
+                items.map(Annotatable::expect_struct_field).collect()
+            ),
+            AstFragmentKind::Variants =>
+                AstFragment::Variants(items.map(Annotatable::expect_variant).collect()),
             AstFragmentKind::Items =>
                 AstFragment::Items(items.map(Annotatable::expect_item).collect()),
             AstFragmentKind::ImplItems =>
@@ -177,7 +225,7 @@ impl AstFragmentKind {
 
 pub struct Invocation {
     pub kind: InvocationKind,
-    fragment_kind: AstFragmentKind,
+    pub fragment_kind: AstFragmentKind,
     pub expansion_data: ExpansionData,
 }
 
@@ -482,6 +530,27 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             Annotatable::Expr(mut expr) => {
                 Annotatable::Expr({ cfg.visit_expr(&mut expr); expr })
             }
+            Annotatable::Arm(arm) => {
+                Annotatable::Arm(cfg.flat_map_arm(arm).pop().unwrap())
+            }
+            Annotatable::Field(field) => {
+                Annotatable::Field(cfg.flat_map_field(field).pop().unwrap())
+            }
+            Annotatable::FieldPat(fp) => {
+                Annotatable::FieldPat(cfg.flat_map_field_pattern(fp).pop().unwrap())
+            }
+            Annotatable::GenericParam(param) => {
+                Annotatable::GenericParam(cfg.flat_map_generic_param(param).pop().unwrap())
+            }
+            Annotatable::Param(param) => {
+                Annotatable::Param(cfg.flat_map_param(param).pop().unwrap())
+            }
+            Annotatable::StructField(sf) => {
+                Annotatable::StructField(cfg.flat_map_struct_field(sf).pop().unwrap())
+            }
+            Annotatable::Variant(v) => {
+                Annotatable::Variant(cfg.flat_map_variant(v).pop().unwrap())
+            }
         }
     }
 
@@ -547,6 +616,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         Annotatable::ForeignItem(item) => token::NtForeignItem(item.into_inner()),
                         Annotatable::Stmt(stmt) => token::NtStmt(stmt.into_inner()),
                         Annotatable::Expr(expr) => token::NtExpr(expr),
+                        Annotatable::Arm(..)
+                        | Annotatable::Field(..)
+                        | Annotatable::FieldPat(..)
+                        | Annotatable::GenericParam(..)
+                        | Annotatable::Param(..)
+                        | Annotatable::StructField(..)
+                        | Annotatable::Variant(..)
+                            => panic!("unexpected annotatable"),
                     })), DUMMY_SP).into();
                     let input = self.extract_proc_macro_attr_input(attr.tokens, span);
                     let tok_result = expander.expand(self.cx, span, input, item_tok);
@@ -625,6 +702,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             Annotatable::Expr(_) if self.cx.ecfg.proc_macro_hygiene() => return,
             Annotatable::Stmt(_) => ("statements", sym::proc_macro_hygiene),
             Annotatable::Expr(_) => ("expressions", sym::proc_macro_hygiene),
+            Annotatable::Arm(..)
+            | Annotatable::Field(..)
+            | Annotatable::FieldPat(..)
+            | Annotatable::GenericParam(..)
+            | Annotatable::Param(..)
+            | Annotatable::StructField(..)
+            | Annotatable::Variant(..)
+            => panic!("unexpected annotatable"),
         };
         emit_feature_err(
             self.cx.parse_sess,
@@ -681,6 +766,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             AstFragmentKind::TraitItems => return,
             AstFragmentKind::ImplItems => return,
             AstFragmentKind::ForeignItems => return,
+            AstFragmentKind::Arms
+            | AstFragmentKind::Fields
+            | AstFragmentKind::FieldPats
+            | AstFragmentKind::GenericParams
+            | AstFragmentKind::Params
+            | AstFragmentKind::StructFields
+            | AstFragmentKind::Variants
+                => panic!("unexpected AST fragment kind"),
         };
         if self.cx.ecfg.proc_macro_hygiene() {
             return
@@ -771,6 +864,14 @@ impl<'a> Parser<'a> {
             },
             AstFragmentKind::Ty => AstFragment::Ty(self.parse_ty()?),
             AstFragmentKind::Pat => AstFragment::Pat(self.parse_pat(None)?),
+            AstFragmentKind::Arms
+            | AstFragmentKind::Fields
+            | AstFragmentKind::FieldPats
+            | AstFragmentKind::GenericParams
+            | AstFragmentKind::Params
+            | AstFragmentKind::StructFields
+            | AstFragmentKind::Variants
+                => panic!("unexpected AST fragment kind"),
         })
     }
 
@@ -972,6 +1073,84 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         });
     }
 
+    fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
+        let mut arm = configure!(self, arm);
+
+        let (attr, traits, after_derive) = self.classify_item(&mut arm);
+        if attr.is_some() || !traits.is_empty() {
+            return self.collect_attr(attr, traits, Annotatable::Arm(arm),
+                                     AstFragmentKind::Arms, after_derive)
+                                     .make_arms();
+        }
+
+        noop_flat_map_arm(arm, self)
+    }
+
+    fn flat_map_field(&mut self, field: ast::Field) -> SmallVec<[ast::Field; 1]> {
+        let mut field = configure!(self, field);
+
+        let (attr, traits, after_derive) = self.classify_item(&mut field);
+        if attr.is_some() || !traits.is_empty() {
+            return self.collect_attr(attr, traits, Annotatable::Field(field),
+                                     AstFragmentKind::Fields, after_derive)
+                                     .make_fields();
+        }
+
+        noop_flat_map_field(field, self)
+    }
+
+    fn flat_map_field_pattern(&mut self, fp: ast::FieldPat) -> SmallVec<[ast::FieldPat; 1]> {
+        let mut fp = configure!(self, fp);
+
+        let (attr, traits, after_derive) = self.classify_item(&mut fp);
+        if attr.is_some() || !traits.is_empty() {
+            return self.collect_attr(attr, traits, Annotatable::FieldPat(fp),
+                                     AstFragmentKind::FieldPats, after_derive)
+                                     .make_field_patterns();
+        }
+
+        noop_flat_map_field_pattern(fp, self)
+    }
+
+    fn flat_map_param(&mut self, p: ast::Param) -> SmallVec<[ast::Param; 1]> {
+        let mut p = configure!(self, p);
+
+        let (attr, traits, after_derive) = self.classify_item(&mut p);
+        if attr.is_some() || !traits.is_empty() {
+            return self.collect_attr(attr, traits, Annotatable::Param(p),
+                                     AstFragmentKind::Params, after_derive)
+                                     .make_params();
+        }
+
+        noop_flat_map_param(p, self)
+    }
+
+    fn flat_map_struct_field(&mut self, sf: ast::StructField) -> SmallVec<[ast::StructField; 1]> {
+        let mut sf = configure!(self, sf);
+
+        let (attr, traits, after_derive) = self.classify_item(&mut sf);
+        if attr.is_some() || !traits.is_empty() {
+            return self.collect_attr(attr, traits, Annotatable::StructField(sf),
+                                     AstFragmentKind::StructFields, after_derive)
+                                     .make_struct_fields();
+        }
+
+        noop_flat_map_struct_field(sf, self)
+    }
+
+    fn flat_map_variant(&mut self, variant: ast::Variant) -> SmallVec<[ast::Variant; 1]> {
+        let mut variant = configure!(self, variant);
+
+        let (attr, traits, after_derive) = self.classify_item(&mut variant);
+        if attr.is_some() || !traits.is_empty() {
+            return self.collect_attr(attr, traits, Annotatable::Variant(variant),
+                                     AstFragmentKind::Variants, after_derive)
+                                     .make_variants();
+        }
+
+        noop_flat_map_variant(variant, self)
+    }
+
     fn filter_map_expr(&mut self, expr: P<ast::Expr>) -> Option<P<ast::Expr>> {
         let expr = configure!(self, expr);
         expr.filter_map(|mut expr| {
@@ -1227,12 +1406,20 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         }
     }
 
-   fn flat_map_generic_param(
-       &mut self,
-       param: ast::GenericParam
+    fn flat_map_generic_param(
+        &mut self,
+        param: ast::GenericParam
     ) -> SmallVec<[ast::GenericParam; 1]>
     {
-        let param = configure!(self, param);
+        let mut param = configure!(self, param);
+
+        let (attr, traits, after_derive) = self.classify_item(&mut param);
+        if attr.is_some() || !traits.is_empty() {
+            return self.collect_attr(attr, traits, Annotatable::GenericParam(param),
+                                     AstFragmentKind::GenericParams, after_derive)
+                                     .make_generic_params();
+        }
+
         noop_flat_map_generic_param(param, self)
     }
 
diff --git a/src/libsyntax/ext/placeholders.rs b/src/libsyntax/ext/placeholders.rs
index d800cfedcfb4b..52a0f95bce7ff 100644
--- a/src/libsyntax/ext/placeholders.rs
+++ b/src/libsyntax/ext/placeholders.rs
@@ -32,6 +32,16 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment {
         attrs: ThinVec::new(),
         node: ast::ExprKind::Mac(mac_placeholder()),
     });
+    let ty = P(ast::Ty {
+        id,
+        node: ast::TyKind::Mac(mac_placeholder()),
+        span,
+    });
+    let pat = P(ast::Pat {
+        id,
+        node: ast::PatKind::Mac(mac_placeholder()),
+        span,
+    });
 
     match kind {
         AstFragmentKind::Expr => AstFragment::Expr(expr_placeholder()),
@@ -67,6 +77,81 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId) -> AstFragment {
             let mac = P((mac_placeholder(), ast::MacStmtStyle::Braces, ThinVec::new()));
             ast::Stmt { id, span, node: ast::StmtKind::Mac(mac) }
         }]),
+        AstFragmentKind::Arms => AstFragment::Arms(smallvec![
+            ast::Arm {
+                attrs: Default::default(),
+                body: expr_placeholder(),
+                guard: None,
+                id,
+                pat,
+                span,
+                is_placeholder: true,
+            }
+        ]),
+        AstFragmentKind::Fields => AstFragment::Fields(smallvec![
+            ast::Field {
+                attrs: Default::default(),
+                expr: expr_placeholder(),
+                id,
+                ident,
+                is_shorthand: false,
+                span,
+                is_placeholder: true,
+            }
+        ]),
+        AstFragmentKind::FieldPats => AstFragment::FieldPats(smallvec![
+            ast::FieldPat {
+                attrs: Default::default(),
+                id,
+                ident,
+                is_shorthand: false,
+                pat,
+                span,
+                is_placeholder: true,
+            }
+        ]),
+        AstFragmentKind::GenericParams => AstFragment::GenericParams(smallvec![{
+            ast::GenericParam {
+                attrs: Default::default(),
+                bounds: Default::default(),
+                id,
+                ident,
+                is_placeholder: true,
+                kind: ast::GenericParamKind::Lifetime,
+            }
+        }]),
+        AstFragmentKind::Params => AstFragment::Params(smallvec![
+            ast::Param {
+                attrs: Default::default(),
+                id,
+                pat,
+                span,
+                ty,
+                is_placeholder: true,
+            }
+        ]),
+        AstFragmentKind::StructFields => AstFragment::StructFields(smallvec![
+            ast::StructField {
+                attrs: Default::default(),
+                id,
+                ident: None,
+                span,
+                ty,
+                vis,
+                is_placeholder: true,
+            }
+        ]),
+        AstFragmentKind::Variants => AstFragment::Variants(smallvec![
+            ast::Variant {
+                attrs: Default::default(),
+                data: ast::VariantData::Struct(Default::default(), false),
+                disr_expr: None,
+                id,
+                ident,
+                span,
+                is_placeholder: true,
+            }
+        ])
     }
 }
 
@@ -105,6 +190,66 @@ impl<'a, 'b> PlaceholderExpander<'a, 'b> {
 }
 
 impl<'a, 'b> MutVisitor for PlaceholderExpander<'a, 'b> {
+    fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
+        if arm.is_placeholder {
+            self.remove(arm.id).make_arms()
+        } else {
+            noop_flat_map_arm(arm, self)
+        }
+    }
+
+    fn flat_map_field(&mut self, field: ast::Field) -> SmallVec<[ast::Field; 1]> {
+        if field.is_placeholder {
+            self.remove(field.id).make_fields()
+        } else {
+            noop_flat_map_field(field, self)
+        }
+    }
+
+    fn flat_map_field_pattern(&mut self, fp: ast::FieldPat) -> SmallVec<[ast::FieldPat; 1]> {
+        if fp.is_placeholder {
+            self.remove(fp.id).make_field_patterns()
+        } else {
+            noop_flat_map_field_pattern(fp, self)
+        }
+    }
+
+    fn flat_map_generic_param(
+        &mut self,
+        param: ast::GenericParam
+    ) -> SmallVec<[ast::GenericParam; 1]>
+    {
+        if param.is_placeholder {
+            self.remove(param.id).make_generic_params()
+        } else {
+            noop_flat_map_generic_param(param, self)
+        }
+    }
+
+    fn flat_map_param(&mut self, p: ast::Param) -> SmallVec<[ast::Param; 1]> {
+        if p.is_placeholder {
+            self.remove(p.id).make_params()
+        } else {
+            noop_flat_map_param(p, self)
+        }
+    }
+
+    fn flat_map_struct_field(&mut self, sf: ast::StructField) -> SmallVec<[ast::StructField; 1]> {
+        if sf.is_placeholder {
+            self.remove(sf.id).make_struct_fields()
+        } else {
+            noop_flat_map_struct_field(sf, self)
+        }
+    }
+
+    fn flat_map_variant(&mut self, variant: ast::Variant) -> SmallVec<[ast::Variant; 1]> {
+        if variant.is_placeholder {
+            self.remove(variant.id).make_variants()
+        } else {
+            noop_flat_map_variant(variant, self)
+        }
+    }
+
     fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
         match item.node {
             ast::ItemKind::Mac(_) => return self.remove(item.id).make_items(),
diff --git a/src/libsyntax/ext/proc_macro.rs b/src/libsyntax/ext/proc_macro.rs
index 4a44c9a9f1f31..47b17ced8163e 100644
--- a/src/libsyntax/ext/proc_macro.rs
+++ b/src/libsyntax/ext/proc_macro.rs
@@ -88,6 +88,14 @@ impl MultiItemModifier for ProcMacroDerive {
               item: Annotatable)
               -> Vec<Annotatable> {
         let item = match item {
+            Annotatable::Arm(..) |
+            Annotatable::Field(..) |
+            Annotatable::FieldPat(..) |
+            Annotatable::GenericParam(..) |
+            Annotatable::Param(..) |
+            Annotatable::StructField(..) |
+            Annotatable::Variant(..)
+                => panic!("unexpected annotatable"),
             Annotatable::Item(item) => item,
             Annotatable::ImplItem(_) |
             Annotatable::TraitItem(_) |
diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs
index 1c35688666836..5a37222ee5590 100644
--- a/src/libsyntax/mut_visit.rs
+++ b/src/libsyntax/mut_visit.rs
@@ -370,6 +370,7 @@ pub fn noop_flat_map_field_pattern<T: MutVisitor>(
         attrs,
         id,
         ident,
+        is_placeholder: _,
         is_shorthand: _,
         pat,
         span,
@@ -403,7 +404,7 @@ pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
 }
 
 pub fn noop_flat_map_arm<T: MutVisitor>(mut arm: Arm, vis: &mut T) -> SmallVec<[Arm; 1]> {
-    let Arm { attrs, pat, guard, body, span, id } = &mut arm;
+    let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm;
     visit_attrs(attrs, vis);
     vis.visit_id(id);
     vis.visit_pat(pat);
@@ -477,7 +478,7 @@ pub fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis:
 pub fn noop_flat_map_variant<T: MutVisitor>(mut variant: Variant, vis: &mut T)
     -> SmallVec<[Variant; 1]>
 {
-    let Variant { ident, attrs, id, data, disr_expr, span } = &mut variant;
+    let Variant { ident, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant;
     vis.visit_ident(ident);
     visit_attrs(attrs, vis);
     vis.visit_id(id);
@@ -585,7 +586,7 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
 }
 
 pub fn noop_flat_map_param<T: MutVisitor>(mut param: Param, vis: &mut T) -> SmallVec<[Param; 1]> {
-    let Param { attrs, id, pat, span, ty } = &mut param;
+    let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param;
     vis.visit_id(id);
     visit_thin_attrs(attrs, vis);
     vis.visit_pat(pat);
@@ -736,7 +737,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>(
     vis: &mut T
 ) -> SmallVec<[GenericParam; 1]>
 {
-    let GenericParam { id, ident, attrs, bounds, kind } = &mut param;
+    let GenericParam { id, ident, attrs, bounds, kind, is_placeholder: _ } = &mut param;
     vis.visit_id(id);
     vis.visit_ident(ident);
     visit_thin_attrs(attrs, vis);
@@ -828,7 +829,7 @@ pub fn noop_visit_poly_trait_ref<T: MutVisitor>(p: &mut PolyTraitRef, vis: &mut
 pub fn noop_flat_map_struct_field<T: MutVisitor>(mut sf: StructField, visitor: &mut T)
     -> SmallVec<[StructField; 1]>
 {
-    let StructField { span, ident, vis, id, ty, attrs } = &mut sf;
+    let StructField { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut sf;
     visitor.visit_span(span);
     visit_opt(ident, |ident| visitor.visit_ident(ident));
     visitor.visit_vis(vis);
@@ -839,7 +840,7 @@ pub fn noop_flat_map_struct_field<T: MutVisitor>(mut sf: StructField, visitor: &
 }
 
 pub fn noop_flat_map_field<T: MutVisitor>(mut f: Field, vis: &mut T) -> SmallVec<[Field; 1]> {
-    let Field { ident, expr, span, is_shorthand: _, attrs, id } = &mut f;
+    let Field { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f;
     vis.visit_ident(ident);
     vis.visit_expr(expr);
     vis.visit_id(id);
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index 3120d0e35173d..b74f2492c351f 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -29,7 +29,14 @@ crate fn dummy_arg(ident: Ident) -> Param {
         span: ident.span,
         id: ast::DUMMY_NODE_ID
     };
-    Param { attrs: ThinVec::default(), id: ast::DUMMY_NODE_ID, pat, span: ident.span, ty: P(ty) }
+    Param {
+        attrs: ThinVec::default(),
+        id: ast::DUMMY_NODE_ID,
+        pat,
+        span: ident.span,
+        ty: P(ty),
+        is_placeholder: false,
+    }
 }
 
 pub enum Error {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fcaf5065dac78..fcebfa2996233 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1040,7 +1040,14 @@ impl<'a> Parser<'a> {
 
         let span = lo.to(self.token.span);
 
-        Ok(Param { attrs: attrs.into(), id: DUMMY_NODE_ID, pat, span, ty })
+        Ok(Param {
+            attrs: attrs.into(),
+            id: ast::DUMMY_NODE_ID,
+            is_placeholder: false,
+            pat,
+            span,
+            ty,
+        })
     }
 
     /// Parses mutability (`mut` or nothing).
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 4dbb5ff75eb21..31b28443abbc3 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -1193,7 +1193,8 @@ impl<'a> Parser<'a> {
             ty: t,
             pat,
             span,
-            id: DUMMY_NODE_ID
+            id: DUMMY_NODE_ID,
+            is_placeholder: false,
         })
     }
 
@@ -1455,6 +1456,7 @@ impl<'a> Parser<'a> {
             body: expr,
             span: lo.to(hi),
             id: DUMMY_NODE_ID,
+            is_placeholder: false,
         })
     }
 
@@ -1611,6 +1613,7 @@ impl<'a> Parser<'a> {
                         is_shorthand: false,
                         attrs: ThinVec::new(),
                         id: DUMMY_NODE_ID,
+                        is_placeholder: false,
                     });
                 }
             }
@@ -1697,6 +1700,7 @@ impl<'a> Parser<'a> {
             is_shorthand,
             attrs: attrs.into(),
             id: DUMMY_NODE_ID,
+            is_placeholder: false,
         })
     }
 
diff --git a/src/libsyntax/parse/parser/generics.rs b/src/libsyntax/parse/parser/generics.rs
index 54f24f8ef2b21..3e6118ad86f47 100644
--- a/src/libsyntax/parse/parser/generics.rs
+++ b/src/libsyntax/parse/parser/generics.rs
@@ -49,7 +49,8 @@ impl<'a> Parser<'a> {
             bounds,
             kind: GenericParamKind::Type {
                 default,
-            }
+            },
+            is_placeholder: false
         })
     }
 
@@ -66,7 +67,8 @@ impl<'a> Parser<'a> {
             bounds: Vec::new(),
             kind: GenericParamKind::Const {
                 ty,
-            }
+            },
+            is_placeholder: false
         })
     }
 
@@ -90,6 +92,7 @@ impl<'a> Parser<'a> {
                     attrs: attrs.into(),
                     bounds,
                     kind: ast::GenericParamKind::Lifetime,
+                    is_placeholder: false
                 });
             } else if self.check_keyword(kw::Const) {
                 // Parse const parameter.
diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index be7fc48fdaf66..baae6155f3478 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -1575,6 +1575,7 @@ impl<'a> Parser<'a> {
                 data: struct_def,
                 disr_expr,
                 span: vlo.to(self.prev_span),
+                is_placeholder: false,
             };
             variants.push(vr);
 
@@ -1730,6 +1731,7 @@ impl<'a> Parser<'a> {
                 id: DUMMY_NODE_ID,
                 ty,
                 attrs,
+                is_placeholder: false,
             })
         }).map(|(r, _)| r)
     }
@@ -1821,6 +1823,7 @@ impl<'a> Parser<'a> {
             id: DUMMY_NODE_ID,
             ty,
             attrs,
+            is_placeholder: false,
         })
     }
 
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 49f8d58c6a762..08ee3a6bd86d4 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -882,6 +882,7 @@ impl<'a> Parser<'a> {
             attrs: attrs.into(),
             id: ast::DUMMY_NODE_ID,
             span: lo.to(hi),
+            is_placeholder: false,
         })
     }
 
diff --git a/src/libsyntax/print/pprust/tests.rs b/src/libsyntax/print/pprust/tests.rs
index afd1726adf36b..05d78cdd87ec6 100644
--- a/src/libsyntax/print/pprust/tests.rs
+++ b/src/libsyntax/print/pprust/tests.rs
@@ -61,6 +61,7 @@ fn test_variant_to_string() {
             data: ast::VariantData::Unit(ast::DUMMY_NODE_ID),
             disr_expr: None,
             span: syntax_pos::DUMMY_SP,
+            is_placeholder: false,
         };
 
         let varstr = variant_to_string(&var);
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 893d89f06a168..c53fa7dc706e7 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -1620,6 +1620,7 @@ impl<'a> TraitDef<'a> {
                             id: ast::DUMMY_NODE_ID,
                             span: pat.span.with_ctxt(self.span.ctxt()),
                             pat,
+                            is_placeholder: false
                         }
                     })
                     .collect();
diff --git a/src/test/ui/attrs-resolution-errors.rs b/src/test/ui/attrs-resolution-errors.rs
new file mode 100644
index 0000000000000..a38b3cfa6665e
--- /dev/null
+++ b/src/test/ui/attrs-resolution-errors.rs
@@ -0,0 +1,40 @@
+enum FooEnum {
+    #[test]
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    Bar(i32),
+}
+
+struct FooStruct {
+    #[test]
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    bar: i32,
+}
+
+fn main() {
+    let foo_enum_bar = FooEnum::Bar(1);
+    match foo_enum_bar {
+        FooEnum::Bar(x) => {},
+        _ => {}
+    }
+
+    let foo_struct = FooStruct { bar: 1 };
+    match foo_struct {
+        FooStruct {
+            #[test] bar
+            //~^ ERROR expected an inert attribute, found an attribute macro
+        } => {}
+    }
+
+    match 1 {
+        0 => {}
+        #[test]
+        //~^ ERROR expected an inert attribute, found an attribute macro
+        _ => {}
+    }
+
+    let _another_foo_strunct = FooStruct {
+        #[test]
+        //~^ ERROR expected an inert attribute, found an attribute macro
+        bar: 1,
+    };
+}
diff --git a/src/test/ui/attrs-resolution-errors.stderr b/src/test/ui/attrs-resolution-errors.stderr
new file mode 100644
index 0000000000000..31f2a74edb333
--- /dev/null
+++ b/src/test/ui/attrs-resolution-errors.stderr
@@ -0,0 +1,32 @@
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/attrs-resolution-errors.rs:2:5
+   |
+LL |     #[test]
+   |     ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/attrs-resolution-errors.rs:8:5
+   |
+LL |     #[test]
+   |     ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/attrs-resolution-errors.rs:23:13
+   |
+LL |             #[test] bar
+   |             ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/attrs-resolution-errors.rs:30:9
+   |
+LL |         #[test]
+   |         ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/attrs-resolution-errors.rs:36:9
+   |
+LL |         #[test]
+   |         ^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/attrs-resolution.rs b/src/test/ui/attrs-resolution.rs
new file mode 100644
index 0000000000000..6809773237d2c
--- /dev/null
+++ b/src/test/ui/attrs-resolution.rs
@@ -0,0 +1,37 @@
+// check-pass
+
+enum FooEnum {
+    #[rustfmt::skip]
+    Bar(i32),
+}
+
+struct FooStruct {
+    #[rustfmt::skip]
+    bar: i32,
+}
+
+fn main() {
+    let foo_enum_bar = FooEnum::Bar(1);
+    match foo_enum_bar {
+        FooEnum::Bar(x) => {}
+        _ => {}
+    }
+
+    let foo_struct = FooStruct { bar: 1 };
+    match foo_struct {
+        FooStruct {
+            #[rustfmt::skip] bar
+        } => {}
+    }
+
+    match 1 {
+        0 => {}
+        #[rustfmt::skip]
+        _ => {}
+    }
+
+    let _another_foo_strunct = FooStruct {
+        #[rustfmt::skip]
+        bar: 1,
+    };
+}
diff --git a/src/test/ui/conditional-compilation/cfg-generic-params.rs b/src/test/ui/conditional-compilation/cfg-generic-params.rs
index d80d3ea7b7fe9..faf01957c7e4f 100644
--- a/src/test/ui/conditional-compilation/cfg-generic-params.rs
+++ b/src/test/ui/conditional-compilation/cfg-generic-params.rs
@@ -16,21 +16,23 @@ struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy;
 //~^ ERROR only lifetime parameters can be used in this context
 
 fn f_lt_no<#[cfg_attr(no, unknown)] 'a>() {} // OK
-fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {} //~ ERROR attribute `unknown` is currently unknown
+fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {}
+//~^ ERROR cannot find attribute macro `unknown` in this scope
 fn f_ty_no<#[cfg_attr(no, unknown)] T>() {} // OK
-fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {} //~ ERROR attribute `unknown` is currently unknown
+fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {}
+//~^ ERROR cannot find attribute macro `unknown` in this scope
 
 type FnNo = for<#[cfg_attr(no, unknown)] 'a> fn(); // OK
 type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn();
-//~^ ERROR attribute `unknown` is currently unknown
+//~^ ERROR cannot find attribute macro `unknown` in this scope
 
 type PolyNo = dyn for<#[cfg_attr(no, unknown)] 'a> Copy; // OK
 type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
-//~^ ERROR attribute `unknown` is currently unknown
+//~^ ERROR cannot find attribute macro `unknown` in this scope
 
 struct WhereNo where for<#[cfg_attr(no, unknown)] 'a> u8: Copy; // OK
 struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
-//~^ ERROR attribute `unknown` is currently unknown
+//~^ ERROR cannot find attribute macro `unknown` in this scope
 
 fn main() {
     f_lt::<'static>();
diff --git a/src/test/ui/conditional-compilation/cfg-generic-params.stderr b/src/test/ui/conditional-compilation/cfg-generic-params.stderr
index 1f9731fcfbefb..f6e5732916b91 100644
--- a/src/test/ui/conditional-compilation/cfg-generic-params.stderr
+++ b/src/test/ui/conditional-compilation/cfg-generic-params.stderr
@@ -16,51 +16,35 @@ error: only lifetime parameters can be used in this context
 LL | struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy;
    |                                                      ^
 
-error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/cfg-generic-params.rs:19:29
-   |
-LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {}
-   |                             ^^^^^^^
+error: cannot find attribute macro `unknown` in this scope
+  --> $DIR/cfg-generic-params.rs:34:43
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
+   |                                           ^^^^^^^
 
-error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/cfg-generic-params.rs:21:29
+error: cannot find attribute macro `unknown` in this scope
+  --> $DIR/cfg-generic-params.rs:30:40
    |
-LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {}
-   |                             ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
+   |                                        ^^^^^^^
 
-error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/cfg-generic-params.rs:24:34
+error: cannot find attribute macro `unknown` in this scope
+  --> $DIR/cfg-generic-params.rs:26:34
    |
 LL | type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn();
    |                                  ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/cfg-generic-params.rs:28:40
+error: cannot find attribute macro `unknown` in this scope
+  --> $DIR/cfg-generic-params.rs:22:29
    |
-LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
-   |                                        ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {}
+   |                             ^^^^^^^
 
-error[E0658]: the attribute `unknown` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/cfg-generic-params.rs:32:43
-   |
-LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
-   |                                           ^^^^^^^
+error: cannot find attribute macro `unknown` in this scope
+  --> $DIR/cfg-generic-params.rs:19:29
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {}
+   |                             ^^^^^^^
 
 error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs b/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs
index 8fe11cb02a021..51b5bf5387b5f 100644
--- a/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs
+++ b/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs
@@ -4,54 +4,54 @@
 // gate-test-custom_attribute
 
 struct StLt<#[lt_struct] 'a>(&'a u32);
-//~^ ERROR the attribute `lt_struct` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `lt_struct` in this scope
 struct StTy<#[ty_struct] I>(I);
-//~^ ERROR the attribute `ty_struct` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `ty_struct` in this scope
 
 enum EnLt<#[lt_enum] 'b> { A(&'b u32), B }
-//~^ ERROR the attribute `lt_enum` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `lt_enum` in this scope
 enum EnTy<#[ty_enum] J> { A(J), B }
-//~^ ERROR the attribute `ty_enum` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `ty_enum` in this scope
 
 trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
-//~^ ERROR the attribute `lt_trait` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `lt_trait` in this scope
 trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); }
-//~^ ERROR the attribute `ty_trait` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `ty_trait` in this scope
 
 type TyLt<#[lt_type] 'd> = &'d u32;
-//~^ ERROR the attribute `lt_type` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `lt_type` in this scope
 type TyTy<#[ty_type] L> = (L, );
-//~^ ERROR the attribute `ty_type` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `ty_type` in this scope
 
 impl<#[lt_inherent] 'e> StLt<'e> { }
-//~^ ERROR the attribute `lt_inherent` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `lt_inherent` in this scope
 impl<#[ty_inherent] M> StTy<M> { }
-//~^ ERROR the attribute `ty_inherent` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `ty_inherent` in this scope
 
 impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
-    //~^ ERROR the attribute `lt_impl_for` is currently unknown to the compiler
+    //~^ ERROR cannot find attribute macro `lt_impl_for` in this scope
     fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } }
 }
 impl<#[ty_impl_for] N> TrTy<N> for StTy<N> {
-    //~^ ERROR the attribute `ty_impl_for` is currently unknown to the compiler
+    //~^ ERROR cannot find attribute macro `ty_impl_for` in this scope
     fn foo(&self, _: N) { }
 }
 
 fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
-//~^ ERROR the attribute `lt_fn` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `lt_fn` in this scope
 fn f_ty<#[ty_fn] O>(_: O) { }
-//~^ ERROR the attribute `ty_fn` is currently unknown to the compiler
+//~^ ERROR cannot find attribute macro `ty_fn` in this scope
 
 impl<I> StTy<I> {
     fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
-    //~^ ERROR the attribute `lt_meth` is currently unknown to the compiler
+    //~^ ERROR cannot find attribute macro `lt_meth` in this scope
     fn m_ty<#[ty_meth] P>(_: P) { }
-    //~^ ERROR the attribute `ty_meth` is currently unknown to the compiler
+    //~^ ERROR cannot find attribute macro `ty_meth` in this scope
 }
 
 fn hof_lt<Q>(_: Q)
     where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
-    //~^ ERROR the attribute `lt_hof` is currently unknown to the compiler
+    //~^ ERROR cannot find attribute macro `lt_hof` in this scope
 {
 }
 
diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr b/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr
index 15e0c41b90637..9250616127f3d 100644
--- a/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr
+++ b/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr
@@ -1,156 +1,104 @@
-error[E0658]: the attribute `lt_struct` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:6:13
+error: cannot find attribute macro `lt_hof` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:53:21
    |
-LL | struct StLt<#[lt_struct] 'a>(&'a u32);
-   |             ^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL |     where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
+   |                     ^^^^^^
 
-error[E0658]: the attribute `ty_struct` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:8:13
+error: cannot find attribute macro `ty_meth` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:48:15
    |
-LL | struct StTy<#[ty_struct] I>(I);
-   |             ^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL |     fn m_ty<#[ty_meth] P>(_: P) { }
+   |               ^^^^^^^
 
-error[E0658]: the attribute `lt_enum` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:11:11
+error: cannot find attribute macro `lt_meth` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:46:15
    |
-LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B }
-   |           ^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL |     fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
+   |               ^^^^^^^
 
-error[E0658]: the attribute `ty_enum` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:13:11
-   |
-LL | enum EnTy<#[ty_enum] J> { A(J), B }
-   |           ^^^^^^^^^^
+error: cannot find attribute macro `ty_fn` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:42:11
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | fn f_ty<#[ty_fn] O>(_: O) { }
+   |           ^^^^^
 
-error[E0658]: the attribute `lt_trait` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:16:12
+error: cannot find attribute macro `lt_fn` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:40:11
    |
-LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
-   |            ^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
+   |           ^^^^^
 
-error[E0658]: the attribute `ty_trait` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:18:12
-   |
-LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); }
-   |            ^^^^^^^^^^^
+error: cannot find attribute macro `ty_impl_for` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:35:8
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | impl<#[ty_impl_for] N> TrTy<N> for StTy<N> {
+   |        ^^^^^^^^^^^
 
-error[E0658]: the attribute `lt_type` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:21:11
-   |
-LL | type TyLt<#[lt_type] 'd> = &'d u32;
-   |           ^^^^^^^^^^
+error: cannot find attribute macro `lt_impl_for` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:31:8
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
+   |        ^^^^^^^^^^^
 
-error[E0658]: the attribute `ty_type` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:23:11
-   |
-LL | type TyTy<#[ty_type] L> = (L, );
-   |           ^^^^^^^^^^
+error: cannot find attribute macro `ty_inherent` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:28:8
    |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | impl<#[ty_inherent] M> StTy<M> { }
+   |        ^^^^^^^^^^^
 
-error[E0658]: the attribute `lt_inherent` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:26:6
+error: cannot find attribute macro `lt_inherent` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:26:8
    |
 LL | impl<#[lt_inherent] 'e> StLt<'e> { }
-   |      ^^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+   |        ^^^^^^^^^^^
 
-error[E0658]: the attribute `ty_inherent` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:28:6
+error: cannot find attribute macro `ty_type` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:23:13
    |
-LL | impl<#[ty_inherent] M> StTy<M> { }
-   |      ^^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | type TyTy<#[ty_type] L> = (L, );
+   |             ^^^^^^^
 
-error[E0658]: the attribute `lt_impl_for` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:31:6
+error: cannot find attribute macro `lt_type` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:21:13
    |
-LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
-   |      ^^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | type TyLt<#[lt_type] 'd> = &'d u32;
+   |             ^^^^^^^
 
-error[E0658]: the attribute `ty_impl_for` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:35:6
+error: cannot find attribute macro `ty_trait` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:18:14
    |
-LL | impl<#[ty_impl_for] N> TrTy<N> for StTy<N> {
-   |      ^^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); }
+   |              ^^^^^^^^
 
-error[E0658]: the attribute `lt_fn` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:40:9
+error: cannot find attribute macro `lt_trait` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:16:14
    |
-LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
-   |         ^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
+   |              ^^^^^^^^
 
-error[E0658]: the attribute `ty_fn` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:42:9
+error: cannot find attribute macro `ty_enum` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:13:13
    |
-LL | fn f_ty<#[ty_fn] O>(_: O) { }
-   |         ^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | enum EnTy<#[ty_enum] J> { A(J), B }
+   |             ^^^^^^^
 
-error[E0658]: the attribute `lt_meth` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:46:13
+error: cannot find attribute macro `lt_enum` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:11:13
    |
-LL |     fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
-   |             ^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B }
+   |             ^^^^^^^
 
-error[E0658]: the attribute `ty_meth` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:48:13
+error: cannot find attribute macro `ty_struct` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:8:15
    |
-LL |     fn m_ty<#[ty_meth] P>(_: P) { }
-   |             ^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | struct StTy<#[ty_struct] I>(I);
+   |               ^^^^^^^^^
 
-error[E0658]: the attribute `lt_hof` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/feature-gate-custom_attribute2.rs:53:19
+error: cannot find attribute macro `lt_struct` in this scope
+  --> $DIR/feature-gate-custom_attribute2.rs:6:15
    |
-LL |     where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
-   |                   ^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+LL | struct StLt<#[lt_struct] 'a>(&'a u32);
+   |               ^^^^^^^^^
 
 error: aborting due to 17 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/issues/issue-49934-errors.rs b/src/test/ui/issues/issue-49934-errors.rs
new file mode 100644
index 0000000000000..58f64d137b9f9
--- /dev/null
+++ b/src/test/ui/issues/issue-49934-errors.rs
@@ -0,0 +1,13 @@
+fn foo<#[derive(Debug)] T>() {
+//~^ ERROR `derive` may only be applied to structs, enums and unions
+//~| ERROR expected an inert attribute, found an attribute macro
+    match 0 {
+        #[derive(Debug)]
+        //~^ ERROR `derive` may only be applied to structs, enums and unions
+        //~| ERROR expected an inert attribute, found an attribute macro
+        _ => (),
+    }
+}
+
+fn main() {
+}
diff --git a/src/test/ui/issues/issue-49934-errors.stderr b/src/test/ui/issues/issue-49934-errors.stderr
new file mode 100644
index 0000000000000..fce1f65881266
--- /dev/null
+++ b/src/test/ui/issues/issue-49934-errors.stderr
@@ -0,0 +1,26 @@
+error: `derive` may only be applied to structs, enums and unions
+  --> $DIR/issue-49934-errors.rs:1:8
+   |
+LL | fn foo<#[derive(Debug)] T>() {
+   |        ^^^^^^^^^^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/issue-49934-errors.rs:1:17
+   |
+LL | fn foo<#[derive(Debug)] T>() {
+   |                 ^^^^^
+
+error: `derive` may only be applied to structs, enums and unions
+  --> $DIR/issue-49934-errors.rs:5:9
+   |
+LL |         #[derive(Debug)]
+   |         ^^^^^^^^^^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/issue-49934-errors.rs:5:18
+   |
+LL |         #[derive(Debug)]
+   |                  ^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/issues/issue-49934.rs b/src/test/ui/issues/issue-49934.rs
index e75381afae9ae..262f4931d42d4 100644
--- a/src/test/ui/issues/issue-49934.rs
+++ b/src/test/ui/issues/issue-49934.rs
@@ -1,15 +1,8 @@
-// build-pass (FIXME(62277): could be check-pass?)
+// check-pass
 
 #![feature(stmt_expr_attributes)]
 #![warn(unused_attributes)] //~ NOTE lint level defined here
 
-fn foo<#[derive(Debug)] T>() { //~ WARN unused attribute
-    match 0 {
-        #[derive(Debug)] //~ WARN unused attribute
-        _ => (),
-    }
-}
-
 fn main() {
     // fold_stmt (Item)
     #[allow(dead_code)]
diff --git a/src/test/ui/issues/issue-49934.stderr b/src/test/ui/issues/issue-49934.stderr
index 6ca751a47c47d..dbec379e3c55b 100644
--- a/src/test/ui/issues/issue-49934.stderr
+++ b/src/test/ui/issues/issue-49934.stderr
@@ -1,5 +1,5 @@
 warning: `#[derive]` does nothing on macro invocations
-  --> $DIR/issue-49934.rs:20:5
+  --> $DIR/issue-49934.rs:13:5
    |
 LL |     #[derive(Debug)]
    |     ^^^^^^^^^^^^^^^^
@@ -7,10 +7,10 @@ LL |     #[derive(Debug)]
    = note: this may become a hard error in a future release
 
 warning: unused attribute
-  --> $DIR/issue-49934.rs:6:8
+  --> $DIR/issue-49934.rs:19:5
    |
-LL | fn foo<#[derive(Debug)] T>() {
-   |        ^^^^^^^^^^^^^^^^
+LL |     #[derive(Debug)]
+   |     ^^^^^^^^^^^^^^^^
    |
 note: lint level defined here
   --> $DIR/issue-49934.rs:4:9
@@ -19,31 +19,19 @@ LL | #![warn(unused_attributes)]
    |         ^^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-49934.rs:8:9
-   |
-LL |         #[derive(Debug)]
-   |         ^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-49934.rs:26:5
-   |
-LL |     #[derive(Debug)]
-   |     ^^^^^^^^^^^^^^^^
-
-warning: unused attribute
-  --> $DIR/issue-49934.rs:30:5
+  --> $DIR/issue-49934.rs:23:5
    |
 LL |     #[derive(Debug)]
    |     ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-49934.rs:34:13
+  --> $DIR/issue-49934.rs:27:13
    |
 LL |     let _ = #[derive(Debug)] "Hello, world!";
    |             ^^^^^^^^^^^^^^^^
 
 warning: unused attribute
-  --> $DIR/issue-49934.rs:39:9
+  --> $DIR/issue-49934.rs:32:9
    |
 LL |         #[derive(Debug)]
    |         ^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/proc-macro/proc-macro-gates2.rs b/src/test/ui/proc-macro/proc-macro-gates2.rs
index 35d7fc8042a3d..2fd5efd71f041 100644
--- a/src/test/ui/proc-macro/proc-macro-gates2.rs
+++ b/src/test/ui/proc-macro/proc-macro-gates2.rs
@@ -10,11 +10,11 @@ extern crate test_macros;
 // should either require a feature gate or not be allowed on stable.
 
 fn _test6<#[empty_attr] T>() {}
-//~^ ERROR: unknown to the compiler
+//~^ ERROR: expected an inert attribute, found an attribute macro
 
 fn _test7() {
     match 1 {
-        #[empty_attr] //~ ERROR: unknown to the compiler
+        #[empty_attr] //~ ERROR: expected an inert attribute, found an attribute macro
         0 => {}
         _ => {}
     }
diff --git a/src/test/ui/proc-macro/proc-macro-gates2.stderr b/src/test/ui/proc-macro/proc-macro-gates2.stderr
index a7f6f8bfb13d6..fd271da61553a 100644
--- a/src/test/ui/proc-macro/proc-macro-gates2.stderr
+++ b/src/test/ui/proc-macro/proc-macro-gates2.stderr
@@ -1,21 +1,14 @@
-error[E0658]: the attribute `empty_attr` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-gates2.rs:12:11
    |
 LL | fn _test6<#[empty_attr] T>() {}
    |           ^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `empty_attr` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-gates2.rs:17:9
    |
 LL |         #[empty_attr]
    |         ^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
index b957c673a41f1..a8fe5d6c1f60e 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
@@ -5,7 +5,7 @@ extern "C" {
         /// Foo
         //~^ ERROR documentation comments cannot be applied to function
         #[test] a: i32,
-        //~^ ERROR the attribute `test` is currently unknown to the compiler and may have
+        //~^ ERROR expected an inert attribute, found an attribute macro
         /// Bar
         //~^ ERROR documentation comments cannot be applied to function
         #[must_use]
@@ -21,7 +21,7 @@ type FnType = fn(
     /// Foo
     //~^ ERROR documentation comments cannot be applied to function
     #[test] a: u32,
-    //~^ ERROR the attribute `test` is currently unknown to the compiler and may have
+    //~^ ERROR expected an inert attribute, found an attribute macro
     /// Bar
     //~^ ERROR documentation comments cannot be applied to function
     #[must_use]
@@ -36,7 +36,7 @@ pub fn foo(
     /// Foo
     //~^ ERROR documentation comments cannot be applied to function
     #[test] a: u32,
-    //~^ ERROR the attribute `test` is currently unknown to the compiler and may have
+    //~^ ERROR expected an inert attribute, found an attribute macro
     /// Bar
     //~^ ERROR documentation comments cannot be applied to function
     #[must_use]
@@ -56,7 +56,7 @@ impl SelfStruct {
         /// Bar
         //~^ ERROR documentation comments cannot be applied to function
         #[test] a: i32,
-        //~^ ERROR the attribute `test` is currently unknown to the compiler and may have
+        //~^ ERROR expected an inert attribute, found an attribute macro
         /// Baz
         //~^ ERROR documentation comments cannot be applied to function
         #[must_use]
@@ -77,7 +77,7 @@ impl RefStruct {
         /// Bar
         //~^ ERROR documentation comments cannot be applied to function
         #[test] a: i32,
-        //~^ ERROR the attribute `test` is currently unknown to the compiler and may have
+        //~^ ERROR expected an inert attribute, found an attribute macro
         /// Baz
         //~^ ERROR documentation comments cannot be applied to function
         #[must_use]
@@ -96,7 +96,7 @@ trait RefTrait {
         /// Bar
         //~^ ERROR documentation comments cannot be applied to function
         #[test] a: i32,
-        //~^ ERROR the attribute `test` is currently unknown to the compiler and may have
+        //~^ ERROR expected an inert attribute, found an attribute macro
         /// Baz
         //~^ ERROR documentation comments cannot be applied to function
         #[must_use]
@@ -115,7 +115,7 @@ impl RefTrait for RefStruct {
         /// Bar
         //~^ ERROR documentation comments cannot be applied to function
         #[test] a: i32,
-        //~^ ERROR the attribute `test` is currently unknown to the compiler and may have
+        //~^ ERROR expected an inert attribute, found an attribute macro
         /// Baz
         //~^ ERROR documentation comments cannot be applied to function
         #[must_use]
@@ -132,7 +132,7 @@ fn main() {
         /// Foo
         //~^ ERROR documentation comments cannot be applied to function
         #[test] a: u32,
-        //~^ ERROR the attribute `test` is currently unknown to the compiler and may have
+        //~^ ERROR expected an inert attribute, found an attribute macro
         /// Bar
         //~^ ERROR documentation comments cannot be applied to function
         #[must_use]
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
index a57572abb3513..8ab3fc39a0ccb 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
@@ -1,3 +1,51 @@
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/param-attrs-builtin-attrs.rs:7:9
+   |
+LL |         #[test] a: i32,
+   |         ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/param-attrs-builtin-attrs.rs:23:5
+   |
+LL |     #[test] a: u32,
+   |     ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/param-attrs-builtin-attrs.rs:38:5
+   |
+LL |     #[test] a: u32,
+   |     ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/param-attrs-builtin-attrs.rs:58:9
+   |
+LL |         #[test] a: i32,
+   |         ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/param-attrs-builtin-attrs.rs:79:9
+   |
+LL |         #[test] a: i32,
+   |         ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/param-attrs-builtin-attrs.rs:98:9
+   |
+LL |         #[test] a: i32,
+   |         ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/param-attrs-builtin-attrs.rs:117:9
+   |
+LL |         #[test] a: i32,
+   |         ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+  --> $DIR/param-attrs-builtin-attrs.rs:134:9
+   |
+LL |         #[test] a: u32,
+   |         ^^^^^^^
+
 error: documentation comments cannot be applied to function parameters
   --> $DIR/param-attrs-builtin-attrs.rs:5:9
    |
@@ -262,78 +310,5 @@ error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-i
 LL |         #[no_mangle] b: i32
    |         ^^^^^^^^^^^^
 
-error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/param-attrs-builtin-attrs.rs:7:9
-   |
-LL |         #[test] a: i32,
-   |         ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
-
-error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/param-attrs-builtin-attrs.rs:23:5
-   |
-LL |     #[test] a: u32,
-   |     ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
-
-error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/param-attrs-builtin-attrs.rs:38:5
-   |
-LL |     #[test] a: u32,
-   |     ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
-
-error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/param-attrs-builtin-attrs.rs:58:9
-   |
-LL |         #[test] a: i32,
-   |         ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
-
-error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/param-attrs-builtin-attrs.rs:79:9
-   |
-LL |         #[test] a: i32,
-   |         ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
-
-error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/param-attrs-builtin-attrs.rs:98:9
-   |
-LL |         #[test] a: i32,
-   |         ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
-
-error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/param-attrs-builtin-attrs.rs:117:9
-   |
-LL |         #[test] a: i32,
-   |         ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
-
-error[E0658]: the attribute `test` is currently unknown to the compiler and may have meaning added to it in the future
-  --> $DIR/param-attrs-builtin-attrs.rs:134:9
-   |
-LL |         #[test] a: u32,
-   |         ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
-
 error: aborting due to 52 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
index 8defa26e48d8d..7f00308925442 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
@@ -9,52 +9,52 @@ use ident_mac::id;
 struct W(u8);
 
 extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
-//~^ ERROR the attribute `id` is currently unknown to the compiler
-//~| ERROR the attribute `id` is currently unknown to the compiler
+//~^ ERROR expected an inert attribute, found an attribute macro
+//~| ERROR expected an inert attribute, found an attribute macro
 
 unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
-//~^ ERROR the attribute `id` is currently unknown to the compiler
+//~^ ERROR expected an inert attribute, found an attribute macro
 
 type Alias = extern "C" fn(#[id] u8, #[id] ...);
-    //~^ ERROR the attribute `id` is currently unknown to the compiler
-    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    //~| ERROR expected an inert attribute, found an attribute macro
 
 fn free(#[id] arg1: u8) {
-    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~^ ERROR expected an inert attribute, found an attribute macro
     let lam = |#[id] W(x), #[id] y| ();
-    //~^ ERROR the attribute `id` is currently unknown to the compiler
-    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    //~| ERROR expected an inert attribute, found an attribute macro
 }
 
 impl W {
     fn inherent1(#[id] self, #[id] arg1: u8) {}
-    //~^ ERROR the attribute `id` is currently unknown to the compiler
-    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    //~| ERROR expected an inert attribute, found an attribute macro
     fn inherent2(#[id] &self, #[id] arg1: u8) {}
-    //~^ ERROR the attribute `id` is currently unknown to the compiler
-    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    //~| ERROR expected an inert attribute, found an attribute macro
     fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
-    //~^ ERROR the attribute `id` is currently unknown to the compiler
-    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    //~| ERROR expected an inert attribute, found an attribute macro
     fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
-    //~^ ERROR the attribute `id` is currently unknown to the compiler
-    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    //~| ERROR expected an inert attribute, found an attribute macro
 }
 
 trait A {
     fn trait1(#[id] self, #[id] arg1: u8);
-    //~^ ERROR the attribute `id` is currently unknown to the compiler
-    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    //~| ERROR expected an inert attribute, found an attribute macro
     fn trait2(#[id] &self, #[id] arg1: u8);
-    //~^ ERROR the attribute `id` is currently unknown to the compiler
-    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    //~| ERROR expected an inert attribute, found an attribute macro
     fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
-    //~^ ERROR the attribute `id` is currently unknown to the compiler
-    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    //~| ERROR expected an inert attribute, found an attribute macro
     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
-    //~^ ERROR the attribute `id` is currently unknown to the compiler
-    //~| ERROR the attribute `id` is currently unknown to the compiler
-    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~^ ERROR expected an inert attribute, found an attribute macro
+    //~| ERROR expected an inert attribute, found an attribute macro
+    //~| ERROR expected an inert attribute, found an attribute macro
 }
 
 fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
index 69b9a46b3d502..3b72e8ab4bdf9 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
@@ -1,228 +1,152 @@
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:11:21
    |
 LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
    |                     ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:11:38
    |
 LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
    |                                      ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:15:38
    |
 LL | unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
    |                                      ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:18:28
    |
 LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
    |                            ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:18:38
    |
 LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
    |                                      ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:22:9
    |
 LL | fn free(#[id] arg1: u8) {
    |         ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:24:16
    |
 LL |     let lam = |#[id] W(x), #[id] y| ();
    |                ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:24:28
    |
 LL |     let lam = |#[id] W(x), #[id] y| ();
    |                            ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:30:18
    |
 LL |     fn inherent1(#[id] self, #[id] arg1: u8) {}
    |                  ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:30:30
    |
 LL |     fn inherent1(#[id] self, #[id] arg1: u8) {}
    |                              ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:33:18
    |
 LL |     fn inherent2(#[id] &self, #[id] arg1: u8) {}
    |                  ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:33:31
    |
 LL |     fn inherent2(#[id] &self, #[id] arg1: u8) {}
    |                               ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:36:22
    |
 LL |     fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
    |                      ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:36:42
    |
 LL |     fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
    |                                          ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:39:22
    |
 LL |     fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
    |                      ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:39:45
    |
 LL |     fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
    |                                             ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:45:15
    |
 LL |     fn trait1(#[id] self, #[id] arg1: u8);
    |               ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:45:27
    |
 LL |     fn trait1(#[id] self, #[id] arg1: u8);
    |                           ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:48:15
    |
 LL |     fn trait2(#[id] &self, #[id] arg1: u8);
    |               ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:48:28
    |
 LL |     fn trait2(#[id] &self, #[id] arg1: u8);
    |                            ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:51:19
    |
 LL |     fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
    |                   ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:51:39
    |
 LL |     fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
    |                                       ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:54:19
    |
 LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
    |                   ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:54:42
    |
 LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
    |                                          ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
-error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+error: expected an inert attribute, found an attribute macro
   --> $DIR/proc-macro-cannot-be-used.rs:54:58
    |
 LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
    |                                                          ^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
-   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
 
 error: aborting due to 25 previous errors
 
-For more information about this error, try `rustc --explain E0658`.

From 851a5fd99736eee68faa2074011434f2405d4ef4 Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Mon, 9 Sep 2019 12:50:29 +0000
Subject: [PATCH 632/943] Update clippy

---
 src/tools/clippy | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/clippy b/src/tools/clippy
index 5f28fda13efeb..58e01ea4d7df6 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit 5f28fda13efeb85097fe082af4b4827a58b0ecf6
+Subproject commit 58e01ea4d7df69e658c034afbfa6d0abd90808ed

From 3d7040bdef50c4679b438cabd11ac0f81434a013 Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Mon, 9 Sep 2019 13:01:46 +0200
Subject: [PATCH 633/943] Update miri submodule

---
 src/tools/miri | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/miri b/src/tools/miri
index e479ab26406ed..dd94c7c5a32be 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit e479ab26406ed8a473987e5f4a1f3be3e978e5d2
+Subproject commit dd94c7c5a32be2ee0adeeaf9d46f26f14925797c

From b117bd7366b38061ec91697f9f2c6d1736e01aa4 Mon Sep 17 00:00:00 2001
From: Guanqun Lu <guanqun.lu@gmail.com>
Date: Wed, 4 Sep 2019 23:49:30 +0800
Subject: [PATCH 634/943] check git in bootstrap.py when trying to update
 submodule

---
 src/bootstrap/bootstrap.py | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 14bc90700b76e..65129eeeec504 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -708,6 +708,14 @@ def update_submodules(self):
         if (not os.path.exists(os.path.join(self.rust_root, ".git"))) or \
                 self.get_toml('submodules') == "false":
             return
+
+        # check the existence of 'git' command
+        try:
+            subprocess.check_output(['git', '--version'])
+        except (subprocess.CalledProcessError, OSError):
+            print("error: `git` is not found, please make sure it's installed and in the path.")
+            sys.exit(1)
+
         slow_submodules = self.get_toml('fast-submodules') == "false"
         start_time = time()
         if slow_submodules:

From 50a0ec91e066237acd8cc416cd1c0457c8240b96 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 8 Sep 2019 00:55:38 +0200
Subject: [PATCH 635/943] check_match: refactor + improve non-exhaustive diag
 for default binding modes.

---
 src/librustc/ty/util.rs                       |  18 ++
 src/librustc_mir/hair/pattern/check_match.rs  | 204 +++++++++---------
 src/test/ui/consts/match_ice.stderr           |   3 +
 .../ui/match/non-exhaustive-defined-here.rs   |  65 ++++++
 .../match/non-exhaustive-defined-here.stderr  | 151 +++++++++++++
 5 files changed, 339 insertions(+), 102 deletions(-)
 create mode 100644 src/test/ui/match/non-exhaustive-defined-here.rs
 create mode 100644 src/test/ui/match/non-exhaustive-defined-here.stderr

diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index a08c82a0ae82f..78d94df4fa03b 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -996,6 +996,24 @@ impl<'tcx> ty::TyS<'tcx> {
         debug!("is_type_representable: {:?} is {:?}", self, r);
         r
     }
+
+    /// Peel off all reference types in this type until there are none left.
+    ///
+    /// This method is idempotent, i.e. `ty.peel_refs().peel_refs() == ty.peel_refs()`.
+    ///
+    /// # Examples
+    ///
+    /// - `u8` -> `u8`
+    /// - `&'a mut u8` -> `u8`
+    /// - `&'a &'b u8` -> `u8`
+    /// - `&'a *const &'b u8 -> *const &'b u8`
+    pub fn peel_refs(&'tcx self) -> Ty<'tcx> {
+        let mut ty = self;
+        while let Ref(_, inner_ty, _) = ty.sty {
+            ty = inner_ty;
+        }
+        ty
+    }
 }
 
 fn is_copy_raw<'tcx>(tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool {
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 5352888006c30..c58f5d747e0a2 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -1,4 +1,4 @@
-use super::_match::{MatchCheckCtxt, Matrix, expand_pattern, is_useful};
+use super::_match::{MatchCheckCtxt, Matrix, Witness, expand_pattern, is_useful};
 use super::_match::Usefulness::*;
 use super::_match::WitnessPreference::*;
 
@@ -61,7 +61,7 @@ struct MatchVisitor<'a, 'tcx> {
     signalled_error: SignalledError,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
         NestedVisitorMap::None
     }
@@ -98,8 +98,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
     }
 }
 
-
-impl<'a, 'tcx> PatternContext<'a, 'tcx> {
+impl PatternContext<'_, '_> {
     fn report_inlining_errors(&self, pat_span: Span) {
         for error in &self.errors {
             match *error {
@@ -131,7 +130,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
+impl<'tcx> MatchVisitor<'_, 'tcx> {
     fn check_patterns(&mut self, has_guard: bool, pats: &[P<Pat>]) {
         check_legality_of_move_bindings(self, has_guard, pats);
         for pat in pats {
@@ -277,15 +276,9 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
                 expand_pattern(cx, pattern)
             ]].into_iter().collect();
 
-            let wild_pattern = Pattern {
-                ty: pattern_ty,
-                span: DUMMY_SP,
-                kind: box PatternKind::Wild,
-            };
-            let witness = match is_useful(cx, &pats, &[&wild_pattern], ConstructWitness) {
-                UsefulWithWitness(witness) => witness,
-                NotUseful => return,
-                Useful => bug!()
+            let witness = match check_not_useful(cx, pattern_ty, &pats) {
+                Ok(_) => return,
+                Err((witness, _)) => witness,
             };
 
             let pattern_string = witness[0].single_pattern().to_string();
@@ -294,20 +287,15 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
                 "refutable pattern in {}: `{}` not covered",
                 origin, pattern_string
             );
-            let label_msg = match pat.node {
+            err.span_label(pat.span, match pat.node {
                 PatKind::Path(hir::QPath::Resolved(None, ref path))
                         if path.segments.len() == 1 && path.segments[0].args.is_none() => {
                     format!("interpreted as {} {} pattern, not new variable",
                             path.res.article(), path.res.descr())
                 }
                 _ => format!("pattern `{}` not covered", pattern_string),
-            };
-            err.span_label(pat.span, label_msg);
-            if let ty::Adt(def, _) = pattern_ty.sty {
-                if let Some(sp) = self.tcx.hir().span_if_local(def.did){
-                    err.span_label(sp, format!("`{}` defined here", pattern_ty));
-                }
-            }
+            });
+            adt_defined_here(cx, pattern_ty.peel_refs(), &mut err);
             err.emit();
         });
     }
@@ -362,9 +350,9 @@ fn pat_is_catchall(pat: &Pat) -> bool {
 }
 
 // Check for unreachable patterns
-fn check_arms<'a, 'tcx>(
-    cx: &mut MatchCheckCtxt<'a, 'tcx>,
-    arms: &[(Vec<(&'a Pattern<'tcx>, &hir::Pat)>, Option<&hir::Expr>)],
+fn check_arms<'tcx>(
+    cx: &mut MatchCheckCtxt<'_, 'tcx>,
+    arms: &[(Vec<(&Pattern<'tcx>, &hir::Pat)>, Option<&hir::Expr>)],
     source: hir::MatchSource,
 ) {
     let mut seen = Matrix::empty();
@@ -445,104 +433,116 @@ fn check_arms<'a, 'tcx>(
     }
 }
 
-fn check_exhaustive<'p, 'a, 'tcx>(
-    cx: &mut MatchCheckCtxt<'a, 'tcx>,
+fn check_not_useful(
+    cx: &mut MatchCheckCtxt<'_, 'tcx>,
+    ty: Ty<'tcx>,
+    matrix: &Matrix<'_, 'tcx>,
+) -> Result<(), (Vec<Witness<'tcx>>, Pattern<'tcx>)> {
+    let wild_pattern = Pattern { ty, span: DUMMY_SP, kind: box PatternKind::Wild };
+    match is_useful(cx, matrix, &[&wild_pattern], ConstructWitness) {
+        NotUseful => Ok(()), // This is good, wildcard pattern isn't reachable.
+        UsefulWithWitness(pats) => Err((pats, wild_pattern)),
+        Useful => bug!(),
+    }
+}
+
+fn check_exhaustive<'tcx>(
+    cx: &mut MatchCheckCtxt<'_, 'tcx>,
     scrut_ty: Ty<'tcx>,
     sp: Span,
-    matrix: &Matrix<'p, 'tcx>,
+    matrix: &Matrix<'_, 'tcx>,
 ) {
-    let wild_pattern = Pattern {
-        ty: scrut_ty,
-        span: DUMMY_SP,
-        kind: box PatternKind::Wild,
+    let (pats, wild_pattern) = match check_not_useful(cx, scrut_ty, matrix) {
+        Ok(_) => return,
+        Err(err) => err,
     };
-    match is_useful(cx, matrix, &[&wild_pattern], ConstructWitness) {
-        UsefulWithWitness(pats) => {
-            let witnesses = if pats.is_empty() {
-                vec![&wild_pattern]
-            } else {
-                pats.iter().map(|w| w.single_pattern()).collect()
-            };
 
-            const LIMIT: usize = 3;
-            let joined_patterns = match witnesses.len() {
-                0 => bug!(),
-                1 => format!("`{}`", witnesses[0]),
-                2..=LIMIT => {
-                    let (tail, head) = witnesses.split_last().unwrap();
-                    let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
-                    format!("`{}` and `{}`", head.join("`, `"), tail)
-                }
-                _ => {
-                    let (head, tail) = witnesses.split_at(LIMIT);
-                    let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
-                    format!("`{}` and {} more", head.join("`, `"), tail.len())
-                }
-            };
+    let witnesses = if pats.is_empty() {
+        vec![&wild_pattern]
+    } else {
+        pats.iter().map(|w| w.single_pattern()).collect()
+    };
 
-            let label_text = match witnesses.len() {
-                1 => format!("pattern {} not covered", joined_patterns),
-                _ => format!("patterns {} not covered", joined_patterns),
-            };
-            let mut err = create_e0004(cx.tcx.sess, sp, format!(
-                "non-exhaustive patterns: {} not covered",
-                joined_patterns,
-            ));
-            err.span_label(sp, label_text);
-            // point at the definition of non-covered enum variants
-            if let ty::Adt(def, _) = scrut_ty.sty {
-                if let Some(sp) = cx.tcx.hir().span_if_local(def.did){
-                    err.span_label(sp, format!("`{}` defined here", scrut_ty));
-                }
-            }
-            let patterns = witnesses.iter().map(|p| (**p).clone()).collect::<Vec<Pattern<'_>>>();
-            if patterns.len() < 4 {
-                for sp in maybe_point_at_variant(cx, scrut_ty, patterns.as_slice()) {
-                    err.span_label(sp, "not covered");
-                }
-            }
-            err.help("ensure that all possible cases are being handled, \
-                      possibly by adding wildcards or more match arms");
-            err.emit();
+    const LIMIT: usize = 3;
+    let joined_patterns = match witnesses.len() {
+        0 => bug!(),
+        1 => format!("`{}`", witnesses[0]),
+        2..=LIMIT => {
+            let (tail, head) = witnesses.split_last().unwrap();
+            let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
+            format!("`{}` and `{}`", head.join("`, `"), tail)
         }
-        NotUseful => {
-            // This is good, wildcard pattern isn't reachable
+        _ => {
+            let (head, tail) = witnesses.split_at(LIMIT);
+            let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
+            format!("`{}` and {} more", head.join("`, `"), tail.len())
+        }
+    };
+
+    let mut err = create_e0004(cx.tcx.sess, sp, format!(
+        "non-exhaustive patterns: {} not covered",
+        joined_patterns,
+    ));
+    err.span_label(sp, match witnesses.len() {
+        1 => format!("pattern {} not covered", joined_patterns),
+        _ => format!("patterns {} not covered", joined_patterns),
+    });
+    // point at the definition of non-covered enum variants
+    let scrut_ty = scrut_ty.peel_refs();
+    adt_defined_here(cx, scrut_ty, &mut err);
+    let patterns = witnesses.iter().map(|p| (**p).clone()).collect::<Vec<Pattern<'_>>>();
+    if patterns.len() < 4 {
+        for sp in maybe_point_at_variant(scrut_ty, &patterns) {
+            err.span_label(sp, "not covered");
         }
-        _ => bug!()
     }
+    err.help("ensure that all possible cases are being handled, \
+                possibly by adding wildcards or more match arms");
+    err.emit();
 }
 
-fn maybe_point_at_variant(
-    cx: &mut MatchCheckCtxt<'a, 'tcx>,
-    ty: Ty<'tcx>,
-    patterns: &[Pattern<'_>],
-) -> Vec<Span> {
+fn adt_defined_here(cx: &mut MatchCheckCtxt<'_, '_>, ty: Ty<'_>, err: &mut DiagnosticBuilder<'_>) {
+    if let ty::Adt(def, _) = ty.sty {
+        if let Some(sp) = cx.tcx.hir().span_if_local(def.did) {
+            err.span_label(sp, format!("`{}` defined here", ty));
+        }
+    }
+}
+
+fn maybe_point_at_variant(ty: Ty<'_>, patterns: &[Pattern<'_>]) -> Vec<Span> {
     let mut covered = vec![];
     if let ty::Adt(def, _) = ty.sty {
         // Don't point at variants that have already been covered due to other patterns to avoid
-        // visual clutter
+        // visual clutter.
         for pattern in patterns {
-            let pk: &PatternKind<'_> = &pattern.kind;
-            if let PatternKind::Variant { adt_def, variant_index, subpatterns, .. } = pk {
-                if adt_def.did == def.did {
+            use PatternKind::{AscribeUserType, Deref, Variant, Or, Leaf};
+            match &*pattern.kind {
+                AscribeUserType { subpattern, .. } | Deref { subpattern } => {
+                    covered.extend(maybe_point_at_variant(ty, slice::from_ref(&subpattern)));
+                }
+                Variant { adt_def, variant_index, subpatterns, .. } if adt_def.did == def.did => {
                     let sp = def.variants[*variant_index].ident.span;
                     if covered.contains(&sp) {
                         continue;
                     }
                     covered.push(sp);
-                    let subpatterns = subpatterns.iter()
+
+                    let pats = subpatterns.iter()
                         .map(|field_pattern| field_pattern.pattern.clone())
-                        .collect::<Vec<_>>();
-                    covered.extend(
-                        maybe_point_at_variant(cx, ty, subpatterns.as_slice()),
-                    );
+                        .collect::<Box<[_]>>();
+                    covered.extend(maybe_point_at_variant(ty, &pats));
                 }
-            }
-            if let PatternKind::Leaf { subpatterns } = pk {
-                let subpatterns = subpatterns.iter()
-                    .map(|field_pattern| field_pattern.pattern.clone())
-                    .collect::<Vec<_>>();
-                covered.extend(maybe_point_at_variant(cx, ty, subpatterns.as_slice()));
+                Leaf { subpatterns } => {
+                    let pats = subpatterns.iter()
+                        .map(|field_pattern| field_pattern.pattern.clone())
+                        .collect::<Box<[_]>>();
+                    covered.extend(maybe_point_at_variant(ty, &pats));
+                }
+                Or { pats } => {
+                    let pats = pats.iter().cloned().collect::<Box<[_]>>();
+                    covered.extend(maybe_point_at_variant(ty, &pats));
+                }
+                _ => {}
             }
         }
     }
@@ -709,7 +709,7 @@ struct AtBindingPatternVisitor<'a, 'b, 'tcx> {
     bindings_allowed: bool
 }
 
-impl<'a, 'b, 'tcx, 'v> Visitor<'v> for AtBindingPatternVisitor<'a, 'b, 'tcx> {
+impl<'v> Visitor<'v> for AtBindingPatternVisitor<'_, '_, '_> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'v> {
         NestedVisitorMap::None
     }
diff --git a/src/test/ui/consts/match_ice.stderr b/src/test/ui/consts/match_ice.stderr
index 158581fcb1599..bf0bd3aca97a4 100644
--- a/src/test/ui/consts/match_ice.stderr
+++ b/src/test/ui/consts/match_ice.stderr
@@ -7,6 +7,9 @@ LL |         C => {}
 error[E0004]: non-exhaustive patterns: `&T` not covered
   --> $DIR/match_ice.rs:15:11
    |
+LL | struct T;
+   | --------- `T` defined here
+...
 LL |     match K {
    |           ^ pattern `&T` not covered
    |
diff --git a/src/test/ui/match/non-exhaustive-defined-here.rs b/src/test/ui/match/non-exhaustive-defined-here.rs
new file mode 100644
index 0000000000000..1ba7c2a66ba57
--- /dev/null
+++ b/src/test/ui/match/non-exhaustive-defined-here.rs
@@ -0,0 +1,65 @@
+// Test the "defined here" and "not covered" diagnostic hints.
+// We also make sure that references are peeled off from the scrutinee type
+// so that the diagnostics work better with default binding modes.
+
+#[derive(Clone)]
+enum E {
+//~^ `E` defined here
+//~| `E` defined here
+//~| `E` defined here
+//~| `E` defined here
+//~| `E` defined here
+//~| `E` defined here
+    A,
+    B,
+    //~^ not covered
+    //~| not covered
+    //~| not covered
+    C
+    //~^ not covered
+    //~| not covered
+    //~| not covered
+}
+
+fn by_val(e: E) {
+    let e1 = e.clone();
+    match e1 { //~ ERROR non-exhaustive patterns: `B` and `C` not covered
+        E::A => {}
+    }
+
+    let E::A = e; //~ ERROR refutable pattern in local binding: `B` not covered
+}
+
+fn by_ref_once(e: &E) {
+    match e { //~ ERROR non-exhaustive patterns: `&B` and `&C` not covered
+        E::A => {}
+    }
+
+    let E::A = e; //~ ERROR refutable pattern in local binding: `&B` not covered
+}
+
+fn by_ref_thrice(e: & &mut &E) {
+    match e { //~ ERROR non-exhaustive patterns: `&&mut &B` and `&&mut &C` not covered
+        E::A => {}
+    }
+
+    let E::A = e; //~ ERROR refutable pattern in local binding: `&&mut &B` not covered
+}
+
+enum Opt {
+//~^ `Opt` defined here
+//~| `Opt` defined here
+    Some(u8),
+    None,
+    //~^ not covered
+}
+
+fn ref_pat(e: Opt) {
+    match e {//~ ERROR non-exhaustive patterns: `None` not covered
+        Opt::Some(ref _x) => {}
+    }
+
+    let Opt::Some(ref _x) = e; //~ ERROR refutable pattern in local binding: `None` not covered
+}
+
+fn main() {}
diff --git a/src/test/ui/match/non-exhaustive-defined-here.stderr b/src/test/ui/match/non-exhaustive-defined-here.stderr
new file mode 100644
index 0000000000000..b0dccc975ab87
--- /dev/null
+++ b/src/test/ui/match/non-exhaustive-defined-here.stderr
@@ -0,0 +1,151 @@
+error[E0004]: non-exhaustive patterns: `B` and `C` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:26:11
+   |
+LL | / enum E {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     B,
+   | |     - not covered
+...  |
+LL | |     C
+   | |     - not covered
+...  |
+LL | |
+LL | | }
+   | |_- `E` defined here
+...
+LL |       match e1 {
+   |             ^^ patterns `B` and `C` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0005]: refutable pattern in local binding: `B` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:30:9
+   |
+LL | / enum E {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | | }
+   | |_- `E` defined here
+...
+LL |       let E::A = e;
+   |           ^^^^ pattern `B` not covered
+
+error[E0004]: non-exhaustive patterns: `&B` and `&C` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:34:11
+   |
+LL | / enum E {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     B,
+   | |     - not covered
+...  |
+LL | |     C
+   | |     - not covered
+...  |
+LL | |
+LL | | }
+   | |_- `E` defined here
+...
+LL |       match e {
+   |             ^ patterns `&B` and `&C` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0005]: refutable pattern in local binding: `&B` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:38:9
+   |
+LL | / enum E {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | | }
+   | |_- `E` defined here
+...
+LL |       let E::A = e;
+   |           ^^^^ pattern `&B` not covered
+
+error[E0004]: non-exhaustive patterns: `&&mut &B` and `&&mut &C` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:42:11
+   |
+LL | / enum E {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |     B,
+   | |     - not covered
+...  |
+LL | |     C
+   | |     - not covered
+...  |
+LL | |
+LL | | }
+   | |_- `E` defined here
+...
+LL |       match e {
+   |             ^ patterns `&&mut &B` and `&&mut &C` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0005]: refutable pattern in local binding: `&&mut &B` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:46:9
+   |
+LL | / enum E {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | | }
+   | |_- `E` defined here
+...
+LL |       let E::A = e;
+   |           ^^^^ pattern `&&mut &B` not covered
+
+error[E0004]: non-exhaustive patterns: `None` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:58:11
+   |
+LL | / enum Opt {
+LL | |
+LL | |
+LL | |     Some(u8),
+LL | |     None,
+   | |     ---- not covered
+LL | |
+LL | | }
+   | |_- `Opt` defined here
+...
+LL |       match e {
+   |             ^ pattern `None` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0005]: refutable pattern in local binding: `None` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:62:9
+   |
+LL | / enum Opt {
+LL | |
+LL | |
+LL | |     Some(u8),
+LL | |     None,
+LL | |
+LL | | }
+   | |_- `Opt` defined here
+...
+LL |       let Opt::Some(ref _x) = e;
+   |           ^^^^^^^^^^^^^^^^^ pattern `None` not covered
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0004, E0005.
+For more information about an error, try `rustc --explain E0004`.

From e2640a51eee383dcc337e78c233597d18dc78fa2 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 9 Sep 2019 01:22:03 +0200
Subject: [PATCH 636/943] typeck: use .peel_refs() more.

---
 src/librustc_typeck/check/op.rs | 27 ++++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)

diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index 93855a3b68a7f..18b555dc037c2 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -268,7 +268,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 op.node.as_str(), lhs_ty),
                             );
                             let mut suggested_deref = false;
-                            if let Ref(_, mut rty, _) = lhs_ty.sty {
+                            if let Ref(_, rty, _) = lhs_ty.sty {
                                 if {
                                     self.infcx.type_is_copy_modulo_regions(self.param_env,
                                                                            rty,
@@ -279,13 +279,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                             .is_ok()
                                 } {
                                     if let Ok(lstring) = source_map.span_to_snippet(lhs_expr.span) {
-                                        while let Ref(_, rty_inner, _) = rty.sty {
-                                            rty = rty_inner;
-                                        }
                                         let msg = &format!(
                                             "`{}=` can be used on '{}', you can dereference `{}`",
                                             op.node.as_str(),
-                                            rty,
+                                            rty.peel_refs(),
                                             lstring,
                                         );
                                         err.span_suggestion(
@@ -361,7 +358,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             }
 
                             let mut suggested_deref = false;
-                            if let Ref(_, mut rty, _) = lhs_ty.sty {
+                            if let Ref(_, rty, _) = lhs_ty.sty {
                                 if {
                                     self.infcx.type_is_copy_modulo_regions(self.param_env,
                                                                            rty,
@@ -372,17 +369,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                             .is_ok()
                                 } {
                                     if let Ok(lstring) = source_map.span_to_snippet(lhs_expr.span) {
-                                        while let Ref(_, rty_inner, _) = rty.sty {
-                                            rty = rty_inner;
-                                        }
-                                        let msg = &format!(
-                                                "`{}` can be used on '{}', you can \
-                                                dereference `{2}`: `*{2}`",
-                                                op.node.as_str(),
-                                                rty,
-                                                lstring
-                                        );
-                                        err.help(msg);
+                                        err.help(&format!(
+                                            "`{}` can be used on '{}', you can \
+                                            dereference `{2}`: `*{2}`",
+                                            op.node.as_str(),
+                                            rty.peel_refs(),
+                                            lstring
+                                        ));
                                         suggested_deref = true;
                                     }
                                 }

From 5435b38456547aae42bec55da38e760fc77aabce Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 9 Sep 2019 01:59:22 +0200
Subject: [PATCH 637/943] check_match: extract joined_uncovered_patterns.

---
 src/librustc_mir/hair/pattern/check_match.rs | 34 +++++++++++---------
 1 file changed, 19 insertions(+), 15 deletions(-)

diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index c58f5d747e0a2..245e7534add50 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -463,21 +463,7 @@ fn check_exhaustive<'tcx>(
         pats.iter().map(|w| w.single_pattern()).collect()
     };
 
-    const LIMIT: usize = 3;
-    let joined_patterns = match witnesses.len() {
-        0 => bug!(),
-        1 => format!("`{}`", witnesses[0]),
-        2..=LIMIT => {
-            let (tail, head) = witnesses.split_last().unwrap();
-            let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
-            format!("`{}` and `{}`", head.join("`, `"), tail)
-        }
-        _ => {
-            let (head, tail) = witnesses.split_at(LIMIT);
-            let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
-            format!("`{}` and {} more", head.join("`, `"), tail.len())
-        }
-    };
+    let joined_patterns = joined_uncovered_patterns(&witnesses);
 
     let mut err = create_e0004(cx.tcx.sess, sp, format!(
         "non-exhaustive patterns: {} not covered",
@@ -501,6 +487,24 @@ fn check_exhaustive<'tcx>(
     err.emit();
 }
 
+fn joined_uncovered_patterns(witnesses: &[&Pattern<'_>]) -> String {
+    const LIMIT: usize = 3;
+    match witnesses.len() {
+        0 => bug!(),
+        1 => format!("`{}`", witnesses[0]),
+        2..=LIMIT => {
+            let (tail, head) = witnesses.split_last().unwrap();
+            let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
+            format!("`{}` and `{}`", head.join("`, `"), tail)
+        }
+        _ => {
+            let (head, tail) = witnesses.split_at(LIMIT);
+            let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
+            format!("`{}` and {} more", head.join("`, `"), tail.len())
+        }
+    }
+}
+
 fn adt_defined_here(cx: &mut MatchCheckCtxt<'_, '_>, ty: Ty<'_>, err: &mut DiagnosticBuilder<'_>) {
     if let ty::Adt(def, _) = ty.sty {
         if let Some(sp) = cx.tcx.hir().span_if_local(def.did) {

From b36a206a303e02dd55996f2c709cc36f69c99ff4 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 9 Sep 2019 02:05:54 +0200
Subject: [PATCH 638/943] joined_uncovered_patterns: use slice pats &
 eta-reduce.

---
 src/librustc_mir/hair/pattern/check_match.rs | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index 245e7534add50..a2ca53a9a3f36 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -489,17 +489,16 @@ fn check_exhaustive<'tcx>(
 
 fn joined_uncovered_patterns(witnesses: &[&Pattern<'_>]) -> String {
     const LIMIT: usize = 3;
-    match witnesses.len() {
-        0 => bug!(),
-        1 => format!("`{}`", witnesses[0]),
-        2..=LIMIT => {
-            let (tail, head) = witnesses.split_last().unwrap();
-            let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
+    match witnesses {
+        [] => bug!(),
+        [witness] => format!("`{}`", witness),
+        [head @ .., tail] if head.len() < LIMIT => {
+            let head: Vec<_> = head.iter().map(<_>::to_string).collect();
             format!("`{}` and `{}`", head.join("`, `"), tail)
         }
         _ => {
             let (head, tail) = witnesses.split_at(LIMIT);
-            let head: Vec<_> = head.iter().map(|w| w.to_string()).collect();
+            let head: Vec<_> = head.iter().map(<_>::to_string).collect();
             format!("`{}` and {} more", head.join("`, `"), tail.len())
         }
     }

From 7d4665b0973892c76416d9113debb677342f6ff8 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 9 Sep 2019 16:44:06 +0200
Subject: [PATCH 639/943] check_match: unify check_irrefutable &
 check_exhaustive more.

---
 src/librustc_mir/hair/pattern/_match.rs       |  4 +-
 src/librustc_mir/hair/pattern/check_match.rs  | 94 ++++++++++---------
 .../ui/consts/const-match-check.eval1.stderr  |  4 +-
 .../ui/consts/const-match-check.eval2.stderr  |  4 +-
 .../consts/const-match-check.matchck.stderr   | 16 ++--
 .../ui/consts/const-pattern-irrefutable.rs    |  6 +-
 .../consts/const-pattern-irrefutable.stderr   |  6 +-
 src/test/ui/consts/const_let_refutable.stderr |  4 +-
 src/test/ui/empty/empty-never-array.stderr    |  1 +
 ...oop-refutable-pattern-error-message.stderr |  4 +-
 src/test/ui/issues/issue-15381.rs             |  2 +-
 src/test/ui/issues/issue-15381.stderr         |  4 +-
 src/test/ui/issues/issue-31561.rs             |  2 +-
 src/test/ui/issues/issue-31561.stderr         |  6 +-
 .../ui/match/non-exhaustive-defined-here.rs   | 13 ++-
 .../match/non-exhaustive-defined-here.stderr  | 47 +++++++---
 src/test/ui/refutable-pattern-errors.rs       |  4 +-
 src/test/ui/refutable-pattern-errors.stderr   |  8 +-
 .../uninhabited-irrefutable.stderr            |  1 +
 19 files changed, 135 insertions(+), 95 deletions(-)

diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 222750e602df9..a6d955f336910 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -517,9 +517,9 @@ struct PatternContext<'tcx> {
 pub struct Witness<'tcx>(Vec<Pattern<'tcx>>);
 
 impl<'tcx> Witness<'tcx> {
-    pub fn single_pattern(&self) -> &Pattern<'tcx> {
+    pub fn single_pattern(self) -> Pattern<'tcx> {
         assert_eq!(self.0.len(), 1);
-        &self.0[0]
+        self.0.into_iter().next().unwrap()
     }
 
     fn push_wild_constructor<'a>(
diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index a2ca53a9a3f36..c7eeaaf6f23da 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -1,4 +1,4 @@
-use super::_match::{MatchCheckCtxt, Matrix, Witness, expand_pattern, is_useful};
+use super::_match::{MatchCheckCtxt, Matrix, expand_pattern, is_useful};
 use super::_match::Usefulness::*;
 use super::_match::WitnessPreference::*;
 
@@ -276,26 +276,26 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
                 expand_pattern(cx, pattern)
             ]].into_iter().collect();
 
-            let witness = match check_not_useful(cx, pattern_ty, &pats) {
+            let witnesses = match check_not_useful(cx, pattern_ty, &pats) {
                 Ok(_) => return,
-                Err((witness, _)) => witness,
+                Err(err) => err,
             };
 
-            let pattern_string = witness[0].single_pattern().to_string();
+            let joined_patterns = joined_uncovered_patterns(&witnesses);
             let mut err = struct_span_err!(
                 self.tcx.sess, pat.span, E0005,
-                "refutable pattern in {}: `{}` not covered",
-                origin, pattern_string
+                "refutable pattern in {}: {} not covered",
+                origin, joined_patterns
             );
-            err.span_label(pat.span, match pat.node {
-                PatKind::Path(hir::QPath::Resolved(None, ref path))
-                        if path.segments.len() == 1 && path.segments[0].args.is_none() => {
+            err.span_label(pat.span, match &pat.node {
+                PatKind::Path(hir::QPath::Resolved(None, path))
+                    if path.segments.len() == 1 && path.segments[0].args.is_none() => {
                     format!("interpreted as {} {} pattern, not new variable",
                             path.res.article(), path.res.descr())
                 }
-                _ => format!("pattern `{}` not covered", pattern_string),
+                _ => pattern_not_convered_label(&witnesses, &joined_patterns),
             });
-            adt_defined_here(cx, pattern_ty.peel_refs(), &mut err);
+            adt_defined_here(cx, &mut err, pattern_ty, &witnesses);
             err.emit();
         });
     }
@@ -437,11 +437,15 @@ fn check_not_useful(
     cx: &mut MatchCheckCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
     matrix: &Matrix<'_, 'tcx>,
-) -> Result<(), (Vec<Witness<'tcx>>, Pattern<'tcx>)> {
+) -> Result<(), Vec<Pattern<'tcx>>> {
     let wild_pattern = Pattern { ty, span: DUMMY_SP, kind: box PatternKind::Wild };
     match is_useful(cx, matrix, &[&wild_pattern], ConstructWitness) {
         NotUseful => Ok(()), // This is good, wildcard pattern isn't reachable.
-        UsefulWithWitness(pats) => Err((pats, wild_pattern)),
+        UsefulWithWitness(pats) => Err(if pats.is_empty() {
+            vec![wild_pattern]
+        } else {
+            pats.into_iter().map(|w| w.single_pattern()).collect()
+        }),
         Useful => bug!(),
     }
 }
@@ -452,42 +456,26 @@ fn check_exhaustive<'tcx>(
     sp: Span,
     matrix: &Matrix<'_, 'tcx>,
 ) {
-    let (pats, wild_pattern) = match check_not_useful(cx, scrut_ty, matrix) {
+    let witnesses = match check_not_useful(cx, scrut_ty, matrix) {
         Ok(_) => return,
         Err(err) => err,
     };
 
-    let witnesses = if pats.is_empty() {
-        vec![&wild_pattern]
-    } else {
-        pats.iter().map(|w| w.single_pattern()).collect()
-    };
-
     let joined_patterns = joined_uncovered_patterns(&witnesses);
-
-    let mut err = create_e0004(cx.tcx.sess, sp, format!(
-        "non-exhaustive patterns: {} not covered",
-        joined_patterns,
-    ));
-    err.span_label(sp, match witnesses.len() {
-        1 => format!("pattern {} not covered", joined_patterns),
-        _ => format!("patterns {} not covered", joined_patterns),
-    });
-    // point at the definition of non-covered enum variants
-    let scrut_ty = scrut_ty.peel_refs();
-    adt_defined_here(cx, scrut_ty, &mut err);
-    let patterns = witnesses.iter().map(|p| (**p).clone()).collect::<Vec<Pattern<'_>>>();
-    if patterns.len() < 4 {
-        for sp in maybe_point_at_variant(scrut_ty, &patterns) {
-            err.span_label(sp, "not covered");
-        }
-    }
-    err.help("ensure that all possible cases are being handled, \
-                possibly by adding wildcards or more match arms");
-    err.emit();
+    let mut err = create_e0004(
+        cx.tcx.sess, sp,
+        format!("non-exhaustive patterns: {} not covered", joined_patterns),
+    );
+    err.span_label(sp, pattern_not_convered_label(&witnesses, &joined_patterns));
+    adt_defined_here(cx, &mut err, scrut_ty, &witnesses);
+    err.help(
+        "ensure that all possible cases are being handled, \
+        possibly by adding wildcards or more match arms"
+    )
+    .emit();
 }
 
-fn joined_uncovered_patterns(witnesses: &[&Pattern<'_>]) -> String {
+fn joined_uncovered_patterns(witnesses: &[Pattern<'_>]) -> String {
     const LIMIT: usize = 3;
     match witnesses {
         [] => bug!(),
@@ -504,11 +492,31 @@ fn joined_uncovered_patterns(witnesses: &[&Pattern<'_>]) -> String {
     }
 }
 
-fn adt_defined_here(cx: &mut MatchCheckCtxt<'_, '_>, ty: Ty<'_>, err: &mut DiagnosticBuilder<'_>) {
+fn pattern_not_convered_label(witnesses: &[Pattern<'_>], joined_patterns: &str) -> String {
+    match witnesses.len() {
+        1 => format!("pattern {} not covered", joined_patterns),
+        _ => format!("patterns {} not covered", joined_patterns),
+    }
+}
+
+/// Point at the definition of non-covered `enum` variants.
+fn adt_defined_here(
+    cx: &MatchCheckCtxt<'_, '_>,
+    err: &mut DiagnosticBuilder<'_>,
+    ty: Ty<'_>,
+    witnesses: &[Pattern<'_>],
+) {
+    let ty = ty.peel_refs();
     if let ty::Adt(def, _) = ty.sty {
         if let Some(sp) = cx.tcx.hir().span_if_local(def.did) {
             err.span_label(sp, format!("`{}` defined here", ty));
         }
+
+        if witnesses.len() < 4 {
+            for sp in maybe_point_at_variant(ty, &witnesses) {
+                err.span_label(sp, "not covered");
+            }
+        }
     }
 }
 
diff --git a/src/test/ui/consts/const-match-check.eval1.stderr b/src/test/ui/consts/const-match-check.eval1.stderr
index 3bcb50c6dcf6f..24d2e3ce53937 100644
--- a/src/test/ui/consts/const-match-check.eval1.stderr
+++ b/src/test/ui/consts/const-match-check.eval1.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered
+error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
   --> $DIR/const-match-check.rs:25:15
    |
 LL |     A = { let 0 = 0; 0 },
-   |               ^ pattern `std::i32::MIN..=-1i32` not covered
+   |               ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-match-check.eval2.stderr b/src/test/ui/consts/const-match-check.eval2.stderr
index e292e1cc16585..5d59d06f7982a 100644
--- a/src/test/ui/consts/const-match-check.eval2.stderr
+++ b/src/test/ui/consts/const-match-check.eval2.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered
+error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
   --> $DIR/const-match-check.rs:31:24
    |
 LL |     let x: [i32; { let 0 = 0; 0 }] = [];
-   |                        ^ pattern `std::i32::MIN..=-1i32` not covered
+   |                        ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-match-check.matchck.stderr b/src/test/ui/consts/const-match-check.matchck.stderr
index 8a9fbde8537bf..6d74c26f9f7a5 100644
--- a/src/test/ui/consts/const-match-check.matchck.stderr
+++ b/src/test/ui/consts/const-match-check.matchck.stderr
@@ -1,26 +1,26 @@
-error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered
+error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
   --> $DIR/const-match-check.rs:4:22
    |
 LL | const X: i32 = { let 0 = 0; 0 };
-   |                      ^ pattern `std::i32::MIN..=-1i32` not covered
+   |                      ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
 
-error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered
+error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
   --> $DIR/const-match-check.rs:8:23
    |
 LL | static Y: i32 = { let 0 = 0; 0 };
-   |                       ^ pattern `std::i32::MIN..=-1i32` not covered
+   |                       ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
 
-error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered
+error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
   --> $DIR/const-match-check.rs:13:26
    |
 LL |     const X: i32 = { let 0 = 0; 0 };
-   |                          ^ pattern `std::i32::MIN..=-1i32` not covered
+   |                          ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
 
-error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` not covered
+error[E0005]: refutable pattern in local binding: `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
   --> $DIR/const-match-check.rs:19:26
    |
 LL |     const X: i32 = { let 0 = 0; 0 };
-   |                          ^ pattern `std::i32::MIN..=-1i32` not covered
+   |                          ^ patterns `std::i32::MIN..=-1i32` and `1i32..=std::i32::MAX` not covered
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/consts/const-pattern-irrefutable.rs b/src/test/ui/consts/const-pattern-irrefutable.rs
index d3f7be18a9839..60e16aaf89532 100644
--- a/src/test/ui/consts/const-pattern-irrefutable.rs
+++ b/src/test/ui/consts/const-pattern-irrefutable.rs
@@ -9,8 +9,8 @@ use foo::d;
 const a: u8 = 2;
 
 fn main() {
-    let a = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
-    let c = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
-    let d = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` not covered
+    let a = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` and `3u8..=std::u8::MAX
+    let c = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` and `3u8..=std::u8::MAX
+    let d = 4; //~ ERROR refutable pattern in local binding: `0u8..=1u8` and `3u8..=std::u8::MAX
     fn f() {} // Check that the `NOTE`s still work with an item here (cf. issue #35115).
 }
diff --git a/src/test/ui/consts/const-pattern-irrefutable.stderr b/src/test/ui/consts/const-pattern-irrefutable.stderr
index 48fe24df4d044..06f5e90d2f1f7 100644
--- a/src/test/ui/consts/const-pattern-irrefutable.stderr
+++ b/src/test/ui/consts/const-pattern-irrefutable.stderr
@@ -1,16 +1,16 @@
-error[E0005]: refutable pattern in local binding: `0u8..=1u8` not covered
+error[E0005]: refutable pattern in local binding: `0u8..=1u8` and `3u8..=std::u8::MAX` not covered
   --> $DIR/const-pattern-irrefutable.rs:12:9
    |
 LL |     let a = 4;
    |         ^ interpreted as a constant pattern, not new variable
 
-error[E0005]: refutable pattern in local binding: `0u8..=1u8` not covered
+error[E0005]: refutable pattern in local binding: `0u8..=1u8` and `3u8..=std::u8::MAX` not covered
   --> $DIR/const-pattern-irrefutable.rs:13:9
    |
 LL |     let c = 4;
    |         ^ interpreted as a constant pattern, not new variable
 
-error[E0005]: refutable pattern in local binding: `0u8..=1u8` not covered
+error[E0005]: refutable pattern in local binding: `0u8..=1u8` and `3u8..=std::u8::MAX` not covered
   --> $DIR/const-pattern-irrefutable.rs:14:9
    |
 LL |     let d = 4;
diff --git a/src/test/ui/consts/const_let_refutable.stderr b/src/test/ui/consts/const_let_refutable.stderr
index 31a3098a26376..7f15f02d4d37b 100644
--- a/src/test/ui/consts/const_let_refutable.stderr
+++ b/src/test/ui/consts/const_let_refutable.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in function argument: `&[]` not covered
+error[E0005]: refutable pattern in function argument: `&[]`, `&[_]` and `&[_, _, _]` not covered
   --> $DIR/const_let_refutable.rs:3:16
    |
 LL | const fn slice([a, b]: &[i32]) -> i32 {
-   |                ^^^^^^ pattern `&[]` not covered
+   |                ^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _]` not covered
 
 error[E0723]: can only call other `const fn` within a `const fn`, but `const <&i32 as std::ops::Add>::add` is not stable as `const fn`
   --> $DIR/const_let_refutable.rs:4:5
diff --git a/src/test/ui/empty/empty-never-array.stderr b/src/test/ui/empty/empty-never-array.stderr
index a7f7cfa289e00..7d59d553d88fd 100644
--- a/src/test/ui/empty/empty-never-array.stderr
+++ b/src/test/ui/empty/empty-never-array.stderr
@@ -3,6 +3,7 @@ error[E0005]: refutable pattern in local binding: `T(_, _)` not covered
    |
 LL | / enum Helper<T, U> {
 LL | |     T(T, [!; 0]),
+   | |     - not covered
 LL | |     #[allow(dead_code)]
 LL | |     U(U),
 LL | | }
diff --git a/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr b/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr
index 0d77fd4efdb82..14aea2dc27eea 100644
--- a/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr
+++ b/src/test/ui/for/for-loop-refutable-pattern-error-message.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in `for` loop binding: `&std::i32::MIN..=0i32` not covered
+error[E0005]: refutable pattern in `for` loop binding: `&std::i32::MIN..=0i32` and `&2i32..=std::i32::MAX` not covered
   --> $DIR/for-loop-refutable-pattern-error-message.rs:2:9
    |
 LL |     for &1 in [1].iter() {}
-   |         ^^ pattern `&std::i32::MIN..=0i32` not covered
+   |         ^^ patterns `&std::i32::MIN..=0i32` and `&2i32..=std::i32::MAX` not covered
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-15381.rs b/src/test/ui/issues/issue-15381.rs
index 4c8e1b41beefc..5307153cb4403 100644
--- a/src/test/ui/issues/issue-15381.rs
+++ b/src/test/ui/issues/issue-15381.rs
@@ -2,7 +2,7 @@ fn main() {
     let values: Vec<u8> = vec![1,2,3,4,5,6,7,8];
 
     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
-        //~^ ERROR refutable pattern in `for` loop binding: `&[]` not covered
+        //~^ ERROR refutable pattern in `for` loop binding: `&[]`, `&[_]`, `&[_, _]` and 1 more not
         println!("y={}", y);
         //~^ ERROR borrow of possibly-uninitialized variable: `y`
     }
diff --git a/src/test/ui/issues/issue-15381.stderr b/src/test/ui/issues/issue-15381.stderr
index e8106059052da..47a0d514ad873 100644
--- a/src/test/ui/issues/issue-15381.stderr
+++ b/src/test/ui/issues/issue-15381.stderr
@@ -1,8 +1,8 @@
-error[E0005]: refutable pattern in `for` loop binding: `&[]` not covered
+error[E0005]: refutable pattern in `for` loop binding: `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
   --> $DIR/issue-15381.rs:4:9
    |
 LL |     for &[x,y,z] in values.chunks(3).filter(|&xs| xs.len() == 3) {
-   |         ^^^^^^^^ pattern `&[]` not covered
+   |         ^^^^^^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered
 
 error[E0381]: borrow of possibly-uninitialized variable: `y`
   --> $DIR/issue-15381.rs:6:26
diff --git a/src/test/ui/issues/issue-31561.rs b/src/test/ui/issues/issue-31561.rs
index 87b19fe5ea7cb..813b2409cc8e1 100644
--- a/src/test/ui/issues/issue-31561.rs
+++ b/src/test/ui/issues/issue-31561.rs
@@ -6,5 +6,5 @@ enum Thing {
 
 fn main() {
     let Thing::Foo(y) = Thing::Foo(1);
-    //~^ ERROR refutable pattern in local binding: `Bar` not covered
+    //~^ ERROR refutable pattern in local binding: `Bar` and `Baz` not covered
 }
diff --git a/src/test/ui/issues/issue-31561.stderr b/src/test/ui/issues/issue-31561.stderr
index 246137aeee05c..9ec26b024bce2 100644
--- a/src/test/ui/issues/issue-31561.stderr
+++ b/src/test/ui/issues/issue-31561.stderr
@@ -1,15 +1,17 @@
-error[E0005]: refutable pattern in local binding: `Bar` not covered
+error[E0005]: refutable pattern in local binding: `Bar` and `Baz` not covered
   --> $DIR/issue-31561.rs:8:9
    |
 LL | / enum Thing {
 LL | |     Foo(u8),
 LL | |     Bar,
+   | |     --- not covered
 LL | |     Baz
+   | |     --- not covered
 LL | | }
    | |_- `Thing` defined here
 ...
 LL |       let Thing::Foo(y) = Thing::Foo(1);
-   |           ^^^^^^^^^^^^^ pattern `Bar` not covered
+   |           ^^^^^^^^^^^^^ patterns `Bar` and `Baz` not covered
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/match/non-exhaustive-defined-here.rs b/src/test/ui/match/non-exhaustive-defined-here.rs
index 1ba7c2a66ba57..6f009acbdfe18 100644
--- a/src/test/ui/match/non-exhaustive-defined-here.rs
+++ b/src/test/ui/match/non-exhaustive-defined-here.rs
@@ -15,10 +15,16 @@ enum E {
     //~^ not covered
     //~| not covered
     //~| not covered
+    //~| not covered
+    //~| not covered
+    //~| not covered
     C
     //~^ not covered
     //~| not covered
     //~| not covered
+    //~| not covered
+    //~| not covered
+    //~| not covered
 }
 
 fn by_val(e: E) {
@@ -27,7 +33,7 @@ fn by_val(e: E) {
         E::A => {}
     }
 
-    let E::A = e; //~ ERROR refutable pattern in local binding: `B` not covered
+    let E::A = e; //~ ERROR refutable pattern in local binding: `B` and `C` not covered
 }
 
 fn by_ref_once(e: &E) {
@@ -35,7 +41,7 @@ fn by_ref_once(e: &E) {
         E::A => {}
     }
 
-    let E::A = e; //~ ERROR refutable pattern in local binding: `&B` not covered
+    let E::A = e; //~ ERROR refutable pattern in local binding: `&B` and `&C` not covered
 }
 
 fn by_ref_thrice(e: & &mut &E) {
@@ -43,7 +49,8 @@ fn by_ref_thrice(e: & &mut &E) {
         E::A => {}
     }
 
-    let E::A = e; //~ ERROR refutable pattern in local binding: `&&mut &B` not covered
+    let E::A = e;
+    //~^ ERROR refutable pattern in local binding: `&&mut &B` and `&&mut &C` not covered
 }
 
 enum Opt {
diff --git a/src/test/ui/match/non-exhaustive-defined-here.stderr b/src/test/ui/match/non-exhaustive-defined-here.stderr
index b0dccc975ab87..25b8bbdab2d8e 100644
--- a/src/test/ui/match/non-exhaustive-defined-here.stderr
+++ b/src/test/ui/match/non-exhaustive-defined-here.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `B` and `C` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:26:11
+  --> $DIR/non-exhaustive-defined-here.rs:32:11
    |
 LL | / enum E {
 LL | |
@@ -21,23 +21,29 @@ LL |       match e1 {
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
-error[E0005]: refutable pattern in local binding: `B` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:30:9
+error[E0005]: refutable pattern in local binding: `B` and `C` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:36:9
    |
 LL | / enum E {
 LL | |
 LL | |
 LL | |
 ...  |
+LL | |     B,
+   | |     - not covered
+...  |
+LL | |     C
+   | |     - not covered
+...  |
 LL | |
 LL | | }
    | |_- `E` defined here
 ...
 LL |       let E::A = e;
-   |           ^^^^ pattern `B` not covered
+   |           ^^^^ patterns `B` and `C` not covered
 
 error[E0004]: non-exhaustive patterns: `&B` and `&C` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:34:11
+  --> $DIR/non-exhaustive-defined-here.rs:40:11
    |
 LL | / enum E {
 LL | |
@@ -59,23 +65,29 @@ LL |       match e {
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
-error[E0005]: refutable pattern in local binding: `&B` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:38:9
+error[E0005]: refutable pattern in local binding: `&B` and `&C` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:44:9
    |
 LL | / enum E {
 LL | |
 LL | |
 LL | |
 ...  |
+LL | |     B,
+   | |     - not covered
+...  |
+LL | |     C
+   | |     - not covered
+...  |
 LL | |
 LL | | }
    | |_- `E` defined here
 ...
 LL |       let E::A = e;
-   |           ^^^^ pattern `&B` not covered
+   |           ^^^^ patterns `&B` and `&C` not covered
 
 error[E0004]: non-exhaustive patterns: `&&mut &B` and `&&mut &C` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:42:11
+  --> $DIR/non-exhaustive-defined-here.rs:48:11
    |
 LL | / enum E {
 LL | |
@@ -97,23 +109,29 @@ LL |       match e {
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
-error[E0005]: refutable pattern in local binding: `&&mut &B` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:46:9
+error[E0005]: refutable pattern in local binding: `&&mut &B` and `&&mut &C` not covered
+  --> $DIR/non-exhaustive-defined-here.rs:52:9
    |
 LL | / enum E {
 LL | |
 LL | |
 LL | |
 ...  |
+LL | |     B,
+   | |     - not covered
+...  |
+LL | |     C
+   | |     - not covered
+...  |
 LL | |
 LL | | }
    | |_- `E` defined here
 ...
 LL |       let E::A = e;
-   |           ^^^^ pattern `&&mut &B` not covered
+   |           ^^^^ patterns `&&mut &B` and `&&mut &C` not covered
 
 error[E0004]: non-exhaustive patterns: `None` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:58:11
+  --> $DIR/non-exhaustive-defined-here.rs:65:11
    |
 LL | / enum Opt {
 LL | |
@@ -131,13 +149,14 @@ LL |       match e {
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
 
 error[E0005]: refutable pattern in local binding: `None` not covered
-  --> $DIR/non-exhaustive-defined-here.rs:62:9
+  --> $DIR/non-exhaustive-defined-here.rs:69:9
    |
 LL | / enum Opt {
 LL | |
 LL | |
 LL | |     Some(u8),
 LL | |     None,
+   | |     ---- not covered
 LL | |
 LL | | }
    | |_- `Opt` defined here
diff --git a/src/test/ui/refutable-pattern-errors.rs b/src/test/ui/refutable-pattern-errors.rs
index aa5fa76bb8cff..8bcde1cc4dbbf 100644
--- a/src/test/ui/refutable-pattern-errors.rs
+++ b/src/test/ui/refutable-pattern-errors.rs
@@ -1,7 +1,9 @@
+// ignore-line-length
+
 fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
 //~^ ERROR refutable pattern in function argument: `(_, _)` not covered
 
 fn main() {
     let (1, (Some(1), 2..=3)) = (1, (None, 2));
-    //~^ ERROR refutable pattern in local binding: `(std::i32::MIN..=0i32, _)` not covered
+    //~^ ERROR refutable pattern in local binding: `(std::i32::MIN..=0i32, _)` and `(2i32..=std::i32::MAX, _)` not covered
 }
diff --git a/src/test/ui/refutable-pattern-errors.stderr b/src/test/ui/refutable-pattern-errors.stderr
index c67ae7c6d48d2..3b13e25293d58 100644
--- a/src/test/ui/refutable-pattern-errors.stderr
+++ b/src/test/ui/refutable-pattern-errors.stderr
@@ -1,14 +1,14 @@
 error[E0005]: refutable pattern in function argument: `(_, _)` not covered
-  --> $DIR/refutable-pattern-errors.rs:1:9
+  --> $DIR/refutable-pattern-errors.rs:3:9
    |
 LL | fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
    |         ^^^^^^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered
 
-error[E0005]: refutable pattern in local binding: `(std::i32::MIN..=0i32, _)` not covered
-  --> $DIR/refutable-pattern-errors.rs:5:9
+error[E0005]: refutable pattern in local binding: `(std::i32::MIN..=0i32, _)` and `(2i32..=std::i32::MAX, _)` not covered
+  --> $DIR/refutable-pattern-errors.rs:7:9
    |
 LL |     let (1, (Some(1), 2..=3)) = (1, (None, 2));
-   |         ^^^^^^^^^^^^^^^^^^^^^ pattern `(std::i32::MIN..=0i32, _)` not covered
+   |         ^^^^^^^^^^^^^^^^^^^^^ patterns `(std::i32::MIN..=0i32, _)` and `(2i32..=std::i32::MAX, _)` not covered
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr
index 45976f8ac56ad..29ff1dc376089 100644
--- a/src/test/ui/uninhabited/uninhabited-irrefutable.stderr
+++ b/src/test/ui/uninhabited/uninhabited-irrefutable.stderr
@@ -3,6 +3,7 @@ error[E0005]: refutable pattern in local binding: `A(_)` not covered
    |
 LL | / enum Foo {
 LL | |     A(foo::SecretlyEmpty),
+   | |     - not covered
 LL | |     B(foo::NotSoSecretlyEmpty),
 LL | |     C(NotSoSecretlyEmpty),
 LL | |     D(u32),

From eeca6ee9c2610aece26402e7d4112b83cb648744 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 9 Sep 2019 16:52:58 +0200
Subject: [PATCH 640/943] check_match: use pluralisee!

---
 src/librustc_mir/hair/pattern/check_match.rs | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs
index c7eeaaf6f23da..56b9c782f9497 100644
--- a/src/librustc_mir/hair/pattern/check_match.rs
+++ b/src/librustc_mir/hair/pattern/check_match.rs
@@ -493,10 +493,7 @@ fn joined_uncovered_patterns(witnesses: &[Pattern<'_>]) -> String {
 }
 
 fn pattern_not_convered_label(witnesses: &[Pattern<'_>], joined_patterns: &str) -> String {
-    match witnesses.len() {
-        1 => format!("pattern {} not covered", joined_patterns),
-        _ => format!("patterns {} not covered", joined_patterns),
-    }
+    format!("pattern{} {} not covered", rustc_errors::pluralise!(witnesses.len()), joined_patterns)
 }
 
 /// Point at the definition of non-covered `enum` variants.

From 0d34fe42f724ba094b8d131f869c716204450e5c Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Mon, 9 Sep 2019 17:04:28 +0200
Subject: [PATCH 641/943] Unify escape usage

---
 src/librustdoc/html/static/main.js | 47 ++++++++++++++++++------------
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 309e5575ee403..ef2c6d877bfc6 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -39,6 +39,14 @@ if (!DOMTokenList.prototype.remove) {
     };
 }
 
+function getSearchInput() {
+    return document.getElementsByClassName("search-input")[0];
+}
+
+function getSearchElement() {
+    return document.getElementById("search");
+}
+
 (function() {
     "use strict";
 
@@ -71,7 +79,7 @@ if (!DOMTokenList.prototype.remove) {
                      "derive",
                      "traitalias"];
 
-    var search_input = document.getElementsByClassName("search-input")[0];
+    var search_input = getSearchInput();
 
     // On the search screen, so you remain on the last tab you opened.
     //
@@ -158,7 +166,7 @@ if (!DOMTokenList.prototype.remove) {
         // If we're in mobile mode, we should add the sidebar in any case.
         hideSidebar();
         var elem;
-        var search = document.getElementById("search");
+        var search = getSearchElement();
         var i, from, to, match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
         if (match) {
             from = parseInt(match[1], 10);
@@ -250,7 +258,12 @@ if (!DOMTokenList.prototype.remove) {
         return String.fromCharCode(c);
     }
 
+    function getHelpElement() {
+        return document.getElementById("help");
+    }
+
     function displayHelp(display, ev, help) {
+        var help = help ? help : getHelpElement();
         if (display === true) {
             if (hasClass(help, "hidden")) {
                 ev.preventDefault();
@@ -264,9 +277,10 @@ if (!DOMTokenList.prototype.remove) {
         }
     }
 
-    function handleEscape(ev, help) {
+    function handleEscape(ev) {
+        var help = getHelpElement();
+        var search = getSearchElement();
         hideModal();
-        var search = document.getElementById("search");
         if (hasClass(help, "hidden") === false) {
             displayHelp(false, ev, help);
         } else if (hasClass(search, "hidden") === false) {
@@ -284,22 +298,21 @@ if (!DOMTokenList.prototype.remove) {
             return;
         }
 
-        var help = document.getElementById("help");
         if (document.activeElement.tagName === "INPUT") {
             switch (getVirtualKey(ev)) {
             case "Escape":
-                handleEscape(ev, help);
+                handleEscape(ev);
                 break;
             }
         } else {
             switch (getVirtualKey(ev)) {
             case "Escape":
-                handleEscape(ev, help);
+                handleEscape(ev);
                 break;
 
             case "s":
             case "S":
-                displayHelp(false, ev, help);
+                displayHelp(false, ev);
                 hideModal();
                 ev.preventDefault();
                 focusSearchBar();
@@ -314,7 +327,7 @@ if (!DOMTokenList.prototype.remove) {
             case "?":
                 if (ev.shiftKey) {
                     hideModal();
-                    displayHelp(true, ev, help);
+                    displayHelp(true, ev);
                 }
                 break;
             }
@@ -1285,9 +1298,7 @@ if (!DOMTokenList.prototype.remove) {
                 } else if (e.which === 16) { // shift
                     // Does nothing, it's just to avoid losing "focus" on the highlighted element.
                 } else if (e.which === 27) { // escape
-                    removeClass(actives[currentTab][0], "highlighted");
-                    search_input.value = "";
-                    defocusSearchBar();
+                    handleEscape(e);
                 } else if (actives[currentTab].length > 0) {
                     removeClass(actives[currentTab][0], "highlighted");
                 }
@@ -1438,7 +1449,7 @@ if (!DOMTokenList.prototype.remove) {
                 ret_others[0] + ret_in_args[0] + ret_returned[0] + "</div>";
 
             addClass(main, "hidden");
-            var search = document.getElementById("search");
+            var search = getSearchElement();
             removeClass(search, "hidden");
             search.innerHTML = output;
             var tds = search.getElementsByTagName("td");
@@ -1648,7 +1659,7 @@ if (!DOMTokenList.prototype.remove) {
                     if (hasClass(main, "content")) {
                         removeClass(main, "hidden");
                     }
-                    var search_c = document.getElementById("search");
+                    var search_c = getSearchElement();
                     if (hasClass(search_c, "content")) {
                         addClass(search_c, "hidden");
                     }
@@ -1695,7 +1706,7 @@ if (!DOMTokenList.prototype.remove) {
                         if (hasClass(main, "content")) {
                             removeClass(main, "hidden");
                         }
-                        var search_c = document.getElementById("search");
+                        var search_c = getSearchElement();
                         if (hasClass(search_c, "content")) {
                             addClass(search_c, "hidden");
                         }
@@ -2464,7 +2475,7 @@ if (!DOMTokenList.prototype.remove) {
     var params = getQueryStringParams();
     if (params && params.search) {
         addClass(main, "hidden");
-        var search = document.getElementById("search");
+        var search = getSearchElement();
         removeClass(search, "hidden");
         search.innerHTML = "<h3 style=\"text-align: center;\">Loading search results...</h3>";
     }
@@ -2549,10 +2560,10 @@ if (!DOMTokenList.prototype.remove) {
 
 // Sets the focus on the search bar at the top of the page
 function focusSearchBar() {
-    document.getElementsByClassName("search-input")[0].focus();
+    getSearchInput().focus();
 }
 
 // Removes the focus from the search bar
 function defocusSearchBar() {
-    document.getElementsByClassName("search-input")[0].blur();
+    getSearchInput().blur();
 }

From 20a26055b7afa500e1b00c6e5a3d03a1208c1d00 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Mon, 9 Sep 2019 17:05:41 +0200
Subject: [PATCH 642/943] pacify tidy.

---
 src/test/ui/refutable-pattern-errors.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/ui/refutable-pattern-errors.rs b/src/test/ui/refutable-pattern-errors.rs
index 8bcde1cc4dbbf..d4afe17ca748c 100644
--- a/src/test/ui/refutable-pattern-errors.rs
+++ b/src/test/ui/refutable-pattern-errors.rs
@@ -1,4 +1,4 @@
-// ignore-line-length
+// ignore-tidy-linelength
 
 fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { }
 //~^ ERROR refutable pattern in function argument: `(_, _)` not covered

From 34662c69614028944668f96c91ef294e7da048f0 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Wed, 4 Sep 2019 13:00:14 -0700
Subject: [PATCH 643/943] std: Add a `backtrace` module

This commit adds a `backtrace` module to the standard library, as
designed in [RFC 2504]. The `Backtrace` type is intentionally very
conservative, effectively only allowing capturing it and printing it.

Additionally this commit also adds a `backtrace` method to the `Error`
trait which defaults to returning `None`, as specified in [RFC 2504].
More information about the design here can be found in [RFC 2504] and in
the [tracking issue].

Implementation-wise this is all based on the `backtrace` crate and very
closely mirrors the `backtrace::Backtrace` type on crates.io. Otherwise
it's pretty standard in how it handles everything internally.

[RFC 2504]: https://github.com/rust-lang/rfcs/blob/master/text/2504-fix-error.md
[tracking issue]: https://github.com/rust-lang/rust/issues/53487

cc #53487
---
 src/libstd/backtrace.rs            | 352 +++++++++++++++++++++++++++++
 src/libstd/error.rs                |  15 ++
 src/libstd/lib.rs                  |   1 +
 src/libstd/sys_common/backtrace.rs | 119 +++++-----
 src/test/ui/std-backtrace.rs       |  75 ++++++
 5 files changed, 508 insertions(+), 54 deletions(-)
 create mode 100644 src/libstd/backtrace.rs
 create mode 100644 src/test/ui/std-backtrace.rs

diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs
new file mode 100644
index 0000000000000..5d46ef7dbb10a
--- /dev/null
+++ b/src/libstd/backtrace.rs
@@ -0,0 +1,352 @@
+//! Support for capturing a stack backtrace of an OS thread
+//!
+//! This module contains the support necessary to capture a stack backtrace of a
+//! running OS thread from the OS thread itself. The `Backtrace` type supports
+//! capturing a stack trace via the `Backtrace::capture` and
+//! `Backtrace::force_capture` functions.
+//!
+//! A backtrace is typically quite handy to attach to errors (e.g. types
+//! implementing `std::error::Error`) to get a causal chain of where an error
+//! was generated.
+//!
+//! > **Note**: this module is unstable and is designed in [RFC 2504], and you
+//! > can learn more about its status in the [tracking issue].
+//!
+//! [RFC 2504]: https://github.com/rust-lang/rfcs/blob/master/text/2504-fix-error.md
+//! [tracking issue]: https://github.com/rust-lang/rust/issues/53487
+//!
+//! ## Accuracy
+//!
+//! Backtraces are attempted to be as accurate as possible, but no guarantees
+//! are provided about the exact accuracy of a backtrace. Instruction pointers,
+//! symbol names, filenames, line numbers, etc, may all be incorrect when
+//! reported. Accuracy is attempted on a best-effort basis, however, and bugs
+//! are always welcome to indicate areas of improvement!
+//!
+//! For most platforms a backtrace with a filename/line number requires that
+//! programs be compiled with debug information. Without debug information
+//! filenames/line numbers will not be reported.
+//!
+//! ## Platform support
+//!
+//! Not all platforms that libstd compiles for support capturing backtraces.
+//! Some platforms simply do nothing when capturing a backtrace. To check
+//! whether the platform supports capturing backtraces you can consult the
+//! `BacktraceStatus` enum as a result of `Backtrace::status`.
+//!
+//! Like above with accuracy platform support is done on a best effort basis.
+//! Sometimes libraries may not be available at runtime or something may go
+//! wrong which would cause a backtrace to not be captured. Please feel free to
+//! report issues with platforms where a backtrace cannot be captured though!
+//!
+//! ## Environment Variables
+//!
+//! The `Backtrace::capture` function may not actually capture a backtrace by
+//! default. Its behavior is governed by two environment variables:
+//!
+//! * `RUST_LIB_BACKTRACE` - if this is set to `0` then `Backtrace::capture`
+//!   will never capture a backtrace. Any other value this is set to will enable
+//!   `Backtrace::capture`.
+//!
+//! * `RUST_BACKTRACE` - if `RUST_LIB_BACKTRACE` is not set, then this variable
+//!   is consulted with the same rules of `RUST_LIB_BACKTRACE`.
+//!
+//! * If neither of the above env vars are set, then `Backtrace::capture` will
+//!   be disabled.
+//!
+//! Capturing a backtrace can be a quite expensive runtime operation, so the
+//! environment variables allow either forcibly disabling this runtime
+//! performance hit or allow selectively enabling it in some programs.
+//!
+//! Note that the `Backtrace::force_capture` function can be used to ignore
+//! these environment variables. Also note that the state of environment
+//! variables is cached once the first backtrace is created, so altering
+//! `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` at runtime may not actually change
+//! how backtraces are captured.
+
+#![unstable(feature = "backtrace", issue = "53487")]
+
+// NB: A note on resolution of a backtrace:
+//
+// Backtraces primarily happen in two steps, one is where we actually capture
+// the stack backtrace, giving us a list of instruction pointers corresponding
+// to stack frames. Next we take these instruction pointers and, one-by-one,
+// turn them into a human readable name (like `main`).
+//
+// The first phase can be somewhat expensive (walking the stack), especially
+// on MSVC where debug information is consulted to return inline frames each as
+// their own frame. The second phase, however, is almost always extremely
+// expensive (on the order of milliseconds sometimes) when it's consulting debug
+// information.
+//
+// We attempt to amortize this cost as much as possible by delaying resolution
+// of an address to a human readable name for as long as possible. When
+// `Backtrace::create` is called to capture a backtrace it doesn't actually
+// perform any symbol resolution, but rather we lazily resolve symbols only just
+// before they're needed for printing. This way we can make capturing a
+// backtrace and throwing it away much cheaper, but actually printing a
+// backtrace is still basically the same cost.
+//
+// This strategy comes at the cost of some synchronization required inside of a
+// `Backtrace`, but that's a relatively small price to pay relative to capturing
+// a backtrace or actually symbolizing it.
+
+use crate::env;
+use crate::fmt;
+use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
+use crate::sync::Mutex;
+use crate::sys_common::backtrace::{output_filename, lock};
+use crate::vec::Vec;
+use backtrace::BytesOrWideString;
+
+/// A captured OS thread stack backtrace.
+///
+/// This type represents a stack backtrace for an OS thread captured at a
+/// previous point in time. In some instances the `Backtrace` type may
+/// internally be empty due to configuration. For more information see
+/// `Backtrace::capture`.
+pub struct Backtrace {
+    inner: Inner,
+}
+
+/// The current status of a backtrace, indicating whether it was captured or
+/// whether it is empty for some other reason.
+#[non_exhaustive]
+#[derive(Debug)]
+pub enum BacktraceStatus {
+    /// Capturing a backtrace is not supported, likely because it's not
+    /// implemented for the current platform.
+    Unsupported,
+    /// Capturing a backtrace has been disabled through either the
+    /// `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` environment variables.
+    Disabled,
+    /// A backtrace has been captured and the `Backtrace` should print
+    /// reasonable information when rendered.
+    Captured,
+}
+
+enum Inner {
+    Unsupported,
+    Disabled,
+    Captured(Mutex<Capture>),
+}
+
+struct Capture {
+    actual_start: usize,
+    resolved: bool,
+    frames: Vec<BacktraceFrame>,
+}
+
+fn _assert_send_sync() {
+    fn _assert<T: Send + Sync>() {}
+    _assert::<Backtrace>();
+}
+
+struct BacktraceFrame {
+    frame: backtrace::Frame,
+    symbols: Vec<BacktraceSymbol>,
+}
+
+struct BacktraceSymbol {
+    name: Option<Vec<u8>>,
+    filename: Option<BytesOrWide>,
+    lineno: Option<u32>,
+}
+
+enum BytesOrWide {
+    Bytes(Vec<u8>),
+    Wide(Vec<u16>),
+}
+
+impl Backtrace {
+    /// Returns whether backtrace captures are enabled through environment
+    /// variables.
+    fn enabled() -> bool {
+        // Cache the result of reading the environment variables to make
+        // backtrace captures speedy, because otherwise reading environment
+        // variables every time can be somewhat slow.
+        static ENABLED: AtomicUsize = AtomicUsize::new(0);
+        match ENABLED.load(SeqCst) {
+            0 => {}
+            1 => return false,
+            _ => return true,
+        }
+        let enabled = match env::var("RUST_LIB_BACKTRACE") {
+            Ok(s) => s != "0",
+            Err(_) => match env::var("RUST_BACKTRACE") {
+                Ok(s) => s != "0",
+                Err(_) => false,
+            },
+        };
+        ENABLED.store(enabled as usize + 1, SeqCst);
+        return enabled;
+    }
+
+    /// Capture a stack backtrace of the current thread.
+    ///
+    /// This function will capture a stack backtrace of the current OS thread of
+    /// execution, returning a `Backtrace` type which can be later used to print
+    /// the entire stack trace or render it to a string.
+    ///
+    /// This function will be a noop if the `RUST_BACKTRACE` or
+    /// `RUST_LIB_BACKTRACE` backtrace variables are both not set. If either
+    /// environment variable is set and enabled then this function will actually
+    /// capture a backtrace. Capturing a backtrace can be both memory intensive
+    /// and slow, so these environment variables allow liberally using
+    /// `Backtrace::capture` and only incurring a slowdown when the environment
+    /// variables are set.
+    ///
+    /// To forcibly capture a backtrace regardless of environment variables, use
+    /// the `Backtrace::force_capture` function.
+    #[inline(never)] // want to make sure there's a frame here to remove
+    pub fn capture() -> Backtrace {
+        if !Backtrace::enabled() {
+            return Backtrace { inner: Inner::Disabled };
+        }
+        Backtrace::create(Backtrace::capture as usize)
+    }
+
+    /// Forcibly captures a full backtrace, regardless of environment variable
+    /// configuration.
+    ///
+    /// This function behaves the same as `capture` except that it ignores the
+    /// values of the `RUST_BACKTRACE` and `RUST_LIB_BACKTRACE` environment
+    /// variables, always capturing a backtrace.
+    ///
+    /// Note that capturing a backtrace can be an expensive operation on some
+    /// platforms, so this should be used with caution in performance-sensitive
+    /// parts of code.
+    #[inline(never)] // want to make sure there's a frame here to remove
+    pub fn force_capture() -> Backtrace {
+        Backtrace::create(Backtrace::force_capture as usize)
+    }
+
+    // Capture a backtrace which start just before the function addressed by
+    // `ip`
+    fn create(ip: usize) -> Backtrace {
+        let _lock = lock();
+        let mut frames = Vec::new();
+        let mut actual_start = None;
+        unsafe {
+            backtrace::trace_unsynchronized(|frame| {
+                frames.push(BacktraceFrame { frame: frame.clone(), symbols: Vec::new() });
+                if frame.symbol_address() as usize == ip && actual_start.is_none() {
+                    actual_start = Some(frames.len());
+                }
+                true
+            });
+        }
+
+        // If no frames came out assume that this is an unsupported platform
+        // since `backtrace` doesn't provide a way of learning this right now,
+        // and this should be a good enough approximation.
+        let inner = if frames.len() == 0 {
+            Inner::Unsupported
+        } else {
+            Inner::Captured(Mutex::new(Capture {
+                actual_start: actual_start.unwrap_or(0),
+                frames,
+                resolved: false,
+            }))
+        };
+
+        Backtrace { inner }
+    }
+
+    /// Returns the status of this backtrace, indicating whether this backtrace
+    /// request was unsupported, disabled, or a stack trace was actually
+    /// captured.
+    pub fn status(&self) -> BacktraceStatus {
+        match self.inner {
+            Inner::Unsupported => BacktraceStatus::Unsupported,
+            Inner::Disabled => BacktraceStatus::Disabled,
+            Inner::Captured(_) => BacktraceStatus::Captured,
+        }
+    }
+}
+
+impl fmt::Display for Backtrace {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Debug::fmt(self, fmt)
+    }
+}
+
+impl fmt::Debug for Backtrace {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let mut capture = match &self.inner {
+            Inner::Unsupported => return fmt.write_str("unsupported backtrace"),
+            Inner::Disabled => return fmt.write_str("disabled backtrace"),
+            Inner::Captured(c) => c.lock().unwrap(),
+        };
+        capture.resolve();
+
+        let full = fmt.alternate();
+        let (frames, style) = if full {
+            (&capture.frames[..], backtrace::PrintFmt::Full)
+        } else {
+            (&capture.frames[capture.actual_start..], backtrace::PrintFmt::Short)
+        };
+
+        // When printing paths we try to strip the cwd if it exists, otherwise
+        // we just print the path as-is. Note that we also only do this for the
+        // short format, because if it's full we presumably want to print
+        // everything.
+        let cwd = crate::env::current_dir();
+        let mut print_path = move |fmt: &mut fmt::Formatter<'_>, path: BytesOrWideString<'_>| {
+            output_filename(fmt, path, style, cwd.as_ref().ok())
+        };
+
+        let mut f = backtrace::BacktraceFmt::new(fmt, style, &mut print_path);
+        f.add_context()?;
+        for frame in frames {
+            let mut f = f.frame();
+            if frame.symbols.is_empty() {
+                f.print_raw(frame.frame.ip(), None, None, None)?;
+            } else {
+                for symbol in frame.symbols.iter() {
+                    f.print_raw(
+                        frame.frame.ip(),
+                        symbol.name.as_ref().map(|b| backtrace::SymbolName::new(b)),
+                        symbol.filename.as_ref().map(|b| match b {
+                            BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
+                            BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
+                        }),
+                        symbol.lineno,
+                    )?;
+                }
+            }
+        }
+        f.finish()?;
+        Ok(())
+    }
+}
+
+impl Capture {
+    fn resolve(&mut self) {
+        // If we're already resolved, nothing to do!
+        if self.resolved {
+            return;
+        }
+        self.resolved = true;
+
+        // Use the global backtrace lock to synchronize this as it's a
+        // requirement of the `backtrace` crate, and then actually resolve
+        // everything.
+        let _lock = lock();
+        for frame in self.frames.iter_mut() {
+            let symbols = &mut frame.symbols;
+            unsafe {
+                backtrace::resolve_frame_unsynchronized(&frame.frame, |symbol| {
+                    symbols.push(BacktraceSymbol {
+                        name: symbol.name().map(|m| m.as_bytes().to_vec()),
+                        filename: symbol.filename_raw().map(|b| match b {
+                            BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()),
+                            BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()),
+                        }),
+                        lineno: symbol.lineno(),
+                    });
+                });
+            }
+        }
+    }
+}
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 117a430eec6b9..998d59f90a255 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -17,6 +17,7 @@ use core::array;
 
 use crate::alloc::{AllocErr, LayoutErr, CannotReallocInPlace};
 use crate::any::TypeId;
+use crate::backtrace::Backtrace;
 use crate::borrow::Cow;
 use crate::cell;
 use crate::char;
@@ -204,6 +205,20 @@ pub trait Error: Debug + Display {
     fn type_id(&self, _: private::Internal) -> TypeId where Self: 'static {
         TypeId::of::<Self>()
     }
+
+    /// Returns a stack backtrace, if available, of where this error ocurred.
+    ///
+    /// This function allows inspecting the location, in code, of where an error
+    /// happened. The returned `Backtrace` contains information about the stack
+    /// trace of the OS thread of execution of where the error originated from.
+    ///
+    /// Note that not all errors contain a `Backtrace`. Also note that a
+    /// `Backtrace` may actually be empty. For more information consult the
+    /// `Backtrace` type itself.
+    #[unstable(feature = "backtrace", issue = "53487")]
+    fn backtrace(&self) -> Option<&Backtrace> {
+        None
+    }
 }
 
 mod private {
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 71050b0dcd1f5..388c997d7c77c 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -452,6 +452,7 @@ pub mod f64;
 #[macro_use]
 pub mod thread;
 pub mod ascii;
+pub mod backtrace;
 pub mod collections;
 pub mod env;
 pub mod error;
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index f434b62aced67..839dc51b9e9e8 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -4,8 +4,9 @@
 use crate::env;
 use crate::fmt;
 use crate::io;
+use crate::borrow::Cow;
 use crate::io::prelude::*;
-use crate::path::{self, Path};
+use crate::path::{self, Path, PathBuf};
 use crate::sync::atomic::{self, Ordering};
 use crate::sys::mutex::Mutex;
 
@@ -14,10 +15,26 @@ use backtrace::{BacktraceFmt, BytesOrWideString, PrintFmt};
 /// Max number of frames to print.
 const MAX_NB_FRAMES: usize = 100;
 
-/// Prints the current backtrace.
-pub fn print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
+pub fn lock() -> impl Drop {
+    struct Guard;
     static LOCK: Mutex = Mutex::new();
 
+    impl Drop for Guard {
+        fn drop(&mut self) {
+            unsafe {
+                LOCK.unlock();
+            }
+        }
+    }
+
+    unsafe {
+        LOCK.lock();
+        return Guard;
+    }
+}
+
+/// Prints the current backtrace.
+pub fn print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
     // There are issues currently linking libbacktrace into tests, and in
     // general during libstd's own unit tests we're not testing this path. In
     // test mode immediately return here to optimize away any references to the
@@ -29,71 +46,67 @@ pub fn print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
     // Use a lock to prevent mixed output in multithreading context.
     // Some platforms also requires it, like `SymFromAddr` on Windows.
     unsafe {
-        LOCK.lock();
-        let res = _print(w, format);
-        LOCK.unlock();
-        res
+        let _lock = lock();
+        _print(w, format)
     }
 }
 
-fn _print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
+unsafe fn _print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
     struct DisplayBacktrace {
         format: PrintFmt,
     }
     impl fmt::Display for DisplayBacktrace {
         fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-            _print_fmt(fmt, self.format)
+            unsafe {
+                _print_fmt(fmt, self.format)
+            }
         }
     }
     write!(w, "{}", DisplayBacktrace { format })
 }
 
-fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::Result {
+unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::Result {
+    let cwd = env::current_dir().ok();
     let mut print_path = move |fmt: &mut fmt::Formatter<'_>, bows: BytesOrWideString<'_>| {
-        output_filename(fmt, bows, print_fmt)
+        output_filename(fmt, bows, print_fmt, cwd.as_ref())
     };
     let mut bt_fmt = BacktraceFmt::new(fmt, print_fmt, &mut print_path);
     bt_fmt.add_context()?;
-    let mut skipped = false;
-    unsafe {
-        let mut idx = 0;
-        let mut res = Ok(());
-        backtrace::trace_unsynchronized(|frame| {
-            if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {
-                skipped = true;
-                return false;
-            }
+    let mut idx = 0;
+    let mut res = Ok(());
+    backtrace::trace_unsynchronized(|frame| {
+        if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {
+            return false;
+        }
 
-            let mut hit = false;
-            let mut stop = false;
-            backtrace::resolve_frame_unsynchronized(frame, |symbol| {
-                hit = true;
-                if print_fmt == PrintFmt::Short {
-                    if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
-                        if sym.contains("__rust_begin_short_backtrace") {
-                            skipped = true;
-                            stop = true;
-                            return;
-                        }
+        let mut hit = false;
+        let mut stop = false;
+        backtrace::resolve_frame_unsynchronized(frame, |symbol| {
+            hit = true;
+            if print_fmt == PrintFmt::Short {
+                if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
+                    if sym.contains("__rust_begin_short_backtrace") {
+                        stop = true;
+                        return;
                     }
                 }
-
-                res = bt_fmt.frame().symbol(frame, symbol);
-            });
-            if stop {
-                return false;
-            }
-            if !hit {
-                res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
             }
 
-            idx += 1;
-            res.is_ok()
+            res = bt_fmt.frame().symbol(frame, symbol);
         });
-        res?;
-    }
+        if stop {
+            return false;
+        }
+        if !hit {
+            res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
+        }
+
+        idx += 1;
+        res.is_ok()
+    });
+    res?;
     bt_fmt.finish()?;
-    if skipped {
+    if print_fmt == PrintFmt::Short {
         writeln!(
             fmt,
             "note: Some details are omitted, \
@@ -147,36 +160,34 @@ pub fn log_enabled() -> Option<PrintFmt> {
 /// Prints the filename of the backtrace frame.
 ///
 /// See also `output`.
-fn output_filename(
+pub fn output_filename(
     fmt: &mut fmt::Formatter<'_>,
     bows: BytesOrWideString<'_>,
     print_fmt: PrintFmt,
+    cwd: Option<&PathBuf>,
 ) -> fmt::Result {
-    #[cfg(windows)]
-    let path_buf;
-    let file = match bows {
+    let file: Cow<'_, Path> = match bows {
         #[cfg(unix)]
         BytesOrWideString::Bytes(bytes) => {
             use crate::os::unix::prelude::*;
-            Path::new(crate::ffi::OsStr::from_bytes(bytes))
+            Path::new(crate::ffi::OsStr::from_bytes(bytes)).into()
         }
         #[cfg(not(unix))]
         BytesOrWideString::Bytes(bytes) => {
-            Path::new(crate::str::from_utf8(bytes).unwrap_or("<unknown>"))
+            Path::new(crate::str::from_utf8(bytes).unwrap_or("<unknown>")).into()
         }
         #[cfg(windows)]
         BytesOrWideString::Wide(wide) => {
             use crate::os::windows::prelude::*;
-            path_buf = crate::ffi::OsString::from_wide(wide);
-            Path::new(&path_buf)
+            Cow::Owned(crate::ffi::OsString::from_wide(wide).into())
         }
         #[cfg(not(windows))]
         BytesOrWideString::Wide(_wide) => {
-            Path::new("<unknown>")
+            Path::new("<unknown>").into()
         }
     };
     if print_fmt == PrintFmt::Short && file.is_absolute() {
-        if let Ok(cwd) = env::current_dir() {
+        if let Some(cwd) = cwd {
             if let Ok(stripped) = file.strip_prefix(&cwd) {
                 if let Some(s) = stripped.to_str() {
                     return write!(fmt, ".{}{}", path::MAIN_SEPARATOR, s);
diff --git a/src/test/ui/std-backtrace.rs b/src/test/ui/std-backtrace.rs
new file mode 100644
index 0000000000000..d84c493d53523
--- /dev/null
+++ b/src/test/ui/std-backtrace.rs
@@ -0,0 +1,75 @@
+// run-pass
+// ignore-android FIXME #17520
+// ignore-cloudabi spawning processes is not supported
+// ignore-emscripten spawning processes is not supported
+// ignore-openbsd no support for libbacktrace without filename
+// ignore-sgx no processes
+// ignore-msvc see #62897 and `backtrace-debuginfo.rs` test
+// compile-flags:-g
+
+#![feature(backtrace)]
+
+use std::env;
+use std::process::Command;
+use std::str;
+
+fn main() {
+    let args: Vec<String> = env::args().collect();
+    if args.len() >= 2 && args[1] == "force" {
+        println!("{}", std::backtrace::Backtrace::force_capture());
+    } else if args.len() >= 2 {
+        println!("{}", std::backtrace::Backtrace::capture());
+    } else {
+        runtest(&args[0]);
+        println!("test ok");
+    }
+}
+
+fn runtest(me: &str) {
+    env::remove_var("RUST_BACKTRACE");
+    env::remove_var("RUST_LIB_BACKTRACE");
+
+    let p = Command::new(me).arg("a").env("RUST_BACKTRACE", "1").output().unwrap();
+    assert!(p.status.success());
+    assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n"));
+    assert!(String::from_utf8_lossy(&p.stdout).contains("backtrace::main"));
+
+    let p = Command::new(me).arg("a").env("RUST_BACKTRACE", "0").output().unwrap();
+    assert!(p.status.success());
+    assert!(String::from_utf8_lossy(&p.stdout).contains("disabled backtrace\n"));
+
+    let p = Command::new(me).arg("a").output().unwrap();
+    assert!(p.status.success());
+    assert!(String::from_utf8_lossy(&p.stdout).contains("disabled backtrace\n"));
+
+    let p = Command::new(me)
+        .arg("a")
+        .env("RUST_LIB_BACKTRACE", "1")
+        .env("RUST_BACKTRACE", "1")
+        .output()
+        .unwrap();
+    assert!(p.status.success());
+    assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n"));
+
+    let p = Command::new(me)
+        .arg("a")
+        .env("RUST_LIB_BACKTRACE", "0")
+        .env("RUST_BACKTRACE", "1")
+        .output()
+        .unwrap();
+    assert!(p.status.success());
+    assert!(String::from_utf8_lossy(&p.stdout).contains("disabled backtrace\n"));
+
+    let p = Command::new(me)
+        .arg("force")
+        .env("RUST_LIB_BACKTRACE", "0")
+        .env("RUST_BACKTRACE", "0")
+        .output()
+        .unwrap();
+    assert!(p.status.success());
+    assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n"));
+
+    let p = Command::new(me).arg("force").output().unwrap();
+    assert!(p.status.success());
+    assert!(String::from_utf8_lossy(&p.stdout).contains("stack backtrace:\n"));
+}

From 625a9d6a4b0d0ef89e9a70e91275b7f91d871e65 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Mon, 9 Sep 2019 17:37:38 +0300
Subject: [PATCH 644/943] lldb: avoid mixing "Hit breakpoint" message with
 other output.

---
 src/etc/lldb_batchmode.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/etc/lldb_batchmode.py b/src/etc/lldb_batchmode.py
index 537b419b3279f..7c2e91474c1f1 100644
--- a/src/etc/lldb_batchmode.py
+++ b/src/etc/lldb_batchmode.py
@@ -45,7 +45,10 @@ def normalize_whitespace(s):
 
 def breakpoint_callback(frame, bp_loc, dict):
     """This callback is registered with every breakpoint and makes sure that the
-    frame containing the breakpoint location is selected"""
+    frame containing the breakpoint location is selected """
+
+    # HACK(eddyb) print a newline to avoid continuing an unfinished line.
+    print("")
     print("Hit breakpoint " + str(bp_loc))
 
     # Select the frame and the thread containing it

From 91dae2e233d6b468731eaa8908794d0a7e4e876d Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Sun, 8 Sep 2019 10:28:01 +0200
Subject: [PATCH 645/943] Bump RLS and Rustfmt submodules

---
 src/tools/rls     | 2 +-
 src/tools/rustfmt | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/tools/rls b/src/tools/rls
index 496c892752213..412fb00b37afb 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit 496c89275221303a4b0c2779cb8203fb3ce2a136
+Subproject commit 412fb00b37afb6b7f7fa96a35f2315c7e640b916
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
index f800ce47d1da2..afb1ee1c14594 160000
--- a/src/tools/rustfmt
+++ b/src/tools/rustfmt
@@ -1 +1 @@
-Subproject commit f800ce47d1da2a1c02ffd260deca8b7445f7facf
+Subproject commit afb1ee1c14594aed5bb4a762b357b01f13c9de10

From c2249a4bf996435803ad3f8fbe9fe45d9289e19f Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Sun, 8 Sep 2019 10:28:11 +0200
Subject: [PATCH 646/943] cargo update -p rustfmt-nightly

---
 Cargo.lock | 523 ++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 374 insertions(+), 149 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 108c2fbd8f503..beae224b500dc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -223,9 +223,9 @@ checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
 
 [[package]]
 name = "bytecount"
-version = "0.5.1"
+version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be0fdd54b507df8f22012890aadd099979befdba27713c767993f8380112ca7c"
+checksum = "b0017894339f586ccb943b01b9555de56770c11cda818e7e3d8bd93f4ed7f46e"
 dependencies = [
  "packed_simd",
 ]
@@ -287,7 +287,7 @@ dependencies = [
  "git2-curl",
  "glob",
  "hex",
- "home 0.5.0",
+ "home",
  "ignore",
  "im-rc",
  "jobserver",
@@ -309,7 +309,7 @@ dependencies = [
  "same-file",
  "semver",
  "serde",
- "serde_ignored 0.1.0",
+ "serde_ignored",
  "serde_json",
  "shell-escape",
  "strip-ansi-escapes",
@@ -392,9 +392,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "2.32.0"
+version = "2.33.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
+checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
 dependencies = [
  "ansi_term",
  "atty",
@@ -753,9 +753,9 @@ checksum = "d2a368589465391e127e10c9e3a08efc8df66fd49b87dc8524c764bbe7f2ef82"
 dependencies = [
  "fnv",
  "ident_case",
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
 ]
 
 [[package]]
@@ -765,8 +765,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "244e8987bd4e174385240cde20a3657f607fb0797563c28255c353b5819a07b1"
 dependencies = [
  "darling_core",
- "quote",
- "syn",
+ "quote 0.6.12",
+ "syn 0.15.35",
 ]
 
 [[package]]
@@ -781,9 +781,9 @@ version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6ca414e896ae072546f4d789f452daaecf60ddee4c9df5dc6d5936d769e3d87c"
 dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
 ]
 
 [[package]]
@@ -792,10 +792,10 @@ version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871"
 dependencies = [
- "proc-macro2",
- "quote",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
  "rustc_version",
- "syn",
+ "syn 0.15.35",
 ]
 
 [[package]]
@@ -953,9 +953,9 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
 dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
  "synstructure",
 ]
 
@@ -1259,16 +1259,6 @@ version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
 
-[[package]]
-name = "home"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80dff82fb58cfbbc617fb9a9184b010be0529201553cda50ad04372bc2333aff"
-dependencies = [
- "scopeguard 0.3.3",
- "winapi 0.3.6",
-]
-
 [[package]]
 name = "home"
 version = "0.5.0"
@@ -1288,9 +1278,9 @@ dependencies = [
  "log",
  "mac",
  "markup5ever",
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
 ]
 
 [[package]]
@@ -1528,11 +1518,30 @@ version = "0.11.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be"
 
+[[package]]
+name = "jsonrpc-client-transports"
+version = "13.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39577db48b004cffb4c5b8e5c9b993c177c52599ecbee88711e815acf65144db"
+dependencies = [
+ "failure",
+ "futures",
+ "jsonrpc-core",
+ "jsonrpc-pubsub",
+ "jsonrpc-server-utils",
+ "log",
+ "parity-tokio-ipc",
+ "serde",
+ "serde_json",
+ "tokio",
+ "url 1.7.2",
+]
+
 [[package]]
 name = "jsonrpc-core"
-version = "12.0.0"
+version = "13.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "288dca7f9713710a29e485076b9340156cb701edb46a881f5d0c31aa4f5b9143"
+checksum = "dd42951eb35079520ee29b7efbac654d85821b397ef88c8151600ef7e2d00217"
 dependencies = [
  "futures",
  "log",
@@ -1541,6 +1550,70 @@ dependencies = [
  "serde_json",
 ]
 
+[[package]]
+name = "jsonrpc-core-client"
+version = "13.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f047c10738edee7c3c6acf5241a0ce33df32ef9230c1a7fb03e4a77ee72c992f"
+dependencies = [
+ "jsonrpc-client-transports",
+]
+
+[[package]]
+name = "jsonrpc-derive"
+version = "13.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29f9149f785deaae92a4c834a9a1a83a4313b8cfedccf15362cd4cf039a64501"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
+]
+
+[[package]]
+name = "jsonrpc-ipc-server"
+version = "13.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "256c5e4292c17b4c2ecdf542299dc8e9d6b3939c075c54825570ad9317fe5751"
+dependencies = [
+ "jsonrpc-core",
+ "jsonrpc-server-utils",
+ "log",
+ "parity-tokio-ipc",
+ "parking_lot 0.9.0",
+ "tokio-service",
+]
+
+[[package]]
+name = "jsonrpc-pubsub"
+version = "13.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2c08b444cc0ed70263798834343d0ac875e664257df8079160f23ac1ea79446"
+dependencies = [
+ "jsonrpc-core",
+ "log",
+ "parking_lot 0.9.0",
+ "serde",
+]
+
+[[package]]
+name = "jsonrpc-server-utils"
+version = "13.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44561bfdd31401bad790527f1e951dde144f2341ddc3e1b859d32945e1a34eff"
+dependencies = [
+ "bytes",
+ "globset",
+ "jsonrpc-core",
+ "lazy_static 1.3.0",
+ "log",
+ "num_cpus",
+ "tokio",
+ "tokio-codec",
+ "unicase 2.4.0",
+]
+
 [[package]]
 name = "kernel32-sys"
 version = "0.2.2"
@@ -1655,6 +1728,15 @@ dependencies = [
  "scopeguard 0.3.3",
 ]
 
+[[package]]
+name = "lock_api"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc"
+dependencies = [
+ "scopeguard 1.0.0",
+]
+
 [[package]]
 name = "log"
 version = "0.4.8"
@@ -1686,18 +1768,15 @@ dependencies = [
 
 [[package]]
 name = "lsp-types"
-version = "0.57.2"
+version = "0.60.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b62b77309737b1e262b3bbf37ff8faa740562c633b14702afe9be85dbcb6f88a"
+checksum = "fe3edefcd66dde1f7f1df706f46520a3c93adc5ca4bc5747da6621195e894efd"
 dependencies = [
  "bitflags",
- "num-derive",
- "num-traits",
  "serde",
- "serde_derive",
  "serde_json",
- "url 1.7.2",
- "url_serde",
+ "serde_repr",
+ "url 2.1.0",
 ]
 
 [[package]]
@@ -1800,7 +1879,7 @@ dependencies = [
  "serde",
  "serde_derive",
  "serde_json",
- "structopt",
+ "structopt 0.2.18",
  "url 1.7.2",
 ]
 
@@ -2033,18 +2112,6 @@ version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
 
-[[package]]
-name = "num-derive"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8af1847c907c2f04d7bfd572fb25bbb4385c637fe5be163cf2f8c5d778fe1e7d"
-dependencies = [
- "num-traits",
- "proc-macro2",
- "quote",
- "syn",
-]
-
 [[package]]
 name = "num-integer"
 version = "0.1.39"
@@ -2178,14 +2245,43 @@ dependencies = [
  "unwind",
 ]
 
+[[package]]
+name = "parity-tokio-ipc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8281bf4f1d6429573f89589bf68d89451c46750977a8264f8ea3edbabeba7947"
+dependencies = [
+ "bytes",
+ "futures",
+ "log",
+ "mio-named-pipes",
+ "miow 0.3.3",
+ "rand 0.7.0",
+ "tokio",
+ "tokio-named-pipes",
+ "tokio-uds",
+ "winapi 0.3.6",
+]
+
 [[package]]
 name = "parking_lot"
 version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
 dependencies = [
- "lock_api",
- "parking_lot_core",
+ "lock_api 0.1.3",
+ "parking_lot_core 0.4.0",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252"
+dependencies = [
+ "lock_api 0.3.1",
+ "parking_lot_core 0.6.2",
+ "rustc_version",
 ]
 
 [[package]]
@@ -2201,6 +2297,21 @@ dependencies = [
  "winapi 0.3.6",
 ]
 
+[[package]]
+name = "parking_lot_core"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
+dependencies = [
+ "cfg-if",
+ "cloudabi",
+ "libc",
+ "redox_syscall",
+ "rustc_version",
+ "smallvec",
+ "winapi 0.3.6",
+]
+
 [[package]]
 name = "percent-encoding"
 version = "1.0.1"
@@ -2240,9 +2351,9 @@ checksum = "63120576c4efd69615b5537d3d052257328a4ca82876771d6944424ccfd9f646"
 dependencies = [
  "pest",
  "pest_meta",
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
 ]
 
 [[package]]
@@ -2355,6 +2466,26 @@ dependencies = [
  "log",
 ]
 
+[[package]]
+name = "proc-macro-crate"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e10d4b51f154c8a7fb96fd6dad097cb74b863943ec010ac94b9fd1be8861fe1e"
+dependencies = [
+ "toml",
+]
+
+[[package]]
+name = "proc-macro-error"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aeccfe4d5d8ea175d5f0e4a2ad0637e0f4121d63bd99d356fb1f39ab2e7c6097"
+dependencies = [
+ "proc-macro2 1.0.3",
+ "quote 1.0.2",
+ "syn 1.0.5",
+]
+
 [[package]]
 name = "proc-macro2"
 version = "0.4.30"
@@ -2364,6 +2495,15 @@ dependencies = [
  "unicode-xid 0.1.0",
 ]
 
+[[package]]
+name = "proc-macro2"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e98a83a9f9b331f54b924e68a66acb1bb35cb01fb0a23645139967abefb697e8"
+dependencies = [
+ "unicode-xid 0.2.0",
+]
+
 [[package]]
 name = "proc_macro"
 version = "0.0.0"
@@ -2416,14 +2556,23 @@ version = "0.6.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
 dependencies = [
- "proc-macro2",
+ "proc-macro2 0.4.30",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
+dependencies = [
+ "proc-macro2 1.0.3",
 ]
 
 [[package]]
 name = "racer"
-version = "2.1.25"
+version = "2.1.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0727b9d7baaf9e42851145545d7b980b5c1752bd16a4c77c925c5e573d0069d9"
+checksum = "dde22b84ab75220015cbd91240222402bf885cbe3a5dc856475771abb82533ae"
 dependencies = [
  "bitflags",
  "clap",
@@ -2715,7 +2864,7 @@ checksum = "cabe4fa914dec5870285fa7f71f602645da47c486e68486d2b4ceb4a343e90ac"
 
 [[package]]
 name = "rls"
-version = "1.38.0"
+version = "1.39.0"
 dependencies = [
  "cargo",
  "cargo_metadata",
@@ -2726,7 +2875,7 @@ dependencies = [
  "failure",
  "futures",
  "heck",
- "home 0.3.3",
+ "home",
  "itertools 0.8.0",
  "jsonrpc-core",
  "lazy_static 1.3.0",
@@ -2741,6 +2890,7 @@ dependencies = [
  "regex",
  "rls-analysis",
  "rls-data",
+ "rls-ipc",
  "rls-rustc",
  "rls-span",
  "rls-vfs",
@@ -2750,14 +2900,14 @@ dependencies = [
  "rustfmt-nightly",
  "serde",
  "serde_derive",
- "serde_ignored 0.0.4",
+ "serde_ignored",
  "serde_json",
  "tempfile",
  "tokio",
  "tokio-process",
  "tokio-timer",
  "toml",
- "url 1.7.2",
+ "url 2.1.0",
  "walkdir",
 ]
 
@@ -2788,9 +2938,33 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "rls-ipc"
+version = "0.1.0"
+dependencies = [
+ "jsonrpc-core",
+ "jsonrpc-core-client",
+ "jsonrpc-derive",
+ "jsonrpc-ipc-server",
+ "rls-data",
+ "serde",
+]
+
 [[package]]
 name = "rls-rustc"
 version = "0.6.0"
+dependencies = [
+ "clippy_lints",
+ "env_logger",
+ "failure",
+ "futures",
+ "log",
+ "rand 0.6.1",
+ "rls-data",
+ "rls-ipc",
+ "serde",
+ "tokio",
+]
 
 [[package]]
 name = "rls-span"
@@ -2837,7 +3011,7 @@ dependencies = [
  "log",
  "measureme",
  "num_cpus",
- "parking_lot",
+ "parking_lot 0.7.1",
  "polonius-engine",
  "rustc-rayon",
  "rustc-rayon-core",
@@ -2856,9 +3030,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-arena"
-version = "546.0.0"
+version = "583.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4dc2e1e68b64268c543bfa6e63e3c0d9ea58074c71396f42f76931f35a9287f9"
+checksum = "f59b76d334bd533f3fdc5c651c27678c5e80fac67c6f7da22ba21a58878c55f5"
 dependencies = [
  "rustc-ap-rustc_data_structures",
  "smallvec",
@@ -2866,15 +3040,15 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-graphviz"
-version = "546.0.0"
+version = "583.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c108d647ce0dd46477b048eafff5a6273b5652e02d47424b0cd684147379c811"
+checksum = "3e632ef08ca17458acfd46d2ead3d541a1c249586cd5329f5fe333dacfab6142"
 
 [[package]]
 name = "rustc-ap-rustc_data_structures"
-version = "546.0.0"
+version = "583.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "656771744e0783cb8e4481e3b8b1f975687610aaf18833b898018111a0e0e582"
+checksum = "e89e2c7be68185418f3cd56af3df8b29007a59a1cebefa63612d055f9bcb1a36"
 dependencies = [
  "cfg-if",
  "crossbeam-utils 0.6.5",
@@ -2883,7 +3057,7 @@ dependencies = [
  "jobserver",
  "lazy_static 1.3.0",
  "log",
- "parking_lot",
+ "parking_lot 0.7.1",
  "rustc-ap-graphviz",
  "rustc-ap-serialize",
  "rustc-hash",
@@ -2895,9 +3069,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_errors"
-version = "546.0.0"
+version = "583.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e37064f6624bc799bfaa2968b61ee6880926dea2a8bba69f18aef6c8e69c9604"
+checksum = "1e47cb380abeb72b01e42b2342d592f7eeea7d536c2f1f0d0e550dc509e46333"
 dependencies = [
  "annotate-snippets",
  "atty",
@@ -2905,34 +3079,38 @@ dependencies = [
  "rustc-ap-rustc_data_structures",
  "rustc-ap-serialize",
  "rustc-ap-syntax_pos",
+ "term_size",
  "termcolor",
  "unicode-width",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_lexer"
-version = "546.0.0"
+version = "583.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef5bc0a971823637ea23a857f0ef1467f44b1e05d71968821f83a0abe53e0fe3"
+checksum = "494cfaf67f49217d67d0774eeecbba61ac89acf478db97ef11f113ed8a959305"
+dependencies = [
+ "unicode-xid 0.2.0",
+]
 
 [[package]]
 name = "rustc-ap-rustc_macros"
-version = "546.0.0"
+version = "583.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b90037e3336fe8835f468db44d0848ae10d9cc8533ae89b55828883f905b7e80"
+checksum = "e2e5d36becc59b4497f9cbd3ae0610081de0207a1d0e95c066369167b14f486f"
 dependencies = [
  "itertools 0.8.0",
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
  "synstructure",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_target"
-version = "546.0.0"
+version = "583.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cadf9ca07315eab3a7a21f63872f9cc81e250fd6ede0419c24f8926ade73a45d"
+checksum = "a7bfc5f96dfc3b9f8d5b57884f7f37467ecff6776cd4b8b491a7daece6fdd7c2"
 dependencies = [
  "bitflags",
  "log",
@@ -2943,9 +3121,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-serialize"
-version = "546.0.0"
+version = "583.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61673783f2089e01033ffa82d1988f55175402071b31253a358292e1624d4602"
+checksum = "2bb9ee231cf79eded39c56647499f83d6136ff5c8c0baaa9e21b6febee00f4f6"
 dependencies = [
  "indexmap",
  "smallvec",
@@ -2953,9 +3131,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-syntax"
-version = "546.0.0"
+version = "583.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28f3dd1346d5b0269c07a4a78855e309a298ab569c9c1302d4d4f57f8eee4e84"
+checksum = "b3827fc208814efbde82d613e31d11b4250ce9e8cf8afe4a4d47bbbd099632c9"
 dependencies = [
  "bitflags",
  "lazy_static 1.3.0",
@@ -2973,9 +3151,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-syntax_pos"
-version = "546.0.0"
+version = "583.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "45e67b526dbda3a0c7dab91c8947d43685e7697f52686a4949da3c179cd7c979"
+checksum = "930ed81c34f325e512cc315c04d676fa84a373879d5c43bb54054a0522b05213"
 dependencies = [
  "cfg-if",
  "rustc-ap-arena",
@@ -3071,13 +3249,13 @@ version = "1.0.0"
 dependencies = [
  "byteorder",
  "crossbeam-utils 0.6.5",
- "parking_lot",
+ "parking_lot 0.7.1",
  "rand 0.6.1",
  "scopeguard 0.3.3",
  "serde",
  "serde_json",
  "smallvec",
- "syn",
+ "syn 0.15.35",
  "winapi 0.3.6",
 ]
 
@@ -3131,7 +3309,7 @@ dependencies = [
  "log",
  "memmap",
  "num_cpus",
- "parking_lot",
+ "parking_lot 0.7.1",
  "rustc",
  "rustc_apfloat",
  "rustc_codegen_utils",
@@ -3174,7 +3352,7 @@ dependencies = [
  "jobserver",
  "lazy_static 1.3.0",
  "log",
- "parking_lot",
+ "parking_lot 0.7.1",
  "rustc-hash",
  "rustc-rayon",
  "rustc-rayon-core",
@@ -3314,9 +3492,9 @@ name = "rustc_macros"
 version = "0.1.0"
 dependencies = [
  "itertools 0.8.0",
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
  "synstructure",
 ]
 
@@ -3555,20 +3733,19 @@ dependencies = [
 
 [[package]]
 name = "rustfmt-config_proc_macro"
-version = "0.1.2"
+version = "0.2.0"
 dependencies = [
- "proc-macro2",
- "quote",
+ "proc-macro2 1.0.3",
+ "quote 1.0.2",
  "serde",
- "syn",
+ "syn 1.0.5",
 ]
 
 [[package]]
 name = "rustfmt-nightly"
-version = "1.4.6"
+version = "1.4.8"
 dependencies = [
  "annotate-snippets",
- "atty",
  "bytecount",
  "cargo_metadata",
  "derive-new",
@@ -3589,7 +3766,7 @@ dependencies = [
  "rustfmt-config_proc_macro",
  "serde",
  "serde_json",
- "structopt",
+ "structopt 0.3.1",
  "term 0.6.0",
  "toml",
  "unicode-segmentation",
@@ -3698,18 +3875,9 @@ version = "1.0.81"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "477b13b646f5b5b56fc95bedfc3b550d12141ce84f466f6c44b9a17589923885"
 dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_ignored"
-version = "0.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "190e9765dcedb56be63b6e0993a006c7e3b071a016a304736e4a315dc01fb142"
-dependencies = [
- "serde",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
 ]
 
 [[package]]
@@ -3732,6 +3900,17 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "serde_repr"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd02c7587ec314570041b2754829f84d873ced14a96d1fd1823531e11db40573"
+dependencies = [
+ "proc-macro2 1.0.3",
+ "quote 1.0.2",
+ "syn 1.0.5",
+]
+
 [[package]]
 name = "serde_urlencoded"
 version = "0.5.5"
@@ -3889,8 +4068,8 @@ checksum = "1eea1eee654ef80933142157fdad9dd8bc43cf7c74e999e369263496f04ff4da"
 dependencies = [
  "phf_generator",
  "phf_shared",
- "proc-macro2",
- "quote",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
  "string_cache_shared",
 ]
 
@@ -3911,9 +4090,9 @@ dependencies = [
 
 [[package]]
 name = "strsim"
-version = "0.7.0"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
+checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
 
 [[package]]
 name = "structopt"
@@ -3922,7 +4101,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7"
 dependencies = [
  "clap",
- "structopt-derive",
+ "structopt-derive 0.2.18",
+]
+
+[[package]]
+name = "structopt"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ac9d6e93dd792b217bf89cda5c14566e3043960c6f9da890c2ba5d09d07804c"
+dependencies = [
+ "clap",
+ "structopt-derive 0.3.1",
 ]
 
 [[package]]
@@ -3932,9 +4121,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107"
 dependencies = [
  "heck",
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
+]
+
+[[package]]
+name = "structopt-derive"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ae9e5165d463a0dea76967d021f8d0f9316057bf5163aa2a4843790e842ff37"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2 1.0.3",
+ "quote 1.0.2",
+ "syn 1.0.5",
 ]
 
 [[package]]
@@ -3950,9 +4152,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8baacebd7b7c9b864d83a6ba7a246232983e277b86fa5cdec77f565715a4b136"
 dependencies = [
  "heck",
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
 ]
 
 [[package]]
@@ -3961,20 +4163,31 @@ version = "0.15.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "641e117d55514d6d918490e47102f7e08d096fdde360247e4a10f7a91a8478d3"
 dependencies = [
- "proc-macro2",
- "quote",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
  "unicode-xid 0.1.0",
 ]
 
+[[package]]
+name = "syn"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
+dependencies = [
+ "proc-macro2 1.0.3",
+ "quote 1.0.2",
+ "unicode-xid 0.2.0",
+]
+
 [[package]]
 name = "synstructure"
 version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
 dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 0.4.30",
+ "quote 0.6.12",
+ "syn 0.15.35",
  "unicode-xid 0.1.0",
 ]
 
@@ -4154,9 +4367,9 @@ dependencies = [
 
 [[package]]
 name = "textwrap"
-version = "0.10.0"
+version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
+checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
 dependencies = [
  "unicode-width",
 ]
@@ -4279,6 +4492,19 @@ dependencies = [
  "log",
 ]
 
+[[package]]
+name = "tokio-named-pipes"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d282d483052288b2308ba5ee795f5673b159c9bdf63c385a05609da782a5eae"
+dependencies = [
+ "bytes",
+ "futures",
+ "mio",
+ "mio-named-pipes",
+ "tokio",
+]
+
 [[package]]
 name = "tokio-process"
 version = "0.2.3"
@@ -4307,12 +4533,21 @@ dependencies = [
  "log",
  "mio",
  "num_cpus",
- "parking_lot",
+ "parking_lot 0.7.1",
  "slab",
  "tokio-executor",
  "tokio-io",
 ]
 
+[[package]]
+name = "tokio-service"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162"
+dependencies = [
+ "futures",
+]
+
 [[package]]
 name = "tokio-signal"
 version = "0.2.7"
@@ -4436,8 +4671,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c99ca245ec273c7e75c8ee58f47b882d0146f3c2c8495158082c6671e8b5335"
 dependencies = [
  "darling",
- "quote",
- "syn",
+ "quote 0.6.12",
+ "syn 0.15.35",
 ]
 
 [[package]]
@@ -4574,16 +4809,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "url_serde"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea"
-dependencies = [
- "serde",
- "url 1.7.2",
-]
-
 [[package]]
 name = "utf-8"
 version = "0.7.2"

From 69d503038edc7bd20b6262e60b1640ba88403c52 Mon Sep 17 00:00:00 2001
From: Nikita Popov <nikita.ppv@gmail.com>
Date: Mon, 9 Sep 2019 20:32:03 +0200
Subject: [PATCH 647/943] Update LLVM submodule

---
 src/llvm-project | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/llvm-project b/src/llvm-project
index 48818e9f5d0f2..71fe7ec06b85f 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit 48818e9f5d0f2d5978a9b43ad1a2e8d0b83f6aa0
+Subproject commit 71fe7ec06b85f612fc0e4eb4134c7a7d0f23fac5

From 4dd60f3114ce5b0dcb6cef30cfdd44dc240226f6 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 9 Sep 2019 20:48:57 +0200
Subject: [PATCH 648/943] update reference

---
 src/doc/reference | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/doc/reference b/src/doc/reference
index 090c015f79396..1944efed35989 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit 090c015f7939665866432c334957bd536c811870
+Subproject commit 1944efed35989ba57fa397c0724c4921310311fc

From 6c74bc951804940800da45ba5b9b3c3e5b613eb3 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Mon, 9 Sep 2019 13:01:05 -0700
Subject: [PATCH 649/943] Update version of `rustc-std-workspace-*` crates

This commit updates the version of the `rustc-std-workspace-*` crates
in-tree which are used in `[patch]`. This will guarantee that Cargo will
select these versions even if minor updates are published to crates.io
because otherwise a newer version on crates.io would be preferred which
misses the point of `[patch]`!
---
 Cargo.lock                                     | 6 +++---
 src/tools/rustc-std-workspace-alloc/Cargo.toml | 2 +-
 src/tools/rustc-std-workspace-core/Cargo.toml  | 2 +-
 src/tools/rustc-std-workspace-std/Cargo.toml   | 2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 328d96023bc1f..9ffa250c5720f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3046,21 +3046,21 @@ checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 
 [[package]]
 name = "rustc-std-workspace-alloc"
-version = "1.0.0"
+version = "1.99.0"
 dependencies = [
  "alloc",
 ]
 
 [[package]]
 name = "rustc-std-workspace-core"
-version = "1.0.0"
+version = "1.99.0"
 dependencies = [
  "core",
 ]
 
 [[package]]
 name = "rustc-std-workspace-std"
-version = "1.0.0"
+version = "1.99.0"
 dependencies = [
  "std",
 ]
diff --git a/src/tools/rustc-std-workspace-alloc/Cargo.toml b/src/tools/rustc-std-workspace-alloc/Cargo.toml
index ef7dc812af9d4..9e04b14756e06 100644
--- a/src/tools/rustc-std-workspace-alloc/Cargo.toml
+++ b/src/tools/rustc-std-workspace-alloc/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rustc-std-workspace-alloc"
-version = "1.0.0"
+version = "1.99.0"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 license = 'MIT OR Apache-2.0'
 description = """
diff --git a/src/tools/rustc-std-workspace-core/Cargo.toml b/src/tools/rustc-std-workspace-core/Cargo.toml
index 38ca56a557be6..6b4e7540affc9 100644
--- a/src/tools/rustc-std-workspace-core/Cargo.toml
+++ b/src/tools/rustc-std-workspace-core/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rustc-std-workspace-core"
-version = "1.0.0"
+version = "1.99.0"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 license = 'MIT OR Apache-2.0'
 description = """
diff --git a/src/tools/rustc-std-workspace-std/Cargo.toml b/src/tools/rustc-std-workspace-std/Cargo.toml
index ce1644809dbe6..e41554b74affd 100644
--- a/src/tools/rustc-std-workspace-std/Cargo.toml
+++ b/src/tools/rustc-std-workspace-std/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "rustc-std-workspace-std"
-version = "1.0.0"
+version = "1.99.0"
 authors = ["Alex Crichton <alex@alexcrichton.com>"]
 license = 'MIT OR Apache-2.0'
 description = """

From 3dd0e2b89eec3970467dc10b919923e94a02e258 Mon Sep 17 00:00:00 2001
From: Christian <chris_veenman@hotmail.com>
Date: Mon, 9 Sep 2019 22:10:53 +0200
Subject: [PATCH 650/943] Added some context on SGX. Lists Darwin separately.

---
 src/libstd/time.rs | 50 +++++++++++++++++++++++++++++-----------------
 1 file changed, 32 insertions(+), 18 deletions(-)

diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index c05f02389dfa0..f276ab4200525 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -63,16 +63,23 @@ pub use core::time::Duration;
 /// # Underlying System calls
 /// Currently, the following system calls are being used to get the current time using `now()`:
 ///
-/// |  Platform |               System call                        |
-/// |:---------:|:------------------------------------------------:|
-/// | Cloud ABI | [clock_time_get (Monotonic Clock)](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt) |
-/// |    SGX    | Not implemented                                  |
-/// |    UNIX   | [mach_absolute_time](https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html)                           |
-/// |  VXWorks  | [clock_gettime (Monotonic Clock)](https://linux.die.net/man/3/clock_gettime)                                |
-/// |    WASI   | [__wasi_clock_time_get (Monotonic Clock)](https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get)      |
-/// |  Windows  | [QueryPerformanceCounter] |
-
-[QueryPerformanceCounter]: https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter
+/// |  Platform |               System call                                            |
+/// |:---------:|:--------------------------------------------------------------------:|
+/// | Cloud ABI | [clock_time_get (Monotonic Clock)]                                   |
+/// | SGX       | [`insecure_time` usercall]. More information on [timekeeping in SGX] |
+/// | UNIX      | [clock_time_get (Monotonic Clock)]                                   |
+/// | Darwin    | [mach_absolute_time]                                                 |
+/// | VXWorks   | [clock_gettime (Monotonic Clock)]                                    |
+/// | WASI      | [__wasi_clock_time_get (Monotonic Clock)]                            |
+/// | Windows   | [QueryPerformanceCounter]                                            |
+
+/// [QueryPerformanceCounter]: https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter
+/// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time
+/// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode
+/// [__wasi_clock_time_get (Monotonic Clock)]: https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get
+/// [clock_gettime (Monotonic Clock)]: https://linux.die.net/man/3/clock_gettime
+/// [mach_absolute_time]: https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html
+/// [clock_time_get (Monotonic Clock)]: https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt
 ///
 /// **Disclaimer:** These system calls might change over time.
 ///
@@ -135,14 +142,21 @@ pub struct Instant(time::Instant);
 /// # Underlying System calls
 /// Currently, the following system calls are being used to get the current time using `now()`:
 ///
-/// |  Platform |               System call                        |
-/// |:---------:|:------------------------------------------------:|
-/// | Cloud ABI | [clock_time_get (Realtime Clock)](https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt) |
-/// |    SGX    | Not implemented                                  |
-/// |    UNIX   | [gettimeofday](http://man7.org/linux/man-pages/man2/gettimeofday.2.html)                           |
-/// |  VXWorks  | [clock_gettime (Realtime Clock)](https://linux.die.net/man/3/clock_gettime)                                |
-/// |    WASI   | [__wasi_clock_time_get (Realtime Clock)](https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get)      |
-/// |  Windows  | [GetSystemTimeAsFileTime](https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime)                      |
+/// |  Platform |               System call                                            |
+/// |:---------:|:--------------------------------------------------------------------:|
+/// | Cloud ABI | [clock_time_get (Realtime Clock)]                                    |
+/// | SGX       | [`insecure_time` usercall]. More information on [timekeeping in SGX] |
+/// | UNIX      | [clock_gettime (Realtime Clock)]                                     |
+/// | DARWIN    | [gettimeofday]                                                       |
+/// | VXWorks   | [clock_gettime (Realtime Clock)]                                     |
+/// | WASI      | [__wasi_clock_time_get (Realtime Clock)]                             |
+/// | Windows   | [GetSystemTimeAsFileTime]                                            |
+///
+/// [clock_time_get (Realtime Clock)]: https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt
+/// [gettimeofday]: http://man7.org/linux/man-pages/man2/gettimeofday.2.html
+/// [clock_gettime (Realtime Clock)]: https://linux.die.net/man/3/clock_gettime
+/// [__wasi_clock_time_get (Realtime Clock)]: https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get
+/// [GetSystemTimeAsFileTime]: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime
 ///
 /// **Disclaimer:** These system calls might change over time.
 ///

From e9c41148c0c834d13d6f45bfd99c8f23781c5d31 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Tue, 30 Jul 2019 00:07:28 +0200
Subject: [PATCH 651/943] Convert Place's projection to a boxed slice

---
 src/librustc/mir/mod.rs                       | 290 +++++-----------
 src/librustc/mir/tcx.rs                       |  14 +-
 src/librustc/mir/visit.rs                     |  68 ++--
 src/librustc_codegen_ssa/lib.rs               |   1 +
 src/librustc_codegen_ssa/mir/analyze.rs       |  26 +-
 src/librustc_codegen_ssa/mir/block.rs         |  10 +-
 src/librustc_codegen_ssa/mir/operand.rs       |  68 ++--
 src/librustc_codegen_ssa/mir/place.rs         |  35 +-
 src/librustc_codegen_ssa/mir/rvalue.rs        |   2 +-
 src/librustc_codegen_ssa/mir/statement.rs     |   2 +-
 src/librustc_mir/borrow_check/borrow_set.rs   |   2 +-
 .../borrow_check/conflict_errors.rs           |  44 +--
 .../borrow_check/error_reporting.rs           |  68 ++--
 src/librustc_mir/borrow_check/mod.rs          |  81 +++--
 src/librustc_mir/borrow_check/move_errors.rs  |  25 +-
 .../borrow_check/mutability_errors.rs         | 111 +++---
 .../borrow_check/nll/constraint_generation.rs |  14 +-
 .../borrow_check/nll/explain_borrow/mod.rs    |  20 +-
 .../borrow_check/nll/type_check/mod.rs        | 194 +++++------
 src/librustc_mir/borrow_check/place_ext.rs    |  88 ++---
 .../borrow_check/places_conflict.rs           | 318 +++++++++---------
 src/librustc_mir/borrow_check/prefixes.rs     | 203 ++++++-----
 src/librustc_mir/borrow_check/used_muts.rs    |   2 +-
 src/librustc_mir/build/expr/as_place.rs       |   2 +-
 src/librustc_mir/build/expr/as_rvalue.rs      |  28 +-
 src/librustc_mir/build/expr/into.rs           |   2 +-
 src/librustc_mir/build/matches/mod.rs         |  18 +-
 src/librustc_mir/build/mod.rs                 |   6 +-
 src/librustc_mir/build/scope.rs               |   6 +-
 .../dataflow/drop_flag_effects.rs             |  11 +-
 src/librustc_mir/dataflow/impls/borrows.rs    |   2 +-
 .../dataflow/move_paths/builder.rs            | 134 ++++----
 src/librustc_mir/dataflow/move_paths/mod.rs   |  30 +-
 src/librustc_mir/interpret/operand.rs         |  50 ++-
 src/librustc_mir/interpret/place.rs           |  62 ++--
 src/librustc_mir/interpret/terminator.rs      |   2 +-
 src/librustc_mir/shim.rs                      |   8 +-
 src/librustc_mir/transform/add_retag.rs       |  17 +-
 src/librustc_mir/transform/check_unsafety.rs  | 226 ++++++-------
 src/librustc_mir/transform/const_prop.rs      |  86 ++---
 src/librustc_mir/transform/copy_prop.rs       |  16 +-
 src/librustc_mir/transform/elaborate_drops.rs |  38 +--
 src/librustc_mir/transform/generator.rs       |  34 +-
 src/librustc_mir/transform/inline.rs          |  32 +-
 src/librustc_mir/transform/instcombine.rs     |  38 ++-
 src/librustc_mir/transform/promote_consts.rs  |  12 +-
 src/librustc_mir/transform/qualify_consts.rs  | 189 ++++++-----
 .../transform/qualify_min_const_fn.rs         |  34 +-
 .../transform/remove_noop_landing_pads.rs     |   2 +-
 src/librustc_mir/transform/rustc_peek.rs      |   4 +-
 .../transform/uniform_array_move_out.rs       | 180 +++++-----
 src/librustc_mir/util/alignment.rs            |   9 +-
 src/librustc_mir/util/elaborate_drops.rs      |   5 +-
 53 files changed, 1399 insertions(+), 1570 deletions(-)

diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 18a5142208d2d..602ce12c37d81 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -32,7 +32,6 @@ use rustc_serialize::{Encodable, Decodable};
 use smallvec::SmallVec;
 use std::borrow::Cow;
 use std::fmt::{self, Debug, Display, Formatter, Write};
-use std::iter::FusedIterator;
 use std::ops::{Index, IndexMut};
 use std::slice;
 use std::vec::IntoIter;
@@ -1548,7 +1547,7 @@ pub struct Statement<'tcx> {
 
 // `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(Statement<'_>, 56);
+static_assert_size!(Statement<'_>, 64);
 
 impl Statement<'_> {
     /// Changes a statement to a nop. This is both faster than deleting instructions and avoids
@@ -1717,7 +1716,7 @@ pub struct Place<'tcx> {
     pub base: PlaceBase<'tcx>,
 
     /// projection out of a place (access a field, deref a pointer, etc)
-    pub projection: Option<Box<Projection<'tcx>>>,
+    pub projection: Box<[PlaceElem<'tcx>]>,
 }
 
 #[derive(
@@ -1760,15 +1759,6 @@ impl_stable_hash_for!(struct Static<'tcx> {
     def_id
 });
 
-/// The `Projection` data structure defines things of the form `base.x`, `*b` or `b[index]`.
-#[derive(
-    Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable,
-)]
-pub struct Projection<'tcx> {
-    pub base: Option<Box<Projection<'tcx>>>,
-    pub elem: PlaceElem<'tcx>,
-}
-
 #[derive(
     Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable,
 )]
@@ -1850,14 +1840,22 @@ newtype_index! {
 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct PlaceRef<'a, 'tcx> {
     pub base: &'a PlaceBase<'tcx>,
-    pub projection: &'a Option<Box<Projection<'tcx>>>,
+    pub projection: &'a [PlaceElem<'tcx>],
 }
 
 impl<'tcx> Place<'tcx> {
-    pub const RETURN_PLACE: Place<'tcx> = Place {
-        base: PlaceBase::Local(RETURN_PLACE),
-        projection: None,
-    };
+    // FIXME change this back to a const when projection is a shared slice.
+    //
+    // pub const RETURN_PLACE: Place<'tcx> = Place {
+    //     base: PlaceBase::Local(RETURN_PLACE),
+    //     projection: &[],
+    // };
+    pub fn return_place() -> Place<'tcx> {
+        Place {
+            base: PlaceBase::Local(RETURN_PLACE),
+            projection: Box::new([]),
+        }
+    }
 
     pub fn field(self, f: Field, ty: Ty<'tcx>) -> Place<'tcx> {
         self.elem(ProjectionElem::Field(f, ty))
@@ -1883,9 +1881,13 @@ impl<'tcx> Place<'tcx> {
     }
 
     pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> {
+        // FIXME(spastorino): revisit this again once projection is not a Box<[T]> anymore
+        let mut projection = self.projection.into_vec();
+        projection.push(elem);
+
         Place {
             base: self.base,
-            projection: Some(Box::new(Projection { base: self.projection, elem })),
+            projection: projection.into_boxed_slice(),
         }
     }
 
@@ -1894,7 +1896,7 @@ impl<'tcx> Place<'tcx> {
     /// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
     /// same region of memory as its base.
     pub fn is_indirect(&self) -> bool {
-        self.iterate(|_, mut projections| projections.any(|proj| proj.elem.is_indirect()))
+        self.projection.iter().any(|elem| elem.is_indirect())
     }
 
     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
@@ -1905,61 +1907,16 @@ impl<'tcx> Place<'tcx> {
         match self {
             Place {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: box [],
             } |
             Place {
                 base: PlaceBase::Local(local),
-                projection: Some(box Projection {
-                    base: None,
-                    elem: ProjectionElem::Deref,
-                }),
+                projection: box [ProjectionElem::Deref],
             } => Some(*local),
             _ => None,
         }
     }
 
-    /// Recursively "iterates" over place components, generating a `PlaceBase` and
-    /// `Projections` list and invoking `op` with a `ProjectionsIter`.
-    pub fn iterate<R>(
-        &self,
-        op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
-    ) -> R {
-        Place::iterate_over(&self.base, &self.projection, op)
-    }
-
-    pub fn iterate_over<R>(
-        place_base: &PlaceBase<'tcx>,
-        place_projection: &Option<Box<Projection<'tcx>>>,
-        op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
-    ) -> R {
-        fn iterate_over2<'tcx, R>(
-            place_base: &PlaceBase<'tcx>,
-            place_projection: &Option<Box<Projection<'tcx>>>,
-            next: &Projections<'_, 'tcx>,
-            op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
-        ) -> R {
-            match place_projection {
-                None => {
-                    op(place_base, next.iter())
-                }
-
-                Some(interior) => {
-                    iterate_over2(
-                        place_base,
-                        &interior.base,
-                        &Projections::List {
-                            projection: interior,
-                            next,
-                        },
-                        op,
-                    )
-                }
-            }
-        }
-
-        iterate_over2(place_base, place_projection, &Projections::Empty, op)
-    }
-
     pub fn as_ref(&self) -> PlaceRef<'_, 'tcx> {
         PlaceRef {
             base: &self.base,
@@ -1972,7 +1929,7 @@ impl From<Local> for Place<'_> {
     fn from(local: Local) -> Self {
         Place {
             base: local.into(),
-            projection: None,
+            projection: Box::new([]),
         }
     }
 }
@@ -1984,13 +1941,6 @@ impl From<Local> for PlaceBase<'_> {
 }
 
 impl<'a, 'tcx> PlaceRef<'a, 'tcx> {
-    pub fn iterate<R>(
-        &self,
-        op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
-    ) -> R {
-        Place::iterate_over(self.base, self.projection, op)
-    }
-
     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
     /// a single deref of a local.
     //
@@ -1999,143 +1949,71 @@ impl<'a, 'tcx> PlaceRef<'a, 'tcx> {
         match self {
             PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: [],
             } |
             PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: Some(box Projection {
-                    base: None,
-                    elem: ProjectionElem::Deref,
-                }),
+                projection: [ProjectionElem::Deref],
             } => Some(*local),
             _ => None,
         }
     }
 }
 
-/// A linked list of projections running up the stack; begins with the
-/// innermost projection and extends to the outermost (e.g., `a.b.c`
-/// would have the place `b` with a "next" pointer to `b.c`).
-/// Created by `Place::iterate`.
-///
-/// N.B., this particular impl strategy is not the most obvious. It was
-/// chosen because it makes a measurable difference to NLL
-/// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
-pub enum Projections<'p, 'tcx> {
-    Empty,
-
-    List { projection: &'p Projection<'tcx>, next: &'p Projections<'p, 'tcx> },
-}
-
-impl<'p, 'tcx> Projections<'p, 'tcx> {
-    fn iter(&self) -> ProjectionsIter<'_, 'tcx> {
-        ProjectionsIter { value: self }
-    }
-}
-
-impl<'p, 'tcx> IntoIterator for &'p Projections<'p, 'tcx> {
-    type Item = &'p Projection<'tcx>;
-    type IntoIter = ProjectionsIter<'p, 'tcx>;
-
-    /// Converts a list of `Projection` components into an iterator;
-    /// this iterator yields up a never-ending stream of `Option<&Place>`.
-    /// These begin with the "innermost" projection and then with each
-    /// projection therefrom. So given a place like `a.b.c` it would
-    /// yield up:
-    ///
-    /// ```notrust
-    /// Some(`a`), Some(`a.b`), Some(`a.b.c`), None, None, ...
-    /// ```
-    fn into_iter(self) -> Self::IntoIter {
-        self.iter()
-    }
-}
-
-/// Iterator over components; see `Projections::iter` for more
-/// information.
-///
-/// N.B., this is not a *true* Rust iterator -- the code above just
-/// manually invokes `next`. This is because we (sometimes) want to
-/// keep executing even after `None` has been returned.
-pub struct ProjectionsIter<'p, 'tcx> {
-    pub value: &'p Projections<'p, 'tcx>,
-}
-
-impl<'p, 'tcx> Iterator for ProjectionsIter<'p, 'tcx> {
-    type Item = &'p Projection<'tcx>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        if let &Projections::List { projection, next } = self.value {
-            self.value = next;
-            Some(projection)
-        } else {
-            None
-        }
-    }
-}
-
-impl<'p, 'tcx> FusedIterator for ProjectionsIter<'p, 'tcx> {}
-
 impl Debug for Place<'_> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
-        self.iterate(|_place_base, place_projections| {
-            // FIXME: remove this collect once we have migrated to slices
-            let projs_vec: Vec<_> = place_projections.collect();
-            for projection in projs_vec.iter().rev() {
-                match projection.elem {
-                    ProjectionElem::Downcast(_, _) | ProjectionElem::Field(_, _) => {
-                        write!(fmt, "(").unwrap();
-                    }
-                    ProjectionElem::Deref => {
-                        write!(fmt, "(*").unwrap();
-                    }
-                    ProjectionElem::Index(_)
-                    | ProjectionElem::ConstantIndex { .. }
-                    | ProjectionElem::Subslice { .. } => {}
+        for elem in self.projection.iter().rev() {
+            match elem {
+                ProjectionElem::Downcast(_, _) | ProjectionElem::Field(_, _) => {
+                    write!(fmt, "(").unwrap();
+                }
+                ProjectionElem::Deref => {
+                    write!(fmt, "(*").unwrap();
                 }
+                ProjectionElem::Index(_)
+                | ProjectionElem::ConstantIndex { .. }
+                | ProjectionElem::Subslice { .. } => {}
             }
-        });
+        }
 
-        self.iterate(|place_base, place_projections| {
-            write!(fmt, "{:?}", place_base)?;
+        write!(fmt, "{:?}", self.base)?;
 
-            for projection in place_projections {
-                match projection.elem {
-                    ProjectionElem::Downcast(Some(name), _index) => {
-                        write!(fmt, " as {})", name)?;
-                    }
-                    ProjectionElem::Downcast(None, index) => {
-                        write!(fmt, " as variant#{:?})", index)?;
-                    }
-                    ProjectionElem::Deref => {
-                        write!(fmt, ")")?;
-                    }
-                    ProjectionElem::Field(field, ty) => {
-                        write!(fmt, ".{:?}: {:?})", field.index(), ty)?;
-                    }
-                    ProjectionElem::Index(ref index) => {
-                        write!(fmt, "[{:?}]", index)?;
-                    }
-                    ProjectionElem::ConstantIndex { offset, min_length, from_end: false } => {
-                        write!(fmt, "[{:?} of {:?}]", offset, min_length)?;
-                    }
-                    ProjectionElem::ConstantIndex { offset, min_length, from_end: true } => {
-                        write!(fmt, "[-{:?} of {:?}]", offset, min_length)?;
-                    }
-                    ProjectionElem::Subslice { from, to } if to == 0 => {
-                        write!(fmt, "[{:?}:]", from)?;
-                    }
-                    ProjectionElem::Subslice { from, to } if from == 0 => {
-                        write!(fmt, "[:-{:?}]", to)?;
-                    }
-                    ProjectionElem::Subslice { from, to } => {
-                        write!(fmt, "[{:?}:-{:?}]", from, to)?;
-                    }
+        for elem in self.projection.iter() {
+            match elem {
+                ProjectionElem::Downcast(Some(name), _index) => {
+                    write!(fmt, " as {})", name)?;
+                }
+                ProjectionElem::Downcast(None, index) => {
+                    write!(fmt, " as variant#{:?})", index)?;
+                }
+                ProjectionElem::Deref => {
+                    write!(fmt, ")")?;
+                }
+                ProjectionElem::Field(field, ty) => {
+                    write!(fmt, ".{:?}: {:?})", field.index(), ty)?;
+                }
+                ProjectionElem::Index(ref index) => {
+                    write!(fmt, "[{:?}]", index)?;
+                }
+                ProjectionElem::ConstantIndex { offset, min_length, from_end: false } => {
+                    write!(fmt, "[{:?} of {:?}]", offset, min_length)?;
+                }
+                ProjectionElem::ConstantIndex { offset, min_length, from_end: true } => {
+                    write!(fmt, "[-{:?} of {:?}]", offset, min_length)?;
+                }
+                ProjectionElem::Subslice { from, to } if *to == 0 => {
+                    write!(fmt, "[{:?}:]", from)?;
+                }
+                ProjectionElem::Subslice { from, to } if *from == 0 => {
+                    write!(fmt, "[:-{:?}]", to)?;
+                }
+                ProjectionElem::Subslice { from, to } => {
+                    write!(fmt, "[{:?}:-{:?}]", from, to)?;
                 }
             }
+        }
 
-            Ok(())
-        })
+        Ok(())
     }
 }
 
@@ -3409,30 +3287,26 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for Projection<'tcx> {
+impl<'tcx> TypeFoldable<'tcx> for PlaceElem<'tcx> {
     fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
         use crate::mir::ProjectionElem::*;
 
-        let base = self.base.fold_with(folder);
-        let elem = match self.elem {
+        match self {
             Deref => Deref,
-            Field(f, ref ty) => Field(f, ty.fold_with(folder)),
-            Index(ref v) => Index(v.fold_with(folder)),
-            ref elem => elem.clone(),
-        };
-
-        Projection { base, elem }
+            Field(f, ty) => Field(*f, ty.fold_with(folder)),
+            Index(v) => Index(v.fold_with(folder)),
+            elem => elem.clone(),
+        }
     }
 
     fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
         use crate::mir::ProjectionElem::*;
 
-        self.base.visit_with(visitor)
-            || match self.elem {
-                Field(_, ref ty) => ty.visit_with(visitor),
-                Index(ref v) => v.visit_with(visitor),
-                _ => false,
-            }
+        match self {
+            Field(_, ty) => ty.visit_with(visitor),
+            Index(v) => v.visit_with(visitor),
+            _ => false,
+        }
     }
 }
 
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index e9f7636ba85ae..fbe25de0e762c 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -121,21 +121,19 @@ BraceStructTypeFoldableImpl! {
 impl<'tcx> Place<'tcx> {
     pub fn ty_from<D>(
         base: &PlaceBase<'tcx>,
-        projection: &Option<Box<Projection<'tcx>>>,
+        projection: &[PlaceElem<'tcx>],
         local_decls: &D,
         tcx: TyCtxt<'tcx>
     ) -> PlaceTy<'tcx>
         where D: HasLocalDecls<'tcx>
     {
-        Place::iterate_over(base, projection, |place_base, place_projections| {
-            let mut place_ty = place_base.ty(local_decls);
+        let mut place_ty = base.ty(local_decls);
 
-            for proj in place_projections {
-                place_ty = place_ty.projection_ty(tcx, &proj.elem);
-            }
+        for elem in projection.iter() {
+            place_ty = place_ty.projection_ty(tcx, elem);
+        }
 
-            place_ty
-        })
+        place_ty
     }
 
     pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx>
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 821367e9ea12c..36aa891aaf4aa 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -152,18 +152,18 @@ macro_rules! make_mir_visitor {
             }
 
             fn visit_place_base(&mut self,
-                                place_base: & $($mutability)? PlaceBase<'tcx>,
+                                base: & $($mutability)? PlaceBase<'tcx>,
                                 context: PlaceContext,
                                 location: Location) {
-                self.super_place_base(place_base, context, location);
+                self.super_place_base(base, context, location);
             }
 
             fn visit_projection(&mut self,
-                                place_base: & $($mutability)? PlaceBase<'tcx>,
-                                place: & $($mutability)? Projection<'tcx>,
+                                base: & $($mutability)? PlaceBase<'tcx>,
+                                projection: & $($mutability)? [PlaceElem<'tcx>],
                                 context: PlaceContext,
                                 location: Location) {
-                self.super_projection(place_base, place, context, location);
+                self.super_projection(base, projection, context, location);
             }
 
             fn visit_constant(&mut self,
@@ -685,7 +685,7 @@ macro_rules! make_mir_visitor {
                             location: Location) {
                 let mut context = context;
 
-                if place.projection.is_some() {
+                if !place.projection.is_empty() {
                     context = if context.is_mutating_use() {
                         PlaceContext::MutatingUse(MutatingUseContext::Projection)
                     } else {
@@ -695,9 +695,10 @@ macro_rules! make_mir_visitor {
 
                 self.visit_place_base(& $($mutability)? place.base, context, location);
 
-                if let Some(box proj) = & $($mutability)? place.projection {
-                    self.visit_projection(& $($mutability)? place.base, proj, context, location);
-                }
+                self.visit_projection(& $($mutability)? place.base,
+                                      & $($mutability)? place.projection,
+                                      context,
+                                      location);
             }
 
             fn super_place_base(&mut self,
@@ -715,31 +716,34 @@ macro_rules! make_mir_visitor {
             }
 
             fn super_projection(&mut self,
-                                place_base: & $($mutability)? PlaceBase<'tcx>,
-                                proj: & $($mutability)? Projection<'tcx>,
+                                base: & $($mutability)? PlaceBase<'tcx>,
+                                projection: & $($mutability)? [PlaceElem<'tcx>],
                                 context: PlaceContext,
                                 location: Location) {
-                if let Some(box proj_base) = & $($mutability)? proj.base {
-                    self.visit_projection(place_base, proj_base, context, location);
-                }
-
-                match & $($mutability)? proj.elem {
-                    ProjectionElem::Field(_field, ty) => {
-                        self.visit_ty(ty, TyContext::Location(location));
-                    }
-                    ProjectionElem::Index(local) => {
-                        self.visit_local(
-                            local,
-                            PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
-                            location
-                        );
-                    }
-                    ProjectionElem::Deref |
-                    ProjectionElem::Subslice { from: _, to: _ } |
-                    ProjectionElem::ConstantIndex { offset: _,
-                                                    min_length: _,
-                                                    from_end: _ } |
-                    ProjectionElem::Downcast(_, _) => {
+                if !projection.is_empty() {
+                    let proj_len = projection.len();
+                    let proj_base = & $($mutability)? projection[..proj_len - 1];
+                    self.visit_projection(base, proj_base, context, location);
+
+                    let elem = & $($mutability)? projection[proj_len - 1];
+                    match elem {
+                        ProjectionElem::Field(_field, ty) => {
+                            self.visit_ty(ty, TyContext::Location(location));
+                        }
+                        ProjectionElem::Index(local) => {
+                            self.visit_local(
+                                local,
+                                PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
+                                location
+                            );
+                        }
+                        ProjectionElem::Deref |
+                        ProjectionElem::Subslice { from: _, to: _ } |
+                        ProjectionElem::ConstantIndex { offset: _,
+                                                        min_length: _,
+                                                        from_end: _ } |
+                        ProjectionElem::Downcast(_, _) => {
+                        }
                     }
                 }
             }
diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs
index 90bf964ceaa13..1708d7235b45b 100644
--- a/src/librustc_codegen_ssa/lib.rs
+++ b/src/librustc_codegen_ssa/lib.rs
@@ -4,6 +4,7 @@
 #![feature(box_syntax)]
 #![feature(core_intrinsics)]
 #![feature(libc)]
+#![feature(slice_patterns)]
 #![feature(stmt_expr_attributes)]
 #![feature(try_blocks)]
 #![feature(in_band_lifetimes)]
diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs
index e63f1b91dd7d5..5449dbdc913b8 100644
--- a/src/librustc_codegen_ssa/mir/analyze.rs
+++ b/src/librustc_codegen_ssa/mir/analyze.rs
@@ -105,7 +105,10 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
     ) {
         let cx = self.fx.cx;
 
-        if let Some(proj) = place_ref.projection {
+        if let [.., elem] = place_ref.projection {
+            // FIXME(spastorino) include this in the pattern when stabilized
+            let proj_base = &place_ref.projection[..place_ref.projection.len() - 1];
+
             // Allow uses of projections that are ZSTs or from scalar fields.
             let is_consume = match context {
                 PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
@@ -114,12 +117,12 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
             };
             if is_consume {
                 let base_ty =
-                    mir::Place::ty_from(place_ref.base, &proj.base, self.fx.mir, cx.tcx());
+                    mir::Place::ty_from(place_ref.base, proj_base, self.fx.mir, cx.tcx());
                 let base_ty = self.fx.monomorphize(&base_ty);
 
                 // ZSTs don't require any actual memory access.
                 let elem_ty = base_ty
-                    .projection_ty(cx.tcx(), &proj.elem)
+                    .projection_ty(cx.tcx(), elem)
                     .ty;
                 let elem_ty = self.fx.monomorphize(&elem_ty);
                 let span = if let mir::PlaceBase::Local(index) = place_ref.base {
@@ -131,7 +134,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
                     return;
                 }
 
-                if let mir::ProjectionElem::Field(..) = proj.elem {
+                if let mir::ProjectionElem::Field(..) = elem {
                     let layout = cx.spanned_layout_of(base_ty.ty, span);
                     if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
                         // Recurse with the same context, instead of `Projection`,
@@ -140,7 +143,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
                         self.process_place(
                             &mir::PlaceRef {
                                 base: place_ref.base,
-                                projection: &proj.base,
+                                projection: proj_base,
                             },
                             context,
                             location,
@@ -151,11 +154,11 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
             }
 
             // A deref projection only reads the pointer, never needs the place.
-            if let mir::ProjectionElem::Deref = proj.elem {
+            if let mir::ProjectionElem::Deref = elem {
                 self.process_place(
                     &mir::PlaceRef {
                         base: place_ref.base,
-                        projection: &proj.base,
+                        projection: proj_base,
                     },
                     PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
                     location
@@ -168,7 +171,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
         // visit_place API
         let mut context = context;
 
-        if place_ref.projection.is_some() {
+        if !place_ref.projection.is_empty() {
             context = if context.is_mutating_use() {
                 PlaceContext::MutatingUse(MutatingUseContext::Projection)
             } else {
@@ -177,10 +180,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
         }
 
         self.visit_place_base(place_ref.base, context, location);
-
-        if let Some(box proj) = place_ref.projection {
-            self.visit_projection(place_ref.base, proj, context, location);
-        }
+        self.visit_projection(place_ref.base, place_ref.projection, context, location);
     }
 
 }
@@ -196,7 +196,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
 
         if let mir::Place {
             base: mir::PlaceBase::Local(index),
-            projection: None,
+            projection: box [],
         } = *place {
             self.assign(index, location);
             let decl_span = self.fx.mir.local_decls[index].source_info.span;
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index c41e46398467a..915006938fe56 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -253,7 +253,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
             PassMode::Direct(_) | PassMode::Pair(..) => {
                 let op =
-                    self.codegen_consume(&mut bx, &mir::Place::RETURN_PLACE.as_ref());
+                    self.codegen_consume(&mut bx, &mir::Place::return_place().as_ref());
                 if let Ref(llval, _, align) = op.val {
                     bx.load(llval, align)
                 } else {
@@ -612,7 +612,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                     ty,
                                     def_id: _,
                                 }),
-                                projection: None,
+                                projection: box [],
                             }
                         ) |
                         mir::Operand::Move(
@@ -622,7 +622,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                     ty,
                                     def_id: _,
                                 }),
-                                projection: None,
+                                projection: box [],
                             }
                         ) => {
                             let param_env = ty::ParamEnv::reveal_all();
@@ -1105,7 +1105,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
         let dest = if let mir::Place {
             base: mir::PlaceBase::Local(index),
-            projection: None,
+            projection: box [],
         } = *dest {
             match self.locals[index] {
                 LocalRef::Place(dest) => dest,
@@ -1166,7 +1166,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     ) {
         if let mir::Place {
             base: mir::PlaceBase::Local(index),
-            projection: None,
+            projection: box [],
         } = *dst {
             match self.locals[index] {
                 LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index a8ab3ea10ed16..58a13d685ddf9 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -384,47 +384,45 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     ) -> Option<OperandRef<'tcx, Bx::Value>> {
         debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref);
 
-        place_ref.iterate(|place_base, place_projection| {
-            if let mir::PlaceBase::Local(index) = place_base {
-                match self.locals[*index] {
-                    LocalRef::Operand(Some(mut o)) => {
-                        // Moves out of scalar and scalar pair fields are trivial.
-                        for proj in place_projection {
-                            match proj.elem {
-                                mir::ProjectionElem::Field(ref f, _) => {
-                                    o = o.extract_field(bx, f.index());
-                                }
-                                mir::ProjectionElem::Index(_) |
-                                mir::ProjectionElem::ConstantIndex { .. } => {
-                                    // ZSTs don't require any actual memory access.
-                                    // FIXME(eddyb) deduplicate this with the identical
-                                    // checks in `codegen_consume` and `extract_field`.
-                                    let elem = o.layout.field(bx.cx(), 0);
-                                    if elem.is_zst() {
-                                        o = OperandRef::new_zst(bx, elem);
-                                    } else {
-                                        return None;
-                                    }
+        if let mir::PlaceBase::Local(index) = place_ref.base {
+            match self.locals[*index] {
+                LocalRef::Operand(Some(mut o)) => {
+                    // Moves out of scalar and scalar pair fields are trivial.
+                    for elem in place_ref.projection.iter() {
+                        match elem {
+                            mir::ProjectionElem::Field(ref f, _) => {
+                                o = o.extract_field(bx, f.index());
+                            }
+                            mir::ProjectionElem::Index(_) |
+                            mir::ProjectionElem::ConstantIndex { .. } => {
+                                // ZSTs don't require any actual memory access.
+                                // FIXME(eddyb) deduplicate this with the identical
+                                // checks in `codegen_consume` and `extract_field`.
+                                let elem = o.layout.field(bx.cx(), 0);
+                                if elem.is_zst() {
+                                    o = OperandRef::new_zst(bx, elem);
+                                } else {
+                                    return None;
                                 }
-                                _ => return None,
                             }
+                            _ => return None,
                         }
-
-                        Some(o)
-                    }
-                    LocalRef::Operand(None) => {
-                        bug!("use of {:?} before def", place_ref);
-                    }
-                    LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
-                        // watch out for locals that do not have an
-                        // alloca; they are handled somewhat differently
-                        None
                     }
+
+                    Some(o)
+                }
+                LocalRef::Operand(None) => {
+                    bug!("use of {:?} before def", place_ref);
+                }
+                LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
+                    // watch out for locals that do not have an
+                    // alloca; they are handled somewhat differently
+                    None
                 }
-            } else {
-                None
             }
-        })
+        } else {
+            None
+        }
     }
 
     pub fn codegen_consume(
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index b8e10d3430292..df90da7ee8fae 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -449,7 +449,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let result = match &place_ref {
             mir::PlaceRef {
                 base: mir::PlaceBase::Local(index),
-                projection: None,
+                projection: [],
             } => {
                 match self.locals[*index] {
                     LocalRef::Place(place) => {
@@ -469,7 +469,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     kind: mir::StaticKind::Promoted(promoted, substs),
                     def_id,
                 }),
-                projection: None,
+                projection: [],
             } => {
                 let param_env = ty::ParamEnv::reveal_all();
                 let instance = Instance::new(*def_id, self.monomorphize(substs));
@@ -504,7 +504,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     kind: mir::StaticKind::Static,
                     def_id,
                 }),
-                projection: None,
+                projection: [],
             } => {
                 // NB: The layout of a static may be unsized as is the case when working
                 // with a static that is an extern_type.
@@ -514,11 +514,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             },
             mir::PlaceRef {
                 base,
-                projection: Some(box mir::Projection {
-                    base: proj_base,
-                    elem: mir::ProjectionElem::Deref,
-                }),
+                projection: [.., mir::ProjectionElem::Deref],
             } => {
+                let proj_base = &place_ref.projection[..place_ref.projection.len() - 1];
+
                 // Load the pointer from its location.
                 self.codegen_consume(bx, &mir::PlaceRef {
                     base,
@@ -527,22 +526,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
             mir::PlaceRef {
                 base,
-                projection: Some(projection),
+                projection: [.., elem],
             } => {
+                let proj_base = &place_ref.projection[..place_ref.projection.len() - 1];
+
                 // FIXME turn this recursion into iteration
                 let cg_base = self.codegen_place(bx, &mir::PlaceRef {
                     base,
-                    projection: &projection.base,
+                    projection: proj_base,
                 });
 
-                match projection.elem {
+                match elem {
                     mir::ProjectionElem::Deref => bug!(),
                     mir::ProjectionElem::Field(ref field, _) => {
                         cg_base.project_field(bx, field.index())
                     }
                     mir::ProjectionElem::Index(index) => {
                         let index = &mir::Operand::Copy(
-                            mir::Place::from(index)
+                            mir::Place::from(*index)
                         );
                         let index = self.codegen_operand(bx, index);
                         let llindex = index.immediate();
@@ -551,27 +552,27 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     mir::ProjectionElem::ConstantIndex { offset,
                                                          from_end: false,
                                                          min_length: _ } => {
-                        let lloffset = bx.cx().const_usize(offset as u64);
+                        let lloffset = bx.cx().const_usize(*offset as u64);
                         cg_base.project_index(bx, lloffset)
                     }
                     mir::ProjectionElem::ConstantIndex { offset,
                                                          from_end: true,
                                                          min_length: _ } => {
-                        let lloffset = bx.cx().const_usize(offset as u64);
+                        let lloffset = bx.cx().const_usize(*offset as u64);
                         let lllen = cg_base.len(bx.cx());
                         let llindex = bx.sub(lllen, lloffset);
                         cg_base.project_index(bx, llindex)
                     }
                     mir::ProjectionElem::Subslice { from, to } => {
                         let mut subslice = cg_base.project_index(bx,
-                            bx.cx().const_usize(from as u64));
+                            bx.cx().const_usize(*from as u64));
                         let projected_ty = PlaceTy::from_ty(cg_base.layout.ty)
-                            .projection_ty(tcx, &projection.elem).ty;
+                            .projection_ty(tcx, elem).ty;
                         subslice.layout = bx.cx().layout_of(self.monomorphize(&projected_ty));
 
                         if subslice.layout.is_unsized() {
                             subslice.llextra = Some(bx.sub(cg_base.llextra.unwrap(),
-                                bx.cx().const_usize((from as u64) + (to as u64))));
+                                bx.cx().const_usize((*from as u64) + (*to as u64))));
                         }
 
                         // Cast the place pointer type to the new
@@ -582,7 +583,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         subslice
                     }
                     mir::ProjectionElem::Downcast(_, v) => {
-                        cg_base.project_downcast(bx, v)
+                        cg_base.project_downcast(bx, *v)
                     }
                 }
             }
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index e0ad2527229ba..0a932bc3e1574 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -522,7 +522,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         // because codegen_place() panics if Local is operand.
         if let mir::Place {
             base: mir::PlaceBase::Local(index),
-            projection: None,
+            projection: box [],
         } = *place {
             if let LocalRef::Operand(Some(op)) = self.locals[index] {
                 if let ty::Array(_, n) = op.layout.ty.sty {
diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs
index 594f45c833758..b1bc57c2e90ec 100644
--- a/src/librustc_codegen_ssa/mir/statement.rs
+++ b/src/librustc_codegen_ssa/mir/statement.rs
@@ -19,7 +19,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::StatementKind::Assign(ref place, ref rvalue) => {
                 if let mir::Place {
                     base: mir::PlaceBase::Local(index),
-                    projection: None,
+                    projection: box [],
                 } = *place {
                     match self.locals[index] {
                         LocalRef::Place(cg_dest) => {
diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs
index c9e6e7f70a2b4..db19cbc3175f8 100644
--- a/src/librustc_mir/borrow_check/borrow_set.rs
+++ b/src/librustc_mir/borrow_check/borrow_set.rs
@@ -317,7 +317,7 @@ impl<'a, 'tcx> GatherBorrows<'a, 'tcx> {
         // so extract `temp`.
         let temp = if let &mir::Place {
             base: mir::PlaceBase::Local(temp),
-            projection: None,
+            projection: box [],
         } = assigned_place {
             temp
         } else {
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index bfc7050ebf71c..a6f7c8f227c99 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -2,8 +2,8 @@ use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::mir::{
     self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, Local,
-    LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, Projection, PlaceRef,
-    ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
+    LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, PlaceRef, ProjectionElem, Rvalue,
+    Statement, StatementKind, TerminatorKind, VarBindingForm,
 };
 use rustc::ty::{self, Ty};
 use rustc_data_structures::fx::FxHashSet;
@@ -244,7 +244,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 }
                 let span = if let Place {
                     base: PlaceBase::Local(local),
-                    projection: None,
+                    projection: box [],
                 } = place {
                     let decl = &self.body.local_decls[*local];
                     Some(decl.source_info.span)
@@ -614,9 +614,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     projection,
                 } = first_borrowed_place;
 
-                let mut current = projection;
+                for (i, elem) in projection.iter().enumerate().rev() {
+                    let base_proj = &projection[..i];
 
-                while let Some(box Projection { base: base_proj, elem }) = current {
                     match elem {
                         ProjectionElem::Field(field, _) if union_ty(base, base_proj).is_some() => {
                             return Some((PlaceRef {
@@ -624,7 +624,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                                 projection: base_proj,
                             }, field));
                         },
-                        _ => current = base_proj,
+                        _ => {},
                     }
                 }
                 None
@@ -637,9 +637,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     projection,
                 } = second_borrowed_place;
 
-                let mut current = projection;
+                for (i, elem) in projection.iter().enumerate().rev() {
+                    let proj_base = &projection[..i];
 
-                while let Some(box Projection { base: proj_base, elem }) = current {
                     if let ProjectionElem::Field(field, _) = elem {
                         if let Some(union_ty) = union_ty(base, proj_base) {
                             if field != target_field
@@ -660,8 +660,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             }
                         }
                     }
-
-                    current = proj_base;
                 }
                 None
             })
@@ -707,7 +705,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let borrow_spans = self.retrieve_borrow_spans(borrow);
         let borrow_span = borrow_spans.var_or_use();
 
-        assert!(root_place.projection.is_none());
+        assert!(root_place.projection.is_empty());
         let proper_span = match root_place.base {
             PlaceBase::Local(local) => self.body.local_decls[*local].source_info.span,
             _ => drop_span,
@@ -716,7 +714,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         if self.access_place_error_reported
             .contains(&(Place {
                 base: root_place.base.clone(),
-                projection: root_place.projection.clone(),
+                projection: root_place.projection.to_vec().into_boxed_slice(),
             }, borrow_span))
         {
             debug!(
@@ -729,7 +727,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         self.access_place_error_reported
             .insert((Place {
                 base: root_place.base.clone(),
-                projection: root_place.projection.clone(),
+                projection: root_place.projection.to_vec().into_boxed_slice(),
             }, borrow_span));
 
         if let StorageDeadOrDrop::Destructor(dropped_ty) =
@@ -1107,7 +1105,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             let local_kind = match borrow.borrowed_place {
                 Place {
                     base: PlaceBase::Local(local),
-                    projection: None,
+                    projection: box [],
                 } => {
                     match self.body.local_kind(local) {
                         LocalKind::ReturnPointer
@@ -1136,7 +1134,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 .unwrap();
             let local = if let PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: [],
             } = root_place {
                 local
             } else {
@@ -1446,7 +1444,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     ) {
         let (from_arg, local_decl) = if let Place {
             base: PlaceBase::Local(local),
-            projection: None,
+            projection: box [],
         } = *err_place {
             if let LocalKind::Arg = self.body.local_kind(local) {
                 (true, Some(&self.body.local_decls[local]))
@@ -1519,10 +1517,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn classify_drop_access_kind(&self, place: PlaceRef<'cx, 'tcx>) -> StorageDeadOrDrop<'tcx> {
         let tcx = self.infcx.tcx;
         match place.projection {
-            None => {
+            [] => {
                 StorageDeadOrDrop::LocalStorageDead
             }
-            Some(box Projection { ref base, ref elem }) => {
+            [.., elem] => {
+                // FIXME(spastorino) revisit when we get rid of Box
+                let base = &place.projection[..place.projection.len() - 1];
+
+                // FIXME(spastorino) make this iterate
                 let base_access = self.classify_drop_access_kind(PlaceRef {
                     base: place.base,
                     projection: base,
@@ -1609,7 +1611,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             let mut target = *match reservation {
                 Place {
                     base: PlaceBase::Local(local),
-                    projection: None,
+                    projection: box [],
                 } if self.body.local_kind(*local) == LocalKind::Temp => local,
                 _ => return None,
             };
@@ -1625,7 +1627,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 if let StatementKind::Assign(
                     Place {
                         base: PlaceBase::Local(assigned_to),
-                        projection: None,
+                        projection: box [],
                     },
                     box rvalue
                 ) = &stmt.kind {
@@ -1753,7 +1755,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             if let TerminatorKind::Call {
                 destination: Some((Place {
                     base: PlaceBase::Local(assigned_to),
-                    projection: None,
+                    projection: box [],
                 }, _)),
                 args,
                 ..
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 9f25e98052ec4..1fbedc49ecf3f 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -152,7 +152,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         match place {
             PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: [],
             } => {
                 self.append_local_to_string(*local, buf)?;
             }
@@ -162,7 +162,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         kind: StaticKind::Promoted(..),
                         ..
                     }),
-                projection: None,
+                projection: [],
             } => {
                 buf.push_str("promoted");
             }
@@ -173,15 +173,17 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         def_id,
                         ..
                     }),
-                projection: None,
+                projection: [],
             } => {
                 buf.push_str(&self.infcx.tcx.item_name(*def_id).to_string());
             }
             PlaceRef {
                 base,
-                projection: Some(ref proj),
+                projection: [.., elem],
             } => {
-                match proj.elem {
+                let proj_base = &place.projection[..place.projection.len() - 1];
+
+                match elem {
                     ProjectionElem::Deref => {
                         let upvar_field_projection =
                             self.is_upvar_field_projection(place);
@@ -199,20 +201,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                                 self.append_place_to_string(
                                     PlaceRef {
                                         base,
-                                        projection: &proj.base,
+                                        projection: proj_base,
                                     },
                                     buf,
                                     autoderef,
                                     &including_downcast,
                                 )?;
                             } else {
-                                match (&proj.base, base) {
-                                    (None, PlaceBase::Local(local)) => {
+                                match (proj_base, base) {
+                                    ([], PlaceBase::Local(local)) => {
                                         if self.body.local_decls[*local].is_ref_for_guard() {
                                             self.append_place_to_string(
                                                 PlaceRef {
                                                     base,
-                                                    projection: &proj.base,
+                                                    projection: proj_base,
                                                 },
                                                 buf,
                                                 autoderef,
@@ -224,7 +226,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                                             self.append_place_to_string(
                                                 PlaceRef {
                                                     base,
-                                                    projection: &proj.base,
+                                                    projection: proj_base,
                                                 },
                                                 buf,
                                                 autoderef,
@@ -238,7 +240,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                                         self.append_place_to_string(
                                             PlaceRef {
                                                 base,
-                                                projection: &proj.base,
+                                                projection: proj_base,
                                             },
                                             buf,
                                             autoderef,
@@ -253,7 +255,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         self.append_place_to_string(
                             PlaceRef {
                                 base,
-                                projection: &proj.base,
+                                projection: proj_base,
                             },
                             buf,
                             autoderef,
@@ -275,12 +277,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         } else {
                             let field_name = self.describe_field(PlaceRef {
                                 base,
-                                projection: &proj.base,
-                            }, field);
+                                projection: proj_base,
+                            }, *field);
                             self.append_place_to_string(
                                 PlaceRef {
                                     base,
-                                    projection: &proj.base,
+                                    projection: proj_base,
                                 },
                                 buf,
                                 autoderef,
@@ -295,14 +297,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         self.append_place_to_string(
                             PlaceRef {
                                 base,
-                                projection: &proj.base,
+                                projection: proj_base,
                             },
                             buf,
                             autoderef,
                             &including_downcast,
                         )?;
                         buf.push_str("[");
-                        if self.append_local_to_string(index, buf).is_err() {
+                        if self.append_local_to_string(*index, buf).is_err() {
                             buf.push_str("_");
                         }
                         buf.push_str("]");
@@ -315,7 +317,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         self.append_place_to_string(
                             PlaceRef {
                                 base,
-                                projection: &proj.base,
+                                projection: proj_base,
                             },
                             buf,
                             autoderef,
@@ -349,28 +351,32 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         match place {
             PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: [],
             } => {
                 let local = &self.body.local_decls[*local];
                 self.describe_field_from_ty(&local.ty, field, None)
             }
             PlaceRef {
                 base: PlaceBase::Static(static_),
-                projection: None,
+                projection: [],
             } =>
                 self.describe_field_from_ty(&static_.ty, field, None),
             PlaceRef {
                 base,
-                projection: Some(proj),
-            } => match proj.elem {
-                ProjectionElem::Deref => self.describe_field(PlaceRef {
-                    base,
-                    projection: &proj.base,
-                }, field),
+                projection: [.., elem],
+            } => match elem {
+                ProjectionElem::Deref => {
+                    let proj_base = &place.projection[..place.projection.len() - 1];
+
+                    self.describe_field(PlaceRef {
+                        base,
+                        projection: proj_base,
+                    }, field)
+                }
                 ProjectionElem::Downcast(_, variant_index) => {
                     let base_ty =
                         Place::ty_from(place.base, place.projection, self.body, self.infcx.tcx).ty;
-                    self.describe_field_from_ty(&base_ty, field, Some(variant_index))
+                    self.describe_field_from_ty(&base_ty, field, Some(*variant_index))
                 }
                 ProjectionElem::Field(_, field_type) => {
                     self.describe_field_from_ty(&field_type, field, None)
@@ -378,9 +384,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 ProjectionElem::Index(..)
                 | ProjectionElem::ConstantIndex { .. }
                 | ProjectionElem::Subslice { .. } => {
+                    let proj_base = &place.projection[..place.projection.len() - 1];
+
                     self.describe_field(PlaceRef {
                         base,
-                        projection: &proj.base,
+                        projection: proj_base,
                     }, field)
                 }
             },
@@ -445,7 +453,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 def_id,
                 ..
             }),
-            projection: None,
+            projection: [],
         } = place_ref {
             let attrs = self.infcx.tcx.get_attrs(*def_id);
             let is_thread_local = attrs.iter().any(|attr| attr.check_name(sym::thread_local));
@@ -830,7 +838,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             Some(&Statement {
                 kind: StatementKind::Assign(Place {
                     base: PlaceBase::Local(local),
-                    projection: None,
+                    projection: box [],
                 }, _),
                 ..
             }) => local,
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 9ad7cbc478bb0..041047bf7cdc8 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -10,10 +10,10 @@ use rustc::lint::builtin::{MUTABLE_BORROW_RESERVATION_CONFLICT};
 use rustc::middle::borrowck::SignalledError;
 use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
 use rustc::mir::{
-    ClearCrossCrate, Local, Location, Body, Mutability, Operand, Place, PlaceBase, PlaceRef,
-    Static, StaticKind
+    ClearCrossCrate, Local, Location, Body, Mutability, Operand, Place, PlaceBase, PlaceElem,
+    PlaceRef, Static, StaticKind
 };
-use rustc::mir::{Field, Projection, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
+use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind};
 use rustc::mir::{Terminator, TerminatorKind};
 use rustc::ty::query::Providers;
 use rustc::ty::{self, TyCtxt};
@@ -905,7 +905,7 @@ enum InitializationRequiringAction {
 
 struct RootPlace<'d, 'tcx> {
     place_base: &'d PlaceBase<'tcx>,
-    place_projection: &'d Option<Box<Projection<'tcx>>>,
+    place_projection: &'d [PlaceElem<'tcx>],
     is_local_mutation_allowed: LocalMutationIsAllowed,
 }
 
@@ -1191,7 +1191,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         // before (at this point in the flow).
         if let Place {
             base: PlaceBase::Local(local),
-            projection: None,
+            projection: box [],
         } = place_span.0 {
             if let Mutability::Not = self.body.local_decls[*local].mutability {
                 // check for reassignments to immutable local variables
@@ -1331,7 +1331,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
     fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) {
         let propagate_closure_used_mut_place = |this: &mut Self, place: &Place<'tcx>| {
-            if place.projection.is_some() {
+            if !place.projection.is_empty() {
                 if let Some(field) = this.is_upvar_field_projection(place.as_ref()) {
                     this.used_mut_upvars.push(field);
                 }
@@ -1346,11 +1346,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         match *operand {
             Operand::Move(Place {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: box [],
             }) |
             Operand::Copy(Place {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: box [],
             }) if self.body.local_decls[local].is_user_variable.is_none() => {
                 if self.body.local_decls[local].ty.is_mutable_ptr() {
                     // The variable will be marked as mutable by the borrow.
@@ -1468,7 +1468,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         //
         // FIXME: allow thread-locals to borrow other thread locals?
 
-        assert!(root_place.projection.is_none());
+        assert!(root_place.projection.is_empty());
         let (might_be_alive, will_be_dropped) = match root_place.base {
             PlaceBase::Static(box Static {
                 kind: StaticKind::Promoted(..),
@@ -1756,13 +1756,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         flow_state: &Flows<'cx, 'tcx>,
     ) {
         debug!("check_if_assigned_path_is_moved place: {:?}", place);
-        // recur down place; dispatch to external checks when necessary
-        let mut place_projection = &place.projection;
 
         // None case => assigning to `x` does not require `x` be initialized.
-        while let Some(proj) = place_projection {
-            let Projection { ref base, ref elem } = **proj;
-            match *elem {
+        for (i, elem) in place.projection.iter().enumerate().rev() {
+            match elem {
                 ProjectionElem::Index(_/*operand*/) |
                 ProjectionElem::ConstantIndex { .. } |
                 // assigning to P[i] requires P to be valid.
@@ -1774,11 +1771,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
                 // assigning to (*P) requires P to be initialized
                 ProjectionElem::Deref => {
+                    let proj_base = &place.projection[..i];
+
                     self.check_if_full_path_is_moved(
                         location, InitializationRequiringAction::Use,
                         (PlaceRef {
                             base: &place.base,
-                            projection: base,
+                            projection: proj_base,
                         }, span), flow_state);
                     // (base initialized; no need to
                     // recur further)
@@ -1791,18 +1790,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 }
 
                 ProjectionElem::Field(..) => {
+                    let proj_base = &place.projection[..i];
                     // if type of `P` has a dtor, then
                     // assigning to `P.f` requires `P` itself
                     // be already initialized
                     let tcx = self.infcx.tcx;
-                    let base_ty = Place::ty_from(&place.base, base, self.body, tcx).ty;
+                    let base_ty = Place::ty_from(&place.base, proj_base, self.body, tcx).ty;
                     match base_ty.sty {
                         ty::Adt(def, _) if def.has_dtor(tcx) => {
                             self.check_if_path_or_subpath_is_moved(
                                 location, InitializationRequiringAction::Assignment,
                                 (PlaceRef {
                                     base: &place.base,
-                                    projection: base,
+                                    projection: proj_base,
                                 }, span), flow_state);
 
                             // (base initialized; no need to
@@ -1815,7 +1815,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         ty::Adt(..) | ty::Tuple(..) => {
                             check_parent_of_field(self, location, PlaceRef {
                                 base: &place.base,
-                                projection: base,
+                                projection: proj_base,
                             }, span, flow_state);
 
                             if let PlaceBase::Local(local) = place.base {
@@ -1835,8 +1835,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     }
                 }
             }
-
-            place_projection = base;
         }
 
         fn check_parent_of_field<'cx, 'tcx>(
@@ -2084,7 +2082,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         match root_place {
             RootPlace {
                 place_base: PlaceBase::Local(local),
-                place_projection: None,
+                place_projection: [],
                 is_local_mutation_allowed,
             } => {
                 // If the local may have been initialized, and it is now currently being
@@ -2103,7 +2101,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             } => {}
             RootPlace {
                 place_base,
-                place_projection: place_projection @ Some(_),
+                place_projection: place_projection @ [.., _],
                 is_local_mutation_allowed: _,
             } => {
                 if let Some(field) = self.is_upvar_field_projection(PlaceRef {
@@ -2115,7 +2113,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             }
             RootPlace {
                 place_base: PlaceBase::Static(..),
-                place_projection: None,
+                place_projection: [],
                 is_local_mutation_allowed: _,
             } => {}
         }
@@ -2131,7 +2129,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         match place {
             PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: [],
             } => {
                 let local = &self.body.local_decls[*local];
                 match local.mutability {
@@ -2162,7 +2160,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     kind: StaticKind::Promoted(..),
                     ..
                 }),
-                projection: None,
+                projection: [],
             } =>
                 Ok(RootPlace {
                     place_base: place.base,
@@ -2175,7 +2173,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     def_id,
                     ..
                 }),
-                projection: None,
+                projection: [],
             } => {
                 if !self.infcx.tcx.is_mutable_static(*def_id) {
                     Err(place)
@@ -2189,12 +2187,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             }
             PlaceRef {
                 base: _,
-                projection: Some(proj),
+                projection: [.., elem],
             } => {
-                match proj.elem {
+                let proj_base = &place.projection[..place.projection.len() - 1];
+
+                match elem {
                     ProjectionElem::Deref => {
                         let base_ty =
-                            Place::ty_from(place.base, &proj.base, self.body, self.infcx.tcx).ty;
+                            Place::ty_from(place.base, proj_base, self.body, self.infcx.tcx).ty;
 
                         // Check the kind of deref to decide
                         match base_ty.sty {
@@ -2216,7 +2216,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
                                         self.is_mutable(PlaceRef {
                                             base: place.base,
-                                            projection: &proj.base,
+                                            projection: proj_base,
                                         }, mode)
                                     }
                                 }
@@ -2240,7 +2240,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             _ if base_ty.is_box() => {
                                 self.is_mutable(PlaceRef {
                                     base: place.base,
-                                    projection: &proj.base,
+                                    projection: proj_base,
                                 }, is_local_mutation_allowed)
                             }
                             // Deref should only be for reference, pointers or boxes
@@ -2297,7 +2297,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                                     // ```
                                     let _ = self.is_mutable(PlaceRef {
                                         base: place.base,
-                                        projection: &proj.base,
+                                        projection: proj_base,
                                     }, is_local_mutation_allowed)?;
                                     Ok(RootPlace {
                                         place_base: place.base,
@@ -2309,7 +2309,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         } else {
                             self.is_mutable(PlaceRef {
                                 base: place.base,
-                                projection: &proj.base,
+                                projection: proj_base,
                             }, is_local_mutation_allowed)
                         }
                     }
@@ -2326,21 +2326,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let mut place_projection = place_ref.projection;
         let mut by_ref = false;
 
-        if let Some(box Projection {
-            base,
-            elem: ProjectionElem::Deref,
-        }) = place_projection {
-            place_projection = &base;
+        if let [.., ProjectionElem::Deref] = place_projection {
+            place_projection = &place_projection[..place_projection.len() - 1];
             by_ref = true;
         }
 
         match place_projection {
-            Some(box Projection {
-                base,
-                elem: ProjectionElem::Field(field, _ty),
-            }) => {
+            [.., ProjectionElem::Field(field, _ty)] => {
+                let base = &place_projection[..place_projection.len() - 1];
                 let tcx = self.infcx.tcx;
-                let base_ty = Place::ty_from(place_ref.base, &base, self.body, tcx).ty;
+                let base_ty = Place::ty_from(place_ref.base, base, self.body, tcx).ty;
 
                 if (base_ty.is_closure() || base_ty.is_generator()) &&
                     (!by_ref || self.upvars[field.index()].by_ref) {
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index 0d13db2f5a413..d346a4cdfa21a 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -91,7 +91,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 if let Some(StatementKind::Assign(
                     Place {
                         base: PlaceBase::Local(local),
-                        projection: None,
+                        projection: box [],
                     },
                     box Rvalue::Use(Operand::Move(move_from)),
                 )) = self.body.basic_blocks()[location.block]
@@ -274,16 +274,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         place: &Place<'tcx>,
         span: Span
     ) -> DiagnosticBuilder<'a> {
-        let description = if place.projection.is_none() {
+        let description = if place.projection.is_empty() {
             format!("static item `{}`", self.describe_place(place.as_ref()).unwrap())
         } else {
-            let mut base_static = &place.projection;
-            while let Some(box Projection { base: Some(ref proj), .. }) = base_static {
-                base_static = &proj.base;
-            }
             let base_static = PlaceRef {
                 base: &place.base,
-                projection: base_static,
+                projection: &place.projection[..1],
             };
 
             format!(
@@ -310,16 +306,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             .find_map(|p| self.is_upvar_field_projection(p));
 
         let deref_base = match deref_target_place.projection {
-            Some(box Projection { ref base, elem: ProjectionElem::Deref }) => PlaceRef {
-                base: &deref_target_place.base,
-                projection: base,
-            },
+            box [.., ProjectionElem::Deref] => {
+                let proj_base =
+                    &deref_target_place.projection[..deref_target_place.projection.len() - 1];
+
+                PlaceRef {
+                    base: &deref_target_place.base,
+                    projection: proj_base,
+                }
+            }
             _ => bug!("deref_target_place is not a deref projection"),
         };
 
         if let PlaceRef {
             base: PlaceBase::Local(local),
-            projection: None,
+            projection: [],
         } = deref_base {
             let decl = &self.body.local_decls[*local];
             if decl.is_ref_for_guard() {
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 8f2ce80aafa22..dbc1d1700933f 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -2,7 +2,7 @@ use rustc::hir;
 use rustc::hir::Node;
 use rustc::mir::{self, BindingForm, ClearCrossCrate, Local, Location, Body};
 use rustc::mir::{
-    Mutability, Place, PlaceRef, PlaceBase, Projection, ProjectionElem, Static, StaticKind
+    Mutability, Place, PlaceRef, PlaceBase, ProjectionElem, Static, StaticKind
 };
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc_data_structures::indexed_vec::Idx;
@@ -47,12 +47,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         match the_place_err {
             PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: [],
             } => {
                 item_msg = format!("`{}`", access_place_desc.unwrap());
                 if let Place {
                     base: PlaceBase::Local(_),
-                    projection: None,
+                    projection: box [],
                 } = access_place {
                     reason = ", as it is not declared as mutable".to_string();
                 } else {
@@ -65,14 +65,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
             PlaceRef {
                 base: _,
-                projection:
-                    Some(box Projection {
-                        base,
-                        elem: ProjectionElem::Field(upvar_index, _),
-                    }),
+                projection: [.., ProjectionElem::Field(upvar_index, _)],
             } => {
+                let proj_base = &the_place_err.projection[..the_place_err.projection.len() - 1];
+
                 debug_assert!(is_closure_or_generator(
-                    Place::ty_from(&the_place_err.base, &base, self.body, self.infcx.tcx).ty
+                    Place::ty_from(&the_place_err.base, proj_base, self.body, self.infcx.tcx).ty
                 ));
 
                 item_msg = format!("`{}`", access_place_desc.unwrap());
@@ -86,14 +84,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
             PlaceRef {
                 base: _,
-                projection:
-                    Some(box Projection {
-                        base,
-                        elem: ProjectionElem::Deref,
-                    }),
+                projection: [.., ProjectionElem::Deref],
             } => {
+                // FIXME(spastorino) once released use box [base @ .., ProjectionElem::Deref]
+                let base = &the_place_err.projection[..the_place_err.projection.len() - 1];
+
                 if the_place_err.base == &PlaceBase::Local(Local::new(1)) &&
-                    base.is_none() &&
+                    base.is_empty() &&
                     !self.upvars.is_empty() {
                     item_msg = format!("`{}`", access_place_desc.unwrap());
                     debug_assert!(self.body.local_decls[Local::new(1)].ty.is_region_ptr());
@@ -114,7 +111,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                             ", as `Fn` closures cannot mutate their captured variables".to_string()
                         }
                 } else if {
-                    if let (PlaceBase::Local(local), None) = (&the_place_err.base, base) {
+                    if let (PlaceBase::Local(local), []) = (&the_place_err.base, base) {
                         self.body.local_decls[*local].is_ref_for_guard()
                     } else {
                         false
@@ -151,7 +148,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         kind: StaticKind::Promoted(..),
                         ..
                     }),
-                projection: None,
+                projection: [],
             } => unreachable!(),
 
             PlaceRef {
@@ -161,11 +158,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         def_id,
                         ..
                     }),
-                projection: None,
+                projection: [],
             } => {
                 if let Place {
                     base: PlaceBase::Static(_),
-                    projection: None,
+                    projection: box [],
                 } = access_place {
                     item_msg = format!("immutable static item `{}`", access_place_desc.unwrap());
                     reason = String::new();
@@ -178,33 +175,19 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
             PlaceRef {
                 base: _,
-                projection:
-                    Some(box Projection {
-                        base: _,
-                        elem: ProjectionElem::Index(_),
-                    }),
+                projection: [.., ProjectionElem::Index(_)],
             }
             | PlaceRef {
                 base: _,
-                projection:
-                    Some(box Projection {
-                        base: _,
-                        elem: ProjectionElem::ConstantIndex { .. },
-                    }),
+                projection: [.., ProjectionElem::ConstantIndex { .. }],
             }
             | PlaceRef {
                 base: _,
-                projection: Some(box Projection {
-                    base: _,
-                    elem: ProjectionElem::Subslice { .. },
-                }),
+                projection: [.., ProjectionElem::Subslice { .. }],
             }
             | PlaceRef {
                 base: _,
-                projection: Some(box Projection {
-                    base: _,
-                    elem: ProjectionElem::Downcast(..),
-                }),
+                projection: [.., ProjectionElem::Downcast(..)],
             } => bug!("Unexpected immutable place."),
         }
 
@@ -262,22 +245,19 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             // after the field access).
             PlaceRef {
                 base,
-                projection: Some(box Projection {
-                    base: Some(box Projection {
-                        base: Some(box Projection {
-                            base: base_proj,
-                            elem: ProjectionElem::Deref,
-                        }),
-                        elem: ProjectionElem::Field(field, _),
-                    }),
-                    elem: ProjectionElem::Deref,
-                }),
+                projection: [..,
+                             ProjectionElem::Deref,
+                             ProjectionElem::Field(field, _),
+                             ProjectionElem::Deref,
+                ],
             } => {
+                let base_proj = &the_place_err.projection[..the_place_err.projection.len() - 3];
+
                 err.span_label(span, format!("cannot {ACT}", ACT = act));
 
                 if let Some((span, message)) = annotate_struct_field(
                     self.infcx.tcx,
-                    Place::ty_from(&base, &base_proj, self.body, self.infcx.tcx).ty,
+                    Place::ty_from(base, base_proj, self.body, self.infcx.tcx).ty,
                     field,
                 ) {
                     err.span_suggestion(
@@ -292,7 +272,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             // Suggest removing a `&mut` from the use of a mutable reference.
             PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: [],
             } if {
                 self.body.local_decls.get(*local).map(|local_decl| {
                     if let ClearCrossCrate::Set(
@@ -328,7 +308,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             // variable) mutations...
             PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: [],
             } if self.body.local_decls[*local].can_be_made_mutable() => {
                 // ... but it doesn't make sense to suggest it on
                 // variables that are `ref x`, `ref mut x`, `&self`,
@@ -349,13 +329,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             // Also suggest adding mut for upvars
             PlaceRef {
                 base,
-                projection: Some(box Projection {
-                    base: proj_base,
-                    elem: ProjectionElem::Field(upvar_index, _),
-                }),
+                projection: [.., ProjectionElem::Field(upvar_index, _)],
             } => {
+                let proj_base = &the_place_err.projection[..the_place_err.projection.len() - 1];
+
                 debug_assert!(is_closure_or_generator(
-                    Place::ty_from(&base, &proj_base, self.body, self.infcx.tcx).ty
+                    Place::ty_from(base, proj_base, self.body, self.infcx.tcx).ty
                 ));
 
                 err.span_label(span, format!("cannot {ACT}", ACT = act));
@@ -385,7 +364,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             // a local variable, then just suggest the user remove it.
             PlaceRef {
                 base: PlaceBase::Local(_),
-                projection: None,
+                projection: [],
             } if {
                     if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
                         snippet.starts_with("&mut ")
@@ -400,10 +379,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
             PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: Some(box Projection {
-                    base: None,
-                    elem: ProjectionElem::Deref,
-                }),
+                projection: [ProjectionElem::Deref],
             } if {
                 if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) =
                     self.body.local_decls[*local].is_user_variable
@@ -427,10 +403,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             // arbitrary base for the projection?
             PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: Some(box Projection {
-                    base: None,
-                    elem: ProjectionElem::Deref,
-                }),
+                projection: [ProjectionElem::Deref],
             } if self.body.local_decls[*local].is_user_variable.is_some() =>
             {
                 let local_decl = &self.body.local_decls[*local];
@@ -510,10 +483,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
             PlaceRef {
                 base,
-                projection: Some(box Projection {
-                    base: None,
-                    elem: ProjectionElem::Deref,
-                }),
+                projection: [ProjectionElem::Deref],
             // FIXME document what is this 1 magic number about
             } if *base == PlaceBase::Local(Local::new(1)) &&
                   !self.upvars.is_empty() =>
@@ -527,10 +497,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
             PlaceRef {
                 base: _,
-                projection: Some(box Projection {
-                    base: _,
-                    elem: ProjectionElem::Deref,
-                }),
+                projection: [.., ProjectionElem::Deref],
             } => {
                 err.span_label(span, format!("cannot {ACT}", ACT = act));
 
diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
index 5c230913a0da3..1e5f613aedc23 100644
--- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs
+++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
@@ -8,9 +8,8 @@ use rustc::infer::InferCtxt;
 use rustc::mir::visit::TyContext;
 use rustc::mir::visit::Visitor;
 use rustc::mir::{
-    BasicBlock, BasicBlockData, Body, Local, Location, Place, PlaceBase, Projection,
-    ProjectionElem, Rvalue, SourceInfo, Statement, StatementKind, Terminator, TerminatorKind,
-    UserTypeProjection,
+    BasicBlock, BasicBlockData, Body, Local, Location, Place, PlaceBase, ProjectionElem, Rvalue,
+    SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UserTypeProjection,
 };
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid, Ty};
@@ -229,14 +228,11 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> {
             match place {
                 Place {
                     base: PlaceBase::Local(local),
-                    projection: None,
+                    projection: box [],
                 } |
                 Place {
                     base: PlaceBase::Local(local),
-                    projection: Some(box Projection {
-                        base: None,
-                        elem: ProjectionElem::Deref,
-                    }),
+                    projection: box [ProjectionElem::Deref],
                 } => {
                     debug!(
                         "Recording `killed` facts for borrows of local={:?} at location={:?}",
@@ -261,7 +257,7 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> {
 
                 Place {
                     base: PlaceBase::Local(local),
-                    projection: Some(_),
+                    projection: box [.., _],
                 } => {
                     // Kill conflicting borrows of the innermost local.
                     debug!(
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
index aba3ef1cbbfc9..ad68b4bc054bb 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -274,7 +274,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     if let Some((WriteKind::StorageDeadOrDrop, place)) = kind_place {
                         if let Place {
                             base: PlaceBase::Local(borrowed_local),
-                            projection: None,
+                            projection: box [],
                         } = place {
                              if body.local_decls[*borrowed_local].name.is_some()
                                 && local != *borrowed_local
@@ -495,11 +495,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                             Operand::Constant(c) => c.span,
                             Operand::Copy(Place {
                                 base: PlaceBase::Local(l),
-                                projection: None,
+                                projection: box [],
                             }) |
                             Operand::Move(Place {
                                 base: PlaceBase::Local(l),
-                                projection: None,
+                                projection: box [],
                             }) => {
                                 let local_decl = &self.body.local_decls[*l];
                                 if local_decl.name.is_none() {
@@ -543,7 +543,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let mut target = if let Some(&Statement {
             kind: StatementKind::Assign(Place {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: box [],
             }, _),
             ..
         }) = stmt
@@ -583,11 +583,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         Rvalue::Use(operand) => match operand {
                             Operand::Copy(Place {
                                 base: PlaceBase::Local(from),
-                                projection: None,
+                                projection: box [],
                             })
                             | Operand::Move(Place {
                                 base: PlaceBase::Local(from),
-                                projection: None,
+                                projection: box [],
                             })
                                 if *from == target =>
                             {
@@ -602,11 +602,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         ) => match operand {
                             Operand::Copy(Place {
                                 base: PlaceBase::Local(from),
-                                projection: None,
+                                projection: box [],
                             })
                             | Operand::Move(Place {
                                 base: PlaceBase::Local(from),
-                                projection: None,
+                                projection: box [],
                             })
                                 if *from == target =>
                             {
@@ -639,7 +639,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 if let TerminatorKind::Call {
                     destination: Some((Place {
                         base: PlaceBase::Local(dest),
-                        projection: None,
+                        projection: box [],
                     }, block)),
                     args,
                     ..
@@ -653,7 +653,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     let found_target = args.iter().any(|arg| {
                         if let Operand::Move(Place {
                             base: PlaceBase::Local(potential),
-                            projection: None,
+                            projection: box [],
                         }) = arg {
                             *potential == target
                         } else {
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index da1f64b05151b..599472958f4fc 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -421,107 +421,104 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
     ) -> PlaceTy<'tcx> {
         debug!("sanitize_place: {:?}", place);
 
-        place.iterate(|place_base, place_projection| {
-            let mut place_ty = match place_base {
-                PlaceBase::Local(index) =>
-                    PlaceTy::from_ty(self.body.local_decls[*index].ty),
-                PlaceBase::Static(box Static { kind, ty: sty, def_id }) => {
-                    let sty = self.sanitize_type(place, sty);
-                    let check_err =
-                        |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
-                         place: &Place<'tcx>,
-                         ty,
-                         sty| {
-                            if let Err(terr) = verifier.cx.eq_types(
-                                sty,
-                                ty,
-                                location.to_locations(),
-                                ConstraintCategory::Boring,
-                            ) {
-                                span_mirbug!(
-                                verifier,
-                                place,
-                                "bad promoted type ({:?}: {:?}): {:?}",
-                                ty,
-                                sty,
-                                terr
-                            );
-                            };
+        let mut place_ty = match &place.base {
+            PlaceBase::Local(index) =>
+                PlaceTy::from_ty(self.body.local_decls[*index].ty),
+            PlaceBase::Static(box Static { kind, ty: sty, def_id }) => {
+                let sty = self.sanitize_type(place, sty);
+                let check_err =
+                    |verifier: &mut TypeVerifier<'a, 'b, 'tcx>,
+                     place: &Place<'tcx>,
+                     ty,
+                     sty| {
+                        if let Err(terr) = verifier.cx.eq_types(
+                            sty,
+                            ty,
+                            location.to_locations(),
+                            ConstraintCategory::Boring,
+                        ) {
+                            span_mirbug!(
+                            verifier,
+                            place,
+                            "bad promoted type ({:?}: {:?}): {:?}",
+                            ty,
+                            sty,
+                            terr
+                        );
                         };
-                    match kind {
-                        StaticKind::Promoted(promoted, _) => {
-                            if !self.errors_reported {
-                                let promoted_body = &self.promoted[*promoted];
-                                self.sanitize_promoted(promoted_body, location);
-
-                                let promoted_ty = promoted_body.return_ty();
-                                check_err(self, place, promoted_ty, sty);
-                            }
+                    };
+                match kind {
+                    StaticKind::Promoted(promoted, _) => {
+                        if !self.errors_reported {
+                            let promoted_body = &self.promoted[*promoted];
+                            self.sanitize_promoted(promoted_body, location);
+
+                            let promoted_ty = promoted_body.return_ty();
+                            check_err(self, place, promoted_ty, sty);
                         }
-                        StaticKind::Static => {
-                            let ty = self.tcx().type_of(*def_id);
-                            let ty = self.cx.normalize(ty, location);
+                    }
+                    StaticKind::Static => {
+                        let ty = self.tcx().type_of(*def_id);
+                        let ty = self.cx.normalize(ty, location);
 
-                            check_err(self, place, ty, sty);
-                        }
+                        check_err(self, place, ty, sty);
                     }
-                    PlaceTy::from_ty(sty)
                 }
-            };
+                PlaceTy::from_ty(sty)
+            }
+        };
 
-            // FIXME use place_projection.is_empty() when is available
-            if place.projection.is_none() {
-                if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
-                    let is_promoted = match place {
-                        Place {
-                            base: PlaceBase::Static(box Static {
-                                kind: StaticKind::Promoted(..),
-                                ..
-                            }),
-                            projection: None,
-                        } => true,
-                        _ => false,
-                    };
+        if place.projection.is_empty() {
+            if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context {
+                let is_promoted = match place {
+                    Place {
+                        base: PlaceBase::Static(box Static {
+                            kind: StaticKind::Promoted(..),
+                            ..
+                        }),
+                        projection: box [],
+                    } => true,
+                    _ => false,
+                };
 
-                    if !is_promoted {
-                        let tcx = self.tcx();
-                        let trait_ref = ty::TraitRef {
-                            def_id: tcx.lang_items().copy_trait().unwrap(),
-                            substs: tcx.mk_substs_trait(place_ty.ty, &[]),
-                        };
+                if !is_promoted {
+                    let tcx = self.tcx();
+                    let trait_ref = ty::TraitRef {
+                        def_id: tcx.lang_items().copy_trait().unwrap(),
+                        substs: tcx.mk_substs_trait(place_ty.ty, &[]),
+                    };
 
-                        // In order to have a Copy operand, the type T of the
-                        // value must be Copy. Note that we prove that T: Copy,
-                        // rather than using the `is_copy_modulo_regions`
-                        // test. This is important because
-                        // `is_copy_modulo_regions` ignores the resulting region
-                        // obligations and assumes they pass. This can result in
-                        // bounds from Copy impls being unsoundly ignored (e.g.,
-                        // #29149). Note that we decide to use Copy before knowing
-                        // whether the bounds fully apply: in effect, the rule is
-                        // that if a value of some type could implement Copy, then
-                        // it must.
-                        self.cx.prove_trait_ref(
-                            trait_ref,
-                            location.to_locations(),
-                            ConstraintCategory::CopyBound,
-                        );
-                    }
+                    // In order to have a Copy operand, the type T of the
+                    // value must be Copy. Note that we prove that T: Copy,
+                    // rather than using the `is_copy_modulo_regions`
+                    // test. This is important because
+                    // `is_copy_modulo_regions` ignores the resulting region
+                    // obligations and assumes they pass. This can result in
+                    // bounds from Copy impls being unsoundly ignored (e.g.,
+                    // #29149). Note that we decide to use Copy before knowing
+                    // whether the bounds fully apply: in effect, the rule is
+                    // that if a value of some type could implement Copy, then
+                    // it must.
+                    self.cx.prove_trait_ref(
+                        trait_ref,
+                        location.to_locations(),
+                        ConstraintCategory::CopyBound,
+                    );
                 }
             }
+        }
 
-            for proj in place_projection {
-                if place_ty.variant_index.is_none() {
-                    if place_ty.ty.references_error() {
-                        assert!(self.errors_reported);
-                        return PlaceTy::from_ty(self.tcx().types.err);
-                    }
+        for elem in place.projection.iter() {
+            if place_ty.variant_index.is_none() {
+                if place_ty.ty.references_error() {
+                    assert!(self.errors_reported);
+                    return PlaceTy::from_ty(self.tcx().types.err);
                 }
-                place_ty = self.sanitize_projection(place_ty, &proj.elem, place, location)
             }
+            place_ty = self.sanitize_projection(place_ty, elem, place, location)
+        }
 
-            place_ty
-        })
+        place_ty
     }
 
     fn sanitize_promoted(&mut self, promoted_body: &'b Body<'tcx>, location: Location) {
@@ -1354,7 +1351,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 let category = match *place {
                     Place {
                         base: PlaceBase::Local(RETURN_PLACE),
-                        projection: None,
+                        projection: box [],
                     } => if let BorrowCheckContext {
                         universal_regions:
                             UniversalRegions {
@@ -1373,7 +1370,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     },
                     Place {
                         base: PlaceBase::Local(l),
-                        projection: None,
+                        projection: box [],
                     } if !body.local_decls[l].is_user_variable.is_some() => {
                         ConstraintCategory::Boring
                     }
@@ -1660,7 +1657,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 let category = match *dest {
                     Place {
                         base: PlaceBase::Local(RETURN_PLACE),
-                        projection: None,
+                        projection: box [],
                     } => {
                         if let BorrowCheckContext {
                             universal_regions:
@@ -1682,7 +1679,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     }
                     Place {
                         base: PlaceBase::Local(l),
-                        projection: None,
+                        projection: box [],
                     } if !body.local_decls[l].is_user_variable.is_some() => {
                         ConstraintCategory::Boring
                     }
@@ -2416,19 +2413,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         // *p`, where the `p` has type `&'b mut Foo`, for example, we
         // need to ensure that `'b: 'a`.
 
-        let mut borrowed_projection = &borrowed_place.projection;
-
         debug!(
             "add_reborrow_constraint({:?}, {:?}, {:?})",
             location, borrow_region, borrowed_place
         );
-        while let Some(box proj) = borrowed_projection {
-            debug!("add_reborrow_constraint - iteration {:?}", borrowed_projection);
+        for (i, elem) in borrowed_place.projection.iter().enumerate().rev() {
+            debug!("add_reborrow_constraint - iteration {:?}", elem);
+            let proj_base = &borrowed_place.projection[..i];
 
-            match proj.elem {
+            match elem {
                 ProjectionElem::Deref => {
                     let tcx = self.infcx.tcx;
-                    let base_ty = Place::ty_from(&borrowed_place.base, &proj.base, body, tcx).ty;
+                    let base_ty = Place::ty_from(&borrowed_place.base, proj_base, body, tcx).ty;
 
                     debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
                     match base_ty.sty {
@@ -2490,10 +2486,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     // other field access
                 }
             }
-
-            // The "propagate" case. We need to check that our base is valid
-            // for the borrow's lifetime.
-            borrowed_projection = &proj.base;
         }
     }
 
diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs
index 5caba637ccc4a..50067345c65ee 100644
--- a/src/librustc_mir/borrow_check/place_ext.rs
+++ b/src/librustc_mir/borrow_check/place_ext.rs
@@ -25,55 +25,55 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
         body: &Body<'tcx>,
         locals_state_at_exit: &LocalsStateAtExit,
     ) -> bool {
-        self.iterate(|place_base, place_projection| {
-            let ignore = match place_base {
-                // If a local variable is immutable, then we only need to track borrows to guard
-                // against two kinds of errors:
-                // * The variable being dropped while still borrowed (e.g., because the fn returns
-                //   a reference to a local variable)
-                // * The variable being moved while still borrowed
-                //
-                // In particular, the variable cannot be mutated -- the "access checks" will fail --
-                // so we don't have to worry about mutation while borrowed.
-                PlaceBase::Local(index) => {
-                    match locals_state_at_exit {
-                        LocalsStateAtExit::AllAreInvalidated => false,
-                        LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
-                            let ignore = !has_storage_dead_or_moved.contains(*index) &&
-                                body.local_decls[*index].mutability == Mutability::Not;
-                            debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
-                            ignore
-                        }
+        let ignore = match self.base {
+            // If a local variable is immutable, then we only need to track borrows to guard
+            // against two kinds of errors:
+            // * The variable being dropped while still borrowed (e.g., because the fn returns
+            //   a reference to a local variable)
+            // * The variable being moved while still borrowed
+            //
+            // In particular, the variable cannot be mutated -- the "access checks" will fail --
+            // so we don't have to worry about mutation while borrowed.
+            PlaceBase::Local(index) => {
+                match locals_state_at_exit {
+                    LocalsStateAtExit::AllAreInvalidated => false,
+                    LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved } => {
+                        let ignore = !has_storage_dead_or_moved.contains(index) &&
+                            body.local_decls[index].mutability == Mutability::Not;
+                        debug!("ignore_borrow: local {:?} => {:?}", index, ignore);
+                        ignore
                     }
                 }
-                PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_, _), .. }) =>
-                    false,
-                PlaceBase::Static(box Static{ kind: StaticKind::Static, def_id, .. }) => {
-                    tcx.is_mutable_static(*def_id)
-                }
-            };
+            }
+            PlaceBase::Static(box Static{ kind: StaticKind::Promoted(_, _), .. }) =>
+                false,
+            PlaceBase::Static(box Static{ kind: StaticKind::Static, def_id, .. }) => {
+                tcx.is_mutable_static(def_id)
+            }
+        };
 
-            for proj in place_projection {
-                if proj.elem == ProjectionElem::Deref {
-                    let ty = Place::ty_from(place_base, &proj.base, body, tcx).ty;
-                    match ty.sty {
-                        // For both derefs of raw pointers and `&T`
-                        // references, the original path is `Copy` and
-                        // therefore not significant.  In particular,
-                        // there is nothing the user can do to the
-                        // original path that would invalidate the
-                        // newly created reference -- and if there
-                        // were, then the user could have copied the
-                        // original path into a new variable and
-                        // borrowed *that* one, leaving the original
-                        // path unborrowed.
-                        ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => return true,
-                        _ => {}
-                    }
+        for (i, elem) in self.projection.iter().enumerate() {
+            let proj_base = &self.projection[..i];
+
+            if *elem == ProjectionElem::Deref {
+                let ty = Place::ty_from(&self.base, proj_base, body, tcx).ty;
+                match ty.sty {
+                    // For both derefs of raw pointers and `&T`
+                    // references, the original path is `Copy` and
+                    // therefore not significant.  In particular,
+                    // there is nothing the user can do to the
+                    // original path that would invalidate the
+                    // newly created reference -- and if there
+                    // were, then the user could have copied the
+                    // original path into a new variable and
+                    // borrowed *that* one, leaving the original
+                    // path unborrowed.
+                    ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => return true,
+                    _ => {}
                 }
             }
+        }
 
-            ignore
-        })
+        ignore
     }
 }
diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs
index 4f469174b392d..dafa0b6631fe2 100644
--- a/src/librustc_mir/borrow_check/places_conflict.rs
+++ b/src/librustc_mir/borrow_check/places_conflict.rs
@@ -3,8 +3,7 @@ use crate::borrow_check::Overlap;
 use crate::borrow_check::{Deep, Shallow, AccessDepth};
 use rustc::hir;
 use rustc::mir::{
-    Body, BorrowKind, Place, PlaceBase, PlaceRef, Projection, ProjectionElem, ProjectionsIter,
-    StaticKind,
+    Body, BorrowKind, Place, PlaceBase, PlaceElem, PlaceRef, ProjectionElem, StaticKind,
 };
 use rustc::ty::{self, TyCtxt};
 use std::cmp::max;
@@ -67,39 +66,35 @@ pub(super) fn borrow_conflicts_with_place<'tcx>(
     // it's so common that it's a speed win to check for it first.
     if let Place {
         base: PlaceBase::Local(l1),
-        projection: None,
+        projection: box [],
     } = borrow_place {
         if let PlaceRef {
             base: PlaceBase::Local(l2),
-            projection: None,
+            projection: [],
         } = access_place {
             return l1 == l2;
         }
     }
 
-    borrow_place.iterate(|borrow_base, borrow_projections| {
-        access_place.iterate(|access_base, access_projections| {
-            place_components_conflict(
-                tcx,
-                param_env,
-                body,
-                (borrow_base, borrow_projections),
-                borrow_kind,
-                (access_base, access_projections),
-                access,
-                bias,
-            )
-        })
-    })
+    place_components_conflict(
+        tcx,
+        param_env,
+        body,
+        borrow_place,
+        borrow_kind,
+        access_place,
+        access,
+        bias,
+    )
 }
 
 fn place_components_conflict<'tcx>(
     tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     body: &Body<'tcx>,
-    borrow_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>),
+    borrow_place: &Place<'tcx>,
     borrow_kind: BorrowKind,
-    access_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>),
+    access_place: PlaceRef<'_, 'tcx>,
     access: AccessDepth,
     bias: PlaceConflictBias,
 ) -> bool {
@@ -145,8 +140,8 @@ fn place_components_conflict<'tcx>(
     //    and either equal or disjoint.
     //  - If we did run out of access, the borrow can access a part of it.
 
-    let borrow_base = borrow_projections.0;
-    let access_base = access_projections.0;
+    let borrow_base = &borrow_place.base;
+    let access_base = access_place.base;
 
     match place_base_conflict(tcx, param_env, borrow_base, access_base) {
         Overlap::Arbitrary => {
@@ -163,147 +158,157 @@ fn place_components_conflict<'tcx>(
         }
     }
 
-    let mut borrow_projections = borrow_projections.1;
-    let mut access_projections = access_projections.1;
-
-    loop {
-        // loop invariant: borrow_c is always either equal to access_c or disjoint from it.
-        if let Some(borrow_c) = borrow_projections.next() {
-            debug!("borrow_conflicts_with_place: borrow_c = {:?}", borrow_c);
+    // loop invariant: borrow_c is always either equal to access_c or disjoint from it.
+    for (i, (borrow_c, access_c)) in
+        borrow_place.projection.iter().zip(access_place.projection.iter()).enumerate()
+    {
+        debug!("borrow_conflicts_with_place: borrow_c = {:?}", borrow_c);
+        let borrow_proj_base = &borrow_place.projection[..i];
 
-            if let Some(access_c) = access_projections.next() {
-                debug!("borrow_conflicts_with_place: access_c = {:?}", access_c);
+        debug!("borrow_conflicts_with_place: access_c = {:?}", access_c);
 
-                // Borrow and access path both have more components.
-                //
-                // Examples:
-                //
-                // - borrow of `a.(...)`, access to `a.(...)`
-                // - borrow of `a.(...)`, access to `b.(...)`
-                //
-                // Here we only see the components we have checked so
-                // far (in our examples, just the first component). We
-                // check whether the components being borrowed vs
-                // accessed are disjoint (as in the second example,
-                // but not the first).
-                match place_projection_conflict(tcx, body, borrow_base, borrow_c, access_c, bias) {
-                    Overlap::Arbitrary => {
-                        // We have encountered different fields of potentially
-                        // the same union - the borrow now partially overlaps.
-                        //
-                        // There is no *easy* way of comparing the fields
-                        // further on, because they might have different types
-                        // (e.g., borrows of `u.a.0` and `u.b.y` where `.0` and
-                        // `.y` come from different structs).
-                        //
-                        // We could try to do some things here - e.g., count
-                        // dereferences - but that's probably not a good
-                        // idea, at least for now, so just give up and
-                        // report a conflict. This is unsafe code anyway so
-                        // the user could always use raw pointers.
-                        debug!("borrow_conflicts_with_place: arbitrary -> conflict");
-                        return true;
-                    }
-                    Overlap::EqualOrDisjoint => {
-                        // This is the recursive case - proceed to the next element.
-                    }
-                    Overlap::Disjoint => {
-                        // We have proven the borrow disjoint - further
-                        // projections will remain disjoint.
-                        debug!("borrow_conflicts_with_place: disjoint");
-                        return false;
-                    }
-                }
-            } else {
-                // Borrow path is longer than the access path. Examples:
+        // Borrow and access path both have more components.
+        //
+        // Examples:
+        //
+        // - borrow of `a.(...)`, access to `a.(...)`
+        // - borrow of `a.(...)`, access to `b.(...)`
+        //
+        // Here we only see the components we have checked so
+        // far (in our examples, just the first component). We
+        // check whether the components being borrowed vs
+        // accessed are disjoint (as in the second example,
+        // but not the first).
+        match place_projection_conflict(
+            tcx,
+            body,
+            borrow_base,
+            borrow_proj_base,
+            borrow_c,
+            access_c,
+            bias,
+        ) {
+            Overlap::Arbitrary => {
+                // We have encountered different fields of potentially
+                // the same union - the borrow now partially overlaps.
                 //
-                // - borrow of `a.b.c`, access to `a.b`
+                // There is no *easy* way of comparing the fields
+                // further on, because they might have different types
+                // (e.g., borrows of `u.a.0` and `u.b.y` where `.0` and
+                // `.y` come from different structs).
                 //
-                // Here, we know that the borrow can access a part of
-                // our place. This is a conflict if that is a part our
-                // access cares about.
+                // We could try to do some things here - e.g., count
+                // dereferences - but that's probably not a good
+                // idea, at least for now, so just give up and
+                // report a conflict. This is unsafe code anyway so
+                // the user could always use raw pointers.
+                debug!("borrow_conflicts_with_place: arbitrary -> conflict");
+                return true;
+            }
+            Overlap::EqualOrDisjoint => {
+                // This is the recursive case - proceed to the next element.
+            }
+            Overlap::Disjoint => {
+                // We have proven the borrow disjoint - further
+                // projections will remain disjoint.
+                debug!("borrow_conflicts_with_place: disjoint");
+                return false;
+            }
+        }
+    }
+
+    if borrow_place.projection.len() > access_place.projection.len() {
+        for (i, elem) in borrow_place.projection[access_place.projection.len()..].iter().enumerate()
+        {
+            // Borrow path is longer than the access path. Examples:
+            //
+            // - borrow of `a.b.c`, access to `a.b`
+            //
+            // Here, we know that the borrow can access a part of
+            // our place. This is a conflict if that is a part our
+            // access cares about.
 
-                let base = &borrow_c.base;
-                let elem = &borrow_c.elem;
-                let base_ty = Place::ty_from(borrow_base, base, body, tcx).ty;
+            let proj_base = &borrow_place.projection[..access_place.projection.len() + i];
+            let base_ty = Place::ty_from(borrow_base, proj_base, body, tcx).ty;
 
-                match (elem, &base_ty.sty, access) {
-                    (_, _, Shallow(Some(ArtificialField::ArrayLength)))
-                    | (_, _, Shallow(Some(ArtificialField::ShallowBorrow))) => {
-                        // The array length is like  additional fields on the
-                        // type; it does not overlap any existing data there.
-                        // Furthermore, if cannot actually be a prefix of any
-                        // borrowed place (at least in MIR as it is currently.)
-                        //
-                        // e.g., a (mutable) borrow of `a[5]` while we read the
-                        // array length of `a`.
-                        debug!("borrow_conflicts_with_place: implicit field");
-                        return false;
-                    }
+            match (elem, &base_ty.sty, access) {
+                (_, _, Shallow(Some(ArtificialField::ArrayLength)))
+                | (_, _, Shallow(Some(ArtificialField::ShallowBorrow))) => {
+                    // The array length is like  additional fields on the
+                    // type; it does not overlap any existing data there.
+                    // Furthermore, if cannot actually be a prefix of any
+                    // borrowed place (at least in MIR as it is currently.)
+                    //
+                    // e.g., a (mutable) borrow of `a[5]` while we read the
+                    // array length of `a`.
+                    debug!("borrow_conflicts_with_place: implicit field");
+                    return false;
+                }
 
-                    (ProjectionElem::Deref, _, Shallow(None)) => {
-                        // e.g., a borrow of `*x.y` while we shallowly access `x.y` or some
-                        // prefix thereof - the shallow access can't touch anything behind
-                        // the pointer.
-                        debug!("borrow_conflicts_with_place: shallow access behind ptr");
-                        return false;
-                    }
-                    (ProjectionElem::Deref, ty::Ref(_, _, hir::MutImmutable), _) => {
-                        // Shouldn't be tracked
-                        bug!("Tracking borrow behind shared reference.");
-                    }
-                    (ProjectionElem::Deref, ty::Ref(_, _, hir::MutMutable), AccessDepth::Drop) => {
-                        // Values behind a mutable reference are not access either by dropping a
-                        // value, or by StorageDead
-                        debug!("borrow_conflicts_with_place: drop access behind ptr");
-                        return false;
-                    }
+                (ProjectionElem::Deref, _, Shallow(None)) => {
+                    // e.g., a borrow of `*x.y` while we shallowly access `x.y` or some
+                    // prefix thereof - the shallow access can't touch anything behind
+                    // the pointer.
+                    debug!("borrow_conflicts_with_place: shallow access behind ptr");
+                    return false;
+                }
+                (ProjectionElem::Deref, ty::Ref(_, _, hir::MutImmutable), _) => {
+                    // Shouldn't be tracked
+                    bug!("Tracking borrow behind shared reference.");
+                }
+                (ProjectionElem::Deref, ty::Ref(_, _, hir::MutMutable), AccessDepth::Drop) => {
+                    // Values behind a mutable reference are not access either by dropping a
+                    // value, or by StorageDead
+                    debug!("borrow_conflicts_with_place: drop access behind ptr");
+                    return false;
+                }
 
-                    (ProjectionElem::Field { .. }, ty::Adt(def, _), AccessDepth::Drop) => {
-                        // Drop can read/write arbitrary projections, so places
-                        // conflict regardless of further projections.
-                        if def.has_dtor(tcx) {
-                            return true;
-                        }
+                (ProjectionElem::Field { .. }, ty::Adt(def, _), AccessDepth::Drop) => {
+                    // Drop can read/write arbitrary projections, so places
+                    // conflict regardless of further projections.
+                    if def.has_dtor(tcx) {
+                        return true;
                     }
+                }
 
-                    (ProjectionElem::Deref, _, Deep)
-                    | (ProjectionElem::Deref, _, AccessDepth::Drop)
-                    | (ProjectionElem::Field { .. }, _, _)
-                    | (ProjectionElem::Index { .. }, _, _)
-                    | (ProjectionElem::ConstantIndex { .. }, _, _)
-                    | (ProjectionElem::Subslice { .. }, _, _)
-                    | (ProjectionElem::Downcast { .. }, _, _) => {
-                        // Recursive case. This can still be disjoint on a
-                        // further iteration if this a shallow access and
-                        // there's a deref later on, e.g., a borrow
-                        // of `*x.y` while accessing `x`.
-                    }
+                (ProjectionElem::Deref, _, Deep)
+                | (ProjectionElem::Deref, _, AccessDepth::Drop)
+                | (ProjectionElem::Field { .. }, _, _)
+                | (ProjectionElem::Index { .. }, _, _)
+                | (ProjectionElem::ConstantIndex { .. }, _, _)
+                | (ProjectionElem::Subslice { .. }, _, _)
+                | (ProjectionElem::Downcast { .. }, _, _) => {
+                    // Recursive case. This can still be disjoint on a
+                    // further iteration if this a shallow access and
+                    // there's a deref later on, e.g., a borrow
+                    // of `*x.y` while accessing `x`.
                 }
             }
-        } else {
-            // Borrow path ran out but access path may not
-            // have. Examples:
-            //
-            // - borrow of `a.b`, access to `a.b.c`
-            // - borrow of `a.b`, access to `a.b`
-            //
-            // In the first example, where we didn't run out of
-            // access, the borrow can access all of our place, so we
-            // have a conflict.
-            //
-            // If the second example, where we did, then we still know
-            // that the borrow can access a *part* of our place that
-            // our access cares about, so we still have a conflict.
-            if borrow_kind == BorrowKind::Shallow && access_projections.next().is_some() {
-                debug!("borrow_conflicts_with_place: shallow borrow");
-                return false;
-            } else {
-                debug!("borrow_conflicts_with_place: full borrow, CONFLICT");
-                return true;
-            }
         }
     }
+
+    // Borrow path ran out but access path may not
+    // have. Examples:
+    //
+    // - borrow of `a.b`, access to `a.b.c`
+    // - borrow of `a.b`, access to `a.b`
+    //
+    // In the first example, where we didn't run out of
+    // access, the borrow can access all of our place, so we
+    // have a conflict.
+    //
+    // If the second example, where we did, then we still know
+    // that the borrow can access a *part* of our place that
+    // our access cares about, so we still have a conflict.
+    if borrow_kind == BorrowKind::Shallow
+        && borrow_place.projection.len() < access_place.projection.len()
+    {
+        debug!("borrow_conflicts_with_place: shallow borrow");
+        false
+    } else {
+        debug!("borrow_conflicts_with_place: full borrow, CONFLICT");
+        true
+    }
 }
 
 // Given that the bases of `elem1` and `elem2` are always either equal
@@ -381,11 +386,12 @@ fn place_projection_conflict<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
     pi1_base: &PlaceBase<'tcx>,
-    pi1: &Projection<'tcx>,
-    pi2: &Projection<'tcx>,
+    pi1_proj_base: &[PlaceElem<'tcx>],
+    pi1_elem: &PlaceElem<'tcx>,
+    pi2_elem: &PlaceElem<'tcx>,
     bias: PlaceConflictBias,
 ) -> Overlap {
-    match (&pi1.elem, &pi2.elem) {
+    match (pi1_elem, pi2_elem) {
         (ProjectionElem::Deref, ProjectionElem::Deref) => {
             // derefs (e.g., `*x` vs. `*x`) - recur.
             debug!("place_element_conflict: DISJOINT-OR-EQ-DEREF");
@@ -397,7 +403,7 @@ fn place_projection_conflict<'tcx>(
                 debug!("place_element_conflict: DISJOINT-OR-EQ-FIELD");
                 Overlap::EqualOrDisjoint
             } else {
-                let ty = Place::ty_from(pi1_base, &pi1.base, body, tcx).ty;
+                let ty = Place::ty_from(pi1_base, pi1_proj_base, body, tcx).ty;
                 match ty.sty {
                     ty::Adt(def, _) if def.is_union() => {
                         // Different fields of a union, we are basically stuck.
@@ -493,7 +499,7 @@ fn place_projection_conflict<'tcx>(
             // element (like -1 in Python) and `min_length` the first.
             // Therefore, `min_length - offset_from_end` gives the minimal possible
             // offset from the beginning
-            if *offset_from_begin >= min_length - offset_from_end {
+            if *offset_from_begin >= *min_length - *offset_from_end {
                 debug!("place_element_conflict: DISJOINT-OR-EQ-ARRAY-CONSTANT-INDEX-FE");
                 Overlap::EqualOrDisjoint
             } else {
@@ -538,8 +544,8 @@ fn place_projection_conflict<'tcx>(
         | (ProjectionElem::Subslice { .. }, _)
         | (ProjectionElem::Downcast(..), _) => bug!(
             "mismatched projections in place_element_conflict: {:?} and {:?}",
-            pi1,
-            pi2
+            pi1_elem,
+            pi2_elem
         ),
     }
 }
diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs
index 4c6be23de28be..6adc693527f01 100644
--- a/src/librustc_mir/borrow_check/prefixes.rs
+++ b/src/librustc_mir/borrow_check/prefixes.rs
@@ -19,17 +19,9 @@ pub trait IsPrefixOf<'cx, 'tcx> {
 
 impl<'cx, 'tcx> IsPrefixOf<'cx, 'tcx> for PlaceRef<'cx, 'tcx> {
     fn is_prefix_of(&self, other: PlaceRef<'cx, 'tcx>) -> bool {
-        let mut cursor = other.projection;
-        loop {
-            if self.projection == cursor {
-                return self.base == other.base;
-            }
-
-            match cursor {
-                None => return false,
-                Some(proj) => cursor = &proj.base,
-            }
-        }
+        self.base == other.base
+            && self.projection.len() <= other.projection.len()
+            && self.projection == &other.projection[..self.projection.len()]
     }
 }
 
@@ -81,112 +73,115 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
         // downcasts here, but may return a base of a downcast).
 
         'cursor: loop {
-            let proj = match &cursor {
+            match &cursor {
                 PlaceRef {
                     base: PlaceBase::Local(_),
-                    projection: None,
+                    projection: [],
                 }
                 | // search yielded this leaf
                 PlaceRef {
                     base: PlaceBase::Static(_),
-                    projection: None,
+                    projection: [],
                 } => {
                     self.next = None;
                     return Some(cursor);
                 }
                 PlaceRef {
                     base: _,
-                    projection: Some(proj),
-                } => proj,
-            };
-
-            match proj.elem {
-                ProjectionElem::Field(_ /*field*/, _ /*ty*/) => {
-                    // FIXME: add union handling
-                    self.next = Some(PlaceRef {
-                        base: cursor.base,
-                        projection: &proj.base,
-                    });
-                    return Some(cursor);
-                }
-                ProjectionElem::Downcast(..) |
-                ProjectionElem::Subslice { .. } |
-                ProjectionElem::ConstantIndex { .. } |
-                ProjectionElem::Index(_) => {
-                    cursor = PlaceRef {
-                        base: cursor.base,
-                        projection: &proj.base,
-                    };
-                    continue 'cursor;
-                }
-                ProjectionElem::Deref => {
-                    // (handled below)
-                }
-            }
-
-            assert_eq!(proj.elem, ProjectionElem::Deref);
-
-            match self.kind {
-                PrefixSet::Shallow => {
-                    // shallow prefixes are found by stripping away
-                    // fields, but stop at *any* dereference.
-                    // So we can just stop the traversal now.
-                    self.next = None;
-                    return Some(cursor);
-                }
-                PrefixSet::All => {
-                    // all prefixes: just blindly enqueue the base
-                    // of the projection.
-                    self.next = Some(PlaceRef {
-                        base: cursor.base,
-                        projection: &proj.base,
-                    });
-                    return Some(cursor);
-                }
-                PrefixSet::Supporting => {
-                    // fall through!
-                }
-            }
-
-            assert_eq!(self.kind, PrefixSet::Supporting);
-            // supporting prefixes: strip away fields and
-            // derefs, except we stop at the deref of a shared
-            // reference.
-
-            let ty = Place::ty_from(cursor.base, &proj.base, self.body, self.tcx).ty;
-            match ty.sty {
-                ty::RawPtr(_) |
-                ty::Ref(
-                    _, /*rgn*/
-                    _, /*ty*/
-                    hir::MutImmutable
-                    ) => {
-                    // don't continue traversing over derefs of raw pointers or shared borrows.
-                    self.next = None;
-                    return Some(cursor);
-                }
-
-                ty::Ref(
-                    _, /*rgn*/
-                    _, /*ty*/
-                    hir::MutMutable,
-                    ) => {
-                    self.next = Some(PlaceRef {
-                        base: cursor.base,
-                        projection: &proj.base,
-                    });
-                    return Some(cursor);
-                }
-
-                ty::Adt(..) if ty.is_box() => {
-                    self.next = Some(PlaceRef {
-                        base: cursor.base,
-                        projection: &proj.base,
-                    });
-                    return Some(cursor);
+                    projection: [.., elem],
+                } => {
+                    let proj_base = &cursor.projection[..cursor.projection.len() - 1];
+
+                    match elem {
+                        ProjectionElem::Field(_ /*field*/, _ /*ty*/) => {
+                            // FIXME: add union handling
+                            self.next = Some(PlaceRef {
+                                base: cursor.base,
+                                projection: proj_base,
+                            });
+                            return Some(cursor);
+                        }
+                        ProjectionElem::Downcast(..) |
+                        ProjectionElem::Subslice { .. } |
+                        ProjectionElem::ConstantIndex { .. } |
+                        ProjectionElem::Index(_) => {
+                            cursor = PlaceRef {
+                                base: cursor.base,
+                                projection: proj_base,
+                            };
+                            continue 'cursor;
+                        }
+                        ProjectionElem::Deref => {
+                            // (handled below)
+                        }
+                    }
+
+                    assert_eq!(*elem, ProjectionElem::Deref);
+
+                    match self.kind {
+                        PrefixSet::Shallow => {
+                            // shallow prefixes are found by stripping away
+                            // fields, but stop at *any* dereference.
+                            // So we can just stop the traversal now.
+                            self.next = None;
+                            return Some(cursor);
+                        }
+                        PrefixSet::All => {
+                            // all prefixes: just blindly enqueue the base
+                            // of the projection
+                            self.next = Some(PlaceRef {
+                                base: cursor.base,
+                                projection: proj_base,
+                            });
+                            return Some(cursor);
+                        }
+                        PrefixSet::Supporting => {
+                            // fall through!
+                        }
+                    }
+
+                    assert_eq!(self.kind, PrefixSet::Supporting);
+                    // supporting prefixes: strip away fields and
+                    // derefs, except we stop at the deref of a shared
+                    // reference.
+
+                    let ty = Place::ty_from(cursor.base, proj_base, self.body, self.tcx).ty;
+                    match ty.sty {
+                        ty::RawPtr(_) |
+                        ty::Ref(
+                            _, /*rgn*/
+                            _, /*ty*/
+                            hir::MutImmutable
+                            ) => {
+                            // don't continue traversing over derefs of raw pointers or shared
+                            // borrows.
+                            self.next = None;
+                            return Some(cursor);
+                        }
+
+                        ty::Ref(
+                            _, /*rgn*/
+                            _, /*ty*/
+                            hir::MutMutable,
+                            ) => {
+                            self.next = Some(PlaceRef {
+                                base: cursor.base,
+                                projection: proj_base,
+                            });
+                            return Some(cursor);
+                        }
+
+                        ty::Adt(..) if ty.is_box() => {
+                            self.next = Some(PlaceRef {
+                                base: cursor.base,
+                                projection: proj_base,
+                            });
+                            return Some(cursor);
+                        }
+
+                        _ => panic!("unknown type fed to Projection Deref."),
+                    }
                 }
-
-                _ => panic!("unknown type fed to Projection Deref."),
             }
         }
     }
diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs
index 2587d14a73a8f..8bfd24a1e5915 100644
--- a/src/librustc_mir/borrow_check/used_muts.rs
+++ b/src/librustc_mir/borrow_check/used_muts.rs
@@ -120,7 +120,7 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
                 );
                 if let Place {
                     base: PlaceBase::Local(user_local),
-                    projection: None,
+                    projection: box [],
                 } = path.place {
                     self.mbcx.used_mut.insert(user_local);
                 }
diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs
index 98cf4bba1c75f..5af66faf6ee1e 100644
--- a/src/librustc_mir/build/expr/as_place.rs
+++ b/src/librustc_mir/build/expr/as_place.rs
@@ -129,7 +129,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     kind: StaticKind::Static,
                     def_id: id,
                 })),
-                projection: None,
+                projection: box [],
             }),
 
             ExprKind::PlaceTypeAscription { source, user_ty } => {
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 1a186fa932ddb..1371bc5aee82f 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -500,14 +500,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let mutability = match arg_place {
             Place {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: box [],
             } => this.local_decls[local].mutability,
             Place {
                 base: PlaceBase::Local(local),
-                projection: Some(box Projection {
-                    base: None,
-                    elem: ProjectionElem::Deref,
-                })
+                projection: box [ProjectionElem::Deref],
             } => {
                 debug_assert!(
                     this.local_decls[local].is_ref_for_guard(),
@@ -517,21 +514,20 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
             Place {
                 ref base,
-                projection: Some(box Projection {
-                    base: ref base_proj,
-                    elem: ProjectionElem::Field(upvar_index, _),
-                }),
+                projection: box [.., ProjectionElem::Field(upvar_index, _)],
             }
             | Place {
                 ref base,
-                projection: Some(box Projection {
-                    base: Some(box Projection {
-                        base: ref base_proj,
-                        elem: ProjectionElem::Field(upvar_index, _),
-                    }),
-                    elem: ProjectionElem::Deref,
-                }),
+                projection: box [.., ProjectionElem::Field(upvar_index, _), ProjectionElem::Deref],
             } => {
+                let base_proj = if let ProjectionElem::Deref =
+                    arg_place.projection[arg_place.projection.len() - 1]
+                {
+                    &arg_place.projection[..arg_place.projection.len() - 2]
+                } else {
+                    &arg_place.projection[..arg_place.projection.len() - 1]
+                };
+
                 let place = PlaceRef {
                     base,
                     projection: base_proj,
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index 889861b856748..45f4a16853606 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -301,7 +301,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 // Create a "fake" temporary variable so that we check that the
                 // value is Sized. Usually, this is caught in type checking, but
                 // in the case of box expr there is no such check.
-                if destination.projection.is_some() {
+                if !destination.projection.is_empty() {
                     this.local_decls
                         .push(LocalDecl::new_temp(expr.ty, expr.span));
                 }
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 94323b15b696f..8c94723e3cc2e 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -942,13 +942,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             for Binding { source, .. }
                 in matched_candidates.iter().flat_map(|candidate| &candidate.bindings)
             {
-                let mut cursor = &source.projection;
-                while let Some(box Projection { base, elem }) = cursor {
-                    cursor = base;
+                for (i, elem) in source.projection.iter().enumerate().rev() {
+                    let proj_base = &source.projection[..i];
+
                     if let ProjectionElem::Deref = elem {
                         fake_borrows.insert(Place {
                             base: source.base.clone(),
-                            projection: cursor.clone(),
+                            projection: proj_base.to_vec().into_boxed_slice(),
                         });
                         break;
                     }
@@ -1295,18 +1295,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // Insert a Shallow borrow of the prefixes of any fake borrows.
         for place in fake_borrows
         {
-            let mut prefix_cursor = &place.projection;
-            while let Some(box Projection { base, elem }) = prefix_cursor {
+            for (i, elem) in place.projection.iter().enumerate().rev() {
+                let proj_base = &place.projection[..i];
+
                 if let ProjectionElem::Deref = elem {
                     // Insert a shallow borrow after a deref. For other
                     // projections the borrow of prefix_cursor will
                     // conflict with any mutation of base.
                     all_fake_borrows.push(PlaceRef {
                         base: &place.base,
-                        projection: base,
+                        projection: proj_base,
                     });
                 }
-                prefix_cursor = base;
             }
 
             all_fake_borrows.push(place.as_ref());
@@ -1493,7 +1493,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     BorrowKind::Shallow,
                     Place {
                         base: place.base.clone(),
-                        projection: place.projection.clone(),
+                        projection: place.projection.to_vec().into_boxed_slice(),
                     },
                 );
                 self.cfg.push_assign(
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 7ab0bf7d66a64..647d7515fe98d 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -609,7 +609,7 @@ where
         unpack!(block = builder.in_breakable_scope(
             None,
             START_BLOCK,
-            Place::RETURN_PLACE,
+            Place::return_place(),
             |builder| {
                 builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
                     builder.args_and_body(block, &arguments, arg_scope, &body.value)
@@ -670,7 +670,7 @@ fn construct_const<'a, 'tcx>(
     let mut block = START_BLOCK;
     let ast_expr = &tcx.hir().body(body_id).value;
     let expr = builder.hir.mirror(ast_expr);
-    unpack!(block = builder.into_expr(&Place::RETURN_PLACE, block, expr));
+    unpack!(block = builder.into_expr(&Place::return_place(), block, expr));
 
     let source_info = builder.source_info(span);
     builder.cfg.terminate(block, source_info, TerminatorKind::Return);
@@ -871,7 +871,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
 
         let body = self.hir.mirror(ast_body);
-        self.into(&Place::RETURN_PLACE, block, body)
+        self.into(&Place::return_place(), block, body)
     }
 
     fn set_correct_source_scope_for_arg(
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index a04c041ca9dc7..ee6d42de388d9 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -314,7 +314,7 @@ impl<'tcx> Scopes<'tcx> {
         match target {
             BreakableTarget::Return => {
                 let scope = &self.breakable_scopes[0];
-                if scope.break_destination != Place::RETURN_PLACE {
+                if scope.break_destination != Place::return_place() {
                     span_bug!(span, "`return` in item with no return scope");
                 }
                 (scope.break_block, scope.region_scope, Some(scope.break_destination.clone()))
@@ -853,11 +853,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             _ if self.local_scope().is_none() => (),
             Operand::Copy(Place {
                 base: PlaceBase::Local(cond_temp),
-                projection: None,
+                projection: box [],
             })
             | Operand::Move(Place {
                 base: PlaceBase::Local(cond_temp),
-                projection: None,
+                projection: box [],
             }) => {
                 // Manually drop the condition on both branches.
                 let top_scope = self.scopes.scopes.last_mut().unwrap();
diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs
index c071b3101fce3..672bbda7502fe 100644
--- a/src/librustc_mir/dataflow/drop_flag_effects.rs
+++ b/src/librustc_mir/dataflow/drop_flag_effects.rs
@@ -10,17 +10,12 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
                                         path: MovePathIndex,
                                         mut cond: F)
                                         -> Option<MovePathIndex>
-    where F: FnMut(&mir::Projection<'tcx>) -> bool
+    where F: FnMut(&[mir::PlaceElem<'tcx>]) -> bool
 {
     let mut next_child = move_data.move_paths[path].first_child;
     while let Some(child_index) = next_child {
-        match move_data.move_paths[child_index].place.projection {
-            Some(ref proj) => {
-                if cond(proj) {
-                    return Some(child_index)
-                }
-            }
-            _ => {}
+        if cond(&move_data.move_paths[child_index].place.projection) {
+            return Some(child_index)
         }
         next_child = move_data.move_paths[child_index].next_sibling;
     }
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index 2ea6c4ae10fdc..04674fb58cb9f 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -208,7 +208,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
             // If the borrowed place is a local with no projections, all other borrows of this
             // local must conflict. This is purely an optimization so we don't have to call
             // `places_conflict` for every borrow.
-            if place.projection.is_none() {
+            if place.projection.is_empty() {
                 trans.kill_all(other_borrows_of_local);
                 return;
             }
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 81451c2500c47..1d99470d08b0c 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -94,72 +94,74 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     /// Maybe we should have separate "borrowck" and "moveck" modes.
     fn move_path_for(&mut self, place: &Place<'tcx>) -> Result<MovePathIndex, MoveError<'tcx>> {
         debug!("lookup({:?})", place);
-        place.iterate(|place_base, place_projection| {
-            let mut base = match place_base {
-                PlaceBase::Local(local) => self.builder.data.rev_lookup.locals[*local],
-                PlaceBase::Static(..) => {
-                    return Err(MoveError::cannot_move_out_of(self.loc, Static));
-                }
-            };
+        let mut base = match place.base {
+            PlaceBase::Local(local) => self.builder.data.rev_lookup.locals[local],
+            PlaceBase::Static(..) => {
+                return Err(MoveError::cannot_move_out_of(self.loc, Static));
+            }
+        };
 
-            for proj in place_projection {
-                let body = self.builder.body;
-                let tcx = self.builder.tcx;
-                let place_ty = Place::ty_from(place_base, &proj.base, body, tcx).ty;
-                match place_ty.sty {
-                    ty::Ref(..) | ty::RawPtr(..) => {
-                        return Err(MoveError::cannot_move_out_of(
-                            self.loc,
-                            BorrowedContent {
-                                target_place: Place {
-                                    base: place_base.clone(),
-                                    projection: Some(Box::new(proj.clone())),
-                                },
+        for (i, elem) in place.projection.iter().enumerate() {
+            let proj_base = &place.projection[..i];
+            let body = self.builder.body;
+            let tcx = self.builder.tcx;
+            let place_ty = Place::ty_from(&place.base, proj_base, body, tcx).ty;
+            match place_ty.sty {
+                ty::Ref(..) | ty::RawPtr(..) => {
+                    let proj = &place.projection[..i+1];
+                    return Err(MoveError::cannot_move_out_of(
+                        self.loc,
+                        BorrowedContent {
+                            target_place: Place {
+                                base: place.base.clone(),
+                                projection: proj.to_vec().into_boxed_slice(),
                             },
-                        ));
-                    }
-                    ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
+                        },
+                    ));
+                }
+                ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
+                    return Err(MoveError::cannot_move_out_of(
+                        self.loc,
+                        InteriorOfTypeWithDestructor { container_ty: place_ty },
+                    ));
+                }
+                // move out of union - always move the entire union
+                ty::Adt(adt, _) if adt.is_union() => {
+                    return Err(MoveError::UnionMove { path: base });
+                }
+                ty::Slice(_) => {
+                    return Err(MoveError::cannot_move_out_of(
+                        self.loc,
+                        InteriorOfSliceOrArray {
+                            ty: place_ty,
+                            is_index: match elem {
+                                ProjectionElem::Index(..) => true,
+                                _ => false,
+                            },
+                        },
+                    ));
+                }
+                ty::Array(..) => match elem {
+                    ProjectionElem::Index(..) => {
                         return Err(MoveError::cannot_move_out_of(
                             self.loc,
-                            InteriorOfTypeWithDestructor { container_ty: place_ty },
+                            InteriorOfSliceOrArray { ty: place_ty, is_index: true },
                         ));
                     }
-                    // move out of union - always move the entire union
-                    ty::Adt(adt, _) if adt.is_union() => {
-                        return Err(MoveError::UnionMove { path: base });
-                    }
-                    ty::Slice(_) => {
-                        return Err(MoveError::cannot_move_out_of(
-                            self.loc,
-                            InteriorOfSliceOrArray {
-                                ty: place_ty,
-                                is_index: match proj.elem {
-                                    ProjectionElem::Index(..) => true,
-                                    _ => false,
-                                },
-                            },
-                        ));
+                    _ => {
+                        // FIXME: still badly broken
                     }
-                    ty::Array(..) => match proj.elem {
-                        ProjectionElem::Index(..) => {
-                            return Err(MoveError::cannot_move_out_of(
-                                self.loc,
-                                InteriorOfSliceOrArray { ty: place_ty, is_index: true },
-                            ));
-                        }
-                        _ => {
-                            // FIXME: still badly broken
-                        }
-                    },
-                    _ => {}
-                };
+                },
+                _ => {}
+            };
 
-                base = match self
-                    .builder
-                    .data
-                    .rev_lookup
-                    .projections
-                    .entry((base, proj.elem.lift()))
+            let proj = &place.projection[..i+1];
+            base = match self
+                .builder
+                .data
+                .rev_lookup
+                .projections
+                .entry((base, elem.lift()))
                 {
                     Entry::Occupied(ent) => *ent.get(),
                     Entry::Vacant(ent) => {
@@ -169,18 +171,17 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                             &mut self.builder.data.init_path_map,
                             Some(base),
                             Place {
-                                base: place_base.clone(),
-                                projection: Some(Box::new(proj.clone())),
+                                base: place.base.clone(),
+                                projection: proj.to_vec().into_boxed_slice(),
                             },
                         );
                         ent.insert(path);
                         path
                     }
                 };
-            }
+        }
 
-            Ok(base)
-        })
+        Ok(base)
     }
 
     fn create_move_path(&mut self, place: &Place<'tcx>) {
@@ -355,7 +356,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             | TerminatorKind::Unreachable => {}
 
             TerminatorKind::Return => {
-                self.gather_move(&Place::RETURN_PLACE);
+                self.gather_move(&Place::return_place());
             }
 
             TerminatorKind::Assert { ref cond, .. } => {
@@ -435,9 +436,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
 
         // Check if we are assigning into a field of a union, if so, lookup the place
         // of the union so it is marked as initialized again.
-        if let Some(box Projection { base: proj_base, elem: ProjectionElem::Field(_, _) }) =
-            place.projection
-        {
+        if let [.., ProjectionElem::Field(_, _)] = place.projection {
+            let proj_base = &place.projection[..place.projection.len() - 1];
             if let ty::Adt(def, _) =
                 Place::ty_from(place.base, proj_base, self.builder.body, self.builder.tcx).ty.sty
             {
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index 5028e9650918c..156c19c6363e5 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -245,23 +245,21 @@ impl MovePathLookup {
     // alternative will *not* create a MovePath on the fly for an
     // unknown place, but will rather return the nearest available
     // parent.
-    pub fn find(&self, place_ref: PlaceRef<'_, '_>) -> LookupResult {
-        place_ref.iterate(|place_base, place_projection| {
-            let mut result = match place_base {
-                PlaceBase::Local(local) => self.locals[*local],
-                PlaceBase::Static(..) => return LookupResult::Parent(None),
-            };
-
-            for proj in place_projection {
-                if let Some(&subpath) = self.projections.get(&(result, proj.elem.lift())) {
-                    result = subpath;
-                } else {
-                    return LookupResult::Parent(Some(result));
-                }
+    pub fn find(&self, place: PlaceRef<'_, '_>) -> LookupResult {
+        let mut result = match place.base {
+            PlaceBase::Local(local) => self.locals[*local],
+            PlaceBase::Static(..) => return LookupResult::Parent(None),
+        };
+
+        for elem in place.projection.iter() {
+            if let Some(&subpath) = self.projections.get(&(result, elem.lift())) {
+                result = subpath;
+            } else {
+                return LookupResult::Parent(Some(result));
             }
+        }
 
-            LookupResult::Exact(result)
-        })
+        LookupResult::Exact(result)
     }
 
     pub fn find_local(&self, local: Local) -> MovePathIndex {
@@ -329,7 +327,7 @@ impl<'tcx> MoveData<'tcx> {
     pub fn base_local(&self, mut mpi: MovePathIndex) -> Option<Local> {
         loop {
             let path = &self.move_paths[mpi];
-            if let Place { base: PlaceBase::Local(l), projection: None } = path.place {
+            if let Place { base: PlaceBase::Local(l), projection: box [] } = path.place {
                 return Some(l);
             }
             if let Some(parent) = path.parent {
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index b5aab992e3adb..06b7206f4292c 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -472,39 +472,37 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     // avoid allocations.
     pub(super) fn eval_place_to_op(
         &self,
-        mir_place: &mir::Place<'tcx>,
+        place: &mir::Place<'tcx>,
         layout: Option<TyLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         use rustc::mir::PlaceBase;
 
-        mir_place.iterate(|place_base, place_projection| {
-            let mut op = match place_base {
-                PlaceBase::Local(mir::RETURN_PLACE) =>
-                    throw_unsup!(ReadFromReturnPointer),
-                PlaceBase::Local(local) => {
-                    // Do not use the layout passed in as argument if the base we are looking at
-                    // here is not the entire place.
-                    // FIXME use place_projection.is_empty() when is available
-                    let layout = if mir_place.projection.is_none() {
-                        layout
-                    } else {
-                        None
-                    };
-
-                    self.access_local(self.frame(), *local, layout)?
-                }
-                PlaceBase::Static(place_static) => {
-                    self.eval_static_to_mplace(place_static)?.into()
-                }
-            };
+        let mut op = match &place.base {
+            PlaceBase::Local(mir::RETURN_PLACE) =>
+                throw_unsup!(ReadFromReturnPointer),
+            PlaceBase::Local(local) => {
+                // Do not use the layout passed in as argument if the base we are looking at
+                // here is not the entire place.
+                // FIXME use place_projection.is_empty() when is available
+                let layout = if place.projection.is_empty() {
+                    layout
+                } else {
+                    None
+                };
 
-            for proj in place_projection {
-                op = self.operand_projection(op, &proj.elem)?
+                self.access_local(self.frame(), *local, layout)?
+            }
+            PlaceBase::Static(place_static) => {
+                self.eval_static_to_mplace(&place_static)?.into()
             }
+        };
 
-            trace!("eval_place_to_op: got {:?}", *op);
-            Ok(op)
-        })
+        for elem in place.projection.iter() {
+            op = self.operand_projection(op, elem)?
+        }
+
+        trace!("eval_place_to_op: got {:?}", *op);
+        Ok(op)
     }
 
     /// Evaluate the operand, returning a place where you can then find the data.
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index f358bb00f4d12..1a28548618206 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -629,45 +629,43 @@ where
     /// place; for reading, a more efficient alternative is `eval_place_for_read`.
     pub fn eval_place(
         &mut self,
-        mir_place: &mir::Place<'tcx>,
+        place: &mir::Place<'tcx>,
     ) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
         use rustc::mir::PlaceBase;
 
-        mir_place.iterate(|place_base, place_projection| {
-            let mut place = match place_base {
-                PlaceBase::Local(mir::RETURN_PLACE) => match self.frame().return_place {
-                    Some(return_place) => {
-                        // We use our layout to verify our assumption; caller will validate
-                        // their layout on return.
-                        PlaceTy {
-                            place: *return_place,
-                            layout: self.layout_of(
-                                self.subst_from_frame_and_normalize_erasing_regions(
-                                    self.frame().body.return_ty()
-                                )
-                            )?,
-                        }
+        let mut place_ty = match &place.base {
+            PlaceBase::Local(mir::RETURN_PLACE) => match self.frame().return_place {
+                Some(return_place) => {
+                    // We use our layout to verify our assumption; caller will validate
+                    // their layout on return.
+                    PlaceTy {
+                        place: *return_place,
+                        layout: self.layout_of(
+                            self.subst_from_frame_and_normalize_erasing_regions(
+                                self.frame().body.return_ty()
+                            )
+                        )?,
                     }
-                    None => throw_unsup!(InvalidNullPointerUsage),
-                },
-                PlaceBase::Local(local) => PlaceTy {
-                    // This works even for dead/uninitialized locals; we check further when writing
-                    place: Place::Local {
-                        frame: self.cur_frame(),
-                        local: *local,
-                    },
-                    layout: self.layout_of_local(self.frame(), *local, None)?,
+                }
+                None => throw_unsup!(InvalidNullPointerUsage),
+            },
+            PlaceBase::Local(local) => PlaceTy {
+                // This works even for dead/uninitialized locals; we check further when writing
+                place: Place::Local {
+                    frame: self.cur_frame(),
+                    local: *local,
                 },
-                PlaceBase::Static(place_static) => self.eval_static_to_mplace(place_static)?.into(),
-            };
+                layout: self.layout_of_local(self.frame(), *local, None)?,
+            },
+            PlaceBase::Static(place_static) => self.eval_static_to_mplace(&place_static)?.into(),
+        };
 
-            for proj in place_projection {
-                place = self.place_projection(place, &proj.elem)?
-            }
+        for elem in place.projection.iter() {
+            place_ty = self.place_projection(place_ty, elem)?
+        }
 
-            self.dump_place(place.place);
-            Ok(place)
-        })
+        self.dump_place(place_ty.place);
+        Ok(place_ty)
     }
 
     /// Write a scalar to a place
diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs
index 5de297923ce7b..8310ef02f9669 100644
--- a/src/librustc_mir/interpret/terminator.rs
+++ b/src/librustc_mir/interpret/terminator.rs
@@ -391,7 +391,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     // Don't forget to check the return type!
                     if let Some(caller_ret) = dest {
                         let callee_ret = self.eval_place(
-                            &mir::Place::RETURN_PLACE
+                            &mir::Place::return_place()
                         )?;
                         if !Self::check_argument_compat(
                             rust_abi,
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index aa83255bf62f4..9086ae844dd52 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -308,7 +308,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -
     let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
     let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env, builder.span);
 
-    let dest = Place::RETURN_PLACE;
+    let dest = Place::return_place();
     let src = Place::from(Local::new(1+0)).deref();
 
     match self_ty.sty {
@@ -415,7 +415,7 @@ impl CloneShimBuilder<'tcx> {
         let rcvr = Place::from(Local::new(1+0)).deref();
         let ret_statement = self.make_statement(
             StatementKind::Assign(
-                Place::RETURN_PLACE,
+                Place::return_place(),
                 box Rvalue::Use(Operand::Copy(rcvr))
             )
         );
@@ -773,7 +773,7 @@ fn build_call_shim<'tcx>(
     block(&mut blocks, statements, TerminatorKind::Call {
         func: callee,
         args,
-        destination: Some((Place::RETURN_PLACE,
+        destination: Some((Place::return_place(),
                            BasicBlock::new(1))),
         cleanup: if let Adjustment::RefMut = rcvr_adjustment {
             Some(BasicBlock::new(3))
@@ -868,7 +868,7 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> {
     debug!("build_ctor: variant_index={:?}", variant_index);
 
     let statements = expand_aggregate(
-        Place::RETURN_PLACE,
+        Place::return_place(),
         adt_def
             .variants[variant_index]
             .fields
diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index 0fd75cd57b2ac..466f6060827ec 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -17,12 +17,11 @@ pub struct AddRetag;
 fn is_stable(
     place: PlaceRef<'_, '_>,
 ) -> bool {
-    if let Some(proj) = &place.projection {
-        match proj.elem {
+    place.projection.iter().all(|elem| {
+        match elem {
             // Which place this evaluates to can change with any memory write,
             // so cannot assume this to be stable.
-            ProjectionElem::Deref =>
-                false,
+            ProjectionElem::Deref => false,
             // Array indices are intersting, but MIR building generates a *fresh*
             // temporary for every array access, so the index cannot be changed as
             // a side-effect.
@@ -31,15 +30,9 @@ fn is_stable(
             ProjectionElem::Field { .. } |
             ProjectionElem::ConstantIndex { .. } |
             ProjectionElem::Subslice { .. } |
-            ProjectionElem::Downcast { .. } =>
-                is_stable(PlaceRef {
-                    base: place.base,
-                    projection: &proj.base,
-                }),
+            ProjectionElem::Downcast { .. } => true,
         }
-    } else {
-        true
-    }
+    })
 }
 
 /// Determine whether this type may be a reference (or box), and thus needs retagging.
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 539922c54d12d..f8af9b9fcbee0 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -200,127 +200,127 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
                     place: &Place<'tcx>,
                     context: PlaceContext,
                     _location: Location) {
-        place.iterate(|place_base, place_projections| {
-            match place_base {
-                PlaceBase::Local(..) => {
-                    // Locals are safe.
-                }
-                PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => {
-                    bug!("unsafety checking should happen before promotion")
-                }
-                PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }) => {
-                    if self.tcx.is_mutable_static(*def_id) {
-                        self.require_unsafe("use of mutable static",
-                            "mutable statics can be mutated by multiple threads: aliasing \
-                             violations or data races will cause undefined behavior",
-                             UnsafetyViolationKind::General);
-                    } else if self.tcx.is_foreign_item(*def_id) {
-                        let source_info = self.source_info;
-                        let lint_root =
-                            self.source_scope_local_data[source_info.scope].lint_root;
-                        self.register_violations(&[UnsafetyViolation {
-                            source_info,
-                            description: InternedString::intern("use of extern static"),
-                            details: InternedString::intern(
-                                "extern statics are not controlled by the Rust type system: \
-                                invalid data, aliasing violations or data races will cause \
-                                undefined behavior"),
-                            kind: UnsafetyViolationKind::ExternStatic(lint_root)
-                        }], &[]);
-                    }
+        match place.base {
+            PlaceBase::Local(..) => {
+                // Locals are safe.
+            }
+            PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => {
+                bug!("unsafety checking should happen before promotion")
+            }
+            PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }) => {
+                if self.tcx.is_mutable_static(def_id) {
+                    self.require_unsafe("use of mutable static",
+                        "mutable statics can be mutated by multiple threads: aliasing \
+                         violations or data races will cause undefined behavior",
+                         UnsafetyViolationKind::General);
+                } else if self.tcx.is_foreign_item(def_id) {
+                    let source_info = self.source_info;
+                    let lint_root =
+                        self.source_scope_local_data[source_info.scope].lint_root;
+                    self.register_violations(&[UnsafetyViolation {
+                        source_info,
+                        description: InternedString::intern("use of extern static"),
+                        details: InternedString::intern(
+                            "extern statics are not controlled by the Rust type system: \
+                            invalid data, aliasing violations or data races will cause \
+                            undefined behavior"),
+                        kind: UnsafetyViolationKind::ExternStatic(lint_root)
+                    }], &[]);
                 }
             }
+        }
 
-            for proj in place_projections {
-                if context.is_borrow() {
-                    if util::is_disaligned(self.tcx, self.body, self.param_env, place) {
-                        let source_info = self.source_info;
-                        let lint_root =
-                            self.source_scope_local_data[source_info.scope].lint_root;
-                        self.register_violations(&[UnsafetyViolation {
-                            source_info,
-                            description: InternedString::intern("borrow of packed field"),
-                            details: InternedString::intern(
-                                "fields of packed structs might be misaligned: dereferencing a \
-                                misaligned pointer or even just creating a misaligned reference \
-                                is undefined behavior"),
-                            kind: UnsafetyViolationKind::BorrowPacked(lint_root)
-                        }], &[]);
-                    }
+        for (i, elem) in place.projection.iter().enumerate() {
+            let proj_base = &place.projection[..i];
+
+            if context.is_borrow() {
+                if util::is_disaligned(self.tcx, self.body, self.param_env, place) {
+                    let source_info = self.source_info;
+                    let lint_root =
+                        self.source_scope_local_data[source_info.scope].lint_root;
+                    self.register_violations(&[UnsafetyViolation {
+                        source_info,
+                        description: InternedString::intern("borrow of packed field"),
+                        details: InternedString::intern(
+                            "fields of packed structs might be misaligned: dereferencing a \
+                            misaligned pointer or even just creating a misaligned reference \
+                            is undefined behavior"),
+                        kind: UnsafetyViolationKind::BorrowPacked(lint_root)
+                    }], &[]);
                 }
-                let is_borrow_of_interior_mut = context.is_borrow() &&
-                    !Place::ty_from(&place.base, &proj.base, self.body, self.tcx)
-                    .ty
-                    .is_freeze(self.tcx, self.param_env, self.source_info.span);
-                // prevent
-                // * `&mut x.field`
-                // * `x.field = y;`
-                // * `&x.field` if `field`'s type has interior mutability
-                // because either of these would allow modifying the layout constrained field and
-                // insert values that violate the layout constraints.
-                if context.is_mutating_use() || is_borrow_of_interior_mut {
-                    self.check_mut_borrowing_layout_constrained_field(
-                        place, context.is_mutating_use(),
-                    );
+            }
+            let is_borrow_of_interior_mut = context.is_borrow() &&
+                !Place::ty_from(&place.base, proj_base, self.body, self.tcx)
+                .ty
+                .is_freeze(self.tcx, self.param_env, self.source_info.span);
+            // prevent
+            // * `&mut x.field`
+            // * `x.field = y;`
+            // * `&x.field` if `field`'s type has interior mutability
+            // because either of these would allow modifying the layout constrained field and
+            // insert values that violate the layout constraints.
+            if context.is_mutating_use() || is_borrow_of_interior_mut {
+                self.check_mut_borrowing_layout_constrained_field(
+                    place, context.is_mutating_use(),
+                );
+            }
+            let old_source_info = self.source_info;
+            if let (PlaceBase::Local(local), []) = (&place.base, proj_base) {
+                if self.body.local_decls[*local].internal {
+                    // Internal locals are used in the `move_val_init` desugaring.
+                    // We want to check unsafety against the source info of the
+                    // desugaring, rather than the source info of the RHS.
+                    self.source_info = self.body.local_decls[*local].source_info;
                 }
-                let old_source_info = self.source_info;
-                if let (PlaceBase::Local(local), None) = (&place.base, &proj.base) {
-                    if self.body.local_decls[*local].internal {
-                        // Internal locals are used in the `move_val_init` desugaring.
-                        // We want to check unsafety against the source info of the
-                        // desugaring, rather than the source info of the RHS.
-                        self.source_info = self.body.local_decls[*local].source_info;
-                    }
+            }
+            let base_ty = Place::ty_from(&place.base, proj_base, self.body, self.tcx).ty;
+            match base_ty.sty {
+                ty::RawPtr(..) => {
+                    self.require_unsafe("dereference of raw pointer",
+                        "raw pointers may be NULL, dangling or unaligned; they can violate \
+                         aliasing rules and cause data races: all of these are undefined \
+                         behavior", UnsafetyViolationKind::General)
                 }
-                let base_ty = Place::ty_from(&place.base, &proj.base, self.body, self.tcx).ty;
-                match base_ty.sty {
-                    ty::RawPtr(..) => {
-                        self.require_unsafe("dereference of raw pointer",
-                            "raw pointers may be NULL, dangling or unaligned; they can violate \
-                             aliasing rules and cause data races: all of these are undefined \
-                             behavior", UnsafetyViolationKind::General)
-                    }
-                    ty::Adt(adt, _) => {
-                        if adt.is_union() {
-                            if context == PlaceContext::MutatingUse(MutatingUseContext::Store) ||
-                                context == PlaceContext::MutatingUse(MutatingUseContext::Drop) ||
-                                context == PlaceContext::MutatingUse(
-                                    MutatingUseContext::AsmOutput
-                                )
-                            {
-                                let elem_ty = match proj.elem {
-                                    ProjectionElem::Field(_, ty) => ty,
-                                    _ => span_bug!(
-                                        self.source_info.span,
-                                        "non-field projection {:?} from union?",
-                                        place)
-                                };
-                                if !elem_ty.is_copy_modulo_regions(
-                                    self.tcx,
-                                    self.param_env,
+                ty::Adt(adt, _) => {
+                    if adt.is_union() {
+                        if context == PlaceContext::MutatingUse(MutatingUseContext::Store) ||
+                            context == PlaceContext::MutatingUse(MutatingUseContext::Drop) ||
+                            context == PlaceContext::MutatingUse(
+                                MutatingUseContext::AsmOutput
+                            )
+                        {
+                            let elem_ty = match elem {
+                                ProjectionElem::Field(_, ty) => ty,
+                                _ => span_bug!(
                                     self.source_info.span,
-                                ) {
-                                    self.require_unsafe(
-                                        "assignment to non-`Copy` union field",
-                                        "the previous content of the field will be dropped, which \
-                                         causes undefined behavior if the field was not properly \
-                                         initialized", UnsafetyViolationKind::General)
-                                } else {
-                                    // write to non-move union, safe
-                                }
+                                    "non-field projection {:?} from union?",
+                                    place)
+                            };
+                            if !elem_ty.is_copy_modulo_regions(
+                                self.tcx,
+                                self.param_env,
+                                self.source_info.span,
+                            ) {
+                                self.require_unsafe(
+                                    "assignment to non-`Copy` union field",
+                                    "the previous content of the field will be dropped, which \
+                                     causes undefined behavior if the field was not properly \
+                                     initialized", UnsafetyViolationKind::General)
                             } else {
-                                self.require_unsafe("access to union field",
-                                    "the field may not be properly initialized: using \
-                                     uninitialized data will cause undefined behavior",
-                                     UnsafetyViolationKind::General)
+                                // write to non-move union, safe
                             }
+                        } else {
+                            self.require_unsafe("access to union field",
+                                "the field may not be properly initialized: using \
+                                 uninitialized data will cause undefined behavior",
+                                 UnsafetyViolationKind::General)
                         }
                     }
-                    _ => {}
                 }
-                self.source_info = old_source_info;
+                _ => {}
             }
-        });
+            self.source_info = old_source_info;
+        }
     }
 }
 
@@ -407,12 +407,13 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
         place: &Place<'tcx>,
         is_mut_use: bool,
     ) {
-        let mut projection = &place.projection;
-        while let Some(proj) = projection {
-            match proj.elem {
+        for (i, elem) in place.projection.iter().enumerate().rev() {
+            let proj_base = &place.projection[..i];
+
+            match elem {
                 ProjectionElem::Field(..) => {
                     let ty =
-                        Place::ty_from(&place.base, &proj.base, &self.body.local_decls, self.tcx)
+                        Place::ty_from(&place.base, proj_base, &self.body.local_decls, self.tcx)
                             .ty;
                     match ty.sty {
                         ty::Adt(def, _) => match self.tcx.layout_scalar_valid_range(def.did) {
@@ -447,7 +448,6 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
                 }
                 _ => {}
             }
-            projection = &proj.base;
         }
     }
 }
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index e4b186736e2a1..2e91561f2eee1 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -282,53 +282,53 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
 
     fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> {
         trace!("eval_place(place={:?})", place);
-        place.iterate(|place_base, place_projection| {
-            let mut eval = match place_base {
-                PlaceBase::Local(loc) => self.get_const(*loc).clone()?,
-                PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted, _), ..}) => {
-                    let generics = self.tcx.generics_of(self.source.def_id());
-                    if generics.requires_monomorphization(self.tcx) {
-                        // FIXME: can't handle code with generics
-                        return None;
-                    }
-                    let substs = InternalSubsts::identity_for_item(self.tcx, self.source.def_id());
-                    let instance = Instance::new(self.source.def_id(), substs);
-                    let cid = GlobalId {
-                        instance,
-                        promoted: Some(*promoted),
-                    };
-                    let res = self.use_ecx(source_info, |this| {
-                        this.ecx.const_eval_raw(cid)
+        let mut eval = match place.base {
+            PlaceBase::Local(loc) => self.get_const(loc).clone()?,
+            PlaceBase::Static(box Static {kind: StaticKind::Promoted(promoted, _), ..}) => {
+                let generics = self.tcx.generics_of(self.source.def_id());
+                if generics.requires_monomorphization(self.tcx) {
+                    // FIXME: can't handle code with generics
+                    return None;
+                }
+                let substs = InternalSubsts::identity_for_item(self.tcx, self.source.def_id());
+                let instance = Instance::new(self.source.def_id(), substs);
+                let cid = GlobalId {
+                    instance,
+                    promoted: Some(promoted),
+                };
+                let res = self.use_ecx(source_info, |this| {
+                    this.ecx.const_eval_raw(cid)
+                })?;
+                trace!("evaluated promoted {:?} to {:?}", promoted, res);
+                res.into()
+            }
+            _ => return None,
+        };
+
+        for (i, elem) in place.projection.iter().enumerate() {
+            let proj_base = &place.projection[..i];
+
+            match elem {
+                ProjectionElem::Field(field, _) => {
+                    trace!("field proj on {:?}", proj_base);
+                    eval = self.use_ecx(source_info, |this| {
+                        this.ecx.operand_field(eval, field.index() as u64)
                     })?;
-                    trace!("evaluated promoted {:?} to {:?}", promoted, res);
-                    res.into()
+                },
+                ProjectionElem::Deref => {
+                    trace!("processing deref");
+                    eval = self.use_ecx(source_info, |this| {
+                        this.ecx.deref_operand(eval)
+                    })?.into();
                 }
+                // We could get more projections by using e.g., `operand_projection`,
+                // but we do not even have the stack frame set up properly so
+                // an `Index` projection would throw us off-track.
                 _ => return None,
-            };
-
-            for proj in place_projection {
-                match proj.elem {
-                    ProjectionElem::Field(field, _) => {
-                        trace!("field proj on {:?}", proj.base);
-                        eval = self.use_ecx(source_info, |this| {
-                            this.ecx.operand_field(eval, field.index() as u64)
-                        })?;
-                    },
-                    ProjectionElem::Deref => {
-                        trace!("processing deref");
-                        eval = self.use_ecx(source_info, |this| {
-                            this.ecx.deref_operand(eval)
-                        })?.into();
-                    }
-                    // We could get more projections by using e.g., `operand_projection`,
-                    // but we do not even have the stack frame set up properly so
-                    // an `Index` projection would throw us off-track.
-                    _ => return None,
-                }
             }
+        }
 
-            Some(eval)
-        })
+        Some(eval)
     }
 
     fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> {
@@ -673,7 +673,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
                 if let Some(value) = self.const_prop(rval, place_layout, statement.source_info) {
                     if let Place {
                         base: PlaceBase::Local(local),
-                        projection: None,
+                        projection: box [],
                     } = *place {
                         trace!("checking whether {:?} can be stored to {:?}", value, local);
                         if self.can_const_prop[local] {
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs
index f3a523a813413..20bdb4b03f081 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/src/librustc_mir/transform/copy_prop.rs
@@ -96,7 +96,7 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation {
                         StatementKind::Assign(
                             Place {
                                 base: PlaceBase::Local(local),
-                                projection: None,
+                                projection: box [],
                             },
                             box Rvalue::Use(ref operand)
                         ) if local == dest_local => {
@@ -150,21 +150,21 @@ fn eliminate_self_assignments(
                     StatementKind::Assign(
                         Place {
                             base: PlaceBase::Local(local),
-                            projection: None,
+                            projection: box [],
                         },
                         box Rvalue::Use(Operand::Copy(Place {
                             base: PlaceBase::Local(src_local),
-                            projection: None,
+                            projection: box [],
                         })),
                     ) |
                     StatementKind::Assign(
                         Place {
                             base: PlaceBase::Local(local),
-                            projection: None,
+                            projection: box [],
                         },
                         box Rvalue::Use(Operand::Move(Place {
                             base: PlaceBase::Local(src_local),
-                            projection: None,
+                            projection: box [],
                         })),
                     ) if local == dest_local && dest_local == src_local => {}
                     _ => {
@@ -194,7 +194,7 @@ impl<'tcx> Action<'tcx> {
         // The source must be a local.
         let src_local = if let Place {
             base: PlaceBase::Local(local),
-            projection: None,
+            projection: box [],
         } = *src_place {
             local
         } else {
@@ -351,11 +351,11 @@ impl<'tcx> MutVisitor<'tcx> for ConstantPropagationVisitor<'tcx> {
         match *operand {
             Operand::Copy(Place {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: box [],
             }) |
             Operand::Move(Place {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: box [],
             }) if local == self.dest_local => {}
             _ => return,
         }
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index 7a5c00c859629..47c7c2c5cb319 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -236,47 +236,37 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
     }
 
     fn field_subpath(&self, path: Self::Path, field: Field) -> Option<Self::Path> {
-        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| {
-            match p {
-                &Projection {
-                    elem: ProjectionElem::Field(idx, _), ..
-                } => idx == field,
-                _ => false
-            }
+        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| match p {
+            [.., ProjectionElem::Field(idx, _)] => *idx == field,
+            _ => false,
         })
     }
 
     fn array_subpath(&self, path: Self::Path, index: u32, size: u32) -> Option<Self::Path> {
-        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| {
-            match p {
-                &Projection {
-                    elem: ProjectionElem::ConstantIndex{offset, min_length: _, from_end: false}, ..
-                } => offset == index,
-                &Projection {
-                    elem: ProjectionElem::ConstantIndex{offset, min_length: _, from_end: true}, ..
-                } => size - offset == index,
-                _ => false
+        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| match p {
+            [.., ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false }] => {
+                *offset == index
+            }
+            [.., ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true }] => {
+                size - offset == index
             }
+            _ => false,
         })
     }
 
     fn deref_subpath(&self, path: Self::Path) -> Option<Self::Path> {
         dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| {
             match p {
-                &Projection { elem: ProjectionElem::Deref, .. } => true,
+                [.., ProjectionElem::Deref] => true,
                 _ => false
             }
         })
     }
 
     fn downcast_subpath(&self, path: Self::Path, variant: VariantIdx) -> Option<Self::Path> {
-        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| {
-            match p {
-                &Projection {
-                    elem: ProjectionElem::Downcast(_, idx), ..
-                } => idx == variant,
-                _ => false
-            }
+        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| match p {
+            [.., ProjectionElem::Downcast(_, idx)] => *idx == variant,
+            _ => false
         })
     }
 
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index d87331195dd24..cf899c64406bc 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -107,10 +107,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor {
         if place.base == PlaceBase::Local(self_arg()) {
             replace_base(place, Place {
                 base: PlaceBase::Local(self_arg()),
-                projection: Some(Box::new(Projection {
-                    base: None,
-                    elem: ProjectionElem::Deref,
-                })),
+                projection: Box::new([ProjectionElem::Deref]),
             });
         } else {
             self.super_place(place, context, location);
@@ -137,10 +134,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
         if place.base == PlaceBase::Local(self_arg()) {
             replace_base(place, Place {
                 base: PlaceBase::Local(self_arg()),
-                projection: Some(Box::new(Projection {
-                    base: None,
-                    elem: ProjectionElem::Field(Field::new(0), self.ref_gen_ty),
-                })),
+                projection: Box::new([ProjectionElem::Field(Field::new(0), self.ref_gen_ty)]),
             });
         } else {
             self.super_place(place, context, location);
@@ -149,13 +143,12 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
 }
 
 fn replace_base(place: &mut Place<'tcx>, new_base: Place<'tcx>) {
-    let mut projection = &mut place.projection;
-    while let Some(box proj) = projection {
-        projection = &mut proj.base;
-    }
-
     place.base = new_base.base;
-    *projection = new_base.projection;
+
+    let mut new_projection = new_base.projection.to_vec();
+    new_projection.append(&mut place.projection.to_vec());
+
+    place.projection = new_projection.into_boxed_slice();
 }
 
 fn self_arg() -> Local {
@@ -210,13 +203,12 @@ impl TransformVisitor<'tcx> {
     fn make_field(&self, variant_index: VariantIdx, idx: usize, ty: Ty<'tcx>) -> Place<'tcx> {
         let self_place = Place::from(self_arg());
         let base = self_place.downcast_unnamed(variant_index);
-        let field = Projection {
-            base: base.projection,
-            elem: ProjectionElem::Field(Field::new(idx), ty),
-        };
+        let mut projection = base.projection.to_vec();
+        projection.push(ProjectionElem::Field(Field::new(idx), ty));
+
         Place {
             base: base.base,
-            projection: Some(Box::new(field)),
+            projection: projection.into_boxed_slice(),
         }
     }
 
@@ -296,7 +288,7 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
             // We must assign the value first in case it gets declared dead below
             data.statements.push(Statement {
                 source_info,
-                kind: StatementKind::Assign(Place::RETURN_PLACE,
+                kind: StatementKind::Assign(Place::return_place(),
                                             box self.make_state(state_idx, v)),
             });
             let state = if let Some(resume) = resume { // Yield
@@ -848,7 +840,7 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, body: &mut
                 kind: TerminatorKind::Drop {
                     location: Place {
                         base: PlaceBase::Local(local),
-                        projection: None,
+                        projection: box [],
                     },
                     target,
                     unwind
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index f31303c642faa..2b3c6d55f24dd 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -425,22 +425,20 @@ impl Inliner<'tcx> {
                 // writes to `i`. To prevent this we need to create a temporary
                 // borrow of the place and pass the destination as `*temp` instead.
                 fn dest_needs_borrow(place: &Place<'_>) -> bool {
-                    place.iterate(|place_base, place_projection| {
-                        for proj in place_projection {
-                            match proj.elem {
-                                ProjectionElem::Deref |
-                                ProjectionElem::Index(_) => return true,
-                                _ => {}
-                            }
+                    for elem in place.projection.iter() {
+                        match elem {
+                            ProjectionElem::Deref |
+                            ProjectionElem::Index(_) => return true,
+                            _ => {}
                         }
+                    }
 
-                        match place_base {
-                            // Static variables need a borrow because the callee
-                            // might modify the same static.
-                            PlaceBase::Static(_) => true,
-                            _ => false
-                        }
-                    })
+                    match place.base {
+                        // Static variables need a borrow because the callee
+                        // might modify the same static.
+                        PlaceBase::Static(_) => true,
+                        _ => false
+                    }
                 }
 
                 let dest = if dest_needs_borrow(&destination.0) {
@@ -591,7 +589,7 @@ impl Inliner<'tcx> {
 
         if let Operand::Move(Place {
             base: PlaceBase::Local(local),
-            projection: None,
+            projection: box [],
         }) = arg {
             if caller_body.local_kind(local) == LocalKind::Temp {
                 // Reuse the operand if it's a temporary already
@@ -660,7 +658,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
             match self.destination {
                 Place {
                     base: PlaceBase::Local(l),
-                    projection: None,
+                    projection: box [],
                 } => {
                     *local = l;
                     return;
@@ -684,7 +682,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Integrator<'a, 'tcx> {
         match place {
             Place {
                 base: PlaceBase::Local(RETURN_PLACE),
-                projection: None,
+                projection: box [],
             } => {
                 // Return pointer; update the place itself
                 *place = self.destination.clone();
diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs
index abe41606e8079..b949e2f5ddd1d 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/src/librustc_mir/transform/instcombine.rs
@@ -43,12 +43,19 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
             let new_place = match *rvalue {
                 Rvalue::Ref(_, _, Place {
                     ref mut base,
-                    projection: Some(ref mut projection),
-                }) => Place {
-                    // Replace with dummy
-                    base: mem::replace(base, PlaceBase::Local(Local::new(0))),
-                    projection: projection.base.take(),
-                },
+                    projection: ref mut projection @ box [.., _],
+                }) => {
+                    let (proj_l, proj_r) = projection.split_at(projection.len() - 1);
+
+                    let place = Place {
+                        // Replace with dummy
+                        base: mem::replace(base, PlaceBase::Local(Local::new(0))),
+                        projection: proj_l.to_vec().into_boxed_slice(),
+                    };
+                    *projection = proj_r.to_vec().into_boxed_slice();
+
+                    place
+                }
                 _ => bug!("Detected `&*` but didn't find `&*`!"),
             };
             *rvalue = Rvalue::Use(Operand::Copy(new_place))
@@ -83,12 +90,19 @@ impl OptimizationFinder<'b, 'tcx> {
 impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
     fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
         if let Rvalue::Ref(_, _, Place {
-            ref base,
-            projection: Some(ref projection),
-        }) = *rvalue {
-            if let ProjectionElem::Deref = projection.elem {
-                if Place::ty_from(&base, &projection.base, self.body, self.tcx).ty.is_region_ptr() {
-                    self.optimizations.and_stars.insert(location);
+            base: _,
+            projection: box [.., elem],
+        }) = rvalue {
+            if *elem == ProjectionElem::Deref {
+                // FIXME remove this once we can use slices patterns
+                if let Rvalue::Ref(_, _, Place {
+                    base,
+                    projection,
+                }) = rvalue {
+                    let proj_base = &projection[..projection.len() - 1];
+                    if Place::ty_from(base, proj_base, self.body, self.tcx).ty.is_region_ptr() {
+                        self.optimizations.and_stars.insert(location);
+                    }
                 }
             }
         }
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index cdccdfea39943..0723a0c992e8e 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -318,7 +318,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                         ty,
                         def_id,
                     }),
-                    projection: None,
+                    projection: box [],
                 }
             };
             let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();
@@ -334,9 +334,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                             Operand::Move(Place {
                                 base: mem::replace(
                                     &mut place.base,
-                                    promoted_place(ty, span).base
+                                    promoted_place(ty, span).base,
                                 ),
-                                projection: None,
+                                projection: box [],
                             })
                         }
                         _ => bug!()
@@ -422,7 +422,7 @@ pub fn promote_candidates<'tcx>(
                 match body[block].statements[statement_index].kind {
                     StatementKind::Assign(Place {
                         base: PlaceBase::Local(local),
-                        projection: None,
+                        projection: box [],
                     }, _) => {
                         if temps[local] == TempState::PromotedOut {
                             // Already promoted.
@@ -475,7 +475,7 @@ pub fn promote_candidates<'tcx>(
             match statement.kind {
                 StatementKind::Assign(Place {
                     base: PlaceBase::Local(index),
-                    projection: None,
+                    projection: box [],
                 }, _) |
                 StatementKind::StorageLive(index) |
                 StatementKind::StorageDead(index) => {
@@ -488,7 +488,7 @@ pub fn promote_candidates<'tcx>(
         match terminator.kind {
             TerminatorKind::Drop { location: Place {
                 base: PlaceBase::Local(index),
-                projection: None,
+                projection: box [],
             }, target, .. } => {
                 if promoted(index) {
                     terminator.kind = TerminatorKind::Goto {
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 32b49ee942300..27a46d3450317 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -187,26 +187,27 @@ trait Qualif {
         cx: &ConstCx<'_, 'tcx>,
         place: PlaceRef<'_, 'tcx>,
     ) -> bool {
-        let proj = place.projection.as_ref().unwrap();
+        let elem = &place.projection[place.projection.len() - 1];
+        let proj_base = &place.projection[..place.projection.len() - 1];
 
         let base_qualif = Self::in_place(cx, PlaceRef {
             base: place.base,
-            projection: &proj.base,
+            projection: proj_base,
         });
         let qualif = base_qualif && Self::mask_for_ty(
             cx,
-            Place::ty_from(place.base, &proj.base, cx.body, cx.tcx)
-                .projection_ty(cx.tcx, &proj.elem)
+            Place::ty_from(place.base, proj_base, cx.body, cx.tcx)
+                .projection_ty(cx.tcx, elem)
                 .ty,
         );
-        match proj.elem {
+        match elem {
             ProjectionElem::Deref |
             ProjectionElem::Subslice { .. } |
             ProjectionElem::Field(..) |
             ProjectionElem::ConstantIndex { .. } |
             ProjectionElem::Downcast(..) => qualif,
 
-            ProjectionElem::Index(local) => qualif || Self::in_local(cx, local),
+            ProjectionElem::Index(local) => qualif || Self::in_local(cx, *local),
         }
     }
 
@@ -221,24 +222,24 @@ trait Qualif {
         match place {
             PlaceRef {
                 base: PlaceBase::Local(local),
-                projection: None,
+                projection: [],
             } => Self::in_local(cx, *local),
             PlaceRef {
                 base: PlaceBase::Static(box Static {
                     kind: StaticKind::Promoted(..),
                     ..
                 }),
-                projection: None,
+                projection: [],
             } => bug!("qualifying already promoted MIR"),
             PlaceRef {
                 base: PlaceBase::Static(static_),
-                projection: None,
+                projection: [],
             } => {
                 Self::in_static(cx, static_)
             },
             PlaceRef {
                 base: _,
-                projection: Some(_),
+                projection: [.., _],
             } => Self::in_projection(cx, place),
         }
     }
@@ -289,13 +290,16 @@ trait Qualif {
 
             Rvalue::Ref(_, _, ref place) => {
                 // Special-case reborrows to be more like a copy of the reference.
-                if let Some(ref proj) = place.projection {
-                    if let ProjectionElem::Deref = proj.elem {
-                        let base_ty = Place::ty_from(&place.base, &proj.base, cx.body, cx.tcx).ty;
+                if !place.projection.is_empty() {
+                    let elem = &place.projection[place.projection.len() - 1];
+                    let proj_base = &place.projection[..place.projection.len() - 1];
+
+                    if ProjectionElem::Deref == *elem {
+                        let base_ty = Place::ty_from(&place.base, proj_base, cx.body, cx.tcx).ty;
                         if let ty::Ref(..) = base_ty.sty {
                             return Self::in_place(cx, PlaceRef {
                                 base: &place.base,
-                                projection: &proj.base,
+                                projection: proj_base,
                             });
                         }
                     }
@@ -453,9 +457,10 @@ impl Qualif for IsNotPromotable {
         cx: &ConstCx<'_, 'tcx>,
         place: PlaceRef<'_, 'tcx>,
     ) -> bool {
-        let proj = place.projection.as_ref().unwrap();
+        let elem = &place.projection[place.projection.len() - 1];
+        let proj_base = &place.projection[..place.projection.len() - 1];
 
-        match proj.elem {
+        match elem {
             ProjectionElem::Deref |
             ProjectionElem::Downcast(..) => return true,
 
@@ -465,7 +470,7 @@ impl Qualif for IsNotPromotable {
 
             ProjectionElem::Field(..) => {
                 if cx.mode == Mode::NonConstFn {
-                    let base_ty = Place::ty_from(place.base, &proj.base, cx.body, cx.tcx).ty;
+                    let base_ty = Place::ty_from(place.base, proj_base, cx.body, cx.tcx).ty;
                     if let Some(def) = base_ty.ty_adt_def() {
                         // No promotion of union field accesses.
                         if def.is_union() {
@@ -806,23 +811,18 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                     // We might have a candidate for promotion.
                     let candidate = Candidate::Ref(location);
                     // Start by traversing to the "base", with non-deref projections removed.
-                    let mut place_projection = &place.projection;
-                    while let Some(proj) = place_projection {
-                        if proj.elem == ProjectionElem::Deref {
-                            break;
-                        }
-                        place_projection = &proj.base;
-                    }
+                    let deref_proj =
+                        place.projection.iter().rev().find(|&elem| *elem == ProjectionElem::Deref);
 
                     debug!(
                         "qualify_consts: promotion candidate: place={:?} {:?}",
-                        place.base, place_projection
+                        place.base, deref_proj
                     );
                     // We can only promote interior borrows of promotable temps (non-temps
                     // don't get promoted anyway).
                     // (If we bailed out of the loop due to a `Deref` above, we will definitely
                     // not enter the conditional here.)
-                    if let (PlaceBase::Local(local), None) = (&place.base, place_projection) {
+                    if let (PlaceBase::Local(local), None) = (&place.base, deref_proj) {
                         if self.body.local_kind(*local) == LocalKind::Temp {
                             debug!("qualify_consts: promotion candidate: local={:?}", local);
                             // The borrowed place doesn't have `HasMutInterior`
@@ -858,27 +858,29 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
             _ => {},
         }
 
-        let mut dest_projection = &dest.projection;
+        let mut dest_projection = &dest.projection[..];
         let index = loop {
             match (&dest.base, dest_projection) {
                 // We treat all locals equal in constants
-                (&PlaceBase::Local(index), None) => break index,
+                (&PlaceBase::Local(index), []) => break index,
                 // projections are transparent for assignments
                 // we qualify the entire destination at once, even if just a field would have
                 // stricter qualification
-                (base, Some(proj)) => {
+                (base, proj @ [.., _]) => {
+                    let proj_base = &proj[..proj.len() - 1];
+
                     // Catch more errors in the destination. `visit_place` also checks various
                     // projection rules like union field access and raw pointer deref
                     let context = PlaceContext::MutatingUse(MutatingUseContext::Store);
                     self.visit_place_base(base, context, location);
                     self.visit_projection(base, proj, context, location);
-                    dest_projection = &proj.base;
+                    dest_projection = proj_base;
                 },
                 (&PlaceBase::Static(box Static {
                     kind: StaticKind::Promoted(..),
                     ..
-                }), None) => bug!("promoteds don't exist yet during promotion"),
-                (&PlaceBase::Static(box Static{ kind: _, .. }), None) => {
+                }), []) => bug!("promoteds don't exist yet during promotion"),
+                (&PlaceBase::Static(box Static{ kind: _, .. }), []) => {
                     // Catch more errors in the destination. `visit_place` also checks that we
                     // do not try to access statics from constants or try to mutate statics
                     let context = PlaceContext::MutatingUse(MutatingUseContext::Store);
@@ -986,7 +988,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                     if let StatementKind::Assign(_, box Rvalue::Repeat(
                         Operand::Move(Place {
                             base: PlaceBase::Local(index),
-                            projection: None,
+                            projection: box [],
                         }),
                         _
                     )) = self.body[bb].statements[stmt_idx].kind {
@@ -998,7 +1000,7 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                         _,
                         box Rvalue::Ref(_, _, Place {
                             base: PlaceBase::Local(index),
-                            projection: None,
+                            projection: box [],
                         })
                     ) = self.body[bb].statements[stmt_idx].kind {
                         promoted_temps.insert(index);
@@ -1084,7 +1086,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
     fn visit_projection(
         &mut self,
         place_base: &PlaceBase<'tcx>,
-        proj: &Projection<'tcx>,
+        proj: &[PlaceElem<'tcx>],
         context: PlaceContext,
         location: Location,
     ) {
@@ -1093,62 +1095,68 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
             proj, context, location,
         );
         self.super_projection(place_base, proj, context, location);
-        match proj.elem {
-            ProjectionElem::Deref => {
-                if context.is_mutating_use() {
-                    // `not_const` errors out in const contexts
-                    self.not_const()
-                }
-                let base_ty = Place::ty_from(place_base, &proj.base, self.body, self.tcx).ty;
-                match self.mode {
-                    Mode::NonConstFn => {},
-                    _ => {
-                        if let ty::RawPtr(_) = base_ty.sty {
-                            if !self.tcx.features().const_raw_ptr_deref {
-                                emit_feature_err(
-                                    &self.tcx.sess.parse_sess, sym::const_raw_ptr_deref,
-                                    self.span, GateIssue::Language,
-                                    &format!(
-                                        "dereferencing raw pointers in {}s is unstable",
-                                        self.mode,
-                                    ),
-                                );
-                            }
-                        }
-                    }
-                }
-            }
 
-            ProjectionElem::ConstantIndex {..} |
-            ProjectionElem::Subslice {..} |
-            ProjectionElem::Field(..) |
-            ProjectionElem::Index(_) => {
-                let base_ty = Place::ty_from(place_base, &proj.base, self.body, self.tcx).ty;
-                if let Some(def) = base_ty.ty_adt_def() {
-                    if def.is_union() {
-                        match self.mode {
-                            Mode::ConstFn => {
-                                if !self.tcx.features().const_fn_union {
+        if !proj.is_empty() {
+            let elem = &proj[proj.len() - 1];
+            let proj_base = &proj[..proj.len() - 1];
+
+            match elem {
+                ProjectionElem::Deref => {
+                    if context.is_mutating_use() {
+                        // `not_const` errors out in const contexts
+                        self.not_const()
+                    }
+                    let base_ty = Place::ty_from(place_base, proj_base, self.body, self.tcx).ty;
+                    match self.mode {
+                        Mode::NonConstFn => {},
+                        _ => {
+                            if let ty::RawPtr(_) = base_ty.sty {
+                                if !self.tcx.features().const_raw_ptr_deref {
                                     emit_feature_err(
-                                        &self.tcx.sess.parse_sess, sym::const_fn_union,
+                                        &self.tcx.sess.parse_sess, sym::const_raw_ptr_deref,
                                         self.span, GateIssue::Language,
-                                        "unions in const fn are unstable",
+                                        &format!(
+                                            "dereferencing raw pointers in {}s is unstable",
+                                            self.mode,
+                                        ),
                                     );
                                 }
-                            },
+                            }
+                        }
+                    }
+                }
 
-                            | Mode::NonConstFn
-                            | Mode::Static
-                            | Mode::StaticMut
-                            | Mode::Const
-                            => {},
+                ProjectionElem::ConstantIndex {..} |
+                ProjectionElem::Subslice {..} |
+                ProjectionElem::Field(..) |
+                ProjectionElem::Index(_) => {
+                    let base_ty = Place::ty_from(place_base, proj_base, self.body, self.tcx).ty;
+                    if let Some(def) = base_ty.ty_adt_def() {
+                        if def.is_union() {
+                            match self.mode {
+                                Mode::ConstFn => {
+                                    if !self.tcx.features().const_fn_union {
+                                        emit_feature_err(
+                                            &self.tcx.sess.parse_sess, sym::const_fn_union,
+                                            self.span, GateIssue::Language,
+                                            "unions in const fn are unstable",
+                                        );
+                                    }
+                                },
+
+                                | Mode::NonConstFn
+                                | Mode::Static
+                                | Mode::StaticMut
+                                | Mode::Const
+                                => {},
+                            }
                         }
                     }
                 }
-            }
 
-            ProjectionElem::Downcast(..) => {
-                self.not_const()
+                ProjectionElem::Downcast(..) => {
+                    self.not_const()
+                }
             }
         }
     }
@@ -1162,7 +1170,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                 // Mark the consumed locals to indicate later drops are noops.
                 if let Place {
                     base: PlaceBase::Local(local),
-                    projection: None,
+                    projection: box [],
                 } = *place {
                     self.cx.per_local[NeedsDrop].remove(local);
                 }
@@ -1179,11 +1187,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
         if let Rvalue::Ref(_, kind, ref place) = *rvalue {
             // Special-case reborrows.
             let mut reborrow_place = None;
-            if let Some(ref proj) = place.projection {
-                if let ProjectionElem::Deref = proj.elem {
-                    let base_ty = Place::ty_from(&place.base, &proj.base, self.body, self.tcx).ty;
+            if let box [.., elem] = &place.projection {
+                if *elem == ProjectionElem::Deref {
+                    let proj_base = &place.projection[..place.projection.len() - 1];
+                    let base_ty = Place::ty_from(&place.base, proj_base, self.body, self.tcx).ty;
                     if let ty::Ref(..) = base_ty.sty {
-                        reborrow_place = Some(&proj.base);
+                        reborrow_place = Some(proj_base);
                     }
                 }
             }
@@ -1204,9 +1213,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                     ),
                 };
                 self.visit_place_base(&place.base, ctx, location);
-                if let Some(proj) = proj {
-                    self.visit_projection(&place.base, proj, ctx, location);
-                }
+                self.visit_projection(&place.base, proj, ctx, location);
             } else {
                 self.super_rvalue(rvalue, location);
             }
@@ -1477,7 +1484,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                 // conservatively, that drop elaboration will do.
                 let needs_drop = if let Place {
                     base: PlaceBase::Local(local),
-                    projection: None,
+                    projection: box [],
                 } = *place {
                     if NeedsDrop::in_local(self, local) {
                         Some(self.body.local_decls[local].source_info.span)
@@ -1727,7 +1734,7 @@ fn remove_drop_and_storage_dead_on_promoted_locals(
             TerminatorKind::Drop {
                 location: Place {
                     base: PlaceBase::Local(index),
-                    projection: None,
+                    projection: box [],
                 },
                 target,
                 ..
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index 56093527aee24..cb2da1d5ff916 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -249,28 +249,26 @@ fn check_place(
     place: &Place<'tcx>,
     span: Span,
 ) -> McfResult {
-    place.iterate(|place_base, place_projection| {
-        for proj in place_projection {
-            match proj.elem {
-                ProjectionElem::Downcast(..) => {
-                    return Err((span, "`match` or `if let` in `const fn` is unstable".into()));
-                }
-                ProjectionElem::ConstantIndex { .. }
-                | ProjectionElem::Subslice { .. }
-                | ProjectionElem::Deref
-                | ProjectionElem::Field(..)
-                | ProjectionElem::Index(_) => {}
+    for elem in place.projection.iter() {
+        match elem {
+            ProjectionElem::Downcast(..) => {
+                return Err((span, "`match` or `if let` in `const fn` is unstable".into()));
             }
+            ProjectionElem::ConstantIndex { .. }
+            | ProjectionElem::Subslice { .. }
+            | ProjectionElem::Deref
+            | ProjectionElem::Field(..)
+            | ProjectionElem::Index(_) => {}
         }
+    }
 
-        match place_base {
-            PlaceBase::Static(box Static { kind: StaticKind::Static, .. }) => {
-                Err((span, "cannot access `static` items in const fn".into()))
-            }
-            PlaceBase::Local(_)
-            | PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => Ok(()),
+    match place.base {
+        PlaceBase::Static(box Static { kind: StaticKind::Static, .. }) => {
+            Err((span, "cannot access `static` items in const fn".into()))
         }
-    })
+        PlaceBase::Local(_)
+        | PlaceBase::Static(box Static { kind: StaticKind::Promoted(_, _), .. }) => Ok(()),
+    }
 }
 
 fn check_terminator(
diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs
index 73089a2106f6b..07669e2c0c986 100644
--- a/src/librustc_mir/transform/remove_noop_landing_pads.rs
+++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs
@@ -43,7 +43,7 @@ impl RemoveNoopLandingPads {
 
                 StatementKind::Assign(Place {
                     base: PlaceBase::Local(_),
-                    projection: None,
+                    projection: box [],
                 }, box Rvalue::Use(_)) => {
                     // Writing to a local (e.g., a drop flag) does not
                     // turn a landing pad to a non-nop
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index 1d3bf247387a7..208407bb9a5e0 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -120,11 +120,11 @@ fn each_block<'tcx, O>(
     let peek_arg_place = match args[0] {
         mir::Operand::Copy(ref place @ mir::Place {
             base: mir::PlaceBase::Local(_),
-            projection: None,
+            projection: box [],
         }) |
         mir::Operand::Move(ref place @ mir::Place {
             base: mir::PlaceBase::Local(_),
-            projection: None,
+            projection: box [],
         }) => Some(place),
         _ => None,
     };
diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs
index 8199a252e78b0..318049a1ce0fe 100644
--- a/src/librustc_mir/transform/uniform_array_move_out.rs
+++ b/src/librustc_mir/transform/uniform_array_move_out.rs
@@ -61,14 +61,16 @@ impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> {
                     rvalue: &Rvalue<'tcx>,
                     location: Location) {
         if let Rvalue::Use(Operand::Move(ref src_place)) = rvalue {
-            if let Some(ref proj) = src_place.projection {
+            if let box [.., elem] = &src_place.projection {
+                let proj_base = &src_place.projection[..src_place.projection.len() - 1];
+
                 if let ProjectionElem::ConstantIndex{offset: _,
                                                      min_length: _,
-                                                     from_end: false} = proj.elem {
+                                                     from_end: false} = elem {
                     // no need to transformation
                 } else {
                     let place_ty =
-                        Place::ty_from(&src_place.base, &proj.base, self.body, self.tcx).ty;
+                        Place::ty_from(&src_place.base, proj_base, self.body, self.tcx).ty;
                     if let ty::Array(item_ty, const_size) = place_ty.sty {
                         if let Some(size) = const_size.try_eval_usize(self.tcx, self.param_env) {
                             assert!(size <= u32::max_value() as u64,
@@ -78,7 +80,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> {
                                 location,
                                 dst_place,
                                 &src_place.base,
-                                proj,
+                                &src_place.projection,
                                 item_ty,
                                 size as u32,
                             );
@@ -97,73 +99,79 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
                location: Location,
                dst_place: &Place<'tcx>,
                base: &PlaceBase<'tcx>,
-               proj: &Projection<'tcx>,
+               proj: &[PlaceElem<'tcx>],
                item_ty: &'tcx ty::TyS<'tcx>,
                size: u32) {
-        match proj.elem {
-            // uniforms statements like_10 = move _2[:-1];
-            ProjectionElem::Subslice{from, to} => {
-                self.patch.make_nop(location);
-                let temps : Vec<_> = (from..(size-to)).map(|i| {
-                    let temp = self.patch.new_temp(item_ty, self.body.source_info(location).span);
-                    self.patch.add_statement(location, StatementKind::StorageLive(temp));
+        if !proj.is_empty() {
+            let elem = &proj[proj.len() - 1];
+            let proj_base = &proj[..proj.len() - 1];
+
+            match elem {
+                // uniforms statements like_10 = move _2[:-1];
+                ProjectionElem::Subslice{from, to} => {
+                    self.patch.make_nop(location);
+                    let temps : Vec<_> = (*from..(size-*to)).map(|i| {
+                        let temp =
+                            self.patch.new_temp(item_ty, self.body.source_info(location).span);
+                        self.patch.add_statement(location, StatementKind::StorageLive(temp));
+
+                        let mut projection = proj_base.to_vec();
+                        projection.push(ProjectionElem::ConstantIndex {
+                            offset: i,
+                            min_length: size,
+                            from_end: false,
+                        });
+                        self.patch.add_assign(location,
+                                              Place::from(temp),
+                                              Rvalue::Use(
+                                                  Operand::Move(
+                                                      Place {
+                                                          base: base.clone(),
+                                                          projection: projection.into_boxed_slice(),
+                                                      }
+                                                  )
+                                              )
+                        );
+                        temp
+                    }).collect();
+                    self.patch.add_assign(
+                        location,
+                        dst_place.clone(),
+                        Rvalue::Aggregate(
+                            box AggregateKind::Array(item_ty),
+                            temps.iter().map(
+                                |x| Operand::Move(Place::from(*x))
+                            ).collect()
+                        )
+                    );
+                    for temp in temps {
+                        self.patch.add_statement(location, StatementKind::StorageDead(temp));
+                    }
+                }
+                // uniforms statements like _11 = move _2[-1 of 1];
+                ProjectionElem::ConstantIndex{offset, min_length: _, from_end: true} => {
+                    self.patch.make_nop(location);
+
+                    let mut projection = proj_base.to_vec();
+                    projection.push(ProjectionElem::ConstantIndex {
+                        offset: size - offset,
+                        min_length: size,
+                        from_end: false,
+                    });
                     self.patch.add_assign(location,
-                                          Place::from(temp),
+                                          dst_place.clone(),
                                           Rvalue::Use(
                                               Operand::Move(
                                                   Place {
                                                       base: base.clone(),
-                                                      projection: Some(box Projection {
-                                                          base: proj.base.clone(),
-                                                          elem: ProjectionElem::ConstantIndex {
-                                                              offset: i,
-                                                              min_length: size,
-                                                              from_end: false,
-                                                          }
-                                                      }),
+                                                      projection: projection.into_boxed_slice(),
                                                   }
                                               )
                                           )
                     );
-                    temp
-                }).collect();
-                self.patch.add_assign(
-                    location,
-                    dst_place.clone(),
-                    Rvalue::Aggregate(
-                        box AggregateKind::Array(item_ty),
-                        temps.iter().map(
-                            |x| Operand::Move(Place::from(*x))
-                        ).collect()
-                    )
-                );
-                for temp in temps {
-                    self.patch.add_statement(location, StatementKind::StorageDead(temp));
                 }
+                _ => {}
             }
-            // uniforms statements like _11 = move _2[-1 of 1];
-            ProjectionElem::ConstantIndex{offset, min_length: _, from_end: true} => {
-                self.patch.make_nop(location);
-                self.patch.add_assign(location,
-                                      dst_place.clone(),
-                                      Rvalue::Use(
-                                          Operand::Move(
-                                              Place {
-                                                  base: base.clone(),
-                                                  projection: Some(box Projection {
-                                                      base: proj.base.clone(),
-                                                      elem: ProjectionElem::ConstantIndex {
-                                                          offset: size - offset,
-                                                          min_length: size,
-                                                          from_end: false,
-                                                      },
-                                                  }),
-                                              }
-                                          )
-                                      )
-                );
-            }
-            _ => {}
         }
     }
 }
@@ -202,7 +210,7 @@ impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut {
                         let items : Vec<_> = items.iter().map(|item| {
                             if let Operand::Move(Place {
                                 base: PlaceBase::Local(local),
-                                projection: None,
+                                projection: box [],
                             }) = item {
                                 let local_use = &visitor.locals_use[*local];
                                 let opt_index_and_place =
@@ -269,16 +277,17 @@ impl RestoreSubsliceArrayMoveOut {
             }
             patch.make_nop(candidate);
             let size = opt_size.unwrap() as u32;
-            patch.add_assign(candidate,
-                             dst_place.clone(),
-                             Rvalue::Use(
-                                 Operand::Move(
-                                     Place {
-                                         base: src_place.base.clone(),
-                                         projection: Some(box Projection {
-                                             base: src_place.projection.clone(),
-                                             elem: ProjectionElem::Subslice{
-                                                 from: min, to: size - max - 1}})})));
+
+            let mut projection = src_place.projection.to_vec();
+            projection.push(ProjectionElem::Subslice { from: min, to: size - max - 1 });
+            patch.add_assign(
+                candidate,
+                dst_place.clone(),
+                Rvalue::Use(Operand::Move(Place {
+                    base: src_place.base.clone(),
+                    projection: projection.into_boxed_slice(),
+                })),
+            );
         }
     }
 
@@ -291,21 +300,30 @@ impl RestoreSubsliceArrayMoveOut {
                 if let StatementKind::Assign(
                     Place {
                         base: PlaceBase::Local(_),
-                        projection: None,
+                        projection: box [],
                     },
                     box Rvalue::Use(Operand::Move(Place {
-                        base,
-                        projection: Some(box Projection {
-                            base: proj_base,
-                            elem: ProjectionElem::ConstantIndex {
+                        base: _,
+                        projection: box [.., ProjectionElem::ConstantIndex {
                                 offset, min_length: _, from_end: false
-                            }
-                        }),
-                    }))) = &statement.kind {
-                    return Some((*offset, PlaceRef {
-                        base,
-                        projection: proj_base,
-                    }))
+                        }],
+                    })),
+                ) = &statement.kind {
+                    // FIXME remove once we can use slices patterns
+                    if let StatementKind::Assign(
+                        _,
+                        box Rvalue::Use(Operand::Move(Place {
+                            base,
+                            projection,
+                        })),
+                        ) = &statement.kind {
+                        let proj_base = &projection[..projection.len() - 1];
+
+                        return Some((*offset, PlaceRef {
+                            base,
+                            projection: proj_base,
+                        }))
+                    }
                 }
             }
         }
diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs
index b8ef77da02e60..b4c97f9191732 100644
--- a/src/librustc_mir/util/alignment.rs
+++ b/src/librustc_mir/util/alignment.rs
@@ -38,14 +38,14 @@ fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: &Place<'
 where
     L: HasLocalDecls<'tcx>,
 {
-    let mut place_projection = &place.projection;
+    for (i, elem) in place.projection.iter().enumerate().rev() {
+        let proj_base = &place.projection[..i];
 
-    while let Some(proj) = place_projection {
-        match proj.elem {
+        match elem {
             // encountered a Deref, which is ABI-aligned
             ProjectionElem::Deref => break,
             ProjectionElem::Field(..) => {
-                let ty = Place::ty_from(&place.base, &proj.base, local_decls, tcx).ty;
+                let ty = Place::ty_from(&place.base, proj_base, local_decls, tcx).ty;
                 match ty.sty {
                     ty::Adt(def, _) if def.repr.packed() => {
                         return true
@@ -55,7 +55,6 @@ where
             }
             _ => {}
         }
-        place_projection = &proj.base;
     }
 
     false
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index f3e03e7f81daa..c60af70712d1b 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -586,10 +586,7 @@ where
                 BorrowKind::Mut { allow_two_phase_borrow: false },
                 Place {
                     base: PlaceBase::Local(cur),
-                    projection: Some(Box::new(Projection {
-                        base: None,
-                        elem: ProjectionElem::Deref,
-                    })),
+                    projection: Box::new([ProjectionElem::Deref]),
                 }
              ),
              Rvalue::BinaryOp(BinOp::Offset, move_(&Place::from(cur)), one))

From 7efee8dd05b4a2439451b47de8df79c959faffcd Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Sat, 24 Aug 2019 16:04:32 -0700
Subject: [PATCH 652/943] Use rposition to find the position of an elem

---
 src/librustc_mir/build/matches/mod.rs | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 8c94723e3cc2e..64368ab604645 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -942,16 +942,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             for Binding { source, .. }
                 in matched_candidates.iter().flat_map(|candidate| &candidate.bindings)
             {
-                for (i, elem) in source.projection.iter().enumerate().rev() {
+                if let Some(i) =
+                    source.projection.iter().rposition(|elem| *elem == ProjectionElem::Deref)
+                {
                     let proj_base = &source.projection[..i];
 
-                    if let ProjectionElem::Deref = elem {
-                        fake_borrows.insert(Place {
-                            base: source.base.clone(),
-                            projection: proj_base.to_vec().into_boxed_slice(),
-                        });
-                        break;
-                    }
+                    fake_borrows.insert(Place {
+                        base: source.base.clone(),
+                        projection: proj_base.to_vec().into_boxed_slice(),
+                    });
                 }
             }
         }

From b04e6c734451acc8b97657a906dda535874c82cf Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Sat, 24 Aug 2019 19:49:08 -0400
Subject: [PATCH 653/943] Make move_path_children_matching closure take a
 PlaceElem instead of a slice

---
 .../dataflow/drop_flag_effects.rs             | 11 ++++++----
 src/librustc_mir/transform/elaborate_drops.rs | 21 ++++++++-----------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs
index 672bbda7502fe..444cc008ae785 100644
--- a/src/librustc_mir/dataflow/drop_flag_effects.rs
+++ b/src/librustc_mir/dataflow/drop_flag_effects.rs
@@ -10,14 +10,17 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
                                         path: MovePathIndex,
                                         mut cond: F)
                                         -> Option<MovePathIndex>
-    where F: FnMut(&[mir::PlaceElem<'tcx>]) -> bool
+    where F: FnMut(&mir::PlaceElem<'tcx>) -> bool
 {
     let mut next_child = move_data.move_paths[path].first_child;
     while let Some(child_index) = next_child {
-        if cond(&move_data.move_paths[child_index].place.projection) {
-            return Some(child_index)
+        let move_path_children = &move_data.move_paths[child_index];
+        if let Some(elem) = move_path_children.place.projection.last() {
+            if cond(elem) {
+                return Some(child_index)
+            }
         }
-        next_child = move_data.move_paths[child_index].next_sibling;
+        next_child = move_path_children.next_sibling;
     }
 
     None
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index 47c7c2c5cb319..de5978c3a3525 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -236,18 +236,18 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
     }
 
     fn field_subpath(&self, path: Self::Path, field: Field) -> Option<Self::Path> {
-        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| match p {
-            [.., ProjectionElem::Field(idx, _)] => *idx == field,
+        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e {
+            ProjectionElem::Field(idx, _) => *idx == field,
             _ => false,
         })
     }
 
     fn array_subpath(&self, path: Self::Path, index: u32, size: u32) -> Option<Self::Path> {
-        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| match p {
-            [.., ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false }] => {
+        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e {
+            ProjectionElem::ConstantIndex { offset, min_length: _, from_end: false } => {
                 *offset == index
             }
-            [.., ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true }] => {
+            ProjectionElem::ConstantIndex { offset, min_length: _, from_end: true } => {
                 size - offset == index
             }
             _ => false,
@@ -255,17 +255,14 @@ impl<'a, 'b, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, 'b, 'tcx> {
     }
 
     fn deref_subpath(&self, path: Self::Path) -> Option<Self::Path> {
-        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| {
-            match p {
-                [.., ProjectionElem::Deref] => true,
-                _ => false
-            }
+        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| {
+            *e == ProjectionElem::Deref
         })
     }
 
     fn downcast_subpath(&self, path: Self::Path, variant: VariantIdx) -> Option<Self::Path> {
-        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |p| match p {
-            [.., ProjectionElem::Downcast(_, idx)] => *idx == variant,
+        dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e {
+            ProjectionElem::Downcast(_, idx) => *idx == variant,
             _ => false
         })
     }

From e73d189e4e2ad55fcea595a14f9adea0960c65a1 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Sat, 24 Aug 2019 20:53:20 -0400
Subject: [PATCH 654/943] Use slice patterns to match projection base

---
 src/librustc/mir/visit.rs                     |  5 +-
 src/librustc_codegen_ssa/mir/analyze.rs       |  5 +-
 src/librustc_codegen_ssa/mir/place.rs         |  8 +-
 .../borrow_check/error_reporting.rs           | 10 +-
 src/librustc_mir/borrow_check/mod.rs          |  4 +-
 src/librustc_mir/borrow_check/move_errors.rs  |  7 +-
 .../borrow_check/mutability_errors.rs         |  8 +-
 src/librustc_mir/borrow_check/prefixes.rs     |  4 +-
 .../dataflow/move_paths/builder.rs            |  3 +-
 src/librustc_mir/transform/instcombine.rs     | 17 +---
 src/librustc_mir/transform/qualify_consts.rs  | 99 +++++++++----------
 .../transform/uniform_array_move_out.rs       | 15 +--
 12 files changed, 67 insertions(+), 118 deletions(-)

diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 36aa891aaf4aa..9f3df7cc58f60 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -720,12 +720,9 @@ macro_rules! make_mir_visitor {
                                 projection: & $($mutability)? [PlaceElem<'tcx>],
                                 context: PlaceContext,
                                 location: Location) {
-                if !projection.is_empty() {
-                    let proj_len = projection.len();
-                    let proj_base = & $($mutability)? projection[..proj_len - 1];
+                if let [proj_base @ .., elem] = projection {
                     self.visit_projection(base, proj_base, context, location);
 
-                    let elem = & $($mutability)? projection[proj_len - 1];
                     match elem {
                         ProjectionElem::Field(_field, ty) => {
                             self.visit_ty(ty, TyContext::Location(location));
diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs
index 5449dbdc913b8..d192f2ffb6fba 100644
--- a/src/librustc_codegen_ssa/mir/analyze.rs
+++ b/src/librustc_codegen_ssa/mir/analyze.rs
@@ -105,10 +105,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
     ) {
         let cx = self.fx.cx;
 
-        if let [.., elem] = place_ref.projection {
-            // FIXME(spastorino) include this in the pattern when stabilized
-            let proj_base = &place_ref.projection[..place_ref.projection.len() - 1];
-
+        if let [proj_base @ .., elem] = place_ref.projection {
             // Allow uses of projections that are ZSTs or from scalar fields.
             let is_consume = match context {
                 PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index df90da7ee8fae..ef9fc36b0f173 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -514,10 +514,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             },
             mir::PlaceRef {
                 base,
-                projection: [.., mir::ProjectionElem::Deref],
+                projection: [proj_base @ .., mir::ProjectionElem::Deref],
             } => {
-                let proj_base = &place_ref.projection[..place_ref.projection.len() - 1];
-
                 // Load the pointer from its location.
                 self.codegen_consume(bx, &mir::PlaceRef {
                     base,
@@ -526,10 +524,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }
             mir::PlaceRef {
                 base,
-                projection: [.., elem],
+                projection: [proj_base @ .., elem],
             } => {
-                let proj_base = &place_ref.projection[..place_ref.projection.len() - 1];
-
                 // FIXME turn this recursion into iteration
                 let cg_base = self.codegen_place(bx, &mir::PlaceRef {
                     base,
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 1fbedc49ecf3f..aeee961d2d354 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -179,10 +179,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             }
             PlaceRef {
                 base,
-                projection: [.., elem],
+                projection: [proj_base @ .., elem],
             } => {
-                let proj_base = &place.projection[..place.projection.len() - 1];
-
                 match elem {
                     ProjectionElem::Deref => {
                         let upvar_field_projection =
@@ -363,11 +361,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 self.describe_field_from_ty(&static_.ty, field, None),
             PlaceRef {
                 base,
-                projection: [.., elem],
+                projection: [proj_base @ .., elem],
             } => match elem {
                 ProjectionElem::Deref => {
-                    let proj_base = &place.projection[..place.projection.len() - 1];
-
                     self.describe_field(PlaceRef {
                         base,
                         projection: proj_base,
@@ -384,8 +380,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 ProjectionElem::Index(..)
                 | ProjectionElem::ConstantIndex { .. }
                 | ProjectionElem::Subslice { .. } => {
-                    let proj_base = &place.projection[..place.projection.len() - 1];
-
                     self.describe_field(PlaceRef {
                         base,
                         projection: proj_base,
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 041047bf7cdc8..2305984a017d0 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -2187,10 +2187,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             }
             PlaceRef {
                 base: _,
-                projection: [.., elem],
+                projection: [proj_base @ .., elem],
             } => {
-                let proj_base = &place.projection[..place.projection.len() - 1];
-
                 match elem {
                     ProjectionElem::Deref => {
                         let base_ty =
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index d346a4cdfa21a..cdba1aafdacb0 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -305,11 +305,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         let upvar_field = self.prefixes(move_place.as_ref(), PrefixSet::All)
             .find_map(|p| self.is_upvar_field_projection(p));
 
-        let deref_base = match deref_target_place.projection {
-            box [.., ProjectionElem::Deref] => {
-                let proj_base =
-                    &deref_target_place.projection[..deref_target_place.projection.len() - 1];
-
+        let deref_base = match &deref_target_place.projection {
+            box [proj_base @ .., ProjectionElem::Deref] => {
                 PlaceRef {
                     base: &deref_target_place.base,
                     projection: proj_base,
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index dbc1d1700933f..12dc2cd1f91c3 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -65,10 +65,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
             PlaceRef {
                 base: _,
-                projection: [.., ProjectionElem::Field(upvar_index, _)],
+                projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)],
             } => {
-                let proj_base = &the_place_err.projection[..the_place_err.projection.len() - 1];
-
                 debug_assert!(is_closure_or_generator(
                     Place::ty_from(&the_place_err.base, proj_base, self.body, self.infcx.tcx).ty
                 ));
@@ -329,10 +327,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             // Also suggest adding mut for upvars
             PlaceRef {
                 base,
-                projection: [.., ProjectionElem::Field(upvar_index, _)],
+                projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)],
             } => {
-                let proj_base = &the_place_err.projection[..the_place_err.projection.len() - 1];
-
                 debug_assert!(is_closure_or_generator(
                     Place::ty_from(base, proj_base, self.body, self.infcx.tcx).ty
                 ));
diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs
index 6adc693527f01..819678dfaf255 100644
--- a/src/librustc_mir/borrow_check/prefixes.rs
+++ b/src/librustc_mir/borrow_check/prefixes.rs
@@ -88,10 +88,8 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
                 }
                 PlaceRef {
                     base: _,
-                    projection: [.., elem],
+                    projection: [proj_base @ .., elem],
                 } => {
-                    let proj_base = &cursor.projection[..cursor.projection.len() - 1];
-
                     match elem {
                         ProjectionElem::Field(_ /*field*/, _ /*ty*/) => {
                             // FIXME: add union handling
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 1d99470d08b0c..a4427287c4f80 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -436,8 +436,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
 
         // Check if we are assigning into a field of a union, if so, lookup the place
         // of the union so it is marked as initialized again.
-        if let [.., ProjectionElem::Field(_, _)] = place.projection {
-            let proj_base = &place.projection[..place.projection.len() - 1];
+        if let [proj_base @ .., ProjectionElem::Field(_, _)] = place.projection {
             if let ty::Adt(def, _) =
                 Place::ty_from(place.base, proj_base, self.builder.body, self.builder.tcx).ty.sty
             {
diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs
index b949e2f5ddd1d..2b8e66e3dec1b 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/src/librustc_mir/transform/instcombine.rs
@@ -90,20 +90,11 @@ impl OptimizationFinder<'b, 'tcx> {
 impl Visitor<'tcx> for OptimizationFinder<'b, 'tcx> {
     fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
         if let Rvalue::Ref(_, _, Place {
-            base: _,
-            projection: box [.., elem],
+            base,
+            projection: box [proj_base @ .., ProjectionElem::Deref],
         }) = rvalue {
-            if *elem == ProjectionElem::Deref {
-                // FIXME remove this once we can use slices patterns
-                if let Rvalue::Ref(_, _, Place {
-                    base,
-                    projection,
-                }) = rvalue {
-                    let proj_base = &projection[..projection.len() - 1];
-                    if Place::ty_from(base, proj_base, self.body, self.tcx).ty.is_region_ptr() {
-                        self.optimizations.and_stars.insert(location);
-                    }
-                }
+            if Place::ty_from(base, proj_base, self.body, self.tcx).ty.is_region_ptr() {
+                self.optimizations.and_stars.insert(location);
             }
         }
 
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 27a46d3450317..e05b0c9662056 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -187,27 +187,28 @@ trait Qualif {
         cx: &ConstCx<'_, 'tcx>,
         place: PlaceRef<'_, 'tcx>,
     ) -> bool {
-        let elem = &place.projection[place.projection.len() - 1];
-        let proj_base = &place.projection[..place.projection.len() - 1];
+        if let [proj_base @ .., elem] = place.projection {
+            let base_qualif = Self::in_place(cx, PlaceRef {
+                base: place.base,
+                projection: proj_base,
+            });
+            let qualif = base_qualif && Self::mask_for_ty(
+                cx,
+                Place::ty_from(place.base, proj_base, cx.body, cx.tcx)
+                    .projection_ty(cx.tcx, elem)
+                    .ty,
+            );
+            match elem {
+                ProjectionElem::Deref |
+                ProjectionElem::Subslice { .. } |
+                ProjectionElem::Field(..) |
+                ProjectionElem::ConstantIndex { .. } |
+                ProjectionElem::Downcast(..) => qualif,
 
-        let base_qualif = Self::in_place(cx, PlaceRef {
-            base: place.base,
-            projection: proj_base,
-        });
-        let qualif = base_qualif && Self::mask_for_ty(
-            cx,
-            Place::ty_from(place.base, proj_base, cx.body, cx.tcx)
-                .projection_ty(cx.tcx, elem)
-                .ty,
-        );
-        match elem {
-            ProjectionElem::Deref |
-            ProjectionElem::Subslice { .. } |
-            ProjectionElem::Field(..) |
-            ProjectionElem::ConstantIndex { .. } |
-            ProjectionElem::Downcast(..) => qualif,
-
-            ProjectionElem::Index(local) => qualif || Self::in_local(cx, *local),
+                ProjectionElem::Index(local) => qualif || Self::in_local(cx, *local),
+            }
+        } else {
+            bug!("This should be called if projection is not empty");
         }
     }
 
@@ -290,10 +291,7 @@ trait Qualif {
 
             Rvalue::Ref(_, _, ref place) => {
                 // Special-case reborrows to be more like a copy of the reference.
-                if !place.projection.is_empty() {
-                    let elem = &place.projection[place.projection.len() - 1];
-                    let proj_base = &place.projection[..place.projection.len() - 1];
-
+                if let box [proj_base @ .., elem] = &place.projection {
                     if ProjectionElem::Deref == *elem {
                         let base_ty = Place::ty_from(&place.base, proj_base, cx.body, cx.tcx).ty;
                         if let ty::Ref(..) = base_ty.sty {
@@ -457,31 +455,32 @@ impl Qualif for IsNotPromotable {
         cx: &ConstCx<'_, 'tcx>,
         place: PlaceRef<'_, 'tcx>,
     ) -> bool {
-        let elem = &place.projection[place.projection.len() - 1];
-        let proj_base = &place.projection[..place.projection.len() - 1];
-
-        match elem {
-            ProjectionElem::Deref |
-            ProjectionElem::Downcast(..) => return true,
-
-            ProjectionElem::ConstantIndex {..} |
-            ProjectionElem::Subslice {..} |
-            ProjectionElem::Index(_) => {}
+        if let [proj_base @ .., elem] = place.projection {
+            match elem {
+                ProjectionElem::Deref |
+                ProjectionElem::Downcast(..) => return true,
 
-            ProjectionElem::Field(..) => {
-                if cx.mode == Mode::NonConstFn {
-                    let base_ty = Place::ty_from(place.base, proj_base, cx.body, cx.tcx).ty;
-                    if let Some(def) = base_ty.ty_adt_def() {
-                        // No promotion of union field accesses.
-                        if def.is_union() {
-                            return true;
+                ProjectionElem::ConstantIndex {..} |
+                ProjectionElem::Subslice {..} |
+                ProjectionElem::Index(_) => {}
+
+                ProjectionElem::Field(..) => {
+                    if cx.mode == Mode::NonConstFn {
+                        let base_ty = Place::ty_from(place.base, proj_base, cx.body, cx.tcx).ty;
+                        if let Some(def) = base_ty.ty_adt_def() {
+                            // No promotion of union field accesses.
+                            if def.is_union() {
+                                return true;
+                            }
                         }
                     }
                 }
             }
-        }
 
-        Self::in_projection_structurally(cx, place)
+            Self::in_projection_structurally(cx, place)
+        } else {
+            bug!("This should be called if projection is not empty");
+        }
     }
 
     fn in_rvalue(cx: &ConstCx<'_, 'tcx>, rvalue: &Rvalue<'tcx>) -> bool {
@@ -866,14 +865,12 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
                 // projections are transparent for assignments
                 // we qualify the entire destination at once, even if just a field would have
                 // stricter qualification
-                (base, proj @ [.., _]) => {
-                    let proj_base = &proj[..proj.len() - 1];
-
+                (base, [proj_base @ .., _]) => {
                     // Catch more errors in the destination. `visit_place` also checks various
                     // projection rules like union field access and raw pointer deref
                     let context = PlaceContext::MutatingUse(MutatingUseContext::Store);
                     self.visit_place_base(base, context, location);
-                    self.visit_projection(base, proj, context, location);
+                    self.visit_projection(base, dest_projection, context, location);
                     dest_projection = proj_base;
                 },
                 (&PlaceBase::Static(box Static {
@@ -1096,10 +1093,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
         );
         self.super_projection(place_base, proj, context, location);
 
-        if !proj.is_empty() {
-            let elem = &proj[proj.len() - 1];
-            let proj_base = &proj[..proj.len() - 1];
-
+        if let [proj_base @ .., elem] = proj {
             match elem {
                 ProjectionElem::Deref => {
                     if context.is_mutating_use() {
@@ -1187,9 +1181,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
         if let Rvalue::Ref(_, kind, ref place) = *rvalue {
             // Special-case reborrows.
             let mut reborrow_place = None;
-            if let box [.., elem] = &place.projection {
+            if let box [proj_base @ .., elem] = &place.projection {
                 if *elem == ProjectionElem::Deref {
-                    let proj_base = &place.projection[..place.projection.len() - 1];
                     let base_ty = Place::ty_from(&place.base, proj_base, self.body, self.tcx).ty;
                     if let ty::Ref(..) = base_ty.sty {
                         reborrow_place = Some(proj_base);
diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs
index 318049a1ce0fe..2f900f2638f48 100644
--- a/src/librustc_mir/transform/uniform_array_move_out.rs
+++ b/src/librustc_mir/transform/uniform_array_move_out.rs
@@ -61,9 +61,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UniformArrayMoveOutVisitor<'a, 'tcx> {
                     rvalue: &Rvalue<'tcx>,
                     location: Location) {
         if let Rvalue::Use(Operand::Move(ref src_place)) = rvalue {
-            if let box [.., elem] = &src_place.projection {
-                let proj_base = &src_place.projection[..src_place.projection.len() - 1];
-
+            if let box [proj_base @ .., elem] = &src_place.projection {
                 if let ProjectionElem::ConstantIndex{offset: _,
                                                      min_length: _,
                                                      from_end: false} = elem {
@@ -102,10 +100,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
                proj: &[PlaceElem<'tcx>],
                item_ty: &'tcx ty::TyS<'tcx>,
                size: u32) {
-        if !proj.is_empty() {
-            let elem = &proj[proj.len() - 1];
-            let proj_base = &proj[..proj.len() - 1];
-
+        if let [proj_base @ .., elem] = proj {
             match elem {
                 // uniforms statements like_10 = move _2[:-1];
                 ProjectionElem::Subslice{from, to} => {
@@ -314,11 +309,9 @@ impl RestoreSubsliceArrayMoveOut {
                         _,
                         box Rvalue::Use(Operand::Move(Place {
                             base,
-                            projection,
+                            projection: box [proj_base @ .., _],
                         })),
-                        ) = &statement.kind {
-                        let proj_base = &projection[..projection.len() - 1];
-
+                    ) = &statement.kind {
                         return Some((*offset, PlaceRef {
                             base,
                             projection: proj_base,

From 7eb42c98389e30aada94885d5d3a77c4c8ff543e Mon Sep 17 00:00:00 2001
From: Taylor Cramer <cramertj@google.com>
Date: Mon, 9 Sep 2019 13:40:11 -0700
Subject: [PATCH 655/943] Always show backtrace on Fuchsia

---
 src/libstd/sys_common/backtrace.rs | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index f434b62aced67..43550ab04ca66 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -117,6 +117,12 @@ where
 // For now logging is turned off by default, and this function checks to see
 // whether the magical environment variable is present to see if it's turned on.
 pub fn log_enabled() -> Option<PrintFmt> {
+    // Setting environment variables for Fuchsia components isn't a standard
+    // or easily supported workflow. For now, always display backtraces.
+    if cfg!(target_os = "fuchsia") {
+        return Some(PrintFmt::Full);
+    }
+
     static ENABLED: atomic::AtomicIsize = atomic::AtomicIsize::new(0);
     match ENABLED.load(Ordering::SeqCst) {
         0 => {}

From bdfab2049ce6bf67cb8557017d148960c534eb61 Mon Sep 17 00:00:00 2001
From: hman523 <shbarbella@gmail.com>
Date: Mon, 9 Sep 2019 18:50:11 -0500
Subject: [PATCH 656/943] Fixed documentation within c_str::from_ptr

---
 src/libstd/ffi/c_str.rs | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 65f4e0cafe09e..29d86e7146edc 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -935,8 +935,10 @@ impl CStr {
     /// Wraps a raw C string with a safe C string wrapper.
     ///
     /// This function will wrap the provided `ptr` with a `CStr` wrapper, which
-    /// allows inspection and interoperation of non-owned C strings. This method
-    /// is unsafe for a number of reasons:
+    /// allows inspection and interoperation of non-owned C strings. The total
+    /// size of the raw C string must be smaller than `isize::MAX` **bytes**
+    /// in memory due to calling the slice::from_raw_parts function.
+    /// This method is unsafe for a number of reasons:
     ///
     /// * There is no guarantee to the validity of `ptr`.
     /// * The returned lifetime is not guaranteed to be the actual lifetime of

From 9b1456e4c5ebae855278ca6f5618915d6c7ad37e Mon Sep 17 00:00:00 2001
From: hman523 <shbarbella@gmail.com>
Date: Mon, 9 Sep 2019 20:09:17 -0500
Subject: [PATCH 657/943] Update added backticks around a function call

Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
---
 src/libstd/ffi/c_str.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 29d86e7146edc..bb346fb4db515 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -937,7 +937,7 @@ impl CStr {
     /// This function will wrap the provided `ptr` with a `CStr` wrapper, which
     /// allows inspection and interoperation of non-owned C strings. The total
     /// size of the raw C string must be smaller than `isize::MAX` **bytes**
-    /// in memory due to calling the slice::from_raw_parts function.
+    /// in memory due to calling the `slice::from_raw_parts` function.
     /// This method is unsafe for a number of reasons:
     ///
     /// * There is no guarantee to the validity of `ptr`.

From 007a58d4ce01f945426f240d387f69dfe3198a6b Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 9 Sep 2019 21:25:49 -0400
Subject: [PATCH 658/943] Switch rustdoc logging to RUSTDOC_LOG

This better aligns with Cargo (CARGO_LOG) and rustc (RUSTC_LOG).
---
 src/librustdoc/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 25ee8b4273d52..2f6f63dcc8dd0 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -90,7 +90,7 @@ pub fn main() {
         32_000_000 // 32MB on other platforms
     };
     rustc_driver::set_sigpipe_handler();
-    env_logger::init();
+    env_logger::init_from_env("RUSTDOC_LOG");
     let res = std::thread::Builder::new().stack_size(thread_stack_size).spawn(move || {
         get_args().map(|args| main_args(&args)).unwrap_or(1)
     }).unwrap().join().unwrap_or(rustc_driver::EXIT_FAILURE);

From 6eb7b698344cfdee6c25d2c6406db33a2ce87aa2 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 9 Sep 2019 21:34:24 -0400
Subject: [PATCH 659/943] Clarify E0507 to note Fn/FnMut relationship to
 borrowing

---
 src/librustc_mir/error_codes.rs | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs
index 908dd601df3d0..ba299e9463b8d 100644
--- a/src/librustc_mir/error_codes.rs
+++ b/src/librustc_mir/error_codes.rs
@@ -1646,7 +1646,14 @@ fn print_fancy_ref(fancy_ref: &FancyNum){
 "##,
 
 E0507: r##"
-You tried to move out of a value which was borrowed. Erroneous code example:
+You tried to move out of a value which was borrowed.
+
+This can also happen when using a type implementing `Fn` or `FnMut`, as neither
+allows moving out of them (they usually represent closures which can be called
+more than once). Much of the text following applies equally well to non-`FnOnce`
+closure bodies.
+
+Erroneous code example:
 
 ```compile_fail,E0507
 use std::cell::RefCell;

From 2f6e73cb07edc21b1243b270e3e77faf51fcb4e4 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Mon, 2 Sep 2019 22:09:15 -0500
Subject: [PATCH 660/943] test/c-variadic: Fix patterns on powerpc64

On architectures such as powerpc64 that use extend_integer_width_to in
their C ABI processing, integer parameters shorter than the native
register width will be annotated with the ArgAttribute::SExt or
ArgAttribute::ZExt attribute, and that attribute will be included in the
generated LLVM IR.

In this test, all relevant parameters are `i32`, which will get the
`signext` annotation on the relevant 64-bit architectures. Match both
the annotated and non-annotated case, but enforce that the annotation is
applied consistently.
---
 src/test/codegen/c-variadic.rs | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/src/test/codegen/c-variadic.rs b/src/test/codegen/c-variadic.rs
index bb90a9653f573..2acf95de97ee8 100644
--- a/src/test/codegen/c-variadic.rs
+++ b/src/test/codegen/c-variadic.rs
@@ -1,4 +1,5 @@
 // compile-flags: -C no-prepopulate-passes
+// ignore-tidy-linelength
 
 #![crate_type = "lib"]
 #![feature(c_variadic)]
@@ -14,13 +15,13 @@ extern "C" {
 #[unwind(aborts)] // FIXME(#58794)
 pub unsafe extern "C" fn use_foreign_c_variadic_0() {
     // Ensure that we correctly call foreign C-variadic functions.
-    // CHECK: invoke void (i32, ...) @foreign_c_variadic_0(i32 0)
+    // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM:i32( signext)?]] 0)
     foreign_c_variadic_0(0);
-    // CHECK: invoke void (i32, ...) @foreign_c_variadic_0(i32 0, i32 42)
+    // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42)
     foreign_c_variadic_0(0, 42i32);
-    // CHECK: invoke void (i32, ...) @foreign_c_variadic_0(i32 0, i32 42, i32 1024)
+    // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024)
     foreign_c_variadic_0(0, 42i32, 1024i32);
-    // CHECK: invoke void (i32, ...) @foreign_c_variadic_0(i32 0, i32 42, i32 1024, i32 0)
+    // CHECK: invoke void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024, [[PARAM]] 0)
     foreign_c_variadic_0(0, 42i32, 1024i32, 0i32);
 }
 
@@ -34,18 +35,18 @@ pub unsafe extern "C" fn use_foreign_c_variadic_1_0(ap: VaList) {
 
 #[unwind(aborts)] // FIXME(#58794)
 pub unsafe extern "C" fn use_foreign_c_variadic_1_1(ap: VaList) {
-    // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 42)
+    // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 42)
     foreign_c_variadic_1(ap, 42i32);
 }
 #[unwind(aborts)] // FIXME(#58794)
 pub unsafe extern "C" fn use_foreign_c_variadic_1_2(ap: VaList) {
-    // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 2, i32 42)
+    // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42)
     foreign_c_variadic_1(ap, 2i32, 42i32);
 }
 
 #[unwind(aborts)] // FIXME(#58794)
 pub unsafe extern "C" fn use_foreign_c_variadic_1_3(ap: VaList) {
-    // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, i32 2, i32 42, i32 0)
+    // CHECK: invoke void ({{.*}}*, ...) @foreign_c_variadic_1({{.*}} %ap, [[PARAM]] 2, [[PARAM]] 42, [[PARAM]] 0)
     foreign_c_variadic_1(ap, 2i32, 42i32, 0i32);
 }
 
@@ -64,12 +65,12 @@ pub unsafe extern "C" fn c_variadic(n: i32, mut ap: ...) -> i32 {
 // Ensure that we generate the correct `call` signature when calling a Rust
 // defined C-variadic.
 pub unsafe fn test_c_variadic_call() {
-    // CHECK: call i32 (i32, ...) @c_variadic(i32 0)
+    // CHECK: call [[RET:(signext )?i32]] (i32, ...) @c_variadic([[PARAM]] 0)
     c_variadic(0);
-    // CHECK: call i32 (i32, ...) @c_variadic(i32 0, i32 42)
+    // CHECK: call [[RET]] (i32, ...) @c_variadic([[PARAM]] 0, [[PARAM]] 42)
     c_variadic(0, 42i32);
-    // CHECK: call i32 (i32, ...) @c_variadic(i32 0, i32 42, i32 1024)
+    // CHECK: call [[RET]] (i32, ...) @c_variadic([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024)
     c_variadic(0, 42i32, 1024i32);
-    // CHECK: call i32 (i32, ...) @c_variadic(i32 0, i32 42, i32 1024, i32 0)
+    // CHECK: call [[RET]] (i32, ...) @c_variadic([[PARAM]] 0, [[PARAM]] 42, [[PARAM]] 1024, [[PARAM]] 0)
     c_variadic(0, 42i32, 1024i32, 0i32);
 }

From 79263afb3eeb3f02cc7b9b9c328206283d85e30a Mon Sep 17 00:00:00 2001
From: hman523 <shbarbella@gmail.com>
Date: Mon, 9 Sep 2019 21:19:01 -0500
Subject: [PATCH 661/943] Changed instant is earlier to instant is later

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

diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index d59085cd44a6f..dbec4da24f96a 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -216,7 +216,7 @@ impl Instant {
     }
 
     /// Returns the amount of time elapsed from another instant to this one,
-    /// or None if that instant is earlier than this one.
+    /// or None if that instant is later than this one.
     ///
     /// # Examples
     ///

From 21e062da2fa1a476380d64f5479e5049067648cb Mon Sep 17 00:00:00 2001
From: Jiewen Yao <jiewen.yao@intel.com>
Date: Thu, 29 Aug 2019 11:44:37 +0800
Subject: [PATCH 662/943] Add i686-unknown-uefi target

This adds a new rustc target-configuration called 'i686-unknown_uefi'.
This is similar to existing x86_64-unknown_uefi target.

The i686-unknown-uefi target can be used to build Intel Architecture
32bit UEFI application. The ABI defined in UEFI environment (aka IA32)
is similar to cdecl.

We choose i686-unknown-uefi-gnu instead of i686-unknown-uefi to avoid
the intrinsics generated by LLVM. The detail of root-cause and solution
analysis is added as comment in the code.
For x86_64-unknown-uefi, we cannot use -gnu, because the ABI between
MSVC and GNU is totally different, and UEFI chooses ABI similar to MSVC.
For i686-unknown-uefi, the UEFI chooses cdecl ABI, which is same as
MSVC and GNU. According to LLVM code, the only differences between MSVC
and GNU are fmodf(f32), longjmp() and TLS, which have no impact to UEFI.
As such, using i686-unknown-uefi-gnu is the simplest way to pass the build.

Adding the undefined symbols, such as _aulldiv() to rust compiler-builtins
is out of scope. But it may be considered later.

The scope of this patch is limited to support target-configuration.

No standard library support is added in this patch. Such work can be
done in future enhancement.

Cc: Josh Triplett <josh.triplett@intel.com>
Reviewed-by: Josh Triplett <josh.triplett@intel.com>
---
 src/librustc_target/spec/i686_unknown_uefi.rs | 98 +++++++++++++++++++
 src/librustc_target/spec/mod.rs               |  1 +
 2 files changed, 99 insertions(+)
 create mode 100644 src/librustc_target/spec/i686_unknown_uefi.rs

diff --git a/src/librustc_target/spec/i686_unknown_uefi.rs b/src/librustc_target/spec/i686_unknown_uefi.rs
new file mode 100644
index 0000000000000..c60f7b422d18f
--- /dev/null
+++ b/src/librustc_target/spec/i686_unknown_uefi.rs
@@ -0,0 +1,98 @@
+// This defines the ia32 target for UEFI systems as described in the UEFI specification. See the
+// uefi-base module for generic UEFI options. On ia32 systems
+// UEFI systems always run in protected-mode, have the interrupt-controller pre-configured and
+// force a single-CPU execution.
+// The cdecl ABI is used. It differs from the stdcall or fastcall ABI.
+// "i686-unknown-windows" is used to get the minimal subset of windows-specific features.
+
+use crate::spec::{LinkerFlavor, LldFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::uefi_base::opts();
+    base.cpu = "pentium4".to_string();
+    base.max_atomic_width = Some(64);
+
+    // We disable MMX and SSE for now, even though UEFI allows using them. Problem is, you have to
+    // enable these CPU features explicitly before their first use, otherwise their instructions
+    // will trigger an exception. Rust does not inject any code that enables AVX/MMX/SSE
+    // instruction sets, so this must be done by the firmware. However, existing firmware is known
+    // to leave these uninitialized, thus triggering exceptions if we make use of them. Which is
+    // why we avoid them and instead use soft-floats. This is also what GRUB and friends did so
+    // far.
+    // If you initialize FP units yourself, you can override these flags with custom linker
+    // arguments, thus giving you access to full MMX/SSE acceleration.
+    base.features = "-mmx,-sse,+soft-float".to_string();
+
+    // UEFI mirrors the calling-conventions used on windows. In case of i686 this means small
+    // structs will be returned as int. This shouldn't matter much, since the restrictions placed
+    // by the UEFI specifications forbid any ABI to return structures.
+    base.abi_return_struct_as_int = true;
+
+    // Use -GNU here, because of the reason below:
+    // Backgound and Problem:
+    //   If we use i686-unknown-windows, the LLVM IA32 MSVC generates compiler intrinsic
+    //   _alldiv, _aulldiv, _allrem, _aullrem, _allmul, which will cause undefined symbol.
+    //   A real issue is __aulldiv() is refered by __udivdi3() - udivmod_inner!(), from
+    //   https://github.com/rust-lang-nursery/compiler-builtins.
+    //   As result, rust-lld generates link error finally.
+    // Root-cause:
+    //   In rust\src\llvm-project\llvm\lib\Target\X86\X86ISelLowering.cpp,
+    //   we have below code to use MSVC intrinsics. It assumes MSVC target
+    //   will link MSVC library. But that is NOT true in UEFI environment.
+    //   UEFI does not link any MSVC or GCC standard library.
+    //      if (Subtarget.isTargetKnownWindowsMSVC() ||
+    //          Subtarget.isTargetWindowsItanium()) {
+    //        // Setup Windows compiler runtime calls.
+    //        setLibcallName(RTLIB::SDIV_I64, "_alldiv");
+    //        setLibcallName(RTLIB::UDIV_I64, "_aulldiv");
+    //        setLibcallName(RTLIB::SREM_I64, "_allrem");
+    //        setLibcallName(RTLIB::UREM_I64, "_aullrem");
+    //        setLibcallName(RTLIB::MUL_I64, "_allmul");
+    //        setLibcallCallingConv(RTLIB::SDIV_I64, CallingConv::X86_StdCall);
+    //        setLibcallCallingConv(RTLIB::UDIV_I64, CallingConv::X86_StdCall);
+    //        setLibcallCallingConv(RTLIB::SREM_I64, CallingConv::X86_StdCall);
+    //        setLibcallCallingConv(RTLIB::UREM_I64, CallingConv::X86_StdCall);
+    //        setLibcallCallingConv(RTLIB::MUL_I64, CallingConv::X86_StdCall);
+    //      }
+    //   The compiler intrisics should be implemented by compiler-builtins.
+    //   Unfortunately, compiler-builtins has not provided those intrinsics yet. Such as:
+    //      i386/divdi3.S
+    //      i386/lshrdi3.S
+    //      i386/moddi3.S
+    //      i386/muldi3.S
+    //      i386/udivdi3.S
+    //      i386/umoddi3.S
+    // Possible solution:
+    //   1. Eliminate Intrinsics generation.
+    //      1.1 Choose differnt target to bypass isTargetKnownWindowsMSVC().
+    //      1.2 Remove the "Setup Windows compiler runtime calls" in LLVM
+    //   2. Implement Intrinsics.
+    //   We evaluated all options.
+    //   #2 is hard because we need implement the intrinsics (_aulldiv) generated
+    //   from the other intrinscis (__udivdi3) implementation with the same
+    //   functionality (udivmod_inner). If we let _aulldiv() call udivmod_inner!(),
+    //   then we are in loop. We may have to find another way to implement udivmod_inner!().
+    //   #1.2 may break the existing usage.
+    //   #1.1 seems the simplest solution today.
+    //   The IA32 -gnu calling convention is same as the one defined in UEFI specification.
+    //   It uses cdecl, EAX/ECX/EDX as volatile register, and EAX/EDX as return value.
+    //   We also checked the LLVM X86TargetLowering, the differences between -gnu and -msvc
+    //   is fmodf(f32), longjmp() and TLS. None of them impacts the UEFI code.
+    // As a result, we choose -gnu for i686 version before those intrisics are implemented in
+    // compiler-builtins. After compiler-builtins implements all required intrinsics, we may
+    // remove -gnu and use the default one.
+    Ok(Target {
+        llvm_target: "i686-unknown-windows-gnu".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32".to_string(),
+        target_os: "uefi".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
+        arch: "x86".to_string(),
+        linker_flavor: LinkerFlavor::Lld(LldFlavor::Link),
+
+        options: base,
+    })
+}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 503d8a08b6f4f..2d8ae028554a2 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -493,6 +493,7 @@ supported_targets! {
     ("x86_64-fortanix-unknown-sgx", x86_64_fortanix_unknown_sgx),
 
     ("x86_64-unknown-uefi", x86_64_unknown_uefi),
+    ("i686-unknown-uefi", i686_unknown_uefi),
 
     ("nvptx64-nvidia-cuda", nvptx64_nvidia_cuda),
 

From 63fad69a9967a56e33927aa31c50768bc1498588 Mon Sep 17 00:00:00 2001
From: David Wood <david@davidtw.co>
Date: Sun, 8 Sep 2019 21:22:51 +0100
Subject: [PATCH 663/943] lowering: extend temporary lifetimes around await

This commit changes the HIR lowering around `await` so that temporary
lifetimes are extended. Previously, await was lowered as:

```rust
{
    let mut pinned = future;
    loop {
        match ::std::future::poll_with_tls_context(unsafe {
            <::std::pin::Pin>::new_unchecked(&mut pinned)
        }) {
            ::std::task::Poll::Ready(result) => break result,
            ::std::task::Poll::Pending => {}
        }
        yield ();
    }
}
```

With this commit, await is lowered as:

```rust
match future {
    mut pinned => loop {
        match ::std::future::poll_with_tls_context(unsafe {
            <::std::pin::Pin>::new_unchecked(&mut pinned)
        }) {
            ::std::task::Poll::Ready(result) => break result,
            ::std::task::Poll::Pending => {}
        }
        yield ();
    }
}
```

However, this change has the following side-effects:

- All temporaries in future will be considered to live across a
  yield for the purpose of auto-traits.
- Borrowed temporaries in future are likely to be considered to be live
  across the yield for the purpose of the generator transform.

Signed-off-by: David Wood <david@davidtw.co>
---
 src/librustc/hir/lowering/expr.rs             | 35 ++++++++-----------
 .../ui/async-await/async-fn-nonsend.stderr    | 24 ++++++-------
 ...-63832-await-short-temporary-lifetime-1.rs | 19 ++++++++++
 ...ue-63832-await-short-temporary-lifetime.rs | 12 +++++++
 4 files changed, 58 insertions(+), 32 deletions(-)
 create mode 100644 src/test/ui/async-await/issue-63832-await-short-temporary-lifetime-1.rs
 create mode 100644 src/test/ui/async-await/issue-63832-await-short-temporary-lifetime.rs

diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index 0d8986ddec3c7..a46cdabbb518f 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -507,14 +507,13 @@ impl LoweringContext<'_> {
 
     /// Desugar `<expr>.await` into:
     /// ```rust
-    /// {
-    ///     let mut pinned = <expr>;
-    ///     loop {
+    /// match <expr> {
+    ///     mut pinned => loop {
     ///         match ::std::future::poll_with_tls_context(unsafe {
-    ///             ::std::pin::Pin::new_unchecked(&mut pinned)
+    ///             <::std::pin::Pin>::new_unchecked(&mut pinned)
     ///         }) {
     ///             ::std::task::Poll::Ready(result) => break result,
-    ///             ::std::task::Poll::Pending => {},
+    ///             ::std::task::Poll::Pending => {}
     ///         }
     ///         yield ();
     ///     }
@@ -549,21 +548,12 @@ impl LoweringContext<'_> {
             self.allow_gen_future.clone(),
         );
 
-        // let mut pinned = <expr>;
-        let expr = P(self.lower_expr(expr));
         let pinned_ident = Ident::with_dummy_span(sym::pinned);
         let (pinned_pat, pinned_pat_hid) = self.pat_ident_binding_mode(
             span,
             pinned_ident,
             hir::BindingAnnotation::Mutable,
         );
-        let pinned_let = self.stmt_let_pat(
-            ThinVec::new(),
-            span,
-            Some(expr),
-            pinned_pat,
-            hir::LocalSource::AwaitDesugar,
-        );
 
         // ::std::future::poll_with_tls_context(unsafe {
         //     ::std::pin::Pin::new_unchecked(&mut pinned)
@@ -621,7 +611,7 @@ impl LoweringContext<'_> {
             self.arm(hir_vec![pending_pat], empty_block)
         };
 
-        let match_stmt = {
+        let inner_match_stmt = {
             let match_expr = self.expr_match(
                 span,
                 poll_expr,
@@ -643,10 +633,11 @@ impl LoweringContext<'_> {
 
         let loop_block = P(self.block_all(
             span,
-            hir_vec![match_stmt, yield_stmt],
+            hir_vec![inner_match_stmt, yield_stmt],
             None,
         ));
 
+        // loop { .. }
         let loop_expr = P(hir::Expr {
             hir_id: loop_hir_id,
             node: hir::ExprKind::Loop(
@@ -658,10 +649,14 @@ impl LoweringContext<'_> {
             attrs: ThinVec::new(),
         });
 
-        hir::ExprKind::Block(
-            P(self.block_all(span, hir_vec![pinned_let], Some(loop_expr))),
-            None,
-        )
+        // mut pinned => loop { ... }
+        let pinned_arm = self.arm(hir_vec![pinned_pat], loop_expr);
+
+        // match <expr> {
+        //     mut pinned => loop { .. }
+        // }
+        let expr = P(self.lower_expr(expr));
+        hir::ExprKind::Match(expr, hir_vec![pinned_arm], hir::MatchSource::AwaitDesugar)
     }
 
     fn lower_expr_closure(
diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr
index fad90b29c0e6e..d2f92f04f40a7 100644
--- a/src/test/ui/async-await/async-fn-nonsend.stderr
+++ b/src/test/ui/async-await/async-fn-nonsend.stderr
@@ -9,9 +9,9 @@ LL |     assert_send(local_dropped_before_await());
    |
    = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
    = note: required because it appears within the type `impl std::fmt::Debug`
-   = note: required because it appears within the type `{impl std::fmt::Debug, impl std::future::Future, ()}`
-   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, impl std::future::Future, ()}]`
-   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `{impl std::fmt::Debug, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
 
@@ -26,9 +26,9 @@ LL |     assert_send(non_send_temporary_in_match());
    |
    = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
    = note: required because it appears within the type `impl std::fmt::Debug`
-   = note: required because it appears within the type `{fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}`
-   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]`
-   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `{fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
 
@@ -45,9 +45,9 @@ LL |     assert_send(non_sync_with_method_call());
    = note: required because of the requirements on the impl of `std::marker::Send` for `&mut dyn std::fmt::Write`
    = note: required because it appears within the type `std::fmt::Formatter<'_>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>`
-   = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}`
-   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]`
-   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
 
@@ -68,9 +68,9 @@ LL |     assert_send(non_sync_with_method_call());
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::slice::Iter<'_, std::fmt::ArgumentV1<'_>>`
    = note: required because it appears within the type `std::fmt::Formatter<'_>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>`
-   = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}`
-   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]`
-   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>`
+   = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}`
+   = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]`
+   = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, fn() -> impl std::future::Future {fut}, impl std::future::Future, ()}]>`
    = note: required because it appears within the type `impl std::future::Future`
    = note: required because it appears within the type `impl std::future::Future`
 
diff --git a/src/test/ui/async-await/issue-63832-await-short-temporary-lifetime-1.rs b/src/test/ui/async-await/issue-63832-await-short-temporary-lifetime-1.rs
new file mode 100644
index 0000000000000..54059b29f72e2
--- /dev/null
+++ b/src/test/ui/async-await/issue-63832-await-short-temporary-lifetime-1.rs
@@ -0,0 +1,19 @@
+// check-pass
+// edition:2018
+
+struct Test(String);
+
+impl Test {
+    async fn borrow_async(&self) {}
+
+    fn with(&mut self, s: &str) -> &mut Self {
+        self.0 = s.into();
+        self
+    }
+}
+
+async fn test() {
+    Test("".to_string()).with("123").borrow_async().await;
+}
+
+fn main() { }
diff --git a/src/test/ui/async-await/issue-63832-await-short-temporary-lifetime.rs b/src/test/ui/async-await/issue-63832-await-short-temporary-lifetime.rs
new file mode 100644
index 0000000000000..c5ea2b821ad78
--- /dev/null
+++ b/src/test/ui/async-await/issue-63832-await-short-temporary-lifetime.rs
@@ -0,0 +1,12 @@
+// check-pass
+// edition:2018
+
+async fn foo(x: &[Vec<u32>]) -> u32 {
+    0
+}
+
+async fn bar() {
+    foo(&[vec![123]]).await;
+}
+
+fn main() { }

From 1e7faef2204f02d79506559d298f61dc3dcd24b3 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Tue, 10 Sep 2019 13:43:54 +0300
Subject: [PATCH 664/943] rustc_mir: buffer -Zdump-mir output instead of
 pestering the kernel constantly.

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

diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index ac2701971dfd5..c35c9e4da9f48 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -227,12 +227,12 @@ pub(crate) fn create_dump_file(
     pass_name: &str,
     disambiguator: &dyn Display,
     source: MirSource<'tcx>,
-) -> io::Result<fs::File> {
+) -> io::Result<io::BufWriter<fs::File>> {
     let file_path = dump_path(tcx, extension, pass_num, pass_name, disambiguator, source);
     if let Some(parent) = file_path.parent() {
         fs::create_dir_all(parent)?;
     }
-    fs::File::create(&file_path)
+    Ok(io::BufWriter::new(fs::File::create(&file_path)?))
 }
 
 /// Write out a human-readable textual representation for the given MIR.

From 356b4c81a04d1db70621949b25c0cc80d5c94b8e Mon Sep 17 00:00:00 2001
From: Arno Haase <arno.haase@haase-consulting.com>
Date: Tue, 10 Sep 2019 14:03:31 +0200
Subject: [PATCH 665/943] documentation enhancement for 'spin loop hint':
 replace 'CPU' with 'CPU or core'

---
 src/libcore/hint.rs        | 6 +++---
 src/libcore/sync/atomic.rs | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 6439fa0e0c8b8..9a581d90cc205 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -59,12 +59,12 @@ pub unsafe fn unreachable_unchecked() -> ! {
 /// busy-wait spin-loop without yielding control to the system's scheduler.
 ///
 /// Using a busy-wait spin-loop with `spin_loop` is ideally used in situations where a
-/// contended lock is held by another thread executed on a different CPU and where the waiting
+/// contended lock is held by another thread executed on a different CPU or core and where the waiting
 /// times are relatively small. Because entering busy-wait spin-loop does not trigger the system's
 /// scheduler, no overhead for switching threads occurs. However, if the thread holding the
-/// contended lock is running on the same CPU, the spin-loop is likely to occupy an entire CPU slice
+/// contended lock is running on the same CPU or core, the spin-loop is likely to occupy an entire CPU slice
 /// before switching to the thread that holds the lock. If the contending lock is held by a thread
-/// on the same CPU or if the waiting times for acquiring the lock are longer, it is often better to
+/// on the same CPU or thread or if the waiting times for acquiring the lock are longer, it is often better to
 /// use [`std::thread::yield_now`].
 ///
 /// **Note**: On platforms that do not support receiving spin-loop hints this function does not
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 8dfb19fa03296..bdd045f75651e 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -134,12 +134,12 @@ use crate::hint::spin_loop;
 /// busy-wait spin-loop without yielding control to the system's scheduler.
 ///
 /// Using a busy-wait spin-loop with `spin_loop_hint` is ideally used in situations where a
-/// contended lock is held by another thread executed on a different CPU and where the waiting
+/// contended lock is held by another thread executed on a different CPU or core and where the waiting
 /// times are relatively small. Because entering busy-wait spin-loop does not trigger the system's
 /// scheduler, no overhead for switching threads occurs. However, if the thread holding the
-/// contended lock is running on the same CPU, the spin-loop is likely to occupy an entire CPU slice
+/// contended lock is running on the same CPU or core, the spin-loop is likely to occupy an entire CPU slice
 /// before switching to the thread that holds the lock. If the contending lock is held by a thread
-/// on the same CPU or if the waiting times for acquiring the lock are longer, it is often better to
+/// on the same CPU or core or if the waiting times for acquiring the lock are longer, it is often better to
 /// use [`std::thread::yield_now`].
 ///
 /// **Note**: On platforms that do not support receiving spin-loop hints this function does not

From 66e4b3447110bb06930f4a606e5a47c55ca73a8a Mon Sep 17 00:00:00 2001
From: Arno Haase <arno.haase@haase-consulting.com>
Date: Tue, 10 Sep 2019 14:04:52 +0200
Subject: [PATCH 666/943] typo fix

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

diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 9a581d90cc205..861ad6b54201e 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -64,7 +64,7 @@ pub unsafe fn unreachable_unchecked() -> ! {
 /// scheduler, no overhead for switching threads occurs. However, if the thread holding the
 /// contended lock is running on the same CPU or core, the spin-loop is likely to occupy an entire CPU slice
 /// before switching to the thread that holds the lock. If the contending lock is held by a thread
-/// on the same CPU or thread or if the waiting times for acquiring the lock are longer, it is often better to
+/// on the same CPU or core or if the waiting times for acquiring the lock are longer, it is often better to
 /// use [`std::thread::yield_now`].
 ///
 /// **Note**: On platforms that do not support receiving spin-loop hints this function does not

From 7ad44c7c9c7feeca7df5358d7df26cc7cb10cf87 Mon Sep 17 00:00:00 2001
From: Arno Haase <arno.haase@haase-consulting.com>
Date: Tue, 10 Sep 2019 14:18:16 +0200
Subject: [PATCH 667/943] documentation for AtomicPtr CAS operations

---
 src/libcore/sync/atomic.rs | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 8dfb19fa03296..a73111571c2b0 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -979,9 +979,8 @@ impl<T> AtomicPtr<T> {
     /// let some_ptr  = AtomicPtr::new(ptr);
     ///
     /// let other_ptr   = &mut 10;
-    /// let another_ptr = &mut 10;
     ///
-    /// let value = some_ptr.compare_and_swap(other_ptr, another_ptr, Ordering::Relaxed);
+    /// let value = some_ptr.compare_and_swap(ptr, other_ptr, Ordering::Relaxed);
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -1021,9 +1020,8 @@ impl<T> AtomicPtr<T> {
     /// let some_ptr  = AtomicPtr::new(ptr);
     ///
     /// let other_ptr   = &mut 10;
-    /// let another_ptr = &mut 10;
     ///
-    /// let value = some_ptr.compare_exchange(other_ptr, another_ptr,
+    /// let value = some_ptr.compare_exchange(ptr, other_ptr,
     ///                                       Ordering::SeqCst, Ordering::Relaxed);
     /// ```
     #[inline]

From 51c49e257322babe0426327102357877a9015f4d Mon Sep 17 00:00:00 2001
From: Arno Haase <arno.haase@haase-consulting.com>
Date: Tue, 10 Sep 2019 14:25:40 +0200
Subject: [PATCH 668/943] fixed linter error

---
 src/libcore/hint.rs        | 14 +++++++-------
 src/libcore/sync/atomic.rs | 14 +++++++-------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 861ad6b54201e..53c576abb7998 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -59,13 +59,13 @@ pub unsafe fn unreachable_unchecked() -> ! {
 /// busy-wait spin-loop without yielding control to the system's scheduler.
 ///
 /// Using a busy-wait spin-loop with `spin_loop` is ideally used in situations where a
-/// contended lock is held by another thread executed on a different CPU or core and where the waiting
-/// times are relatively small. Because entering busy-wait spin-loop does not trigger the system's
-/// scheduler, no overhead for switching threads occurs. However, if the thread holding the
-/// contended lock is running on the same CPU or core, the spin-loop is likely to occupy an entire CPU slice
-/// before switching to the thread that holds the lock. If the contending lock is held by a thread
-/// on the same CPU or core or if the waiting times for acquiring the lock are longer, it is often better to
-/// use [`std::thread::yield_now`].
+/// contended lock is held by another thread executed on a different CPU or core and where the
+/// waiting times are relatively small. Because entering busy-wait spin-loop does not trigger the
+/// system's scheduler, no overhead for switching threads occurs. However, if the thread holding the
+/// contended lock is running on the same CPU or core, the spin-loop is likely to occupy an entire
+/// CPU slice before switching to the thread that holds the lock. If the contending lock is held by
+/// a thread on the same CPU or core or if the waiting times for acquiring the lock are longer, it
+/// is often better to use [`std::thread::yield_now`].
 ///
 /// **Note**: On platforms that do not support receiving spin-loop hints this function does not
 /// do anything at all.
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index bdd045f75651e..38339996090b1 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -134,13 +134,13 @@ use crate::hint::spin_loop;
 /// busy-wait spin-loop without yielding control to the system's scheduler.
 ///
 /// Using a busy-wait spin-loop with `spin_loop_hint` is ideally used in situations where a
-/// contended lock is held by another thread executed on a different CPU or core and where the waiting
-/// times are relatively small. Because entering busy-wait spin-loop does not trigger the system's
-/// scheduler, no overhead for switching threads occurs. However, if the thread holding the
-/// contended lock is running on the same CPU or core, the spin-loop is likely to occupy an entire CPU slice
-/// before switching to the thread that holds the lock. If the contending lock is held by a thread
-/// on the same CPU or core or if the waiting times for acquiring the lock are longer, it is often better to
-/// use [`std::thread::yield_now`].
+/// contended lock is held by another thread executed on a different CPU or core and where the
+/// waiting times are relatively small. Because entering busy-wait spin-loop does not trigger the
+/// system's scheduler, no overhead for switching threads occurs. However, if the thread holding the
+/// contended lock is running on the same CPU or core, the spin-loop is likely to occupy an entire
+/// CPU slice before switching to the thread that holds the lock. If the contending lock is held by
+/// a thread on the same CPU or core or if the waiting times for acquiring the lock are longer, it
+/// is often better to use [`std::thread::yield_now`].
 ///
 /// **Note**: On platforms that do not support receiving spin-loop hints this function does not
 /// do anything at all.

From 2e9eba7f380f5fd99df92deaa03e00faa519b1a4 Mon Sep 17 00:00:00 2001
From: Aleksi Juvani <aleksi@aleksijuvani.com>
Date: Tue, 10 Sep 2019 09:53:59 +0300
Subject: [PATCH 669/943] Set environment variables for linker instead of
 sysroot

---
 src/librustc_target/spec/apple_base.rs        | 70 ++++---------------
 src/librustc_target/spec/apple_ios_base.rs    | 61 ++++++++++++----
 src/librustc_target/spec/i686_apple_darwin.rs |  7 +-
 .../spec/x86_64_apple_darwin.rs               |  7 +-
 4 files changed, 64 insertions(+), 81 deletions(-)

diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs
index a8d6290aa433b..e2632fc14148f 100644
--- a/src/librustc_target/spec/apple_base.rs
+++ b/src/librustc_target/spec/apple_base.rs
@@ -1,4 +1,4 @@
-use std::{env, path::Path};
+use std::env;
 
 use crate::spec::{LinkArgs, TargetOptions};
 
@@ -52,62 +52,18 @@ pub fn macos_llvm_target(arch: &str) -> String {
     format!("{}-apple-macosx{}.{}.0", arch, major, minor)
 }
 
-#[cfg(target_os = "macos")]
-pub fn sysroot(sdk: &str) -> Result<Option<String>, String> {
-    // Like Clang, allow the `SDKROOT` environment variable used by Xcode to define the sysroot.
-    if let Some(sdk_root) = env::var("SDKROOT").ok() {
-        let actual_sdk_path = sdk_path(sdk)?;
-        let sdk_root_p = Path::new(&sdk_root);
-        // Ignore `SDKROOT` if it's not a valid path.
-        if !sdk_root_p.is_absolute() || sdk_root_p == Path::new("/") || !sdk_root_p.exists() {
-            return Ok(Some(actual_sdk_path));
+pub fn macos_link_env() -> Vec<(String, String)> {
+    let mut env = Vec::with_capacity(2);
+    // Ignore the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
+    // may occur when we're linking a custom build script while targeting iOS for example.
+    if let Some(sdkroot) = env::var("SDKROOT").ok() {
+        if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform") {
+            env.push(("SDKROOT".to_string(), String::new()))
         }
-        // Ignore `SDKROOT` if it's clearly set for the wrong platform, which may occur when we're
-        // compiling a custom build script while targeting iOS for example.
-        return Ok(Some(match sdk {
-            "iphoneos" if sdk_root.contains("iPhoneSimulator.platform")
-                || sdk_root.contains("MacOSX.platform") => actual_sdk_path,
-            "iphonesimulator" if sdk_root.contains("iPhoneOS.platform")
-                || sdk_root.contains("MacOSX.platform") => actual_sdk_path,
-            "macosx" | "macosx10.15" if sdk_root.contains("iPhoneOS.platform")
-                || sdk_root.contains("iPhoneSimulator.platform") => actual_sdk_path,
-            _ => sdk_root,
-        }))
-    }
-    Ok(None)
-}
-
-// `xcrun` is only available on macOS.
-#[cfg(not(target_os = "macos"))]
-pub fn sysroot(_sdk: &str) -> Result<Option<String>, String> {
-    if let Some(sdk_root) = env::var("SDKROOT").ok() {
-        let sdk_root_p = Path::new(&sdk_root);
-        // Use `SDKROOT` only if it's a valid path.
-        if sdk_root_p.is_absolute() && sdk_root_p != Path::new("/") && sdk_root_p.exists() {
-            return Ok(Some(sdk_root));
-        }
-    }
-    Ok(None)
-}
-
-#[cfg(target_os = "macos")]
-fn sdk_path(sdk_name: &str) -> Result<String, String> {
-    let res = std::process::Command::new("xcrun")
-        .arg("--show-sdk-path")
-        .arg("-sdk")
-        .arg(sdk_name)
-        .output()
-        .and_then(|output| {
-            if output.status.success() {
-                Ok(String::from_utf8(output.stdout).unwrap())
-            } else {
-                let error = String::from_utf8(output.stderr);
-                let error = format!("process exit with error: {}", error.unwrap());
-                Err(std::io::Error::new(std::io::ErrorKind::Other, &error[..]))
-            }
-        });
-    match res {
-        Ok(output) => Ok(output.trim().to_string()),
-        Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
     }
+    // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
+    // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
+    // although this is apparently ignored when using the linker at "/usr/bin/ld".
+    env.push(("IPHONEOS_DEPLOYMENT_TARGET".to_string(), String::new()));
+    env
 }
diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs
index 801736944f4f8..6d3900c0b203f 100644
--- a/src/librustc_target/spec/apple_ios_base.rs
+++ b/src/librustc_target/spec/apple_ios_base.rs
@@ -1,3 +1,7 @@
+use std::env;
+use std::io;
+use std::path::Path;
+use std::process::Command;
 use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions};
 
 use Arch::*;
@@ -26,6 +30,42 @@ impl Arch {
     }
 }
 
+pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> {
+    // Following what clang does
+    // (https://github.com/llvm/llvm-project/blob/
+    // 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678)
+    // to allow the SDK path to be set. (For clang, xcrun sets
+    // SDKROOT; for rustc, the user or build system can set it, or we
+    // can fall back to checking for xcrun on PATH.)
+    if let Some(sdkroot) = env::var("SDKROOT").ok() {
+        let sdkroot_path = Path::new(&sdkroot);
+        if sdkroot_path.is_absolute() && sdkroot_path != Path::new("/") && sdkroot_path.exists() {
+            return Ok(sdkroot);
+        }
+    }
+    let res = Command::new("xcrun")
+                      .arg("--show-sdk-path")
+                      .arg("-sdk")
+                      .arg(sdk_name)
+                      .output()
+                      .and_then(|output| {
+                          if output.status.success() {
+                              Ok(String::from_utf8(output.stdout).unwrap())
+                          } else {
+                              let error = String::from_utf8(output.stderr);
+                              let error = format!("process exit with error: {}",
+                                                  error.unwrap());
+                              Err(io::Error::new(io::ErrorKind::Other,
+                                                 &error[..]))
+                          }
+                      });
+
+    match res {
+        Ok(output) => Ok(output.trim().to_string()),
+        Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e))
+    }
+}
+
 fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> {
     let sdk_name = match arch {
         Armv7 | Armv7s | Arm64 => "iphoneos",
@@ -35,19 +75,16 @@ fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> {
 
     let arch_name = arch.to_string();
 
+    let sdk_root = get_sdk_root(sdk_name)?;
+
     let mut args = LinkArgs::new();
-    args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), arch_name.to_string()]);
-    if let Some(sdk_root) = super::apple_base::sysroot(sdk_name)? {
-        args.insert(
-            LinkerFlavor::Gcc,
-            vec![
-                "-isysroot".to_string(),
-                sdk_root.clone(),
-                "-Wl,-syslibroot".to_string(),
-                sdk_root
-            ],
-        );
-    }
+    args.insert(LinkerFlavor::Gcc,
+                vec!["-arch".to_string(),
+                     arch_name.to_string(),
+                     "-isysroot".to_string(),
+                     sdk_root.clone(),
+                     "-Wl,-syslibroot".to_string(),
+                     sdk_root]);
 
     Ok(args)
 }
diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs
index b08ed56025208..ba44cdccb7c48 100644
--- a/src/librustc_target/spec/i686_apple_darwin.rs
+++ b/src/librustc_target/spec/i686_apple_darwin.rs
@@ -5,12 +5,7 @@ pub fn target() -> TargetResult {
     base.cpu = "yonah".to_string();
     base.max_atomic_width = Some(64);
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
-    if let Some(sysroot) = super::apple_base::sysroot("macosx")? {
-        base.pre_link_args.insert(
-            LinkerFlavor::Gcc,
-            vec!["-isysroot".to_string(), sysroot.clone(), "-Wl,-syslibroot".to_string(), sysroot],
-        );
-    }
+    base.link_env.extend(super::apple_base::macos_link_env());
     base.stack_probes = true;
     base.eliminate_frame_pointer = false;
 
diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs
index f299c27e7e1ef..442c2650bbba1 100644
--- a/src/librustc_target/spec/x86_64_apple_darwin.rs
+++ b/src/librustc_target/spec/x86_64_apple_darwin.rs
@@ -6,12 +6,7 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(128); // core2 support cmpxchg16b
     base.eliminate_frame_pointer = false;
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
-    if let Some(sysroot) = super::apple_base::sysroot("macosx")? {
-        base.pre_link_args.insert(
-            LinkerFlavor::Gcc,
-            vec!["-isysroot".to_string(), sysroot.clone(), "-Wl,-syslibroot".to_string(), sysroot],
-        );
-    }
+    base.link_env.extend(super::apple_base::macos_link_env());
     base.stack_probes = true;
 
     // Clang automatically chooses a more specific target based on

From 740dd4bf056b18e198af5ae242b2eb49b94861d7 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Tue, 10 Sep 2019 15:11:05 +0100
Subject: [PATCH 670/943] Add unexpected type to extern type bug message

---
 src/librustc_lint/types.rs | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 217e10ab24f55..bdb6844920d41 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -624,7 +624,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                     AdtKind::Struct => {
                         if !def.repr.c() && !def.repr.transparent() {
                             return FfiUnsafe {
-                                ty: ty,
+                                ty,
                                 reason: "this struct has unspecified layout",
                                 help: Some("consider adding a `#[repr(C)]` or \
                                             `#[repr(transparent)]` attribute to this struct"),
@@ -633,7 +633,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
                         if def.non_enum_variant().fields.is_empty() {
                             return FfiUnsafe {
-                                ty: ty,
+                                ty,
                                 reason: "this struct has no fields",
                                 help: Some("consider adding a member to this struct"),
                             };
@@ -669,7 +669,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                     AdtKind::Union => {
                         if !def.repr.c() && !def.repr.transparent() {
                             return FfiUnsafe {
-                                ty: ty,
+                                ty,
                                 reason: "this union has unspecified layout",
                                 help: Some("consider adding a `#[repr(C)]` or \
                                             `#[repr(transparent)]` attribute to this union"),
@@ -678,7 +678,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
                         if def.non_enum_variant().fields.is_empty() {
                             return FfiUnsafe {
-                                ty: ty,
+                                ty,
                                 reason: "this union has no fields",
                                 help: Some("consider adding a field to this union"),
                             };
@@ -721,7 +721,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                             // Special-case types like `Option<extern fn()>`.
                             if !is_repr_nullable_ptr(cx, ty, def, substs) {
                                 return FfiUnsafe {
-                                    ty: ty,
+                                    ty,
                                     reason: "enum has no representation hint",
                                     help: Some("consider adding a `#[repr(C)]`, \
                                                 `#[repr(transparent)]`, or integer `#[repr(...)]` \
@@ -750,7 +750,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                                     }
                                     FfiPhantom(..) => {
                                         return FfiUnsafe {
-                                            ty: ty,
+                                            ty,
                                             reason: "this enum contains a PhantomData field",
                                             help: None,
                                         };
@@ -764,13 +764,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             }
 
             ty::Char => FfiUnsafe {
-                ty: ty,
+                ty,
                 reason: "the `char` type has no C equivalent",
                 help: Some("consider using `u32` or `libc::wchar_t` instead"),
             },
 
             ty::Int(ast::IntTy::I128) | ty::Uint(ast::UintTy::U128) => FfiUnsafe {
-                ty: ty,
+                ty,
                 reason: "128-bit integers don't currently have a known stable ABI",
                 help: None,
             },
@@ -779,25 +779,25 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             ty::Bool | ty::Int(..) | ty::Uint(..) | ty::Float(..) | ty::Never => FfiSafe,
 
             ty::Slice(_) => FfiUnsafe {
-                ty: ty,
+                ty,
                 reason: "slices have no C equivalent",
                 help: Some("consider using a raw pointer instead"),
             },
 
             ty::Dynamic(..) => FfiUnsafe {
-                ty: ty,
+                ty,
                 reason: "trait objects have no C equivalent",
                 help: None,
             },
 
             ty::Str => FfiUnsafe {
-                ty: ty,
+                ty,
                 reason: "string slices have no C equivalent",
                 help: Some("consider using `*const u8` and a length instead"),
             },
 
             ty::Tuple(..) => FfiUnsafe {
-                ty: ty,
+                ty,
                 reason: "tuples have unspecified layout",
                 help: Some("consider using a struct instead"),
             },
@@ -811,7 +811,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                 match sig.abi() {
                     Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic | Abi::RustCall => {
                         return FfiUnsafe {
-                            ty: ty,
+                            ty,
                             reason: "this function pointer has Rust-specific calling convention",
                             help: Some("consider using an `extern fn(...) -> ...` \
                                         function pointer instead"),
@@ -855,7 +855,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             ty::UnnormalizedProjection(..) |
             ty::Projection(..) |
             ty::Opaque(..) |
-            ty::FnDef(..) => bug!("Unexpected type in foreign function"),
+            ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
         }
     }
 

From 5318f98c06bc99292ea6241804a03b26eab8d8b5 Mon Sep 17 00:00:00 2001
From: Baoshan Pang <baoshan.pang@windriver.com>
Date: Tue, 10 Sep 2019 09:25:22 -0700
Subject: [PATCH 671/943] remove Copyright notic

---
 src/libstd/sys/vxworks/fast_thread_local.rs       | 2 --
 src/libstd/sys/vxworks/process/process_vxworks.rs | 2 --
 src/libstd/sys/vxworks/thread.rs                  | 2 --
 3 files changed, 6 deletions(-)

diff --git a/src/libstd/sys/vxworks/fast_thread_local.rs b/src/libstd/sys/vxworks/fast_thread_local.rs
index 2e021980778e5..8b55939b8e54a 100644
--- a/src/libstd/sys/vxworks/fast_thread_local.rs
+++ b/src/libstd/sys/vxworks/fast_thread_local.rs
@@ -1,5 +1,3 @@
-// Copyright (c) 2019 Wind River Systems, Inc.
-
 #![cfg(target_thread_local)]
 #![unstable(feature = "thread_local_internals", issue = "0")]
 
diff --git a/src/libstd/sys/vxworks/process/process_vxworks.rs b/src/libstd/sys/vxworks/process/process_vxworks.rs
index 12aa779746866..8780df17a1c7e 100644
--- a/src/libstd/sys/vxworks/process/process_vxworks.rs
+++ b/src/libstd/sys/vxworks/process/process_vxworks.rs
@@ -1,5 +1,3 @@
-// Copyright (c) 2019 Wind River Systems, Inc.
-
 use crate::io::{self, Error, ErrorKind};
 use libc::{self, c_int, c_char};
 use libc::{RTP_ID};
diff --git a/src/libstd/sys/vxworks/thread.rs b/src/libstd/sys/vxworks/thread.rs
index f9305afdeb6d1..e4396b05c0065 100644
--- a/src/libstd/sys/vxworks/thread.rs
+++ b/src/libstd/sys/vxworks/thread.rs
@@ -1,5 +1,3 @@
-// Copyright (c) 2019 Wind River Systems, Inc.
-
 use crate::cmp;
 use crate::ffi::CStr;
 use crate::io;

From df7e496f855331acd0cb9c6133a77197cd6118cf Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Tue, 10 Sep 2019 18:16:35 +0100
Subject: [PATCH 672/943] Forbid opaque types in extern blocks

---
 src/librustc_lint/types.rs                   | 33 ++++++++++++++++++++
 src/test/ui/lint/opaque-ty-ffi-unsafe.rs     | 16 ++++++++++
 src/test/ui/lint/opaque-ty-ffi-unsafe.stderr | 14 +++++++++
 3 files changed, 63 insertions(+)
 create mode 100644 src/test/ui/lint/opaque-ty-ffi-unsafe.rs
 create mode 100644 src/test/ui/lint/opaque-ty-ffi-unsafe.stderr

diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index bdb6844920d41..63fe11f3443e6 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -859,7 +859,40 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         }
     }
 
+    fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
+        use crate::rustc::ty::TypeFoldable;
+
+        struct ProhibitOpaqueTypes<'a, 'tcx> {
+            cx: &'a LateContext<'a, 'tcx>,
+            sp: Span,
+        };
+
+        impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> {
+            fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
+                if let ty::Opaque(..) = ty.sty {
+                    self.cx.span_lint(IMPROPER_CTYPES,
+                        self.sp,
+                        &format!("`extern` block uses type `{}` which is not FFI-safe: \
+                                  opaque types have no C equivalent", ty));
+                    true
+                } else {
+                    ty.super_visit_with(self)
+                }
+            }
+        }
+
+        let mut visitor = ProhibitOpaqueTypes { cx: self.cx, sp };
+        ty.visit_with(&mut visitor)
+    }
+
     fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
+        // We have to check for opaque types before `normalize_erasing_regions`,
+        // which will replace opaque types with their underlying concrete type.
+        if self.check_for_opaque_ty(sp, ty) {
+            // We've already emitted an error due to an opaque type.
+            return;
+        }
+
         // it is only OK to use this function because extern fns cannot have
         // any generic types right now:
         let ty = self.cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs
new file mode 100644
index 0000000000000..907ad068035bc
--- /dev/null
+++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs
@@ -0,0 +1,16 @@
+#![feature(type_alias_impl_trait)]
+
+#![deny(improper_ctypes)]
+
+type A = impl Fn();
+
+pub fn ret_closure() -> A {
+    || {}
+}
+
+extern "C" {
+    pub fn a(_: A);
+    //~^ ERROR `extern` block uses type `A` which is not FFI-safe: opaque types have no C equivalent
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
new file mode 100644
index 0000000000000..6e234aa300b76
--- /dev/null
+++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
@@ -0,0 +1,14 @@
+error: `extern` block uses type `A` which is not FFI-safe: opaque types have no C equivalent
+  --> $DIR/opaque-ty-ffi-unsafe.rs:12:17
+   |
+LL |     pub fn a(_: A);
+   |                 ^
+   |
+note: lint level defined here
+  --> $DIR/opaque-ty-ffi-unsafe.rs:3:9
+   |
+LL | #![deny(improper_ctypes)]
+   |         ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+

From 79368db1ce0b6c14d295593a1c12ab691e74b41c Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Tue, 10 Sep 2019 18:16:47 +0100
Subject: [PATCH 673/943] Surround `PhantomData` in backticks

---
 src/librustc_lint/types.rs          | 2 +-
 src/test/ui/lint/lint-ctypes.rs     | 6 +++---
 src/test/ui/lint/lint-ctypes.stderr | 6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 63fe11f3443e6..1df1ca9cc5e42 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -903,7 +903,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                 self.cx.span_lint(IMPROPER_CTYPES,
                                   sp,
                                   &format!("`extern` block uses type `{}` which is not FFI-safe: \
-                                            composed only of PhantomData", ty));
+                                            composed only of `PhantomData`", ty));
             }
             FfiResult::FfiUnsafe { ty: unsafe_ty, reason, help } => {
                 let msg = format!("`extern` block uses type `{}` which is not FFI-safe: {}",
diff --git a/src/test/ui/lint/lint-ctypes.rs b/src/test/ui/lint/lint-ctypes.rs
index a3d9b6febdbb7..39206cd0418f1 100644
--- a/src/test/ui/lint/lint-ctypes.rs
+++ b/src/test/ui/lint/lint-ctypes.rs
@@ -1,7 +1,7 @@
-#![deny(improper_ctypes)]
 #![feature(rustc_private)]
 
 #![allow(private_in_public)]
+#![deny(improper_ctypes)]
 
 extern crate libc;
 
@@ -55,9 +55,9 @@ extern {
     pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
     pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
     pub fn zero_size(p: ZeroSize); //~ ERROR struct has no fields
-    pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); //~ ERROR composed only of PhantomData
+    pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); //~ ERROR composed only of `PhantomData`
     pub fn zero_size_phantom_toplevel()
-        -> ::std::marker::PhantomData<bool>; //~ ERROR: composed only of PhantomData
+        -> ::std::marker::PhantomData<bool>; //~ ERROR: composed only of `PhantomData`
     pub fn fn_type(p: RustFn); //~ ERROR function pointer has Rust-specific
     pub fn fn_type2(p: fn()); //~ ERROR function pointer has Rust-specific
     pub fn fn_contained(p: RustBadRet); //~ ERROR: uses type `std::boxed::Box<u32>`
diff --git a/src/test/ui/lint/lint-ctypes.stderr b/src/test/ui/lint/lint-ctypes.stderr
index c78463beb6559..0dbfd7be41d68 100644
--- a/src/test/ui/lint/lint-ctypes.stderr
+++ b/src/test/ui/lint/lint-ctypes.stderr
@@ -5,7 +5,7 @@ LL |     pub fn ptr_type1(size: *const Foo);
    |                            ^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/lint-ctypes.rs:1:9
+  --> $DIR/lint-ctypes.rs:4:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
@@ -108,13 +108,13 @@ note: type defined here
 LL | pub struct ZeroSize;
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `ZeroSizeWithPhantomData` which is not FFI-safe: composed only of PhantomData
+error: `extern` block uses type `ZeroSizeWithPhantomData` which is not FFI-safe: composed only of `PhantomData`
   --> $DIR/lint-ctypes.rs:58:33
    |
 LL |     pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `std::marker::PhantomData<bool>` which is not FFI-safe: composed only of PhantomData
+error: `extern` block uses type `std::marker::PhantomData<bool>` which is not FFI-safe: composed only of `PhantomData`
   --> $DIR/lint-ctypes.rs:60:12
    |
 LL |         -> ::std::marker::PhantomData<bool>;

From 02ff4524b582214f8d57da120c7d986612032e9a Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Tue, 10 Sep 2019 12:01:05 -0700
Subject: [PATCH 674/943] Update cargo

---
 src/tools/cargo | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/cargo b/src/tools/cargo
index fe0e5a48b75da..9655d70af8a6d 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit fe0e5a48b75da2b405c8ce1ba2674e174ae11d5d
+Subproject commit 9655d70af8a6dddac238e3afa2fec75088c9226f

From 2fc32b9e727f0ac372348b9de9016c9311a387dc Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 9 Sep 2019 21:01:41 -0400
Subject: [PATCH 675/943] Locate rustc binary similarly to codegen backend
 loading

This ensures that the failure cases for finding the codegen backend and
for finding the rustc binary are essentially the same, and since we
almost always will load the codegen backend, this is essentially meaning
that the rustc change is not a regression.
---
 Cargo.lock                        |   7 ++
 src/bootstrap/builder.rs          |   2 +
 src/bootstrap/config.rs           |   5 +-
 src/bootstrap/install.rs          |   3 +-
 src/librustc_interface/Cargo.toml |   1 +
 src/librustc_interface/build.rs   |   4 +
 src/librustc_interface/util.rs    | 184 ++++++++++++++++++------------
 src/librustdoc/test.rs            |   2 +-
 8 files changed, 129 insertions(+), 79 deletions(-)
 create mode 100644 src/librustc_interface/build.rs

diff --git a/Cargo.lock b/Cargo.lock
index 27ee38146097b..f2eaf470658b3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2137,6 +2137,12 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "once_cell"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6a04cb71e910d0034815600180f62a95bf6e67942d7ab52a166a68c7d7e9cd0"
+
 [[package]]
 name = "open"
 version = "1.2.1"
@@ -3425,6 +3431,7 @@ name = "rustc_interface"
 version = "0.0.0"
 dependencies = [
  "log",
+ "once_cell",
  "rustc",
  "rustc-rayon",
  "rustc_ast_borrowck",
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 4f5de1ecd2b44..b7873fd1d3581 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -1167,6 +1167,8 @@ impl<'a> Builder<'a> {
             cargo.arg("--frozen");
         }
 
+        cargo.env("RUSTC_INSTALL_BINDIR", &self.config.bindir);
+
         self.ci_env.force_coloring_in_ci(&mut cargo);
 
         cargo
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 43d9264eaca92..52b5cd888df9c 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -137,7 +137,7 @@ pub struct Config {
     pub sysconfdir: Option<PathBuf>,
     pub datadir: Option<PathBuf>,
     pub docdir: Option<PathBuf>,
-    pub bindir: Option<PathBuf>,
+    pub bindir: PathBuf,
     pub libdir: Option<PathBuf>,
     pub mandir: Option<PathBuf>,
     pub codegen_tests: bool,
@@ -400,6 +400,7 @@ impl Config {
         config.incremental = flags.incremental;
         config.dry_run = flags.dry_run;
         config.keep_stage = flags.keep_stage;
+        config.bindir = "bin".into(); // default
         if let Some(value) = flags.deny_warnings {
             config.deny_warnings = value;
         }
@@ -482,7 +483,7 @@ impl Config {
             config.sysconfdir = install.sysconfdir.clone().map(PathBuf::from);
             config.datadir = install.datadir.clone().map(PathBuf::from);
             config.docdir = install.docdir.clone().map(PathBuf::from);
-            config.bindir = install.bindir.clone().map(PathBuf::from);
+            set(&mut config.bindir, install.bindir.clone().map(PathBuf::from));
             config.libdir = install.libdir.clone().map(PathBuf::from);
             config.mandir = install.mandir.clone().map(PathBuf::from);
         }
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index 557586709c612..384219c38fd04 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -67,7 +67,6 @@ fn install_sh(
     let sysconfdir_default = PathBuf::from("/etc");
     let datadir_default = PathBuf::from("share");
     let docdir_default = datadir_default.join("doc/rust");
-    let bindir_default = PathBuf::from("bin");
     let libdir_default = PathBuf::from("lib");
     let mandir_default = datadir_default.join("man");
     let prefix = builder.config.prefix.as_ref().map_or(prefix_default, |p| {
@@ -76,7 +75,7 @@ fn install_sh(
     let sysconfdir = builder.config.sysconfdir.as_ref().unwrap_or(&sysconfdir_default);
     let datadir = builder.config.datadir.as_ref().unwrap_or(&datadir_default);
     let docdir = builder.config.docdir.as_ref().unwrap_or(&docdir_default);
-    let bindir = builder.config.bindir.as_ref().unwrap_or(&bindir_default);
+    let bindir = &builder.config.bindir;
     let libdir = builder.config.libdir.as_ref().unwrap_or(&libdir_default);
     let mandir = builder.config.mandir.as_ref().unwrap_or(&mandir_default);
 
diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml
index 16b377d5bccea..f6293107a940e 100644
--- a/src/librustc_interface/Cargo.toml
+++ b/src/librustc_interface/Cargo.toml
@@ -34,3 +34,4 @@ rustc_plugin = { path = "../librustc_plugin", package = "rustc_plugin_impl" }
 rustc_privacy = { path = "../librustc_privacy" }
 rustc_resolve = { path = "../librustc_resolve" }
 tempfile = "3.0.5"
+once_cell = "1"
diff --git a/src/librustc_interface/build.rs b/src/librustc_interface/build.rs
new file mode 100644
index 0000000000000..79a343e0fee0b
--- /dev/null
+++ b/src/librustc_interface/build.rs
@@ -0,0 +1,4 @@
+fn main() {
+    println!("cargo:rerun-if-changed=build.rs");
+    println!("cargo:rerun-if-env-changed=RUSTC_INSTALL_BINDIR");
+}
diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs
index 9eaf7b77716f3..b81f814de0f4a 100644
--- a/src/librustc_interface/util.rs
+++ b/src/librustc_interface/util.rs
@@ -289,20 +289,39 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
     backend
 }
 
-pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
-    // For now we only allow this function to be called once as it'll dlopen a
-    // few things, which seems to work best if we only do that once. In
-    // general this assertion never trips due to the once guard in `get_codegen_backend`,
-    // but there's a few manual calls to this function in this file we protect
-    // against.
-    static LOADED: AtomicBool = AtomicBool::new(false);
-    assert!(!LOADED.fetch_or(true, Ordering::SeqCst),
-            "cannot load the default codegen backend twice");
+// This is used for rustdoc, but it uses similar machinery to codegen backend
+// loading, so we leave the code here. It is potentially useful for other tools
+// that want to invoke the rustc binary while linking to rustc as well.
+pub fn rustc_path<'a>() -> Option<&'a Path> {
+    static RUSTC_PATH: once_cell::sync::OnceCell<Option<PathBuf>> =
+        once_cell::sync::OnceCell::new();
 
+    const BIN_PATH: &str = env!("RUSTC_INSTALL_BINDIR");
+
+    RUSTC_PATH.get_or_init(|| get_rustc_path_inner(BIN_PATH)).as_ref().map(|v| &**v)
+}
+
+fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
+    sysroot_candidates().iter()
+        .filter_map(|sysroot| {
+            let candidate = sysroot.join(bin_path).join(if cfg!(target_os = "windows") {
+                "rustc.exe"
+            } else {
+                "rustc"
+            });
+            if candidate.exists() {
+                Some(candidate)
+            } else {
+                None
+            }
+        })
+        .next()
+}
+
+fn sysroot_candidates() -> Vec<PathBuf> {
     let target = session::config::host_triple();
     let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()];
-    let path = current_dll_path()
-        .and_then(|s| s.canonicalize().ok());
+    let path = current_dll_path().and_then(|s| s.canonicalize().ok());
     if let Some(dll) = path {
         // use `parent` twice to chop off the file name and then also the
         // directory containing the dll which should be either `lib` or `bin`.
@@ -327,69 +346,7 @@ pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend
         }
     }
 
-    let sysroot = sysroot_candidates.iter()
-        .map(|sysroot| {
-            let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
-            sysroot.join(libdir).with_file_name(
-                option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("codegen-backends"))
-        })
-        .filter(|f| {
-            info!("codegen backend candidate: {}", f.display());
-            f.exists()
-        })
-        .next();
-    let sysroot = sysroot.unwrap_or_else(|| {
-        let candidates = sysroot_candidates.iter()
-            .map(|p| p.display().to_string())
-            .collect::<Vec<_>>()
-            .join("\n* ");
-        let err = format!("failed to find a `codegen-backends` folder \
-                           in the sysroot candidates:\n* {}", candidates);
-        early_error(ErrorOutputType::default(), &err);
-    });
-    info!("probing {} for a codegen backend", sysroot.display());
-
-    let d = sysroot.read_dir().unwrap_or_else(|e| {
-        let err = format!("failed to load default codegen backend, couldn't \
-                           read `{}`: {}", sysroot.display(), e);
-        early_error(ErrorOutputType::default(), &err);
-    });
-
-    let mut file: Option<PathBuf> = None;
-
-    let expected_name = format!("rustc_codegen_llvm-{}", backend_name);
-    for entry in d.filter_map(|e| e.ok()) {
-        let path = entry.path();
-        let filename = match path.file_name().and_then(|s| s.to_str()) {
-            Some(s) => s,
-            None => continue,
-        };
-        if !(filename.starts_with(DLL_PREFIX) && filename.ends_with(DLL_SUFFIX)) {
-            continue
-        }
-        let name = &filename[DLL_PREFIX.len() .. filename.len() - DLL_SUFFIX.len()];
-        if name != expected_name {
-            continue
-        }
-        if let Some(ref prev) = file {
-            let err = format!("duplicate codegen backends found\n\
-                               first:  {}\n\
-                               second: {}\n\
-            ", prev.display(), path.display());
-            early_error(ErrorOutputType::default(), &err);
-        }
-        file = Some(path.clone());
-    }
-
-    match file {
-        Some(ref s) => return load_backend_from_dylib(s),
-        None => {
-            let err = format!("failed to load default codegen backend for `{}`, \
-                               no appropriate codegen dylib found in `{}`",
-                              backend_name, sysroot.display());
-            early_error(ErrorOutputType::default(), &err);
-        }
-    }
+    return sysroot_candidates;
 
     #[cfg(unix)]
     fn current_dll_path() -> Option<PathBuf> {
@@ -459,6 +416,85 @@ pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend
     }
 }
 
+pub fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<dyn CodegenBackend> {
+    // For now we only allow this function to be called once as it'll dlopen a
+    // few things, which seems to work best if we only do that once. In
+    // general this assertion never trips due to the once guard in `get_codegen_backend`,
+    // but there's a few manual calls to this function in this file we protect
+    // against.
+    static LOADED: AtomicBool = AtomicBool::new(false);
+    assert!(!LOADED.fetch_or(true, Ordering::SeqCst),
+            "cannot load the default codegen backend twice");
+
+    let target = session::config::host_triple();
+    let sysroot_candidates = sysroot_candidates();
+
+    let sysroot = sysroot_candidates.iter()
+        .map(|sysroot| {
+            let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
+            sysroot.join(libdir).with_file_name(
+                option_env!("CFG_CODEGEN_BACKENDS_DIR").unwrap_or("codegen-backends"))
+        })
+        .filter(|f| {
+            info!("codegen backend candidate: {}", f.display());
+            f.exists()
+        })
+        .next();
+    let sysroot = sysroot.unwrap_or_else(|| {
+        let candidates = sysroot_candidates.iter()
+            .map(|p| p.display().to_string())
+            .collect::<Vec<_>>()
+            .join("\n* ");
+        let err = format!("failed to find a `codegen-backends` folder \
+                           in the sysroot candidates:\n* {}", candidates);
+        early_error(ErrorOutputType::default(), &err);
+    });
+    info!("probing {} for a codegen backend", sysroot.display());
+
+    let d = sysroot.read_dir().unwrap_or_else(|e| {
+        let err = format!("failed to load default codegen backend, couldn't \
+                           read `{}`: {}", sysroot.display(), e);
+        early_error(ErrorOutputType::default(), &err);
+    });
+
+    let mut file: Option<PathBuf> = None;
+
+    let expected_name = format!("rustc_codegen_llvm-{}", backend_name);
+    for entry in d.filter_map(|e| e.ok()) {
+        let path = entry.path();
+        let filename = match path.file_name().and_then(|s| s.to_str()) {
+            Some(s) => s,
+            None => continue,
+        };
+        if !(filename.starts_with(DLL_PREFIX) && filename.ends_with(DLL_SUFFIX)) {
+            continue
+        }
+        let name = &filename[DLL_PREFIX.len() .. filename.len() - DLL_SUFFIX.len()];
+        if name != expected_name {
+            continue
+        }
+        if let Some(ref prev) = file {
+            let err = format!("duplicate codegen backends found\n\
+                               first:  {}\n\
+                               second: {}\n\
+            ", prev.display(), path.display());
+            early_error(ErrorOutputType::default(), &err);
+        }
+        file = Some(path.clone());
+    }
+
+    match file {
+        Some(ref s) => return load_backend_from_dylib(s),
+        None => {
+            let err = format!("failed to load default codegen backend for `{}`, \
+                               no appropriate codegen dylib found in `{}`",
+                              backend_name, sysroot.display());
+            early_error(ErrorOutputType::default(), &err);
+        }
+    }
+
+}
+
 pub(crate) fn compute_crate_disambiguator(session: &Session) -> CrateDisambiguator {
     use std::hash::Hasher;
 
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 6f1eb0394429f..30ed725ad2089 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -248,7 +248,7 @@ fn run_test(
     };
     let output_file = outdir.path().join("rust_out");
 
-    let mut compiler = Command::new(std::env::current_exe().unwrap().with_file_name("rustc"));
+    let mut compiler = Command::new(rustc_interface::util::rustc_path().expect("found rustc"));
     compiler.arg("--crate-type").arg("bin");
     for cfg in &options.cfgs {
         compiler.arg("--cfg").arg(&cfg);

From 093cbd60fc331e9aab63fc4cdd8b8c9a043eaa3e Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Mon, 9 Sep 2019 21:11:27 -0400
Subject: [PATCH 676/943] Add unstable --test-builder to rustdoc

This allows overriding the rustc binary used to build tests; it should
not generally be necessary as we fallback to the sysroot.
---
 src/librustdoc/config.rs | 6 ++++++
 src/librustdoc/lib.rs    | 5 +++++
 src/librustdoc/test.rs   | 5 ++++-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 995a340143f78..19ea781430041 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -86,6 +86,10 @@ pub struct Options {
     /// contains "foo" as a substring
     pub enable_per_target_ignores: bool,
 
+    /// The path to a rustc-like binary to build tests with. If not set, we
+    /// default to loading from $sysroot/bin/rustc.
+    pub test_builder: Option<PathBuf>,
+
     // Options that affect the documentation process
 
     /// The selected default set of passes to use.
@@ -476,6 +480,7 @@ impl Options {
         let generate_search_filter = !matches.opt_present("disable-per-crate-search");
         let persist_doctests = matches.opt_str("persist-doctests").map(PathBuf::from);
         let generate_redirect_pages = matches.opt_present("generate-redirect-pages");
+        let test_builder = matches.opt_str("test-builder").map(PathBuf::from);
         let codegen_options_strs = matches.opt_strs("C");
         let lib_strs = matches.opt_strs("L");
         let extern_strs = matches.opt_strs("extern");
@@ -515,6 +520,7 @@ impl Options {
             runtool,
             runtool_args,
             enable_per_target_ignores,
+            test_builder,
             render_options: RenderOptions {
                 output,
                 external_html,
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 88da1b16686b0..d77e790d4a481 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -373,6 +373,11 @@ fn opts() -> Vec<RustcOptGroup> {
                        "",
                        "One (of possibly many) arguments to pass to the runtool")
         }),
+        unstable("test-builder", |o| {
+            o.optflag("",
+                      "test-builder",
+                      "specified the rustc-like binary to use as the test builder")
+        }),
     ]
 }
 
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 30ed725ad2089..816b7836fb12a 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -248,7 +248,10 @@ fn run_test(
     };
     let output_file = outdir.path().join("rust_out");
 
-    let mut compiler = Command::new(rustc_interface::util::rustc_path().expect("found rustc"));
+    let rustc_binary = options.test_builder.as_ref().map(|v| &**v).unwrap_or_else(|| {
+        rustc_interface::util::rustc_path().expect("found rustc")
+    });
+    let mut compiler = Command::new(&rustc_binary);
     compiler.arg("--crate-type").arg("bin");
     for cfg in &options.cfgs {
         compiler.arg("--cfg").arg(&cfg);

From 9d712177a34d42c9d78aab4a77d1a36692bc7fc1 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Tue, 10 Sep 2019 22:29:31 +0100
Subject: [PATCH 677/943] Refactor "not FFI-safe" diagnostic

---
 src/librustc_lint/types.rs                   |  72 +++++++----
 src/test/ui/issues/issue-14309.rs            |   2 +-
 src/test/ui/issues/issue-14309.stderr        |  25 ++--
 src/test/ui/issues/issue-16250.rs            |   2 +-
 src/test/ui/issues/issue-16250.stderr        |   5 +-
 src/test/ui/lint/lint-ctypes-enum.rs         |  21 ++--
 src/test/ui/lint/lint-ctypes-enum.stderr     |  57 +++++----
 src/test/ui/lint/lint-ctypes.rs              |  11 +-
 src/test/ui/lint/lint-ctypes.stderr          | 125 ++++++++++++-------
 src/test/ui/lint/opaque-ty-ffi-unsafe.rs     |   2 +-
 src/test/ui/lint/opaque-ty-ffi-unsafe.stderr |   5 +-
 src/test/ui/union/union-repr-c.rs            |   2 +-
 src/test/ui/union/union-repr-c.stderr        |   5 +-
 13 files changed, 202 insertions(+), 132 deletions(-)

diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 1df1ca9cc5e42..3b8c06ba154c6 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -859,21 +859,42 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         }
     }
 
+    fn emit_ffi_unsafe_type_lint(
+        &mut self,
+        ty: Ty<'tcx>,
+        sp: Span,
+        note: &str,
+        help: Option<&str>,
+    ) {
+        let mut diag = self.cx.struct_span_lint(
+            IMPROPER_CTYPES,
+            sp,
+            &format!("`extern` block uses type `{}`, which is not FFI-safe", ty),
+        );
+        diag.span_label(sp, "not FFI-safe");
+        if let Some(help) = help {
+            diag.help(help);
+        }
+        diag.note(note);
+        if let ty::Adt(def, _) = ty.sty {
+            if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did) {
+                diag.span_note(sp, "type defined here");
+            }
+        }
+        diag.emit();
+    }
+
     fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool {
         use crate::rustc::ty::TypeFoldable;
 
-        struct ProhibitOpaqueTypes<'a, 'tcx> {
-            cx: &'a LateContext<'a, 'tcx>,
-            sp: Span,
+        struct ProhibitOpaqueTypes<'tcx> {
+            ty: Option<Ty<'tcx>>,
         };
 
-        impl<'a, 'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'a, 'tcx> {
+        impl<'tcx> ty::fold::TypeVisitor<'tcx> for ProhibitOpaqueTypes<'tcx> {
             fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
                 if let ty::Opaque(..) = ty.sty {
-                    self.cx.span_lint(IMPROPER_CTYPES,
-                        self.sp,
-                        &format!("`extern` block uses type `{}` which is not FFI-safe: \
-                                  opaque types have no C equivalent", ty));
+                    self.ty = Some(ty);
                     true
                 } else {
                     ty.super_visit_with(self)
@@ -881,8 +902,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             }
         }
 
-        let mut visitor = ProhibitOpaqueTypes { cx: self.cx, sp };
-        ty.visit_with(&mut visitor)
+        let mut visitor = ProhibitOpaqueTypes { ty: None };
+        ty.visit_with(&mut visitor);
+        if let Some(ty) = visitor.ty {
+            self.emit_ffi_unsafe_type_lint(
+                ty,
+                sp,
+                "opaque types have no C equivalent",
+                None,
+            );
+            true
+        } else {
+            false
+        }
     }
 
     fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
@@ -900,24 +932,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         match self.check_type_for_ffi(&mut FxHashSet::default(), ty) {
             FfiResult::FfiSafe => {}
             FfiResult::FfiPhantom(ty) => {
-                self.cx.span_lint(IMPROPER_CTYPES,
-                                  sp,
-                                  &format!("`extern` block uses type `{}` which is not FFI-safe: \
-                                            composed only of `PhantomData`", ty));
+                self.emit_ffi_unsafe_type_lint(ty, sp, "composed only of `PhantomData`", None);
             }
-            FfiResult::FfiUnsafe { ty: unsafe_ty, reason, help } => {
-                let msg = format!("`extern` block uses type `{}` which is not FFI-safe: {}",
-                                  unsafe_ty, reason);
-                let mut diag = self.cx.struct_span_lint(IMPROPER_CTYPES, sp, &msg);
-                if let Some(s) = help {
-                    diag.help(s);
-                }
-                if let ty::Adt(def, _) = unsafe_ty.sty {
-                    if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did) {
-                        diag.span_note(sp, "type defined here");
-                    }
-                }
-                diag.emit();
+            FfiResult::FfiUnsafe { ty, reason, help } => {
+                self.emit_ffi_unsafe_type_lint(ty, sp, reason, help);
             }
         }
     }
diff --git a/src/test/ui/issues/issue-14309.rs b/src/test/ui/issues/issue-14309.rs
index d0e532a264656..328a4c982b81e 100644
--- a/src/test/ui/issues/issue-14309.rs
+++ b/src/test/ui/issues/issue-14309.rs
@@ -27,7 +27,7 @@ struct D {
 }
 
 extern "C" {
-    fn foo(x: A); //~ ERROR type `A` which is not FFI-safe
+    fn foo(x: A); //~ ERROR type `A`, which is not FFI-safe
     fn bar(x: B); //~ ERROR type `A`
     fn baz(x: C);
     fn qux(x: A2); //~ ERROR type `A`
diff --git a/src/test/ui/issues/issue-14309.stderr b/src/test/ui/issues/issue-14309.stderr
index e0491093a722a..f598e1f9e2f6d 100644
--- a/src/test/ui/issues/issue-14309.stderr
+++ b/src/test/ui/issues/issue-14309.stderr
@@ -1,8 +1,8 @@
-error: `extern` block uses type `A` which is not FFI-safe: this struct has unspecified layout
+error: `extern` block uses type `A`, which is not FFI-safe
   --> $DIR/issue-14309.rs:30:15
    |
 LL |     fn foo(x: A);
-   |               ^
+   |               ^ not FFI-safe
    |
 note: lint level defined here
   --> $DIR/issue-14309.rs:1:9
@@ -10,6 +10,7 @@ note: lint level defined here
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
 note: type defined here
   --> $DIR/issue-14309.rs:4:1
    |
@@ -18,13 +19,14 @@ LL | |     x: i32
 LL | | }
    | |_^
 
-error: `extern` block uses type `A` which is not FFI-safe: this struct has unspecified layout
+error: `extern` block uses type `A`, which is not FFI-safe
   --> $DIR/issue-14309.rs:31:15
    |
 LL |     fn bar(x: B);
-   |               ^
+   |               ^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
 note: type defined here
   --> $DIR/issue-14309.rs:4:1
    |
@@ -33,13 +35,14 @@ LL | |     x: i32
 LL | | }
    | |_^
 
-error: `extern` block uses type `A` which is not FFI-safe: this struct has unspecified layout
+error: `extern` block uses type `A`, which is not FFI-safe
   --> $DIR/issue-14309.rs:33:15
    |
 LL |     fn qux(x: A2);
-   |               ^^
+   |               ^^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
 note: type defined here
   --> $DIR/issue-14309.rs:4:1
    |
@@ -48,13 +51,14 @@ LL | |     x: i32
 LL | | }
    | |_^
 
-error: `extern` block uses type `A` which is not FFI-safe: this struct has unspecified layout
+error: `extern` block uses type `A`, which is not FFI-safe
   --> $DIR/issue-14309.rs:34:16
    |
 LL |     fn quux(x: B2);
-   |                ^^
+   |                ^^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
 note: type defined here
   --> $DIR/issue-14309.rs:4:1
    |
@@ -63,13 +67,14 @@ LL | |     x: i32
 LL | | }
    | |_^
 
-error: `extern` block uses type `A` which is not FFI-safe: this struct has unspecified layout
+error: `extern` block uses type `A`, which is not FFI-safe
   --> $DIR/issue-14309.rs:36:16
    |
 LL |     fn fred(x: D);
-   |                ^
+   |                ^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
 note: type defined here
   --> $DIR/issue-14309.rs:4:1
    |
diff --git a/src/test/ui/issues/issue-16250.rs b/src/test/ui/issues/issue-16250.rs
index bf01627adfc1f..a3c6751ad897c 100644
--- a/src/test/ui/issues/issue-16250.rs
+++ b/src/test/ui/issues/issue-16250.rs
@@ -3,7 +3,7 @@
 pub struct Foo;
 
 extern {
-    pub fn foo(x: (Foo)); //~ ERROR unspecified layout
+    pub fn foo(x: (Foo)); //~ ERROR `extern` block uses type `Foo`
 }
 
 fn main() {
diff --git a/src/test/ui/issues/issue-16250.stderr b/src/test/ui/issues/issue-16250.stderr
index f3686e82b05a4..5686ac3774215 100644
--- a/src/test/ui/issues/issue-16250.stderr
+++ b/src/test/ui/issues/issue-16250.stderr
@@ -1,8 +1,8 @@
-error: `extern` block uses type `Foo` which is not FFI-safe: this struct has unspecified layout
+error: `extern` block uses type `Foo`, which is not FFI-safe
   --> $DIR/issue-16250.rs:6:20
    |
 LL |     pub fn foo(x: (Foo));
-   |                    ^^^
+   |                    ^^^ not FFI-safe
    |
 note: lint level defined here
   --> $DIR/issue-16250.rs:1:9
@@ -11,6 +11,7 @@ LL | #![deny(warnings)]
    |         ^^^^^^^^
    = note: `#[deny(improper_ctypes)]` implied by `#[deny(warnings)]`
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
 note: type defined here
   --> $DIR/issue-16250.rs:3:1
    |
diff --git a/src/test/ui/lint/lint-ctypes-enum.rs b/src/test/ui/lint/lint-ctypes-enum.rs
index e1f4b0b34ebaa..3898e67a07f7e 100644
--- a/src/test/ui/lint/lint-ctypes-enum.rs
+++ b/src/test/ui/lint/lint-ctypes-enum.rs
@@ -36,36 +36,37 @@ struct Rust<T>(T);
 
 extern {
    fn zf(x: Z);
-   fn uf(x: U); //~ ERROR enum has no representation hint
-   fn bf(x: B); //~ ERROR enum has no representation hint
-   fn tf(x: T); //~ ERROR enum has no representation hint
+   fn uf(x: U); //~ ERROR `extern` block uses type `U`
+   fn bf(x: B); //~ ERROR `extern` block uses type `B`
+   fn tf(x: T); //~ ERROR `extern` block uses type `T`
    fn repr_c(x: ReprC);
    fn repr_u8(x: U8);
    fn repr_isize(x: Isize);
    fn option_ref(x: Option<&'static u8>);
    fn option_fn(x: Option<extern "C" fn()>);
    fn nonnull(x: Option<std::ptr::NonNull<u8>>);
-   fn unique(x: Option<std::ptr::Unique<u8>>); //~ ERROR enum has no representation hint
+   fn unique(x: Option<std::ptr::Unique<u8>>);
+   //~^ ERROR `extern` block uses type `std::option::Option<std::ptr::Unique<u8>>`
    fn nonzero_u8(x: Option<num::NonZeroU8>);
    fn nonzero_u16(x: Option<num::NonZeroU16>);
    fn nonzero_u32(x: Option<num::NonZeroU32>);
    fn nonzero_u64(x: Option<num::NonZeroU64>);
    fn nonzero_u128(x: Option<num::NonZeroU128>);
-   //~^ ERROR 128-bit integers don't currently have a known stable ABI
+   //~^ ERROR `extern` block uses type `u128`
    fn nonzero_usize(x: Option<num::NonZeroUsize>);
    fn nonzero_i8(x: Option<num::NonZeroI8>);
    fn nonzero_i16(x: Option<num::NonZeroI16>);
    fn nonzero_i32(x: Option<num::NonZeroI32>);
    fn nonzero_i64(x: Option<num::NonZeroI64>);
    fn nonzero_i128(x: Option<num::NonZeroI128>);
-   //~^ ERROR 128-bit integers don't currently have a known stable ABI
+   //~^ ERROR `extern` block uses type `i128`
    fn nonzero_isize(x: Option<num::NonZeroIsize>);
    fn transparent_struct(x: Option<TransparentStruct<num::NonZeroU8>>);
    fn transparent_enum(x: Option<TransparentEnum<num::NonZeroU8>>);
    fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
-   //~^ ERROR enum has no representation hint
-   fn repr_rust(x: Option<Rust<num::NonZeroU8>>); //~ ERROR enum has no representation hint
-   fn no_result(x: Result<(), num::NonZeroI32>); //~ ERROR enum has no representation hint
+   //~^ ERROR `extern` block uses type
+   fn repr_rust(x: Option<Rust<num::NonZeroU8>>); //~ ERROR `extern` block uses type
+   fn no_result(x: Result<(), num::NonZeroI32>); //~ ERROR `extern` block uses type
 }
 
-pub fn main() { }
+pub fn main() {}
diff --git a/src/test/ui/lint/lint-ctypes-enum.stderr b/src/test/ui/lint/lint-ctypes-enum.stderr
index 20e438606642c..81939e6ee206c 100644
--- a/src/test/ui/lint/lint-ctypes-enum.stderr
+++ b/src/test/ui/lint/lint-ctypes-enum.stderr
@@ -1,8 +1,8 @@
-error: `extern` block uses type `U` which is not FFI-safe: enum has no representation hint
+error: `extern` block uses type `U`, which is not FFI-safe
   --> $DIR/lint-ctypes-enum.rs:39:13
    |
 LL |    fn uf(x: U);
-   |             ^
+   |             ^ not FFI-safe
    |
 note: lint level defined here
   --> $DIR/lint-ctypes-enum.rs:3:9
@@ -10,81 +10,92 @@ note: lint level defined here
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+   = note: enum has no representation hint
 note: type defined here
   --> $DIR/lint-ctypes-enum.rs:9:1
    |
 LL | enum U { A }
    | ^^^^^^^^^^^^
 
-error: `extern` block uses type `B` which is not FFI-safe: enum has no representation hint
+error: `extern` block uses type `B`, which is not FFI-safe
   --> $DIR/lint-ctypes-enum.rs:40:13
    |
 LL |    fn bf(x: B);
-   |             ^
+   |             ^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+   = note: enum has no representation hint
 note: type defined here
   --> $DIR/lint-ctypes-enum.rs:10:1
    |
 LL | enum B { C, D }
    | ^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `T` which is not FFI-safe: enum has no representation hint
+error: `extern` block uses type `T`, which is not FFI-safe
   --> $DIR/lint-ctypes-enum.rs:41:13
    |
 LL |    fn tf(x: T);
-   |             ^
+   |             ^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+   = note: enum has no representation hint
 note: type defined here
   --> $DIR/lint-ctypes-enum.rs:11:1
    |
 LL | enum T { E, F, G }
    | ^^^^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `std::option::Option<std::ptr::Unique<u8>>` which is not FFI-safe: enum has no representation hint
+error: `extern` block uses type `std::option::Option<std::ptr::Unique<u8>>`, which is not FFI-safe
   --> $DIR/lint-ctypes-enum.rs:48:17
    |
 LL |    fn unique(x: Option<std::ptr::Unique<u8>>);
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+   = note: enum has no representation hint
 
-error: `extern` block uses type `u128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
-  --> $DIR/lint-ctypes-enum.rs:53:23
+error: `extern` block uses type `u128`, which is not FFI-safe
+  --> $DIR/lint-ctypes-enum.rs:54:23
    |
 LL |    fn nonzero_u128(x: Option<num::NonZeroU128>);
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
 
-error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
-  --> $DIR/lint-ctypes-enum.rs:60:23
+error: `extern` block uses type `i128`, which is not FFI-safe
+  --> $DIR/lint-ctypes-enum.rs:61:23
    |
 LL |    fn nonzero_i128(x: Option<num::NonZeroI128>);
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
 
-error: `extern` block uses type `std::option::Option<TransparentUnion<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:65:28
+error: `extern` block uses type `std::option::Option<TransparentUnion<std::num::NonZeroU8>>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-enum.rs:66:28
    |
 LL |    fn transparent_union(x: Option<TransparentUnion<num::NonZeroU8>>);
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+   = note: enum has no representation hint
 
-error: `extern` block uses type `std::option::Option<Rust<std::num::NonZeroU8>>` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:67:20
+error: `extern` block uses type `std::option::Option<Rust<std::num::NonZeroU8>>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-enum.rs:68:20
    |
 LL |    fn repr_rust(x: Option<Rust<num::NonZeroU8>>);
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+   = note: enum has no representation hint
 
-error: `extern` block uses type `std::result::Result<(), std::num::NonZeroI32>` which is not FFI-safe: enum has no representation hint
-  --> $DIR/lint-ctypes-enum.rs:68:20
+error: `extern` block uses type `std::result::Result<(), std::num::NonZeroI32>`, which is not FFI-safe
+  --> $DIR/lint-ctypes-enum.rs:69:20
    |
 LL |    fn no_result(x: Result<(), num::NonZeroI32>);
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
+   = note: enum has no representation hint
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/lint/lint-ctypes.rs b/src/test/ui/lint/lint-ctypes.rs
index 39206cd0418f1..e20503a395c89 100644
--- a/src/test/ui/lint/lint-ctypes.rs
+++ b/src/test/ui/lint/lint-ctypes.rs
@@ -54,12 +54,13 @@ extern {
     pub fn trait_type(p: &dyn Clone); //~ ERROR uses type `dyn std::clone::Clone`
     pub fn tuple_type(p: (i32, i32)); //~ ERROR uses type `(i32, i32)`
     pub fn tuple_type2(p: I32Pair); //~ ERROR uses type `(i32, i32)`
-    pub fn zero_size(p: ZeroSize); //~ ERROR struct has no fields
-    pub fn zero_size_phantom(p: ZeroSizeWithPhantomData); //~ ERROR composed only of `PhantomData`
+    pub fn zero_size(p: ZeroSize); //~ ERROR uses type `ZeroSize`
+    pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
+    //~^ ERROR uses type `ZeroSizeWithPhantomData`
     pub fn zero_size_phantom_toplevel()
-        -> ::std::marker::PhantomData<bool>; //~ ERROR: composed only of `PhantomData`
-    pub fn fn_type(p: RustFn); //~ ERROR function pointer has Rust-specific
-    pub fn fn_type2(p: fn()); //~ ERROR function pointer has Rust-specific
+        -> ::std::marker::PhantomData<bool>; //~ ERROR uses type `std::marker::PhantomData<bool>`
+    pub fn fn_type(p: RustFn); //~ ERROR uses type `fn()`
+    pub fn fn_type2(p: fn()); //~ ERROR uses type `fn()`
     pub fn fn_contained(p: RustBadRet); //~ ERROR: uses type `std::boxed::Box<u32>`
     pub fn transparent_i128(p: TransparentI128); //~ ERROR: uses type `i128`
     pub fn transparent_str(p: TransparentStr); //~ ERROR: uses type `str`
diff --git a/src/test/ui/lint/lint-ctypes.stderr b/src/test/ui/lint/lint-ctypes.stderr
index 0dbfd7be41d68..e533a767b317f 100644
--- a/src/test/ui/lint/lint-ctypes.stderr
+++ b/src/test/ui/lint/lint-ctypes.stderr
@@ -1,8 +1,8 @@
-error: `extern` block uses type `Foo` which is not FFI-safe: this struct has unspecified layout
+error: `extern` block uses type `Foo`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:46:28
    |
 LL |     pub fn ptr_type1(size: *const Foo);
-   |                            ^^^^^^^^^^
+   |                            ^^^^^^^^^^ not FFI-safe
    |
 note: lint level defined here
   --> $DIR/lint-ctypes.rs:4:9
@@ -10,161 +10,192 @@ note: lint level defined here
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
 note: type defined here
   --> $DIR/lint-ctypes.rs:24:1
    |
 LL | pub struct Foo;
    | ^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `Foo` which is not FFI-safe: this struct has unspecified layout
+error: `extern` block uses type `Foo`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:47:28
    |
 LL |     pub fn ptr_type2(size: *const Foo);
-   |                            ^^^^^^^^^^
+   |                            ^^^^^^^^^^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
 note: type defined here
   --> $DIR/lint-ctypes.rs:24:1
    |
 LL | pub struct Foo;
    | ^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `[u32]` which is not FFI-safe: slices have no C equivalent
+error: `extern` block uses type `[u32]`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:48:26
    |
 LL |     pub fn slice_type(p: &[u32]);
-   |                          ^^^^^^
+   |                          ^^^^^^ not FFI-safe
    |
    = help: consider using a raw pointer instead
+   = note: slices have no C equivalent
 
-error: `extern` block uses type `str` which is not FFI-safe: string slices have no C equivalent
+error: `extern` block uses type `str`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:49:24
    |
 LL |     pub fn str_type(p: &str);
-   |                        ^^^^
+   |                        ^^^^ not FFI-safe
    |
    = help: consider using `*const u8` and a length instead
+   = note: string slices have no C equivalent
 
-error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: this struct has unspecified layout
+error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:50:24
    |
 LL |     pub fn box_type(p: Box<u32>);
-   |                        ^^^^^^^^
+   |                        ^^^^^^^^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
 
-error: `extern` block uses type `char` which is not FFI-safe: the `char` type has no C equivalent
+error: `extern` block uses type `char`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:51:25
    |
 LL |     pub fn char_type(p: char);
-   |                         ^^^^
+   |                         ^^^^ not FFI-safe
    |
    = help: consider using `u32` or `libc::wchar_t` instead
+   = note: the `char` type has no C equivalent
 
-error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
+error: `extern` block uses type `i128`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:52:25
    |
 LL |     pub fn i128_type(p: i128);
-   |                         ^^^^
+   |                         ^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
 
-error: `extern` block uses type `u128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
+error: `extern` block uses type `u128`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:53:25
    |
 LL |     pub fn u128_type(p: u128);
-   |                         ^^^^
+   |                         ^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
 
-error: `extern` block uses type `dyn std::clone::Clone` which is not FFI-safe: trait objects have no C equivalent
+error: `extern` block uses type `dyn std::clone::Clone`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:54:26
    |
 LL |     pub fn trait_type(p: &dyn Clone);
-   |                          ^^^^^^^^^^
+   |                          ^^^^^^^^^^ not FFI-safe
+   |
+   = note: trait objects have no C equivalent
 
-error: `extern` block uses type `(i32, i32)` which is not FFI-safe: tuples have unspecified layout
+error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:55:26
    |
 LL |     pub fn tuple_type(p: (i32, i32));
-   |                          ^^^^^^^^^^
+   |                          ^^^^^^^^^^ not FFI-safe
    |
    = help: consider using a struct instead
+   = note: tuples have unspecified layout
 
-error: `extern` block uses type `(i32, i32)` which is not FFI-safe: tuples have unspecified layout
+error: `extern` block uses type `(i32, i32)`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:56:27
    |
 LL |     pub fn tuple_type2(p: I32Pair);
-   |                           ^^^^^^^
+   |                           ^^^^^^^ not FFI-safe
    |
    = help: consider using a struct instead
+   = note: tuples have unspecified layout
 
-error: `extern` block uses type `ZeroSize` which is not FFI-safe: this struct has no fields
+error: `extern` block uses type `ZeroSize`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:57:25
    |
 LL |     pub fn zero_size(p: ZeroSize);
-   |                         ^^^^^^^^
+   |                         ^^^^^^^^ not FFI-safe
    |
    = help: consider adding a member to this struct
+   = note: this struct has no fields
 note: type defined here
   --> $DIR/lint-ctypes.rs:20:1
    |
 LL | pub struct ZeroSize;
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `ZeroSizeWithPhantomData` which is not FFI-safe: composed only of `PhantomData`
+error: `extern` block uses type `ZeroSizeWithPhantomData`, which is not FFI-safe
   --> $DIR/lint-ctypes.rs:58:33
    |
 LL |     pub fn zero_size_phantom(p: ZeroSizeWithPhantomData);
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: composed only of `PhantomData`
+note: type defined here
+  --> $DIR/lint-ctypes.rs:43:1
+   |
+LL | pub struct ZeroSizeWithPhantomData(::std::marker::PhantomData<i32>);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: `extern` block uses type `std::marker::PhantomData<bool>` which is not FFI-safe: composed only of `PhantomData`
-  --> $DIR/lint-ctypes.rs:60:12
+error: `extern` block uses type `std::marker::PhantomData<bool>`, which is not FFI-safe
+  --> $DIR/lint-ctypes.rs:61:12
    |
 LL |         -> ::std::marker::PhantomData<bool>;
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: composed only of `PhantomData`
 
-error: `extern` block uses type `fn()` which is not FFI-safe: this function pointer has Rust-specific calling convention
-  --> $DIR/lint-ctypes.rs:61:23
+error: `extern` block uses type `fn()`, which is not FFI-safe
+  --> $DIR/lint-ctypes.rs:62:23
    |
 LL |     pub fn fn_type(p: RustFn);
-   |                       ^^^^^^
+   |                       ^^^^^^ not FFI-safe
    |
    = help: consider using an `extern fn(...) -> ...` function pointer instead
+   = note: this function pointer has Rust-specific calling convention
 
-error: `extern` block uses type `fn()` which is not FFI-safe: this function pointer has Rust-specific calling convention
-  --> $DIR/lint-ctypes.rs:62:24
+error: `extern` block uses type `fn()`, which is not FFI-safe
+  --> $DIR/lint-ctypes.rs:63:24
    |
 LL |     pub fn fn_type2(p: fn());
-   |                        ^^^^
+   |                        ^^^^ not FFI-safe
    |
    = help: consider using an `extern fn(...) -> ...` function pointer instead
+   = note: this function pointer has Rust-specific calling convention
 
-error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: this struct has unspecified layout
-  --> $DIR/lint-ctypes.rs:63:28
+error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
+  --> $DIR/lint-ctypes.rs:64:28
    |
 LL |     pub fn fn_contained(p: RustBadRet);
-   |                            ^^^^^^^^^^
+   |                            ^^^^^^^^^^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
 
-error: `extern` block uses type `i128` which is not FFI-safe: 128-bit integers don't currently have a known stable ABI
-  --> $DIR/lint-ctypes.rs:64:32
+error: `extern` block uses type `i128`, which is not FFI-safe
+  --> $DIR/lint-ctypes.rs:65:32
    |
 LL |     pub fn transparent_i128(p: TransparentI128);
-   |                                ^^^^^^^^^^^^^^^
+   |                                ^^^^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: 128-bit integers don't currently have a known stable ABI
 
-error: `extern` block uses type `str` which is not FFI-safe: string slices have no C equivalent
-  --> $DIR/lint-ctypes.rs:65:31
+error: `extern` block uses type `str`, which is not FFI-safe
+  --> $DIR/lint-ctypes.rs:66:31
    |
 LL |     pub fn transparent_str(p: TransparentStr);
-   |                               ^^^^^^^^^^^^^^
+   |                               ^^^^^^^^^^^^^^ not FFI-safe
    |
    = help: consider using `*const u8` and a length instead
+   = note: string slices have no C equivalent
 
-error: `extern` block uses type `std::boxed::Box<u32>` which is not FFI-safe: this struct has unspecified layout
-  --> $DIR/lint-ctypes.rs:66:30
+error: `extern` block uses type `std::boxed::Box<u32>`, which is not FFI-safe
+  --> $DIR/lint-ctypes.rs:67:30
    |
 LL |     pub fn transparent_fn(p: TransparentBadFn);
-   |                              ^^^^^^^^^^^^^^^^
+   |                              ^^^^^^^^^^^^^^^^ not FFI-safe
    |
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct
+   = note: this struct has unspecified layout
 
 error: aborting due to 20 previous errors
 
diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs
index 907ad068035bc..25d5f8ec68aa0 100644
--- a/src/test/ui/lint/opaque-ty-ffi-unsafe.rs
+++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.rs
@@ -10,7 +10,7 @@ pub fn ret_closure() -> A {
 
 extern "C" {
     pub fn a(_: A);
-    //~^ ERROR `extern` block uses type `A` which is not FFI-safe: opaque types have no C equivalent
+    //~^ ERROR `extern` block uses type `A`, which is not FFI-safe
 }
 
 fn main() {}
diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
index 6e234aa300b76..136d564d1ab3d 100644
--- a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
+++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr
@@ -1,14 +1,15 @@
-error: `extern` block uses type `A` which is not FFI-safe: opaque types have no C equivalent
+error: `extern` block uses type `A`, which is not FFI-safe
   --> $DIR/opaque-ty-ffi-unsafe.rs:12:17
    |
 LL |     pub fn a(_: A);
-   |                 ^
+   |                 ^ not FFI-safe
    |
 note: lint level defined here
   --> $DIR/opaque-ty-ffi-unsafe.rs:3:9
    |
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
+   = note: opaque types have no C equivalent
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/union/union-repr-c.rs b/src/test/ui/union/union-repr-c.rs
index 658452d57f748..1367835e67781 100644
--- a/src/test/ui/union/union-repr-c.rs
+++ b/src/test/ui/union/union-repr-c.rs
@@ -12,7 +12,7 @@ union W {
 
 extern "C" {
     static FOREIGN1: U; // OK
-    static FOREIGN2: W; //~ ERROR union has unspecified layout
+    static FOREIGN2: W; //~ ERROR `extern` block uses type `W`
 }
 
 fn main() {}
diff --git a/src/test/ui/union/union-repr-c.stderr b/src/test/ui/union/union-repr-c.stderr
index c60817a849a3b..c8bc0380dee68 100644
--- a/src/test/ui/union/union-repr-c.stderr
+++ b/src/test/ui/union/union-repr-c.stderr
@@ -1,8 +1,8 @@
-error: `extern` block uses type `W` which is not FFI-safe: this union has unspecified layout
+error: `extern` block uses type `W`, which is not FFI-safe
   --> $DIR/union-repr-c.rs:15:22
    |
 LL |     static FOREIGN2: W;
-   |                      ^
+   |                      ^ not FFI-safe
    |
 note: lint level defined here
   --> $DIR/union-repr-c.rs:2:9
@@ -10,6 +10,7 @@ note: lint level defined here
 LL | #![deny(improper_ctypes)]
    |         ^^^^^^^^^^^^^^^
    = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union
+   = note: this union has unspecified layout
 note: type defined here
   --> $DIR/union-repr-c.rs:9:1
    |

From 14e6947fa4b9a144802869286a937c987d6a3c54 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Tue, 10 Sep 2019 18:46:27 +0100
Subject: [PATCH 678/943] Correct the polymorphic extern fn error for const
 parameters

---
 src/librustc_typeck/check/mod.rs              | 33 +++++++++++++++----
 .../foreign-item-const-parameter.rs           | 10 ++++++
 .../foreign-item-const-parameter.stderr       | 27 +++++++++++++++
 3 files changed, 63 insertions(+), 7 deletions(-)
 create mode 100644 src/test/ui/const-generics/foreign-item-const-parameter.rs
 create mode 100644 src/test/ui/const-generics/foreign-item-const-parameter.stderr

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index d8d01624f1d56..e76ef14f06c87 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1511,20 +1511,39 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
             } else {
                 for item in &m.items {
                     let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id));
-                    if generics.params.len() - generics.own_counts().lifetimes != 0 {
+                    let own_counts = generics.own_counts();
+                    if generics.params.len() - own_counts.lifetimes != 0 {
+                        let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
+                            (_, 0) => ("type", "types", Some("u32")),
+                            // We don't specify an example value, because we can't generate
+                            // a valid value for any type.
+                            (0, _) => ("const", "consts", None),
+                            _ => ("type or const", "types or consts", None),
+                        };
                         let mut err = struct_span_err!(
                             tcx.sess,
                             item.span,
                             E0044,
-                            "foreign items may not have type parameters"
+                            "foreign items may not have {} parameters",
+                            kinds,
+                        );
+                        err.span_label(
+                            item.span,
+                            &format!("can't have {} parameters", kinds),
                         );
-                        err.span_label(item.span, "can't have type parameters");
                         // FIXME: once we start storing spans for type arguments, turn this into a
                         // suggestion.
-                        err.help(
-                            "use specialization instead of type parameters by replacing them \
-                             with concrete types like `u32`",
-                        );
+                        err.help(&format!(
+                            "use specialization instead of {} parameters by replacing \
+                            them with concrete {}{}",
+                            kinds,
+                            kinds_pl,
+                            if let Some(egs) = egs {
+                                format!(" like `{}`", egs)
+                            } else {
+                                "".to_string()
+                            },
+                        ));
                         err.emit();
                     }
 
diff --git a/src/test/ui/const-generics/foreign-item-const-parameter.rs b/src/test/ui/const-generics/foreign-item-const-parameter.rs
new file mode 100644
index 0000000000000..4673c8606c393
--- /dev/null
+++ b/src/test/ui/const-generics/foreign-item-const-parameter.rs
@@ -0,0 +1,10 @@
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+extern "C" {
+    fn foo<const X: usize>(); //~ ERROR foreign items may not have const parameters
+
+    fn bar<T, const X: usize>(_: T); //~ ERROR foreign items may not have type or const parameters
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/foreign-item-const-parameter.stderr b/src/test/ui/const-generics/foreign-item-const-parameter.stderr
new file mode 100644
index 0000000000000..0a74537dfef35
--- /dev/null
+++ b/src/test/ui/const-generics/foreign-item-const-parameter.stderr
@@ -0,0 +1,27 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/foreign-item-const-parameter.rs:1:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0044]: foreign items may not have const parameters
+  --> $DIR/foreign-item-const-parameter.rs:5:5
+   |
+LL |     fn foo<const X: usize>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters
+   |
+   = help: use specialization instead of const parameters by replacing them with concrete consts
+
+error[E0044]: foreign items may not have type or const parameters
+  --> $DIR/foreign-item-const-parameter.rs:7:5
+   |
+LL |     fn bar<T, const X: usize>(_: T);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have type or const parameters
+   |
+   = help: use specialization instead of type or const parameters by replacing them with concrete types or consts
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0044`.

From 5287885481c018eeef3ee815f9ceab4b4106d5a2 Mon Sep 17 00:00:00 2001
From: Baoshan Pang <baoshan.pang@windriver.com>
Date: Tue, 10 Sep 2019 14:58:31 -0700
Subject: [PATCH 679/943] use randSecure and randABytes

---
 src/libstd/sys/vxworks/rand.rs | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/src/libstd/sys/vxworks/rand.rs b/src/libstd/sys/vxworks/rand.rs
index 1ec0cbe4dcf5b..c22880db2bf03 100644
--- a/src/libstd/sys/vxworks/rand.rs
+++ b/src/libstd/sys/vxworks/rand.rs
@@ -14,17 +14,24 @@ pub fn hashmap_random_keys() -> (u64, u64) {
 mod imp {
     use libc;
     use crate::io;
-
-    extern "C" {
-        fn randBytes (randBuf: *mut libc::c_uchar,
-                      numOfBytes: libc::c_int) -> libc::c_int;
-    }
+    use core::sync::atomic::{AtomicBool, Ordering::Relaxed};
 
     pub fn fill_bytes(v: &mut [u8]) {
+        static RNG_INIT: AtomicBool = AtomicBool::new(false);
+        while !RNG_INIT.load(Relaxed) {
+            let ret = unsafe { libc::randSecure() };
+            if ret < 0 {
+                panic!("couldn't generate random bytes: {}", io::Error::last_os_error());
+            } else if ret > 0 {
+                RNG_INIT.store(true, Relaxed);
+                break;
+            }
+            unsafe { libc::usleep(10) };
+        }
         let ret = unsafe {
-            randBytes(v.as_mut_ptr() as *mut libc::c_uchar, v.len() as libc::c_int)
+            libc::randABytes(v.as_mut_ptr() as *mut libc::c_uchar, v.len() as libc::c_int)
         };
-        if ret == -1 {
+        if ret < 0 {
             panic!("couldn't generate random bytes: {}", io::Error::last_os_error());
         }
     }

From ef62e050624fabc57f17dd6744ff29f79b39e8cd Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Tue, 10 Sep 2019 22:35:10 +0100
Subject: [PATCH 680/943] Make wording less confusing

---
 src/librustc_typeck/check/mod.rs              | 30 ++++++++-----------
 .../foreign-item-const-parameter.stderr       |  4 +--
 src/test/ui/error-codes/E0044.rs              |  2 +-
 src/test/ui/error-codes/E0044.stderr          |  2 +-
 src/test/ui/generic/generic-extern.stderr     |  2 +-
 5 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index e76ef14f06c87..02e7d97ccdf7b 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1520,31 +1520,25 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
                             (0, _) => ("const", "consts", None),
                             _ => ("type or const", "types or consts", None),
                         };
-                        let mut err = struct_span_err!(
+                        struct_span_err!(
                             tcx.sess,
                             item.span,
                             E0044,
                             "foreign items may not have {} parameters",
                             kinds,
-                        );
-                        err.span_label(
+                        ).span_label(
                             item.span,
                             &format!("can't have {} parameters", kinds),
-                        );
-                        // FIXME: once we start storing spans for type arguments, turn this into a
-                        // suggestion.
-                        err.help(&format!(
-                            "use specialization instead of {} parameters by replacing \
-                            them with concrete {}{}",
-                            kinds,
-                            kinds_pl,
-                            if let Some(egs) = egs {
-                                format!(" like `{}`", egs)
-                            } else {
-                                "".to_string()
-                            },
-                        ));
-                        err.emit();
+                        ).help(
+                            // FIXME: once we start storing spans for type arguments, turn this
+                            // into a suggestion.
+                            &format!(
+                                "replace the {} parameters with concrete {}{}",
+                                kinds,
+                                kinds_pl,
+                                egs.map(|egs| format!(" like `{}`", egs)).unwrap_or_default(),
+                            ),
+                        ).emit();
                     }
 
                     if let hir::ForeignItemKind::Fn(ref fn_decl, _, _) = item.node {
diff --git a/src/test/ui/const-generics/foreign-item-const-parameter.stderr b/src/test/ui/const-generics/foreign-item-const-parameter.stderr
index 0a74537dfef35..999feed2d3b20 100644
--- a/src/test/ui/const-generics/foreign-item-const-parameter.stderr
+++ b/src/test/ui/const-generics/foreign-item-const-parameter.stderr
@@ -12,7 +12,7 @@ error[E0044]: foreign items may not have const parameters
 LL |     fn foo<const X: usize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ can't have const parameters
    |
-   = help: use specialization instead of const parameters by replacing them with concrete consts
+   = help: replace the const parameters with concrete consts
 
 error[E0044]: foreign items may not have type or const parameters
   --> $DIR/foreign-item-const-parameter.rs:7:5
@@ -20,7 +20,7 @@ error[E0044]: foreign items may not have type or const parameters
 LL |     fn bar<T, const X: usize>(_: T);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't have type or const parameters
    |
-   = help: use specialization instead of type or const parameters by replacing them with concrete types or consts
+   = help: replace the type or const parameters with concrete types or consts
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/error-codes/E0044.rs b/src/test/ui/error-codes/E0044.rs
index a5265e7dc1708..9eee9c31d3c38 100644
--- a/src/test/ui/error-codes/E0044.rs
+++ b/src/test/ui/error-codes/E0044.rs
@@ -1,7 +1,7 @@
 extern {
     fn sqrt<T>(f: T) -> T;
     //~^ ERROR foreign items may not have type parameters [E0044]
-    //~| HELP use specialization instead of type parameters by replacing them with concrete types
+    //~| HELP replace the type parameters with concrete types
     //~| NOTE can't have type parameters
 }
 
diff --git a/src/test/ui/error-codes/E0044.stderr b/src/test/ui/error-codes/E0044.stderr
index 57c21116b2856..e889c167b98d2 100644
--- a/src/test/ui/error-codes/E0044.stderr
+++ b/src/test/ui/error-codes/E0044.stderr
@@ -4,7 +4,7 @@ error[E0044]: foreign items may not have type parameters
 LL |     fn sqrt<T>(f: T) -> T;
    |     ^^^^^^^^^^^^^^^^^^^^^^ can't have type parameters
    |
-   = help: use specialization instead of type parameters by replacing them with concrete types like `u32`
+   = help: replace the type parameters with concrete types like `u32`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/generic/generic-extern.stderr b/src/test/ui/generic/generic-extern.stderr
index e7625abb1c831..c90215b612d4c 100644
--- a/src/test/ui/generic/generic-extern.stderr
+++ b/src/test/ui/generic/generic-extern.stderr
@@ -4,7 +4,7 @@ error[E0044]: foreign items may not have type parameters
 LL |     fn foo<T>();
    |     ^^^^^^^^^^^^ can't have type parameters
    |
-   = help: use specialization instead of type parameters by replacing them with concrete types like `u32`
+   = help: replace the type parameters with concrete types like `u32`
 
 error: aborting due to previous error
 

From 5a57f46cbc4dc1e84553b0c3093912dc3955bfe9 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Thu, 5 Sep 2019 10:36:30 +1000
Subject: [PATCH 681/943] Store `InternedString`s in
 `AssertModuleSource::available_cgus`.

---
 src/librustc_incremental/assert_module_sources.rs | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/librustc_incremental/assert_module_sources.rs b/src/librustc_incremental/assert_module_sources.rs
index 046fdc72270db..e08eeaf85758e 100644
--- a/src/librustc_incremental/assert_module_sources.rs
+++ b/src/librustc_incremental/assert_module_sources.rs
@@ -27,7 +27,7 @@ use rustc::mir::mono::CodegenUnitNameBuilder;
 use rustc::ty::TyCtxt;
 use std::collections::BTreeSet;
 use syntax::ast;
-use syntax::symbol::{Symbol, sym};
+use syntax::symbol::{InternedString, Symbol, sym};
 use rustc::ich::{ATTR_PARTITION_REUSED, ATTR_PARTITION_CODEGENED,
                  ATTR_EXPECTED_CGU_REUSE};
 
@@ -45,8 +45,8 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) {
             .collect_and_partition_mono_items(LOCAL_CRATE)
             .1
             .iter()
-            .map(|cgu| format!("{}", cgu.name()))
-            .collect::<BTreeSet<String>>();
+            .map(|cgu| *cgu.name())
+            .collect::<BTreeSet<InternedString>>();
 
         let ams = AssertModuleSource {
             tcx,
@@ -61,7 +61,7 @@ pub fn assert_module_sources(tcx: TyCtxt<'_>) {
 
 struct AssertModuleSource<'tcx> {
     tcx: TyCtxt<'tcx>,
-    available_cgus: BTreeSet<String>,
+    available_cgus: BTreeSet<InternedString>,
 }
 
 impl AssertModuleSource<'tcx> {
@@ -127,7 +127,7 @@ impl AssertModuleSource<'tcx> {
 
         debug!("mapping '{}' to cgu name '{}'", self.field(attr, MODULE), cgu_name);
 
-        if !self.available_cgus.contains(&cgu_name.as_str()[..]) {
+        if !self.available_cgus.contains(&cgu_name) {
             self.tcx.sess.span_err(attr.span,
                 &format!("no module named `{}` (mangled: {}). \
                           Available modules: {}",
@@ -135,7 +135,7 @@ impl AssertModuleSource<'tcx> {
                     cgu_name,
                     self.available_cgus
                         .iter()
-                        .cloned()
+                        .map(|cgu| cgu.as_str().to_string())
                         .collect::<Vec<_>>()
                         .join(", ")));
         }

From 482d63673cbb2cec971f85653ff5babbf9bce0ce Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Thu, 5 Sep 2019 11:23:45 +1000
Subject: [PATCH 682/943] Use `Symbol` in `Linker`.

---
 src/librustc_codegen_llvm/back/archive.rs |  3 +-
 src/librustc_codegen_ssa/back/archive.rs  |  5 +-
 src/librustc_codegen_ssa/back/command.rs  |  6 ++
 src/librustc_codegen_ssa/back/link.rs     | 24 +++----
 src/librustc_codegen_ssa/back/linker.rs   | 79 ++++++++++++-----------
 5 files changed, 65 insertions(+), 52 deletions(-)

diff --git a/src/librustc_codegen_llvm/back/archive.rs b/src/librustc_codegen_llvm/back/archive.rs
index e3b7cb235c678..68d3f90cd3991 100644
--- a/src/librustc_codegen_llvm/back/archive.rs
+++ b/src/librustc_codegen_llvm/back/archive.rs
@@ -12,6 +12,7 @@ use crate::llvm::{self, ArchiveKind};
 use rustc_codegen_ssa::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION};
 use rustc_codegen_ssa::back::archive::{ArchiveBuilder, find_library};
 use rustc::session::Session;
+use syntax::symbol::Symbol;
 
 struct ArchiveConfig<'a> {
     pub sess: &'a Session,
@@ -109,7 +110,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
 
     /// Adds all of the contents of a native library to this archive. This will
     /// search in the relevant locations for a library named `name`.
-    fn add_native_library(&mut self, name: &str) {
+    fn add_native_library(&mut self, name: Symbol) {
         let location = find_library(name, &self.config.lib_search_paths,
                                     self.config.sess);
         self.add_archive(&location, |_| false).unwrap_or_else(|e| {
diff --git a/src/librustc_codegen_ssa/back/archive.rs b/src/librustc_codegen_ssa/back/archive.rs
index 23d580ef08b2d..8d2120a345a8d 100644
--- a/src/librustc_codegen_ssa/back/archive.rs
+++ b/src/librustc_codegen_ssa/back/archive.rs
@@ -1,9 +1,10 @@
 use rustc::session::Session;
+use syntax::symbol::Symbol;
 
 use std::io;
 use std::path::{Path, PathBuf};
 
-pub fn find_library(name: &str, search_paths: &[PathBuf], sess: &Session)
+pub fn find_library(name: Symbol, search_paths: &[PathBuf], sess: &Session)
                     -> PathBuf {
     // On Windows, static libraries sometimes show up as libfoo.a and other
     // times show up as foo.lib
@@ -40,7 +41,7 @@ pub trait ArchiveBuilder<'a> {
         lto: bool,
         skip_objects: bool,
     ) -> io::Result<()>;
-    fn add_native_library(&mut self, name: &str);
+    fn add_native_library(&mut self, name: Symbol);
     fn update_symbols(&mut self);
 
     fn build(self);
diff --git a/src/librustc_codegen_ssa/back/command.rs b/src/librustc_codegen_ssa/back/command.rs
index 340cc772e5f07..2c2ede5e189be 100644
--- a/src/librustc_codegen_ssa/back/command.rs
+++ b/src/librustc_codegen_ssa/back/command.rs
@@ -8,6 +8,7 @@ use std::mem;
 use std::process::{self, Output};
 
 use rustc_target::spec::LldFlavor;
+use syntax::symbol::Symbol;
 
 #[derive(Clone)]
 pub struct Command {
@@ -49,6 +50,11 @@ impl Command {
         self
     }
 
+    pub fn sym_arg(&mut self, arg: Symbol) -> &mut Command {
+        self.arg(&arg.as_str());
+        self
+    }
+
     pub fn args<I>(&mut self, args: I) -> &mut Command
     where
         I: IntoIterator<Item: AsRef<OsStr>>,
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 8603d61fb5453..c6e0e6a1e80e5 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -13,6 +13,7 @@ use rustc::hir::def_id::CrateNum;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_fs_util::fix_windows_verbatim_for_gcc;
 use rustc_target::spec::{PanicStrategy, RelroLevel, LinkerFlavor};
+use syntax::symbol::Symbol;
 
 use crate::{METADATA_FILENAME, RLIB_BYTECODE_EXTENSION, CrateInfo, CodegenResults};
 use super::archive::ArchiveBuilder;
@@ -316,7 +317,7 @@ fn link_rlib<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
             NativeLibraryKind::NativeUnknown => continue,
         }
         if let Some(name) = lib.name {
-            ab.add_native_library(&name.as_str());
+            ab.add_native_library(name);
         }
     }
 
@@ -1273,15 +1274,14 @@ pub fn add_local_native_libraries(cmd: &mut dyn Linker,
     let search_path = archive_search_paths(sess);
     for lib in relevant_libs {
         let name = match lib.name {
-            Some(ref l) => l,
+            Some(l) => l,
             None => continue,
         };
         match lib.kind {
-            NativeLibraryKind::NativeUnknown => cmd.link_dylib(&name.as_str()),
-            NativeLibraryKind::NativeFramework => cmd.link_framework(&name.as_str()),
-            NativeLibraryKind::NativeStaticNobundle => cmd.link_staticlib(&name.as_str()),
-            NativeLibraryKind::NativeStatic => cmd.link_whole_staticlib(&name.as_str(),
-                                                                        &search_path)
+            NativeLibraryKind::NativeUnknown => cmd.link_dylib(name),
+            NativeLibraryKind::NativeFramework => cmd.link_framework(name),
+            NativeLibraryKind::NativeStaticNobundle => cmd.link_staticlib(name),
+            NativeLibraryKind::NativeStatic => cmd.link_whole_staticlib(name, &search_path)
         }
     }
 }
@@ -1594,7 +1594,7 @@ fn add_upstream_rust_crates<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker,
             cmd.include_path(&fix_windows_verbatim_for_gcc(dir));
         }
         let filestem = cratepath.file_stem().unwrap().to_str().unwrap();
-        cmd.link_rust_dylib(&unlib(&sess.target, filestem),
+        cmd.link_rust_dylib(Symbol::intern(&unlib(&sess.target, filestem)),
                             parent.unwrap_or(Path::new("")));
     }
 }
@@ -1637,22 +1637,22 @@ pub fn add_upstream_native_libraries(cmd: &mut dyn Linker,
     for &(cnum, _) in crates {
         for lib in codegen_results.crate_info.native_libraries[&cnum].iter() {
             let name = match lib.name {
-                Some(ref l) => l,
+                Some(l) => l,
                 None => continue,
             };
             if !relevant_lib(sess, &lib) {
                 continue
             }
             match lib.kind {
-                NativeLibraryKind::NativeUnknown => cmd.link_dylib(&name.as_str()),
-                NativeLibraryKind::NativeFramework => cmd.link_framework(&name.as_str()),
+                NativeLibraryKind::NativeUnknown => cmd.link_dylib(name),
+                NativeLibraryKind::NativeFramework => cmd.link_framework(name),
                 NativeLibraryKind::NativeStaticNobundle => {
                     // Link "static-nobundle" native libs only if the crate they originate from
                     // is being linked statically to the current crate.  If it's linked dynamically
                     // or is an rlib already included via some other dylib crate, the symbols from
                     // native libs will have already been included in that dylib.
                     if data[cnum.as_usize() - 1] == Linkage::Static {
-                        cmd.link_staticlib(&name.as_str())
+                        cmd.link_staticlib(name)
                     }
                 },
                 // ignore statically included native libraries here as we've
diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs
index de481d2262478..c42cd024926dc 100644
--- a/src/librustc_codegen_ssa/back/linker.rs
+++ b/src/librustc_codegen_ssa/back/linker.rs
@@ -17,6 +17,7 @@ use rustc::session::config::{self, CrateType, OptLevel, DebugInfo,
 use rustc::ty::TyCtxt;
 use rustc_target::spec::{LinkerFlavor, LldFlavor};
 use rustc_serialize::{json, Encoder};
+use syntax::symbol::Symbol;
 
 /// For all the linkers we support, and information they might
 /// need out of the shared crate context before we get rid of it.
@@ -99,13 +100,13 @@ impl LinkerInfo {
 /// used to dispatch on whether a GNU-like linker (generally `ld.exe`) or an
 /// MSVC linker (e.g., `link.exe`) is being used.
 pub trait Linker {
-    fn link_dylib(&mut self, lib: &str);
-    fn link_rust_dylib(&mut self, lib: &str, path: &Path);
-    fn link_framework(&mut self, framework: &str);
-    fn link_staticlib(&mut self, lib: &str);
+    fn link_dylib(&mut self, lib: Symbol);
+    fn link_rust_dylib(&mut self, lib: Symbol, path: &Path);
+    fn link_framework(&mut self, framework: Symbol);
+    fn link_staticlib(&mut self, lib: Symbol);
     fn link_rlib(&mut self, lib: &Path);
     fn link_whole_rlib(&mut self, lib: &Path);
-    fn link_whole_staticlib(&mut self, lib: &str, search_path: &[PathBuf]);
+    fn link_whole_staticlib(&mut self, lib: Symbol, search_path: &[PathBuf]);
     fn include_path(&mut self, path: &Path);
     fn framework_path(&mut self, path: &Path);
     fn output_filename(&mut self, path: &Path);
@@ -215,9 +216,13 @@ impl<'a> GccLinker<'a> {
 }
 
 impl<'a> Linker for GccLinker<'a> {
-    fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg(format!("-l{}", lib)); }
-    fn link_staticlib(&mut self, lib: &str) {
-        self.hint_static(); self.cmd.arg(format!("-l{}", lib));
+    fn link_dylib(&mut self, lib: Symbol) {
+        self.hint_dynamic();
+        self.cmd.arg(format!("-l{}", lib));
+    }
+    fn link_staticlib(&mut self, lib: Symbol) {
+        self.hint_static();
+        self.cmd.arg(format!("-l{}", lib));
     }
     fn link_rlib(&mut self, lib: &Path) { self.hint_static(); self.cmd.arg(lib); }
     fn include_path(&mut self, path: &Path) { self.cmd.arg("-L").arg(path); }
@@ -232,14 +237,14 @@ impl<'a> Linker for GccLinker<'a> {
     fn build_static_executable(&mut self) { self.cmd.arg("-static"); }
     fn args(&mut self, args: &[String]) { self.cmd.args(args); }
 
-    fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
+    fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) {
         self.hint_dynamic();
         self.cmd.arg(format!("-l{}", lib));
     }
 
-    fn link_framework(&mut self, framework: &str) {
+    fn link_framework(&mut self, framework: Symbol) {
         self.hint_dynamic();
-        self.cmd.arg("-framework").arg(framework);
+        self.cmd.arg("-framework").sym_arg(framework);
     }
 
     // Here we explicitly ask that the entire archive is included into the
@@ -248,7 +253,7 @@ impl<'a> Linker for GccLinker<'a> {
     // don't otherwise explicitly reference them. This can occur for
     // libraries which are just providing bindings, libraries with generic
     // functions, etc.
-    fn link_whole_staticlib(&mut self, lib: &str, search_path: &[PathBuf]) {
+    fn link_whole_staticlib(&mut self, lib: Symbol, search_path: &[PathBuf]) {
         self.hint_static();
         let target = &self.sess.target.target;
         if !target.options.is_like_osx {
@@ -539,11 +544,11 @@ impl<'a> Linker for MsvcLinker<'a> {
         }
     }
 
-    fn link_dylib(&mut self, lib: &str) {
+    fn link_dylib(&mut self, lib: Symbol) {
         self.cmd.arg(&format!("{}.lib", lib));
     }
 
-    fn link_rust_dylib(&mut self, lib: &str, path: &Path) {
+    fn link_rust_dylib(&mut self, lib: Symbol, path: &Path) {
         // When producing a dll, the MSVC linker may not actually emit a
         // `foo.lib` file if the dll doesn't actually export any symbols, so we
         // check to see if the file is there and just omit linking to it if it's
@@ -554,7 +559,7 @@ impl<'a> Linker for MsvcLinker<'a> {
         }
     }
 
-    fn link_staticlib(&mut self, lib: &str) {
+    fn link_staticlib(&mut self, lib: Symbol) {
         self.cmd.arg(&format!("{}.lib", lib));
     }
 
@@ -605,11 +610,11 @@ impl<'a> Linker for MsvcLinker<'a> {
     fn framework_path(&mut self, _path: &Path) {
         bug!("frameworks are not supported on windows")
     }
-    fn link_framework(&mut self, _framework: &str) {
+    fn link_framework(&mut self, _framework: Symbol) {
         bug!("frameworks are not supported on windows")
     }
 
-    fn link_whole_staticlib(&mut self, lib: &str, _search_path: &[PathBuf]) {
+    fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) {
         // not supported?
         self.link_staticlib(lib);
     }
@@ -740,8 +745,8 @@ impl<'a> Linker for EmLinker<'a> {
         self.cmd.arg("-L").arg(path);
     }
 
-    fn link_staticlib(&mut self, lib: &str) {
-        self.cmd.arg("-l").arg(lib);
+    fn link_staticlib(&mut self, lib: Symbol) {
+        self.cmd.arg("-l").sym_arg(lib);
     }
 
     fn output_filename(&mut self, path: &Path) {
@@ -752,12 +757,12 @@ impl<'a> Linker for EmLinker<'a> {
         self.cmd.arg(path);
     }
 
-    fn link_dylib(&mut self, lib: &str) {
+    fn link_dylib(&mut self, lib: Symbol) {
         // Emscripten always links statically
         self.link_staticlib(lib);
     }
 
-    fn link_whole_staticlib(&mut self, lib: &str, _search_path: &[PathBuf]) {
+    fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) {
         // not supported?
         self.link_staticlib(lib);
     }
@@ -767,7 +772,7 @@ impl<'a> Linker for EmLinker<'a> {
         self.link_rlib(lib);
     }
 
-    fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
+    fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) {
         self.link_dylib(lib);
     }
 
@@ -803,7 +808,7 @@ impl<'a> Linker for EmLinker<'a> {
         bug!("frameworks are not supported on Emscripten")
     }
 
-    fn link_framework(&mut self, _framework: &str) {
+    fn link_framework(&mut self, _framework: Symbol) {
         bug!("frameworks are not supported on Emscripten")
     }
 
@@ -948,12 +953,12 @@ impl<'a> WasmLd<'a> {
 }
 
 impl<'a> Linker for WasmLd<'a> {
-    fn link_dylib(&mut self, lib: &str) {
-        self.cmd.arg("-l").arg(lib);
+    fn link_dylib(&mut self, lib: Symbol) {
+        self.cmd.arg("-l").sym_arg(lib);
     }
 
-    fn link_staticlib(&mut self, lib: &str) {
-        self.cmd.arg("-l").arg(lib);
+    fn link_staticlib(&mut self, lib: Symbol) {
+        self.cmd.arg("-l").sym_arg(lib);
     }
 
     fn link_rlib(&mut self, lib: &Path) {
@@ -995,16 +1000,16 @@ impl<'a> Linker for WasmLd<'a> {
         self.cmd.args(args);
     }
 
-    fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
-        self.cmd.arg("-l").arg(lib);
+    fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) {
+        self.cmd.arg("-l").sym_arg(lib);
     }
 
-    fn link_framework(&mut self, _framework: &str) {
+    fn link_framework(&mut self, _framework: Symbol) {
         panic!("frameworks not supported")
     }
 
-    fn link_whole_staticlib(&mut self, lib: &str, _search_path: &[PathBuf]) {
-        self.cmd.arg("-l").arg(lib);
+    fn link_whole_staticlib(&mut self, lib: Symbol, _search_path: &[PathBuf]) {
+        self.cmd.arg("-l").sym_arg(lib);
     }
 
     fn link_whole_rlib(&mut self, lib: &Path) {
@@ -1162,19 +1167,19 @@ impl<'a> Linker for PtxLinker<'a> {
         ::std::mem::replace(&mut self.cmd, Command::new(""))
     }
 
-    fn link_dylib(&mut self, _lib: &str) {
+    fn link_dylib(&mut self, _lib: Symbol) {
         panic!("external dylibs not supported")
     }
 
-    fn link_rust_dylib(&mut self, _lib: &str, _path: &Path) {
+    fn link_rust_dylib(&mut self, _lib: Symbol, _path: &Path) {
         panic!("external dylibs not supported")
     }
 
-    fn link_staticlib(&mut self, _lib: &str) {
+    fn link_staticlib(&mut self, _lib: Symbol) {
         panic!("staticlibs not supported")
     }
 
-    fn link_whole_staticlib(&mut self, _lib: &str, _search_path: &[PathBuf]) {
+    fn link_whole_staticlib(&mut self, _lib: Symbol, _search_path: &[PathBuf]) {
         panic!("staticlibs not supported")
     }
 
@@ -1182,7 +1187,7 @@ impl<'a> Linker for PtxLinker<'a> {
         panic!("frameworks not supported")
     }
 
-    fn link_framework(&mut self, _framework: &str) {
+    fn link_framework(&mut self, _framework: Symbol) {
         panic!("frameworks not supported")
     }
 

From fe08ac6da4643fa30e0da5e78f1d040d2aff4f01 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Thu, 5 Sep 2019 11:26:51 +1000
Subject: [PATCH 683/943] Use `ast::Name` in
 `report_ambiguous_associated_type()`.

---
 src/librustc_typeck/astconv.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 9e52eae88ef45..af0818053a460 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1461,7 +1461,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         span: Span,
         type_str: &str,
         trait_str: &str,
-        name: &str,
+        name: ast::Name,
     ) {
         let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type");
         if let (Some(_), Ok(snippet)) = (
@@ -1688,7 +1688,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         span,
                         &qself_ty.to_string(),
                         "Trait",
-                        &assoc_ident.as_str(),
+                        assoc_ident.name,
                     );
                 }
                 return Err(ErrorReported);
@@ -1761,7 +1761,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 span,
                 "Type",
                 &path_str,
-                &item_segment.ident.as_str(),
+                item_segment.ident.name,
             );
             return tcx.types.err;
         };

From 5e5611ab4320b892e2e3b999a683dabf5e120a2f Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Thu, 5 Sep 2019 11:35:39 +1000
Subject: [PATCH 684/943] Use `Symbol` in `weak_lang_items!`.

---
 src/librustc/middle/weak_lang_items.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index 4fb88dadd1f44..fa5fa2257dbc8 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -116,8 +116,8 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>,
 }
 
 impl<'a, 'tcx> Context<'a, 'tcx> {
-    fn register(&mut self, name: &str, span: Span) {
-        $(if name == stringify!($name) {
+    fn register(&mut self, name: Symbol, span: Span) {
+        $(if name == sym::$name {
             if self.items.$name().is_none() {
                 self.items.missing.push(lang_items::$item);
             }
@@ -136,7 +136,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
 
     fn visit_foreign_item(&mut self, i: &hir::ForeignItem) {
         if let Some((lang_item, _)) = lang_items::extract(&i.attrs) {
-            self.register(&lang_item.as_str(), i.span);
+            self.register(lang_item, i.span);
         }
         intravisit::walk_foreign_item(self, i)
     }

From 4fd18c9c06dd7d8165c5259f19847ac22248af66 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Thu, 5 Sep 2019 11:43:05 +1000
Subject: [PATCH 685/943] Use `Symbol` in `external_path()`.

---
 src/librustdoc/clean/mod.rs | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 38eff43bad2be..ae70fdc530be6 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1039,7 +1039,7 @@ impl GenericBound {
     fn maybe_sized(cx: &DocContext<'_>) -> GenericBound {
         let did = cx.tcx.require_lang_item(lang_items::SizedTraitLangItem, None);
         let empty = cx.tcx.intern_substs(&[]);
-        let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
+        let path = external_path(cx, cx.tcx.item_name(did),
             Some(did), false, vec![], empty);
         inline::record_extern_fqn(cx, did, TypeKind::Trait);
         GenericBound::TraitBound(PolyTrait {
@@ -1138,13 +1138,13 @@ fn external_generic_args(
 
 // trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar
 // from Fn<(A, B,), C> to Fn(A, B) -> C
-fn external_path(cx: &DocContext<'_>, name: &str, trait_did: Option<DefId>, has_self: bool,
+fn external_path(cx: &DocContext<'_>, name: Symbol, trait_did: Option<DefId>, has_self: bool,
                  bindings: Vec<TypeBinding>, substs: SubstsRef<'_>) -> Path {
     Path {
         global: false,
         res: Res::Err,
         segments: vec![PathSegment {
-            name: name.to_string(),
+            name: name.as_str().to_string(),
             args: external_generic_args(cx, trait_did, has_self, bindings, substs)
         }],
     }
@@ -1154,7 +1154,7 @@ impl<'a, 'tcx> Clean<GenericBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>
     fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
         let (trait_ref, ref bounds) = *self;
         inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait);
-        let path = external_path(cx, &cx.tcx.item_name(trait_ref.def_id).as_str(),
+        let path = external_path(cx, cx.tcx.item_name(trait_ref.def_id),
                                  Some(trait_ref.def_id), true, bounds.clone(), trait_ref.substs);
 
         debug!("ty::TraitRef\n  subst: {:?}\n", trait_ref.substs);
@@ -3089,8 +3089,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                     AdtKind::Enum => TypeKind::Enum,
                 };
                 inline::record_extern_fqn(cx, did, kind);
-                let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
-                                         None, false, vec![], substs);
+                let path = external_path(cx, cx.tcx.item_name(did), None, false, vec![], substs);
                 ResolvedPath {
                     path,
                     param_names: None,
@@ -3100,7 +3099,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
             }
             ty::Foreign(did) => {
                 inline::record_extern_fqn(cx, did, TypeKind::Foreign);
-                let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
+                let path = external_path(cx, cx.tcx.item_name(did),
                                          None, false, vec![], InternalSubsts::empty());
                 ResolvedPath {
                     path: path,
@@ -3129,7 +3128,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                 reg.clean(cx).map(|b| param_names.push(GenericBound::Outlives(b)));
                 for did in dids {
                     let empty = cx.tcx.intern_substs(&[]);
-                    let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
+                    let path = external_path(cx, cx.tcx.item_name(did),
                         Some(did), false, vec![], empty);
                     inline::record_extern_fqn(cx, did, TypeKind::Trait);
                     let bound = GenericBound::TraitBound(PolyTrait {
@@ -3154,7 +3153,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                     });
                 }
 
-                let path = external_path(cx, &cx.tcx.item_name(did).as_str(), Some(did),
+                let path = external_path(cx, cx.tcx.item_name(did), Some(did),
                     false, bindings, substs);
                 ResolvedPath {
                     path,

From 8138efae16aea425e9306a41519d97ddb58b6794 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Thu, 5 Sep 2019 11:54:01 +1000
Subject: [PATCH 686/943] Avoid two `Symbol::as_str()` calls.

---
 src/librustc_metadata/native_libs.rs | 4 ++--
 src/librustc_mir/const_eval.rs       | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustc_metadata/native_libs.rs b/src/librustc_metadata/native_libs.rs
index 66971bb6f8b1c..ed9a20ec1aa48 100644
--- a/src/librustc_metadata/native_libs.rs
+++ b/src/librustc_metadata/native_libs.rs
@@ -8,7 +8,7 @@ use rustc_target::spec::abi::Abi;
 use syntax::attr;
 use syntax::source_map::Span;
 use syntax::feature_gate::{self, GateIssue};
-use syntax::symbol::{Symbol, sym};
+use syntax::symbol::{kw, sym, Symbol};
 use syntax::{span_err, struct_span_err};
 
 pub fn collect(tcx: TyCtxt<'_>) -> Vec<NativeLibrary> {
@@ -132,7 +132,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> {
 
 impl Collector<'tcx> {
     fn register_native_lib(&mut self, span: Option<Span>, lib: NativeLibrary) {
-        if lib.name.as_ref().map(|s| s.as_str().is_empty()).unwrap_or(false) {
+        if lib.name.as_ref().map(|&s| s == kw::Invalid).unwrap_or(false) {
             match span {
                 Some(span) => {
                     struct_span_err!(self.tcx.sess, span, E0454,
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index db679024dc5a2..3e02497947aa8 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -383,7 +383,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
             return Ok(());
         }
         // An intrinsic that we do not support
-        let intrinsic_name = &ecx.tcx.item_name(instance.def_id()).as_str()[..];
+        let intrinsic_name = ecx.tcx.item_name(instance.def_id());
         Err(
             ConstEvalError::NeedsRfc(format!("calling intrinsic `{}`", intrinsic_name)).into()
         )

From b731e11d527639a0d297db9c6ef9ab5a5da1fb5d Mon Sep 17 00:00:00 2001
From: Baoshan Pang <baoshan.pang@windriver.com>
Date: Tue, 10 Sep 2019 21:35:01 -0700
Subject: [PATCH 687/943] declare EnvKey before use to fix build error

---
 src/libstd/sys/vxworks/process/mod.rs            | 1 +
 src/libstd/sys/vxworks/process/process_common.rs | 2 --
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/libstd/sys/vxworks/process/mod.rs b/src/libstd/sys/vxworks/process/mod.rs
index 4dc706006f4ce..1fc88fbde742f 100644
--- a/src/libstd/sys/vxworks/process/mod.rs
+++ b/src/libstd/sys/vxworks/process/mod.rs
@@ -1,5 +1,6 @@
 pub use self::process_common::{Command, ExitStatus, ExitCode, Stdio, StdioPipes};
 pub use self::process_inner::Process;
+pub use crate::ffi::OsString as EnvKey;
 
 mod process_common;
 #[path = "process_vxworks.rs"]
diff --git a/src/libstd/sys/vxworks/process/process_common.rs b/src/libstd/sys/vxworks/process/process_common.rs
index 509140229fd3a..13648abd1e447 100644
--- a/src/libstd/sys/vxworks/process/process_common.rs
+++ b/src/libstd/sys/vxworks/process/process_common.rs
@@ -12,8 +12,6 @@ use crate::collections::BTreeMap;
 
 use libc::{c_int, gid_t, uid_t, c_char, EXIT_SUCCESS, EXIT_FAILURE};
 
-pub use crate::ffi::OsString as EnvKey;
-
 ////////////////////////////////////////////////////////////////////////////////
 // Command
 ////////////////////////////////////////////////////////////////////////////////

From a8c5f90b06c9bf2bfa2c2f4aedd7c395cb92195d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20R=C3=B3=C5=BCa=C5=84ski?= <rosto@tlen.pl>
Date: Wed, 11 Sep 2019 14:03:40 +0200
Subject: [PATCH 688/943] Fix inconsistent link formatting.

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

diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 990c0eb8955e4..c798ee0e2209a 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -201,9 +201,9 @@ pub struct StdinLock<'a> {
 ///
 /// Each handle returned is a reference to a shared global buffer whose access
 /// is synchronized via a mutex. If you need more explicit control over
-/// locking, see the [`lock() method`][lock].
+/// locking, see the [`Stdin::lock`] method.
 ///
-/// [lock]: struct.Stdin.html#method.lock
+/// [`Stdin::lock`]: struct.Stdin.html#method.lock
 ///
 /// ### Note: Windows Portability Consideration
 /// When operating in a console, the Windows implementation of this stream does not support
@@ -425,9 +425,9 @@ pub struct StdoutLock<'a> {
 ///
 /// Each handle returned is a reference to a shared global buffer whose access
 /// is synchronized via a mutex. If you need more explicit control over
-/// locking, see the [Stdout::lock] method.
+/// locking, see the [`Stdout::lock`] method.
 ///
-/// [Stdout::lock]: struct.Stdout.html#method.lock
+/// [`Stdout::lock`]: struct.Stdout.html#method.lock
 ///
 /// ### Note: Windows Portability Consideration
 /// When operating in a console, the Windows implementation of this stream does not support

From 299d696b91e833f01f37e97b69767fcf6f5cccf0 Mon Sep 17 00:00:00 2001
From: Caio <c410.f3r@gmail.com>
Date: Thu, 29 Aug 2019 20:44:30 -0300
Subject: [PATCH 689/943] Stabilize `param_attrs` in Rust 1.39.0

---
 .../src/language-features/param-attrs.md      |  27 -----
 src/libsyntax/feature_gate/accepted.rs        |   2 +
 src/libsyntax/feature_gate/active.rs          |   3 -
 src/libsyntax/feature_gate/check.rs           |   1 -
 src/libsyntax/parse/attr.rs                   |   7 --
 src/libsyntax/parse/mod.rs                    |   2 -
 src/libsyntax/parse/parser.rs                 |   4 +-
 src/libsyntax/parse/parser/expr.rs            |   2 +-
 src/test/ui/lint/lint-unused-mut-variables.rs |   2 +-
 src/test/ui/lint/lint-unused-variables.rs     |   2 +-
 src/test/ui/parser/fn-arg-doc-comment.rs      |   4 -
 src/test/ui/parser/fn-arg-doc-comment.stderr  |  33 ++----
 .../rfc-2565-param-attrs/param-attrs-2018.rs  |   2 -
 .../param-attrs-2018.stderr                   |   2 +-
 .../param-attrs-allowed.rs                    |   1 -
 .../param-attrs-builtin-attrs.rs              |   2 -
 .../param-attrs-builtin-attrs.stderr          | 104 +++++++++---------
 .../rfc-2565-param-attrs/param-attrs-cfg.rs   |   2 +-
 .../param-attrs-feature-gate.rs               |  16 ---
 .../param-attrs-feature-gate.stderr           |  27 -----
 .../param-attrs-pretty.rs                     |   1 -
 .../proc-macro-cannot-be-used.rs              |   1 -
 .../proc-macro-cannot-be-used.stderr          |  50 ++++-----
 23 files changed, 93 insertions(+), 204 deletions(-)
 delete mode 100644 src/doc/unstable-book/src/language-features/param-attrs.md
 delete mode 100644 src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs
 delete mode 100644 src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr

diff --git a/src/doc/unstable-book/src/language-features/param-attrs.md b/src/doc/unstable-book/src/language-features/param-attrs.md
deleted file mode 100644
index 4b83c204ba105..0000000000000
--- a/src/doc/unstable-book/src/language-features/param-attrs.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# `param_attrs`
-
-The tracking issue for this feature is: [#60406]
-
-[#60406]: https://github.com/rust-lang/rust/issues/60406
-
-Allow attributes in formal function parameter position so external tools and compiler internals can
-take advantage of the additional information that the parameters provide.
-
-Enables finer conditional compilation with `#[cfg(..)]` and linting control of variables. Moreover,
-opens the path to richer DSLs created by users.
-
-------------------------
-
-Example:
-
-```rust
-#![feature(param_attrs)]
-
-fn len(
-  #[cfg(windows)] slice: &[u16],
-  #[cfg(not(windows))] slice: &[u8],
-) -> usize
-{
-  slice.len()
-}
-```
diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs
index eff9f90a8619e..5538daf388e2f 100644
--- a/src/libsyntax/feature_gate/accepted.rs
+++ b/src/libsyntax/feature_gate/accepted.rs
@@ -243,6 +243,8 @@ declare_features! (
     (accepted, async_await, "1.39.0", Some(50547), None),
     /// Allows mixing bind-by-move in patterns and references to those identifiers in guards.
     (accepted, bind_by_move_pattern_guards, "1.39.0", Some(15287), None),
+    /// Allows attributes in formal function parameters.
+    (accepted, param_attrs, "1.39.0", Some(60406), None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index dd78777b56986..38c16dbac6ab7 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -489,9 +489,6 @@ declare_features! (
     /// Allows the user of associated type bounds.
     (active, associated_type_bounds, "1.34.0", Some(52662), None),
 
-    /// Attributes on formal function params.
-    (active, param_attrs, "1.36.0", Some(60406), None),
-
     /// Allows calling constructor functions in `const fn`.
     (active, const_constructor, "1.37.0", Some(61456), None),
 
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 5711b269ff092..6b76a6a60c3d6 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -892,7 +892,6 @@ pub fn check_crate(krate: &ast::Crate,
         }
     }
 
-    gate_all!(param_attrs, "attributes on function parameters are unstable");
     gate_all!(let_chains, "`let` expressions in this position are experimental");
     gate_all!(async_closure, "async closures are unstable");
     gate_all!(yields, generators, "yield syntax is experimental");
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 9aa1ec0b14fe9..bba70973631fe 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -19,13 +19,6 @@ const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
                                                      permitted in this context";
 
 impl<'a> Parser<'a> {
-    crate fn parse_param_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
-        let attrs = self.parse_outer_attributes()?;
-        self.sess.gated_spans.param_attrs.borrow_mut()
-            .extend(attrs.iter().map(|a| a.span));
-        Ok(attrs)
-    }
-
     /// Parses attributes that appear before an item.
     crate fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let mut attrs: Vec<ast::Attribute> = Vec::new();
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index bc1bc00ac8405..6a8a64f369d99 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -42,8 +42,6 @@ pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
 /// used and should be feature gated accordingly in `check_crate`.
 #[derive(Default)]
 pub struct GatedSpans {
-    /// Spans collected for gating `param_attrs`, e.g. `fn foo(#[attr] x: u8) {}`.
-    pub param_attrs: Lock<Vec<Span>>,
     /// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`.
     pub let_chains: Lock<Vec<Span>>,
     /// Spans collected for gating `async_closure`, e.g. `async || ..`.
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fcebfa2996233..b2b6504919e96 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -979,7 +979,7 @@ impl<'a> Parser<'a> {
         is_name_required: impl Fn(&token::Token) -> bool,
     ) -> PResult<'a, Param> {
         let lo = self.token.span;
-        let attrs = self.parse_param_attributes()?;
+        let attrs = self.parse_outer_attributes()?;
         if let Some(mut param) = self.parse_self_param()? {
             param.attrs = attrs.into();
             return self.recover_bad_self_param(param, is_trait_item);
@@ -1362,7 +1362,7 @@ impl<'a> Parser<'a> {
     /// Returns the parsed optional self parameter with attributes and whether a self
     /// shortcut was used.
     fn parse_self_parameter_with_attrs(&mut self) -> PResult<'a, Option<Param>> {
-        let attrs = self.parse_param_attributes()?;
+        let attrs = self.parse_outer_attributes()?;
         let param_opt = self.parse_self_param()?;
         Ok(param_opt.map(|mut param| {
             param.attrs = attrs.into();
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 31b28443abbc3..b383498b7b64d 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -1176,7 +1176,7 @@ impl<'a> Parser<'a> {
     /// Parses a parameter in a closure header (e.g., `|arg, arg|`).
     fn parse_fn_block_param(&mut self) -> PResult<'a, Param> {
         let lo = self.token.span;
-        let attrs = self.parse_param_attributes()?;
+        let attrs = self.parse_outer_attributes()?;
         let pat = self.parse_pat(PARAM_EXPECTED)?;
         let t = if self.eat(&token::Colon) {
             self.parse_ty()?
diff --git a/src/test/ui/lint/lint-unused-mut-variables.rs b/src/test/ui/lint/lint-unused-mut-variables.rs
index f140546b04819..1af44ecf362bf 100644
--- a/src/test/ui/lint/lint-unused-mut-variables.rs
+++ b/src/test/ui/lint/lint-unused-mut-variables.rs
@@ -3,7 +3,7 @@
 // Exercise the unused_mut attribute in some positive and negative cases
 
 #![deny(unused_mut)]
-#![feature(async_closure, param_attrs)]
+#![feature(async_closure)]
 
 async fn baz_async(
     mut a: i32,
diff --git a/src/test/ui/lint/lint-unused-variables.rs b/src/test/ui/lint/lint-unused-variables.rs
index 06b818636f956..1a6b5183f0fae 100644
--- a/src/test/ui/lint/lint-unused-variables.rs
+++ b/src/test/ui/lint/lint-unused-variables.rs
@@ -1,7 +1,7 @@
 // compile-flags: --cfg something
 // edition:2018
 
-#![feature(async_closure, param_attrs)]
+#![feature(async_closure)]
 #![deny(unused_variables)]
 
 async fn foo_async(
diff --git a/src/test/ui/parser/fn-arg-doc-comment.rs b/src/test/ui/parser/fn-arg-doc-comment.rs
index 4a4f959e21353..995eb62d0bb59 100644
--- a/src/test/ui/parser/fn-arg-doc-comment.rs
+++ b/src/test/ui/parser/fn-arg-doc-comment.rs
@@ -2,14 +2,10 @@ pub fn f(
     /// Comment
     //~^ ERROR documentation comments cannot be applied to function parameters
     //~| NOTE doc comments are not allowed here
-    //~| ERROR attributes on function parameters are unstable
-    //~| NOTE https://github.com/rust-lang/rust/issues/60406
     id: u8,
     /// Other
     //~^ ERROR documentation comments cannot be applied to function parameters
     //~| NOTE doc comments are not allowed here
-    //~| ERROR attributes on function parameters are unstable
-    //~| NOTE https://github.com/rust-lang/rust/issues/60406
     a: u8,
 ) {}
 
diff --git a/src/test/ui/parser/fn-arg-doc-comment.stderr b/src/test/ui/parser/fn-arg-doc-comment.stderr
index d8884de1fe84d..669785af45f93 100644
--- a/src/test/ui/parser/fn-arg-doc-comment.stderr
+++ b/src/test/ui/parser/fn-arg-doc-comment.stderr
@@ -1,5 +1,5 @@
 error: attributes cannot be applied to a function parameter's type
-  --> $DIR/fn-arg-doc-comment.rs:16:12
+  --> $DIR/fn-arg-doc-comment.rs:12:12
    |
 LL | fn bar(id: #[allow(dead_code)] i32) {}
    |            ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
@@ -11,31 +11,13 @@ LL |     /// Comment
    |     ^^^^^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/fn-arg-doc-comment.rs:8:5
+  --> $DIR/fn-arg-doc-comment.rs:6:5
    |
 LL |     /// Other
    |     ^^^^^^^^^ doc comments are not allowed here
 
-error[E0658]: attributes on function parameters are unstable
-  --> $DIR/fn-arg-doc-comment.rs:2:5
-   |
-LL |     /// Comment
-   |     ^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/60406
-   = help: add `#![feature(param_attrs)]` to the crate attributes to enable
-
-error[E0658]: attributes on function parameters are unstable
-  --> $DIR/fn-arg-doc-comment.rs:8:5
-   |
-LL |     /// Other
-   |     ^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/60406
-   = help: add `#![feature(param_attrs)]` to the crate attributes to enable
-
 error[E0308]: mismatched types
-  --> $DIR/fn-arg-doc-comment.rs:22:7
+  --> $DIR/fn-arg-doc-comment.rs:18:7
    |
 LL |     f("", "");
    |       ^^ expected u8, found reference
@@ -44,7 +26,7 @@ LL |     f("", "");
               found type `&'static str`
 
 error[E0308]: mismatched types
-  --> $DIR/fn-arg-doc-comment.rs:22:11
+  --> $DIR/fn-arg-doc-comment.rs:18:11
    |
 LL |     f("", "");
    |           ^^ expected u8, found reference
@@ -53,7 +35,7 @@ LL |     f("", "");
               found type `&'static str`
 
 error[E0308]: mismatched types
-  --> $DIR/fn-arg-doc-comment.rs:29:9
+  --> $DIR/fn-arg-doc-comment.rs:25:9
    |
 LL |     bar("");
    |         ^^ expected i32, found reference
@@ -61,7 +43,6 @@ LL |     bar("");
    = note: expected type `i32`
               found type `&'static str`
 
-error: aborting due to 8 previous errors
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0308, E0658.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs
index d71711336b06e..a6f693bd5b5f4 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(param_attrs)]
-
 trait Trait2015 { fn foo(#[allow(C)] i32); }
 //~^ ERROR expected one of `:`, `@`, or `|`, found `)`
 
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
index 26b414e426805..9860e9805b2ed 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
@@ -1,5 +1,5 @@
 error: expected one of `:`, `@`, or `|`, found `)`
-  --> $DIR/param-attrs-2018.rs:5:41
+  --> $DIR/param-attrs-2018.rs:3:41
    |
 LL | trait Trait2015 { fn foo(#[allow(C)] i32); }
    |                                         ^ expected one of `:`, `@`, or `|` here
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
index 5eeda66173ded..1217f89cb3168 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
@@ -2,7 +2,6 @@
 // compile-flags: --cfg something
 
 #![deny(unused_mut)]
-#![feature(param_attrs)]
 
 extern "C" {
     fn ffi(
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
index a8fe5d6c1f60e..c4684a3fa82b0 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
@@ -1,5 +1,3 @@
-#![feature(param_attrs)]
-
 extern "C" {
     fn ffi(
         /// Foo
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
index 8ab3fc39a0ccb..0fc6ca2f7f37a 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
@@ -1,311 +1,311 @@
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:7:9
+  --> $DIR/param-attrs-builtin-attrs.rs:5:9
    |
 LL |         #[test] a: i32,
    |         ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:23:5
+  --> $DIR/param-attrs-builtin-attrs.rs:21:5
    |
 LL |     #[test] a: u32,
    |     ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:38:5
+  --> $DIR/param-attrs-builtin-attrs.rs:36:5
    |
 LL |     #[test] a: u32,
    |     ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:58:9
+  --> $DIR/param-attrs-builtin-attrs.rs:56:9
    |
 LL |         #[test] a: i32,
    |         ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:79:9
+  --> $DIR/param-attrs-builtin-attrs.rs:77:9
    |
 LL |         #[test] a: i32,
    |         ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:98:9
+  --> $DIR/param-attrs-builtin-attrs.rs:96:9
    |
 LL |         #[test] a: i32,
    |         ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:117:9
+  --> $DIR/param-attrs-builtin-attrs.rs:115:9
    |
 LL |         #[test] a: i32,
    |         ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:134:9
+  --> $DIR/param-attrs-builtin-attrs.rs:132:9
    |
 LL |         #[test] a: u32,
    |         ^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:5:9
+  --> $DIR/param-attrs-builtin-attrs.rs:3:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:9:9
+  --> $DIR/param-attrs-builtin-attrs.rs:7:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:11:9
+  --> $DIR/param-attrs-builtin-attrs.rs:9:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:13:9
+  --> $DIR/param-attrs-builtin-attrs.rs:11:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:15:9
+  --> $DIR/param-attrs-builtin-attrs.rs:13:9
    |
 LL |         #[no_mangle] b: i32,
    |         ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:21:5
+  --> $DIR/param-attrs-builtin-attrs.rs:19:5
    |
 LL |     /// Foo
    |     ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:25:5
+  --> $DIR/param-attrs-builtin-attrs.rs:23:5
    |
 LL |     /// Bar
    |     ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:27:5
+  --> $DIR/param-attrs-builtin-attrs.rs:25:5
    |
 LL |     #[must_use]
    |     ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:29:5
+  --> $DIR/param-attrs-builtin-attrs.rs:27:5
    |
 LL |     /// Baz
    |     ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:31:5
+  --> $DIR/param-attrs-builtin-attrs.rs:29:5
    |
 LL |     #[no_mangle] b: i32,
    |     ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:36:5
+  --> $DIR/param-attrs-builtin-attrs.rs:34:5
    |
 LL |     /// Foo
    |     ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:40:5
+  --> $DIR/param-attrs-builtin-attrs.rs:38:5
    |
 LL |     /// Bar
    |     ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:42:5
+  --> $DIR/param-attrs-builtin-attrs.rs:40:5
    |
 LL |     #[must_use]
    |     ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:44:5
+  --> $DIR/param-attrs-builtin-attrs.rs:42:5
    |
 LL |     /// Baz
    |     ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:46:5
+  --> $DIR/param-attrs-builtin-attrs.rs:44:5
    |
 LL |     #[no_mangle] b: i32,
    |     ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:53:9
+  --> $DIR/param-attrs-builtin-attrs.rs:51:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:56:9
+  --> $DIR/param-attrs-builtin-attrs.rs:54:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:60:9
+  --> $DIR/param-attrs-builtin-attrs.rs:58:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:62:9
+  --> $DIR/param-attrs-builtin-attrs.rs:60:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:64:9
+  --> $DIR/param-attrs-builtin-attrs.rs:62:9
    |
 LL |         /// Qux
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:66:9
+  --> $DIR/param-attrs-builtin-attrs.rs:64:9
    |
 LL |         #[no_mangle] b: i32,
    |         ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:74:9
+  --> $DIR/param-attrs-builtin-attrs.rs:72:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:77:9
+  --> $DIR/param-attrs-builtin-attrs.rs:75:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:81:9
+  --> $DIR/param-attrs-builtin-attrs.rs:79:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:83:9
+  --> $DIR/param-attrs-builtin-attrs.rs:81:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:85:9
+  --> $DIR/param-attrs-builtin-attrs.rs:83:9
    |
 LL |         /// Qux
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:87:9
+  --> $DIR/param-attrs-builtin-attrs.rs:85:9
    |
 LL |         #[no_mangle] b: i32,
    |         ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:93:9
+  --> $DIR/param-attrs-builtin-attrs.rs:91:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:96:9
+  --> $DIR/param-attrs-builtin-attrs.rs:94:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:100:9
+  --> $DIR/param-attrs-builtin-attrs.rs:98:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:102:9
+  --> $DIR/param-attrs-builtin-attrs.rs:100:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:104:9
+  --> $DIR/param-attrs-builtin-attrs.rs:102:9
    |
 LL |         /// Qux
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:106:9
+  --> $DIR/param-attrs-builtin-attrs.rs:104:9
    |
 LL |         #[no_mangle] b: i32,
    |         ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:112:9
+  --> $DIR/param-attrs-builtin-attrs.rs:110:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:115:9
+  --> $DIR/param-attrs-builtin-attrs.rs:113:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:119:9
+  --> $DIR/param-attrs-builtin-attrs.rs:117:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:121:9
+  --> $DIR/param-attrs-builtin-attrs.rs:119:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:123:9
+  --> $DIR/param-attrs-builtin-attrs.rs:121:9
    |
 LL |         /// Qux
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:125:9
+  --> $DIR/param-attrs-builtin-attrs.rs:123:9
    |
 LL |         #[no_mangle] b: i32,
    |         ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:132:9
+  --> $DIR/param-attrs-builtin-attrs.rs:130:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:136:9
+  --> $DIR/param-attrs-builtin-attrs.rs:134:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:138:9
+  --> $DIR/param-attrs-builtin-attrs.rs:136:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:140:9
+  --> $DIR/param-attrs-builtin-attrs.rs:138:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:142:9
+  --> $DIR/param-attrs-builtin-attrs.rs:140:9
    |
 LL |         #[no_mangle] b: i32
    |         ^^^^^^^^^^^^
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
index 5ad6e23cf2a63..d44ff14e99247 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
@@ -1,7 +1,7 @@
 // compile-flags: --cfg something
 // edition:2018
 
-#![feature(async_closure, param_attrs)]
+#![feature(async_closure)]
 #![deny(unused_variables)]
 
 extern "C" {
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs
deleted file mode 100644
index a7f4855915b24..0000000000000
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// gate-test-param_attrs
-
-#![deny(unused_variables)]
-
-fn foo(
-    /// Foo
-    //~^ ERROR documentation comments cannot be applied to function parameters
-    //~| NOTE doc comments are not allowed here
-    //~| ERROR attributes on function parameters are unstable
-    //~| NOTE https://github.com/rust-lang/rust/issues/60406
-    #[allow(unused_variables)] a: u8
-    //~^ ERROR attributes on function parameters are unstable
-    //~| NOTE https://github.com/rust-lang/rust/issues/60406
-) {}
-
-fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr
deleted file mode 100644
index 0bb9d05dca0ac..0000000000000
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-feature-gate.rs:6:5
-   |
-LL |     /// Foo
-   |     ^^^^^^^ doc comments are not allowed here
-
-error[E0658]: attributes on function parameters are unstable
-  --> $DIR/param-attrs-feature-gate.rs:6:5
-   |
-LL |     /// Foo
-   |     ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/60406
-   = help: add `#![feature(param_attrs)]` to the crate attributes to enable
-
-error[E0658]: attributes on function parameters are unstable
-  --> $DIR/param-attrs-feature-gate.rs:11:5
-   |
-LL |     #[allow(unused_variables)] a: u8
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/60406
-   = help: add `#![feature(param_attrs)]` to the crate attributes to enable
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
index 1a7e948174506..fb86020d992e9 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
@@ -2,7 +2,6 @@
 
 // check-pass
 
-#![feature(param_attrs)]
 #![feature(c_variadic)]
 
 extern crate param_attrs;
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
index 7f00308925442..9f4e2710dc420 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
@@ -1,6 +1,5 @@
 // aux-build:ident-mac.rs
 
-#![feature(param_attrs)]
 #![feature(c_variadic)]
 
 extern crate ident_mac;
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
index 3b72e8ab4bdf9..b4946fa74943f 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
@@ -1,149 +1,149 @@
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:11:21
+  --> $DIR/proc-macro-cannot-be-used.rs:10:21
    |
 LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
    |                     ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:11:38
+  --> $DIR/proc-macro-cannot-be-used.rs:10:38
    |
 LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
    |                                      ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:15:38
+  --> $DIR/proc-macro-cannot-be-used.rs:14:38
    |
 LL | unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
    |                                      ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:18:28
+  --> $DIR/proc-macro-cannot-be-used.rs:17:28
    |
 LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
    |                            ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:18:38
+  --> $DIR/proc-macro-cannot-be-used.rs:17:38
    |
 LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
    |                                      ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:22:9
+  --> $DIR/proc-macro-cannot-be-used.rs:21:9
    |
 LL | fn free(#[id] arg1: u8) {
    |         ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:24:16
+  --> $DIR/proc-macro-cannot-be-used.rs:23:16
    |
 LL |     let lam = |#[id] W(x), #[id] y| ();
    |                ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:24:28
+  --> $DIR/proc-macro-cannot-be-used.rs:23:28
    |
 LL |     let lam = |#[id] W(x), #[id] y| ();
    |                            ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:30:18
+  --> $DIR/proc-macro-cannot-be-used.rs:29:18
    |
 LL |     fn inherent1(#[id] self, #[id] arg1: u8) {}
    |                  ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:30:30
+  --> $DIR/proc-macro-cannot-be-used.rs:29:30
    |
 LL |     fn inherent1(#[id] self, #[id] arg1: u8) {}
    |                              ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:33:18
+  --> $DIR/proc-macro-cannot-be-used.rs:32:18
    |
 LL |     fn inherent2(#[id] &self, #[id] arg1: u8) {}
    |                  ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:33:31
+  --> $DIR/proc-macro-cannot-be-used.rs:32:31
    |
 LL |     fn inherent2(#[id] &self, #[id] arg1: u8) {}
    |                               ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:36:22
+  --> $DIR/proc-macro-cannot-be-used.rs:35:22
    |
 LL |     fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
    |                      ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:36:42
+  --> $DIR/proc-macro-cannot-be-used.rs:35:42
    |
 LL |     fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
    |                                          ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:39:22
+  --> $DIR/proc-macro-cannot-be-used.rs:38:22
    |
 LL |     fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
    |                      ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:39:45
+  --> $DIR/proc-macro-cannot-be-used.rs:38:45
    |
 LL |     fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
    |                                             ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:45:15
+  --> $DIR/proc-macro-cannot-be-used.rs:44:15
    |
 LL |     fn trait1(#[id] self, #[id] arg1: u8);
    |               ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:45:27
+  --> $DIR/proc-macro-cannot-be-used.rs:44:27
    |
 LL |     fn trait1(#[id] self, #[id] arg1: u8);
    |                           ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:48:15
+  --> $DIR/proc-macro-cannot-be-used.rs:47:15
    |
 LL |     fn trait2(#[id] &self, #[id] arg1: u8);
    |               ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:48:28
+  --> $DIR/proc-macro-cannot-be-used.rs:47:28
    |
 LL |     fn trait2(#[id] &self, #[id] arg1: u8);
    |                            ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:51:19
+  --> $DIR/proc-macro-cannot-be-used.rs:50:19
    |
 LL |     fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
    |                   ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:51:39
+  --> $DIR/proc-macro-cannot-be-used.rs:50:39
    |
 LL |     fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
    |                                       ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:54:19
+  --> $DIR/proc-macro-cannot-be-used.rs:53:19
    |
 LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
    |                   ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:54:42
+  --> $DIR/proc-macro-cannot-be-used.rs:53:42
    |
 LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
    |                                          ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:54:58
+  --> $DIR/proc-macro-cannot-be-used.rs:53:58
    |
 LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
    |                                                          ^^^^^

From b88bcf0f9dd2eab02448d623182e67f69681c6e4 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Wed, 11 Sep 2019 06:55:40 -0700
Subject: [PATCH 690/943] Update bundled OpenSSL to 1.1.1d

Brings in a few minor security fixes to the distributed Cargo/etc.
---
 Cargo.lock | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 27ee38146097b..179d2f509fc70 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2174,9 +2174,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
 
 [[package]]
 name = "openssl-src"
-version = "111.3.0+1.1.1c"
+version = "111.6.0+1.1.1d"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53ed5f31d294bdf5f7a4ba0a206c2754b0f60e9a63b7e3076babc5317873c797"
+checksum = "b9c2da1de8a7a3f860919c01540b03a6db16de042405a8a07a5e9d0b4b825d9c"
 dependencies = [
  "cc",
 ]

From 935394f4f85ecf43e0c5c2c66300a130dfe1e6c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= <matti@marinelayer.io>
Date: Wed, 11 Sep 2019 19:03:28 +0200
Subject: [PATCH 691/943] Upgrade parking_lot and tempfile rustc dependencies

---
 Cargo.lock                              | 12 ++++++------
 src/librustc/Cargo.toml                 |  2 +-
 src/librustc_codegen_ssa/Cargo.toml     |  4 ++--
 src/librustc_data_structures/Cargo.toml |  2 +-
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 27ee38146097b..d31a9f1bd9892 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3012,7 +3012,7 @@ dependencies = [
  "log",
  "measureme",
  "num_cpus",
- "parking_lot 0.7.1",
+ "parking_lot 0.9.0",
  "polonius-engine",
  "rustc-rayon",
  "rustc-rayon-core",
@@ -3310,7 +3310,7 @@ dependencies = [
  "log",
  "memmap",
  "num_cpus",
- "parking_lot 0.7.1",
+ "parking_lot 0.9.0",
  "rustc",
  "rustc_apfloat",
  "rustc_codegen_utils",
@@ -3353,7 +3353,7 @@ dependencies = [
  "jobserver",
  "lazy_static 1.3.0",
  "log",
- "parking_lot 0.7.1",
+ "parking_lot 0.9.0",
  "rustc-hash",
  "rustc-rayon",
  "rustc-rayon-core",
@@ -4258,13 +4258,13 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.0.5"
+version = "3.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7e91405c14320e5c79b3d148e1c86f40749a36e490642202a31689cb1a3452b2"
+checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
 dependencies = [
  "cfg-if",
  "libc",
- "rand 0.6.1",
+ "rand 0.7.0",
  "redox_syscall",
  "remove_dir_all",
  "winapi 0.3.6",
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index a479fabafc014..bb4975454df03 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -31,7 +31,7 @@ rustc_serialize = { path = "../libserialize", package = "serialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 backtrace = "0.3.3"
-parking_lot = "0.7"
+parking_lot = "0.9"
 byteorder = { version = "1.1", features = ["i128"]}
 chalk-engine = { version = "0.9.0", default-features=false }
 rustc_fs_util = { path = "../librustc_fs_util" }
diff --git a/src/librustc_codegen_ssa/Cargo.toml b/src/librustc_codegen_ssa/Cargo.toml
index 89a6ec27fe595..bc028d6624279 100644
--- a/src/librustc_codegen_ssa/Cargo.toml
+++ b/src/librustc_codegen_ssa/Cargo.toml
@@ -17,8 +17,8 @@ memmap = "0.6"
 log = "0.4.5"
 libc = "0.2.44"
 jobserver = "0.1.11"
-parking_lot = "0.7"
-tempfile = "3.0.5"
+parking_lot = "0.9"
+tempfile = "3.1"
 
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 syntax = { path = "../libsyntax" }
diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml
index 288676ce3ff67..be9f79c83bb5a 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/src/librustc_data_structures/Cargo.toml
@@ -26,5 +26,5 @@ rustc-hash = "1.0.1"
 smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
 
 [dependencies.parking_lot]
-version = "0.7"
+version = "0.9"
 features = ["nightly"]

From 223600ac2c23715f350ceae7f315f5056aae6fc0 Mon Sep 17 00:00:00 2001
From: Kornel <kornel@geekhood.net>
Date: Wed, 11 Sep 2019 11:46:53 +0100
Subject: [PATCH 692/943] Guarantee vec.clear/truncate is O(1) for trivial
 types

---
 src/liballoc/vec.rs | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index d5dc2d4b8688d..c513658c842e5 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -685,21 +685,25 @@ impl<T> Vec<T> {
     /// [`drain`]: #method.drain
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn truncate(&mut self, len: usize) {
-        let current_len = self.len;
-        unsafe {
-            let mut ptr = self.as_mut_ptr().add(self.len);
-            // Set the final length at the end, keeping in mind that
-            // dropping an element might panic. Works around a missed
-            // optimization, as seen in the following issue:
-            // https://github.com/rust-lang/rust/issues/51802
-            let mut local_len = SetLenOnDrop::new(&mut self.len);
+        if mem::needs_drop::<T>() {
+            let current_len = self.len;
+            unsafe {
+                let mut ptr = self.as_mut_ptr().add(self.len);
+                // Set the final length at the end, keeping in mind that
+                // dropping an element might panic. Works around a missed
+                // optimization, as seen in the following issue:
+                // https://github.com/rust-lang/rust/issues/51802
+                let mut local_len = SetLenOnDrop::new(&mut self.len);
 
-            // drop any extra elements
-            for _ in len..current_len {
-                local_len.decrement_len(1);
-                ptr = ptr.offset(-1);
-                ptr::drop_in_place(ptr);
+                // drop any extra elements
+                for _ in len..current_len {
+                    local_len.decrement_len(1);
+                    ptr = ptr.offset(-1);
+                    ptr::drop_in_place(ptr);
+                }
             }
+        } else if len <= self.len {
+            self.len = len;
         }
     }
 

From 87420cd1bc9b032290e55e1569c6c45398eec929 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Wed, 11 Sep 2019 16:05:45 -0300
Subject: [PATCH 693/943] Make Place Boxed on Statement to reduce size from 64
 bytes to 32 bytes

---
 src/librustc/mir/mod.rs                       | 20 +++---
 src/librustc/mir/visit.rs                     |  9 ++-
 src/librustc_codegen_ssa/mir/statement.rs     | 12 ++--
 .../borrow_check/conflict_errors.rs           | 14 ++--
 .../borrow_check/error_reporting.rs           | 11 ++-
 src/librustc_mir/borrow_check/mod.rs          |  6 +-
 src/librustc_mir/borrow_check/move_errors.rs  | 12 ++--
 .../borrow_check/nll/explain_borrow/mod.rs    |  6 +-
 .../borrow_check/nll/invalidation.rs          |  2 +-
 .../borrow_check/nll/type_check/mod.rs        |  4 +-
 src/librustc_mir/borrow_check/used_muts.rs    |  2 +-
 src/librustc_mir/build/cfg.rs                 |  2 +-
 src/librustc_mir/build/expr/as_place.rs       | 12 ++--
 src/librustc_mir/build/matches/mod.rs         | 26 ++++---
 src/librustc_mir/dataflow/impls/borrows.rs    |  4 +-
 .../dataflow/impls/storage_liveness.rs        |  4 +-
 .../dataflow/move_paths/builder.rs            |  2 +-
 src/librustc_mir/interpret/step.rs            |  2 +-
 src/librustc_mir/shim.rs                      | 68 ++++++++++++-------
 src/librustc_mir/transform/add_retag.rs       | 12 ++--
 .../transform/cleanup_post_borrowck.rs        |  2 +-
 src/librustc_mir/transform/const_prop.rs      |  2 +-
 src/librustc_mir/transform/copy_prop.rs       | 48 +++++++------
 src/librustc_mir/transform/deaggregator.rs    |  6 +-
 src/librustc_mir/transform/elaborate_drops.rs |  2 +-
 src/librustc_mir/transform/generator.rs       | 17 +++--
 src/librustc_mir/transform/inline.rs          |  4 +-
 src/librustc_mir/transform/promote_consts.rs  | 21 +++---
 src/librustc_mir/transform/qualify_consts.rs  | 16 +++--
 .../transform/qualify_min_const_fn.rs         |  2 +-
 .../transform/remove_noop_landing_pads.rs     |  4 +-
 src/librustc_mir/transform/rustc_peek.rs      |  4 +-
 .../transform/uniform_array_move_out.rs       | 36 +++++-----
 src/librustc_mir/util/aggregate.rs            |  6 +-
 src/librustc_mir/util/elaborate_drops.rs      |  2 +-
 src/librustc_mir/util/patch.rs                |  2 +-
 36 files changed, 228 insertions(+), 176 deletions(-)

diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 602ce12c37d81..0ebc70750a6bb 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1547,7 +1547,7 @@ pub struct Statement<'tcx> {
 
 // `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
 #[cfg(target_arch = "x86_64")]
-static_assert_size!(Statement<'_>, 64);
+static_assert_size!(Statement<'_>, 32);
 
 impl Statement<'_> {
     /// Changes a statement to a nop. This is both faster than deleting instructions and avoids
@@ -1568,7 +1568,7 @@ impl Statement<'_> {
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum StatementKind<'tcx> {
     /// Write the RHS Rvalue to the LHS Place.
-    Assign(Place<'tcx>, Box<Rvalue<'tcx>>),
+    Assign(Box<(Place<'tcx>, Rvalue<'tcx>)>),
 
     /// This represents all the reading that a pattern match may do
     /// (e.g., inspecting constants and discriminant values), and the
@@ -1577,10 +1577,10 @@ pub enum StatementKind<'tcx> {
     ///
     /// Note that this also is emitted for regular `let` bindings to ensure that locals that are
     /// never accessed still get some sanity checks for, e.g., `let x: ! = ..;`
-    FakeRead(FakeReadCause, Place<'tcx>),
+    FakeRead(FakeReadCause, Box<Place<'tcx>>),
 
     /// Write the discriminant for a variant to the enum Place.
-    SetDiscriminant { place: Place<'tcx>, variant_index: VariantIdx },
+    SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
 
     /// Start a live range for the storage of the local.
     StorageLive(Local),
@@ -1597,7 +1597,7 @@ pub enum StatementKind<'tcx> {
     /// by miri and only generated when "-Z mir-emit-retag" is passed.
     /// See <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/>
     /// for more details.
-    Retag(RetagKind, Place<'tcx>),
+    Retag(RetagKind, Box<Place<'tcx>>),
 
     /// Encodes a user's type ascription. These need to be preserved
     /// intact so that NLL can respect them. For example:
@@ -1611,7 +1611,7 @@ pub enum StatementKind<'tcx> {
     /// - `Contravariant` -- requires that `T_y :> T`
     /// - `Invariant` -- requires that `T_y == T`
     /// - `Bivariant` -- no effect
-    AscribeUserType(Place<'tcx>, ty::Variance, Box<UserTypeProjection>),
+    AscribeUserType(Box<(Place<'tcx>, UserTypeProjection)>, ty::Variance),
 
     /// No-op. Useful for deleting instructions without affecting statement indices.
     Nop,
@@ -1675,7 +1675,7 @@ impl Debug for Statement<'_> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
         use self::StatementKind::*;
         match self.kind {
-            Assign(ref place, ref rv) => write!(fmt, "{:?} = {:?}", place, rv),
+            Assign(box(ref place, ref rv)) => write!(fmt, "{:?} = {:?}", place, rv),
             FakeRead(ref cause, ref place) => write!(fmt, "FakeRead({:?}, {:?})", cause, place),
             Retag(ref kind, ref place) => write!(
                 fmt,
@@ -1696,7 +1696,7 @@ impl Debug for Statement<'_> {
             InlineAsm(ref asm) => {
                 write!(fmt, "asm!({:?} : {:?} : {:?})", asm.asm, asm.outputs, asm.inputs)
             }
-            AscribeUserType(ref place, ref variance, ref c_ty) => {
+            AscribeUserType(box(ref place, ref c_ty), ref variance) => {
                 write!(fmt, "AscribeUserType({:?}, {:?}, {:?})", place, variance, c_ty)
             }
             Nop => write!(fmt, "nop"),
@@ -2998,14 +2998,14 @@ BraceStructTypeFoldableImpl! {
 
 EnumTypeFoldableImpl! {
     impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> {
-        (StatementKind::Assign)(a, b),
+        (StatementKind::Assign)(a),
         (StatementKind::FakeRead)(cause, place),
         (StatementKind::SetDiscriminant) { place, variant_index },
         (StatementKind::StorageLive)(a),
         (StatementKind::StorageDead)(a),
         (StatementKind::InlineAsm)(a),
         (StatementKind::Retag)(kind, place),
-        (StatementKind::AscribeUserType)(a, v, b),
+        (StatementKind::AscribeUserType)(a, v),
         (StatementKind::Nop),
     }
 }
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index 9f3df7cc58f60..1e3b9eb29c79d 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -344,7 +344,9 @@ macro_rules! make_mir_visitor {
 
                 self.visit_source_info(source_info);
                 match kind {
-                    StatementKind::Assign(place, rvalue) => {
+                    StatementKind::Assign(
+                        box(ref $($mutability)? place, ref $($mutability)? rvalue)
+                    ) => {
                         self.visit_assign(place, rvalue, location);
                     }
                     StatementKind::FakeRead(_, place) => {
@@ -391,7 +393,10 @@ macro_rules! make_mir_visitor {
                     StatementKind::Retag(kind, place) => {
                         self.visit_retag(kind, place, location);
                     }
-                    StatementKind::AscribeUserType(place, variance, user_ty) => {
+                    StatementKind::AscribeUserType(
+                        box(ref $($mutability)? place, ref $($mutability)? user_ty),
+                        variance
+                    ) => {
                         self.visit_ascribe_user_ty(place, variance, user_ty, location);
                     }
                     StatementKind::Nop => {}
diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs
index b1bc57c2e90ec..dab7dfc041751 100644
--- a/src/librustc_codegen_ssa/mir/statement.rs
+++ b/src/librustc_codegen_ssa/mir/statement.rs
@@ -16,12 +16,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         self.set_debug_loc(&mut bx, statement.source_info);
         match statement.kind {
-            mir::StatementKind::Assign(ref place, ref rvalue) => {
+            mir::StatementKind::Assign(box(ref place, ref rvalue)) => {
                 if let mir::Place {
                     base: mir::PlaceBase::Local(index),
                     projection: box [],
-                } = *place {
-                    match self.locals[index] {
+                } = place {
+                    match self.locals[*index] {
                         LocalRef::Place(cg_dest) => {
                             self.codegen_rvalue(bx, cg_dest, rvalue)
                         }
@@ -30,7 +30,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         }
                         LocalRef::Operand(None) => {
                             let (mut bx, operand) = self.codegen_rvalue_operand(bx, rvalue);
-                            if let Some(name) = self.mir.local_decls[index].name {
+                            if let Some(name) = self.mir.local_decls[*index].name {
                                 match operand.val {
                                     OperandValue::Ref(x, ..) |
                                     OperandValue::Immediate(x) => {
@@ -44,7 +44,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                                     }
                                 }
                             }
-                            self.locals[index] = LocalRef::Operand(Some(operand));
+                            self.locals[*index] = LocalRef::Operand(Some(operand));
                             bx
                         }
                         LocalRef::Operand(Some(op)) => {
@@ -64,7 +64,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     self.codegen_rvalue(bx, cg_dest, rvalue)
                 }
             }
-            mir::StatementKind::SetDiscriminant{ref place, variant_index} => {
+            mir::StatementKind::SetDiscriminant{box ref place, variant_index} => {
                 self.codegen_place(&mut bx, &place.as_ref())
                     .codegen_set_discr(&mut bx, variant_index);
                 bx
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index a6f7c8f227c99..413f7e2e40635 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -1600,7 +1600,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             "annotate_argument_and_return_for_borrow: location={:?}",
             location
         );
-        if let Some(&Statement { kind: StatementKind::Assign(ref reservation, _), ..})
+        if let Some(&Statement { kind: StatementKind::Assign(box(ref reservation, _)), ..})
              = &self.body[location.block].statements.get(location.statement_index)
         {
             debug!(
@@ -1625,11 +1625,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     target, stmt
                 );
                 if let StatementKind::Assign(
-                    Place {
-                        base: PlaceBase::Local(assigned_to),
-                        projection: box [],
-                    },
-                    box rvalue
+                    box(
+                        Place {
+                            base: PlaceBase::Local(assigned_to),
+                            projection: box [],
+                        },
+                        rvalue
+                    )
                 ) = &stmt.kind {
                     debug!(
                         "annotate_argument_and_return_for_borrow: assigned_to={:?} \
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index aeee961d2d354..5bccd2835c980 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -41,7 +41,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let mut target = place.local_or_deref_local();
         for stmt in &self.body[location.block].statements[location.statement_index..] {
             debug!("add_moved_or_invoked_closure_note: stmt={:?} target={:?}", stmt, target);
-            if let StatementKind::Assign(into, box Rvalue::Use(from)) = &stmt.kind {
+            if let StatementKind::Assign(box(into, Rvalue::Use(from))) = &stmt.kind {
                 debug!("add_fnonce_closure_note: into={:?} from={:?}", into, from);
                 match from {
                     Operand::Copy(ref place) |
@@ -792,8 +792,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
         debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
         if let  StatementKind::Assign(
-            _,
-            box Rvalue::Aggregate(ref kind, ref places)
+            box(_, Rvalue::Aggregate(ref kind, ref places))
         ) = stmt.kind {
             let (def_id, is_generator) = match kind {
                 box AggregateKind::Closure(def_id, _) => (def_id, false),
@@ -830,10 +829,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             .get(location.statement_index)
         {
             Some(&Statement {
-                kind: StatementKind::Assign(Place {
+                kind: StatementKind::Assign(box(Place {
                     base: PlaceBase::Local(local),
                     projection: box [],
-                }, _),
+                }, _)),
                 ..
             }) => local,
             _ => return OtherUse(use_span),
@@ -846,7 +845,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
         for stmt in &self.body[location.block].statements[location.statement_index + 1..] {
             if let StatementKind::Assign(
-                _, box Rvalue::Aggregate(ref kind, ref places)
+                box(_, Rvalue::Aggregate(ref kind, ref places))
             ) = stmt.kind {
                 let (def_id, is_generator) = match kind {
                     box AggregateKind::Closure(def_id, _) => (def_id, false),
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 2305984a017d0..3b10d8f19668c 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -546,7 +546,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
         self.check_activations(location, span, flow_state);
 
         match stmt.kind {
-            StatementKind::Assign(ref lhs, ref rhs) => {
+            StatementKind::Assign(box(ref lhs, ref rhs)) => {
                 self.consume_rvalue(
                     location,
                     (rhs, span),
@@ -561,7 +561,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx
                     flow_state,
                 );
             }
-            StatementKind::FakeRead(_, ref place) => {
+            StatementKind::FakeRead(_, box ref place) => {
                 // Read for match doesn't access any memory and is used to
                 // assert that a place is safe and live. So we don't have to
                 // do any checks here.
@@ -1387,7 +1387,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 let stmt = &bbd.statements[loc.statement_index];
                 debug!("temporary assigned in: stmt={:?}", stmt);
 
-                if let StatementKind::Assign(_, box Rvalue::Ref(_, _, ref source)) = stmt.kind {
+                if let StatementKind::Assign(box(_, Rvalue::Ref(_, _, ref source))) = stmt.kind {
                     propagate_closure_used_mut_place(self, source);
                 } else {
                     bug!("closures should only capture user variables \
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index cdba1aafdacb0..aa732b0092a22 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -89,11 +89,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 // If that ever stops being the case, then the ever initialized
                 // flow could be used.
                 if let Some(StatementKind::Assign(
-                    Place {
-                        base: PlaceBase::Local(local),
-                        projection: box [],
-                    },
-                    box Rvalue::Use(Operand::Move(move_from)),
+                    box(
+                        Place {
+                            base: PlaceBase::Local(local),
+                            projection: box [],
+                        },
+                        Rvalue::Use(Operand::Move(move_from))
+                    )
                 )) = self.body.basic_blocks()[location.block]
                     .statements
                     .get(location.statement_index)
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
index ad68b4bc054bb..eae2f832ba791 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -541,10 +541,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         // it which simplifies the termination logic.
         let mut queue = vec![location];
         let mut target = if let Some(&Statement {
-            kind: StatementKind::Assign(Place {
+            kind: StatementKind::Assign(box(Place {
                 base: PlaceBase::Local(local),
                 projection: box [],
-            }, _),
+            }, _)),
             ..
         }) = stmt
         {
@@ -567,7 +567,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 debug!("was_captured_by_trait_object: stmt={:?}", stmt);
 
                 // The only kind of statement that we care about is assignments...
-                if let StatementKind::Assign(place, box rvalue) = &stmt.kind {
+                if let StatementKind::Assign(box(place, rvalue)) = &stmt.kind {
                     let into = match place.local_or_deref_local() {
                         Some(into) => into,
                         None => {
diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs
index 71106af767064..1d429e3a6dee6 100644
--- a/src/librustc_mir/borrow_check/nll/invalidation.rs
+++ b/src/librustc_mir/borrow_check/nll/invalidation.rs
@@ -66,7 +66,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
         self.check_activations(location);
 
         match statement.kind {
-            StatementKind::Assign(ref lhs, ref rhs) => {
+            StatementKind::Assign(box(ref lhs, ref rhs)) => {
                 self.consume_rvalue(
                     location,
                     rhs,
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 599472958f4fc..10c038bc3336f 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -1343,7 +1343,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         debug!("check_stmt: {:?}", stmt);
         let tcx = self.tcx();
         match stmt.kind {
-            StatementKind::Assign(ref place, ref rv) => {
+            StatementKind::Assign(box(ref place, ref rv)) => {
                 // Assignments to temporaries are not "interesting";
                 // they are not caused by the user, but rather artifacts
                 // of lowering. Assignments to other sorts of places *are* interesting
@@ -1450,7 +1450,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     );
                 };
             }
-            StatementKind::AscribeUserType(ref place, variance, box ref projection) => {
+            StatementKind::AscribeUserType(box(ref place, ref projection), variance) => {
                 let place_ty = place.ty(body, tcx).ty;
                 if let Err(terr) = self.relate_type_and_user_type(
                     place_ty,
diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs
index 8bfd24a1e5915..695080dfe23d9 100644
--- a/src/librustc_mir/borrow_check/used_muts.rs
+++ b/src/librustc_mir/borrow_check/used_muts.rs
@@ -89,7 +89,7 @@ impl<'visit, 'cx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'tc
         _location: Location,
     ) {
         match &statement.kind {
-            StatementKind::Assign(into, _) => {
+            StatementKind::Assign(box(into, _)) => {
                 if let PlaceBase::Local(local) = into.base {
                     debug!(
                         "visit_statement: statement={:?} local={:?} \
diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs
index 778d1e71cedfc..3ed6b4ff34678 100644
--- a/src/librustc_mir/build/cfg.rs
+++ b/src/librustc_mir/build/cfg.rs
@@ -37,7 +37,7 @@ impl<'tcx> CFG<'tcx> {
                        rvalue: Rvalue<'tcx>) {
         self.push(block, Statement {
             source_info,
-            kind: StatementKind::Assign(place.clone(), box rvalue)
+            kind: StatementKind::Assign(box(place.clone(), rvalue))
         });
     }
 
diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs
index 5af66faf6ee1e..09b33c6654a9d 100644
--- a/src/librustc_mir/build/expr/as_place.rs
+++ b/src/librustc_mir/build/expr/as_place.rs
@@ -147,9 +147,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         Statement {
                             source_info,
                             kind: StatementKind::AscribeUserType(
-                                place.clone(),
+                                box(
+                                    place.clone(),
+                                    UserTypeProjection { base: annotation_index, projs: vec![], }
+                                ),
                                 Variance::Invariant,
-                                box UserTypeProjection { base: annotation_index, projs: vec![], },
                             ),
                         },
                     );
@@ -174,9 +176,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         Statement {
                             source_info,
                             kind: StatementKind::AscribeUserType(
-                                Place::from(temp.clone()),
+                                box(
+                                    Place::from(temp.clone()),
+                                    UserTypeProjection { base: annotation_index, projs: vec![], },
+                                ),
                                 Variance::Invariant,
-                                box UserTypeProjection { base: annotation_index, projs: vec![], },
                             ),
                         },
                     );
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 64368ab604645..613044dba2902 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -135,7 +135,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             source_info,
             kind: StatementKind::FakeRead(
                 FakeReadCause::ForMatchedPlace,
-                scrutinee_place.clone(),
+                box(scrutinee_place.clone()),
             ),
         });
 
@@ -320,7 +320,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     block,
                     Statement {
                         source_info,
-                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, place),
+                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, box(place)),
                     },
                 );
 
@@ -362,12 +362,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     block,
                     Statement {
                         source_info: pattern_source_info,
-                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, place.clone()),
+                        kind: StatementKind::FakeRead(FakeReadCause::ForLet, box(place.clone())),
                     },
                 );
 
                 let ty_source_info = self.source_info(user_ty_span);
-                let user_ty = box pat_ascription_ty.user_ty(
+                let user_ty = pat_ascription_ty.user_ty(
                     &mut self.canonical_user_type_annotations,
                     place.ty(&self.local_decls, self.hir.tcx()).ty,
                     ty_source_info.span,
@@ -377,7 +377,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     Statement {
                         source_info: ty_source_info,
                         kind: StatementKind::AscribeUserType(
-                            place,
+                            box(
+                                place,
+                                user_ty,
+                            ),
                             // We always use invariant as the variance here. This is because the
                             // variance field from the ascription refers to the variance to use
                             // when applying the type to the value being matched, but this
@@ -393,7 +396,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             // contrast, is intended to be used to relate `T` to the type of
                             // `<expr>`.
                             ty::Variance::Invariant,
-                            user_ty,
                         ),
                     },
                 );
@@ -1523,7 +1525,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     source_info: guard_end,
                     kind: StatementKind::FakeRead(
                         FakeReadCause::ForMatchGuard,
-                        Place::from(temp),
+                        box(Place::from(temp)),
                     ),
                 });
             }
@@ -1573,7 +1575,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     post_guard_block,
                     Statement {
                         source_info: guard_end,
-                        kind: StatementKind::FakeRead(FakeReadCause::ForGuardBinding, place),
+                        kind: StatementKind::FakeRead(FakeReadCause::ForGuardBinding, box(place)),
                     },
                 );
             }
@@ -1606,7 +1608,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 ascription.user_ty,
             );
 
-            let user_ty = box ascription.user_ty.clone().user_ty(
+            let user_ty = ascription.user_ty.clone().user_ty(
                 &mut self.canonical_user_type_annotations,
                 ascription.source.ty(&self.local_decls, self.hir.tcx()).ty,
                 source_info.span
@@ -1616,9 +1618,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 Statement {
                     source_info,
                     kind: StatementKind::AscribeUserType(
-                        ascription.source.clone(),
+                        box(
+                            ascription.source.clone(),
+                            user_ty,
+                        ),
                         ascription.variance,
-                        user_ty,
                     ),
                 },
             );
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index 04674fb58cb9f..a86fcb30f4d36 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -268,8 +268,8 @@ impl<'a, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'tcx> {
 
         debug!("Borrows::statement_effect: stmt={:?}", stmt);
         match stmt.kind {
-            mir::StatementKind::Assign(ref lhs, ref rhs) => {
-                if let mir::Rvalue::Ref(_, _, ref place) = **rhs {
+            mir::StatementKind::Assign(box(ref lhs, ref rhs)) => {
+                if let mir::Rvalue::Ref(_, _, ref place) = *rhs {
                     if place.ignore_borrow(
                         self.tcx,
                         self.body,
diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs
index 0e01701ea9e44..0f66b13fdc51a 100644
--- a/src/librustc_mir/dataflow/impls/storage_liveness.rs
+++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs
@@ -119,8 +119,8 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
         match stmt.kind {
             StatementKind::StorageLive(l) => sets.gen(l),
             StatementKind::StorageDead(l) => sets.kill(l),
-            StatementKind::Assign(ref place, _)
-            | StatementKind::SetDiscriminant { ref place, .. } => {
+            StatementKind::Assign(box(ref place, _))
+            | StatementKind::SetDiscriminant { box ref place, .. } => {
                 if let PlaceBase::Local(local) = place.base {
                     sets.gen(local);
                 }
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index a4427287c4f80..698c50166270a 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -268,7 +268,7 @@ struct Gatherer<'b, 'a, 'tcx> {
 impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
         match stmt.kind {
-            StatementKind::Assign(ref place, ref rval) => {
+            StatementKind::Assign(box(ref place, ref rval)) => {
                 self.create_move_path(place);
                 if let RvalueInitializationState::Shallow = rval.initialization_state() {
                     // Box starts out uninitialized - need to create a separate
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index ca4da451a1f2d..affca10bf5265 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -82,7 +82,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         self.memory.tcx.span = stmt.source_info.span;
 
         match stmt.kind {
-            Assign(ref place, ref rvalue) => self.eval_rvalue_into_place(rvalue, place)?,
+            Assign(box(ref place, ref rvalue)) => self.eval_rvalue_into_place(rvalue, place)?,
 
             SetDiscriminant {
                 ref place,
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 9086ae844dd52..6daca5e261431 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -217,7 +217,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
             // Function arguments should be retagged, and we make this one raw.
             body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
                 source_info,
-                kind: StatementKind::Retag(RetagKind::Raw, dropee_ptr.clone()),
+                kind: StatementKind::Retag(RetagKind::Raw, box(dropee_ptr.clone())),
             });
         }
         let patch = {
@@ -415,8 +415,10 @@ impl CloneShimBuilder<'tcx> {
         let rcvr = Place::from(Local::new(1+0)).deref();
         let ret_statement = self.make_statement(
             StatementKind::Assign(
-                Place::return_place(),
-                box Rvalue::Use(Operand::Copy(rcvr))
+                box(
+                    Place::return_place(),
+                    Rvalue::Use(Operand::Copy(rcvr))
+                )
             )
         );
         self.block(vec![ret_statement], TerminatorKind::Return, false);
@@ -458,8 +460,10 @@ impl CloneShimBuilder<'tcx> {
         // `let ref_loc: &ty = &src;`
         let statement = self.make_statement(
             StatementKind::Assign(
-                ref_loc.clone(),
-                box Rvalue::Ref(tcx.lifetimes.re_erased, BorrowKind::Shared, src)
+                box(
+                    ref_loc.clone(),
+                    Rvalue::Ref(tcx.lifetimes.re_erased, BorrowKind::Shared, src)
+                )
             )
         );
 
@@ -486,8 +490,10 @@ impl CloneShimBuilder<'tcx> {
         let cond = self.make_place(Mutability::Mut, tcx.types.bool);
         let compute_cond = self.make_statement(
             StatementKind::Assign(
-                cond.clone(),
-                box Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg))
+                box(
+                    cond.clone(),
+                    Rvalue::BinaryOp(BinOp::Ne, Operand::Copy(end), Operand::Copy(beg))
+                )
             )
         );
 
@@ -521,14 +527,18 @@ impl CloneShimBuilder<'tcx> {
         let inits = vec![
             self.make_statement(
                 StatementKind::Assign(
-                    Place::from(beg),
-                    box Rvalue::Use(Operand::Constant(self.make_usize(0)))
+                    box(
+                        Place::from(beg),
+                        Rvalue::Use(Operand::Constant(self.make_usize(0)))
+                    )
                 )
             ),
             self.make_statement(
                 StatementKind::Assign(
-                    end.clone(),
-                    box Rvalue::Use(Operand::Constant(self.make_usize(len)))
+                    box(
+                        end.clone(),
+                        Rvalue::Use(Operand::Constant(self.make_usize(len)))
+                    )
                 )
             )
         ];
@@ -559,11 +569,13 @@ impl CloneShimBuilder<'tcx> {
         let statements = vec![
             self.make_statement(
                 StatementKind::Assign(
-                    Place::from(beg),
-                    box Rvalue::BinaryOp(
-                        BinOp::Add,
-                        Operand::Copy(Place::from(beg)),
-                        Operand::Constant(self.make_usize(1))
+                    box(
+                        Place::from(beg),
+                        Rvalue::BinaryOp(
+                            BinOp::Add,
+                            Operand::Copy(Place::from(beg)),
+                            Operand::Constant(self.make_usize(1))
+                        )
                     )
                 )
             )
@@ -582,8 +594,10 @@ impl CloneShimBuilder<'tcx> {
         let beg = self.local_decls.push(temp_decl(Mutability::Mut, tcx.types.usize, span));
         let init = self.make_statement(
             StatementKind::Assign(
-                Place::from(beg),
-                box Rvalue::Use(Operand::Constant(self.make_usize(0)))
+                box(
+                    Place::from(beg),
+                    Rvalue::Use(Operand::Constant(self.make_usize(0)))
+                )
             )
         );
         self.block(vec![init], TerminatorKind::Goto { target: BasicBlock::new(6) }, true);
@@ -609,11 +623,13 @@ impl CloneShimBuilder<'tcx> {
         // `goto #6;`
         let statement = self.make_statement(
             StatementKind::Assign(
-                Place::from(beg),
-                box Rvalue::BinaryOp(
-                    BinOp::Add,
-                    Operand::Copy(Place::from(beg)),
-                    Operand::Constant(self.make_usize(1))
+                box(
+                    Place::from(beg),
+                    Rvalue::BinaryOp(
+                        BinOp::Add,
+                        Operand::Copy(Place::from(beg)),
+                        Operand::Constant(self.make_usize(1))
+                    )
                 )
             )
         );
@@ -727,8 +743,10 @@ fn build_call_shim<'tcx>(
             statements.push(Statement {
                 source_info,
                 kind: StatementKind::Assign(
-                    Place::from(ref_rcvr),
-                    box Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l)
+                    box(
+                        Place::from(ref_rcvr),
+                        Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_l)
+                    )
                 )
             });
             Operand::Move(Place::from(ref_rcvr))
diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs
index 466f6060827ec..833c8b1646bb6 100644
--- a/src/librustc_mir/transform/add_retag.rs
+++ b/src/librustc_mir/transform/add_retag.rs
@@ -89,7 +89,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
             basic_blocks[START_BLOCK].statements.splice(0..0,
                 places.into_iter().map(|place| Statement {
                     source_info,
-                    kind: StatementKind::Retag(RetagKind::FnEntry, place),
+                    kind: StatementKind::Retag(RetagKind::FnEntry, box(place)),
                 })
             );
         }
@@ -125,7 +125,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
         for (source_info, dest_place, dest_block) in returns {
             basic_blocks[dest_block].statements.insert(0, Statement {
                 source_info,
-                kind: StatementKind::Retag(RetagKind::Default, dest_place),
+                kind: StatementKind::Retag(RetagKind::Default, box(dest_place)),
             });
         }
 
@@ -137,11 +137,11 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
             for i in (0..block_data.statements.len()).rev() {
                 let (retag_kind, place) = match block_data.statements[i].kind {
                     // If we are casting *from* a reference, we may have to retag-as-raw.
-                    StatementKind::Assign(ref place, box Rvalue::Cast(
+                    StatementKind::Assign(box(ref place, Rvalue::Cast(
                         CastKind::Misc,
                         ref src,
                         dest_ty,
-                    )) => {
+                    ))) => {
                         let src_ty = src.ty(&*local_decls, tcx);
                         if src_ty.is_region_ptr() {
                             // The only `Misc` casts on references are those creating raw pointers.
@@ -155,7 +155,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
                     // Assignments of reference or ptr type are the ones where we may have
                     // to update tags.  This includes `x = &[mut] ...` and hence
                     // we also retag after taking a reference!
-                    StatementKind::Assign(ref place, box ref rvalue) if needs_retag(place) => {
+                    StatementKind::Assign(box(ref place, ref rvalue)) if needs_retag(place) => {
                         let kind = match rvalue {
                             Rvalue::Ref(_, borrow_kind, _)
                                 if borrow_kind.allows_two_phase_borrow()
@@ -173,7 +173,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
                 let source_info = block_data.statements[i].source_info;
                 block_data.statements.insert(i+1, Statement {
                     source_info,
-                    kind: StatementKind::Retag(retag_kind, place),
+                    kind: StatementKind::Retag(retag_kind, box(place)),
                 });
             }
         }
diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs
index ede1cb62f9451..ea173279aa073 100644
--- a/src/librustc_mir/transform/cleanup_post_borrowck.rs
+++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs
@@ -39,7 +39,7 @@ impl<'tcx> MutVisitor<'tcx> for DeleteNonCodegenStatements {
                        location: Location) {
         match statement.kind {
             StatementKind::AscribeUserType(..)
-            | StatementKind::Assign(_, box Rvalue::Ref(_, BorrowKind::Shallow, _))
+            | StatementKind::Assign(box(_, Rvalue::Ref(_, BorrowKind::Shallow, _)))
             | StatementKind::FakeRead(..) => statement.make_nop(),
             _ => (),
         }
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 2e91561f2eee1..614d5d2a4a2fb 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -665,7 +665,7 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
         location: Location,
     ) {
         trace!("visit_statement: {:?}", statement);
-        if let StatementKind::Assign(ref place, ref mut rval) = statement.kind {
+        if let StatementKind::Assign(box(ref place, ref mut rval)) = statement.kind {
             let place_ty: Ty<'tcx> = place
                 .ty(&self.local_decls, self.tcx)
                 .ty;
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs
index 20bdb4b03f081..28f97f41b50cf 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/src/librustc_mir/transform/copy_prop.rs
@@ -94,11 +94,13 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation {
                     // That use of the source must be an assignment.
                     match statement.kind {
                         StatementKind::Assign(
-                            Place {
-                                base: PlaceBase::Local(local),
-                                projection: box [],
-                            },
-                            box Rvalue::Use(ref operand)
+                            box(
+                                Place {
+                                    base: PlaceBase::Local(local),
+                                    projection: box [],
+                                },
+                                Rvalue::Use(ref operand)
+                            )
                         ) if local == dest_local => {
                             let maybe_action = match *operand {
                                 Operand::Copy(ref src_place) |
@@ -148,24 +150,28 @@ fn eliminate_self_assignments(
             if let Some(stmt) = body[location.block].statements.get(location.statement_index) {
                 match stmt.kind {
                     StatementKind::Assign(
-                        Place {
-                            base: PlaceBase::Local(local),
-                            projection: box [],
-                        },
-                        box Rvalue::Use(Operand::Copy(Place {
-                            base: PlaceBase::Local(src_local),
-                            projection: box [],
-                        })),
+                        box(
+                            Place {
+                                base: PlaceBase::Local(local),
+                                projection: box [],
+                            },
+                            Rvalue::Use(Operand::Copy(Place {
+                                base: PlaceBase::Local(src_local),
+                                projection: box [],
+                            })),
+                        )
                     ) |
                     StatementKind::Assign(
-                        Place {
-                            base: PlaceBase::Local(local),
-                            projection: box [],
-                        },
-                        box Rvalue::Use(Operand::Move(Place {
-                            base: PlaceBase::Local(src_local),
-                            projection: box [],
-                        })),
+                        box(
+                            Place {
+                                base: PlaceBase::Local(local),
+                                projection: box [],
+                            },
+                            Rvalue::Use(Operand::Move(Place {
+                                base: PlaceBase::Local(src_local),
+                                projection: box [],
+                            })),
+                        )
                     ) if local == dest_local && dest_local == src_local => {}
                     _ => {
                         continue;
diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs
index 1fc7ce09aa647..c1224be6324e2 100644
--- a/src/librustc_mir/transform/deaggregator.rs
+++ b/src/librustc_mir/transform/deaggregator.rs
@@ -12,8 +12,8 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
         for bb in basic_blocks {
             bb.expand_statements(|stmt| {
                 // FIXME(eddyb) don't match twice on `stmt.kind` (post-NLL).
-                if let StatementKind::Assign(_, ref rhs) = stmt.kind {
-                    if let Rvalue::Aggregate(ref kind, _) = **rhs {
+                if let StatementKind::Assign(box(_, ref rhs)) = stmt.kind {
+                    if let Rvalue::Aggregate(ref kind, _) = *rhs {
                         // FIXME(#48193) Deaggregate arrays when it's cheaper to do so.
                         if let AggregateKind::Array(_) = **kind {
                             return None;
@@ -28,7 +28,7 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
                 let stmt = stmt.replace_nop();
                 let source_info = stmt.source_info;
                 let (lhs, kind, operands) = match stmt.kind {
-                    StatementKind::Assign(lhs, box rvalue) => {
+                    StatementKind::Assign(box(lhs, rvalue)) => {
                         match rvalue {
                             Rvalue::Aggregate(kind, operands) => (lhs, kind, operands),
                             _ => bug!()
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index de5978c3a3525..a9c66b3c8c6d1 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -452,7 +452,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
         assert!(!data.is_cleanup, "DropAndReplace in unwind path not supported");
 
         let assign = Statement {
-            kind: StatementKind::Assign(location.clone(), box Rvalue::Use(value.clone())),
+            kind: StatementKind::Assign(box(location.clone(), Rvalue::Use(value.clone()))),
             source_info: terminator.source_info
         };
 
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index cf899c64406bc..0ce2db93c421d 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -217,7 +217,10 @@ impl TransformVisitor<'tcx> {
         let self_place = Place::from(self_arg());
         Statement {
             source_info,
-            kind: StatementKind::SetDiscriminant { place: self_place, variant_index: state_disc },
+            kind: StatementKind::SetDiscriminant {
+                place: box self_place,
+                variant_index: state_disc,
+            },
         }
     }
 
@@ -230,7 +233,7 @@ impl TransformVisitor<'tcx> {
         let self_place = Place::from(self_arg());
         let assign = Statement {
             source_info: source_info(body),
-            kind: StatementKind::Assign(temp.clone(), box Rvalue::Discriminant(self_place)),
+            kind: StatementKind::Assign(box(temp.clone(), Rvalue::Discriminant(self_place))),
         };
         (assign, temp)
     }
@@ -288,8 +291,12 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
             // We must assign the value first in case it gets declared dead below
             data.statements.push(Statement {
                 source_info,
-                kind: StatementKind::Assign(Place::return_place(),
-                                            box self.make_state(state_idx, v)),
+                kind: StatementKind::Assign(
+                    box(
+                        Place::return_place(),
+                        self.make_state(state_idx, v)
+                    )
+                ),
             });
             let state = if let Some(resume) = resume { // Yield
                 let state = 3 + self.suspension_points.len();
@@ -929,7 +936,7 @@ fn create_generator_drop_shim<'tcx>(
         // Alias tracking must know we changed the type
         body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement {
             source_info,
-            kind: StatementKind::Retag(RetagKind::Raw, Place::from(self_arg())),
+            kind: StatementKind::Retag(RetagKind::Raw, box Place::from(self_arg())),
         })
     }
 
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 2b3c6d55f24dd..5ad026dc143c9 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -457,7 +457,7 @@ impl Inliner<'tcx> {
 
                     let stmt = Statement {
                         source_info: callsite.location,
-                        kind: StatementKind::Assign(tmp.clone(), box dest)
+                        kind: StatementKind::Assign(box(tmp.clone(), dest))
                     };
                     caller_body[callsite.bb]
                         .statements.push(stmt);
@@ -608,7 +608,7 @@ impl Inliner<'tcx> {
 
         let stmt = Statement {
             source_info: callsite.location,
-            kind: StatementKind::Assign(Place::from(arg_tmp), box arg),
+            kind: StatementKind::Assign(box(Place::from(arg_tmp), arg)),
         };
         caller_body[callsite.bb].statements.push(stmt);
         arg_tmp
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 0723a0c992e8e..7d1b96b8be170 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -187,7 +187,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                 span,
                 scope: OUTERMOST_SOURCE_SCOPE
             },
-            kind: StatementKind::Assign(Place::from(dest), box rvalue)
+            kind: StatementKind::Assign(box(Place::from(dest), rvalue))
         });
     }
 
@@ -222,10 +222,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
         // First, take the Rvalue or Call out of the source MIR,
         // or duplicate it, depending on keep_original.
         if loc.statement_index < no_stmts {
-            let (rvalue, source_info) = {
+            let (mut rvalue, source_info) = {
                 let statement = &mut self.source[loc.block].statements[loc.statement_index];
                 let rhs = match statement.kind {
-                    StatementKind::Assign(_, ref mut rhs) => rhs,
+                    StatementKind::Assign(box(_, ref mut rhs)) => rhs,
                     _ => {
                         span_bug!(statement.source_info.span, "{:?} is not an assignment",
                                   statement);
@@ -235,12 +235,11 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                 (if self.keep_original {
                     rhs.clone()
                 } else {
-                    let unit = box Rvalue::Aggregate(box AggregateKind::Tuple, vec![]);
+                    let unit = Rvalue::Aggregate(box AggregateKind::Tuple, vec![]);
                     mem::replace(rhs, unit)
                 }, statement.source_info)
             };
 
-            let mut rvalue = *rvalue;
             self.visit_rvalue(&mut rvalue, loc);
             self.assign(new_temp, rvalue, source_info.span);
         } else {
@@ -326,7 +325,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                 Candidate::Ref(loc) => {
                     let ref mut statement = blocks[loc.block].statements[loc.statement_index];
                     match statement.kind {
-                        StatementKind::Assign(_, box Rvalue::Ref(_, _, ref mut place)) => {
+                        StatementKind::Assign(box(_, Rvalue::Ref(_, _, ref mut place))) => {
                             // Use the underlying local for this (necessarily interior) borrow.
                             let ty = place.base.ty(local_decls).ty;
                             let span = statement.source_info.span;
@@ -345,7 +344,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                 Candidate::Repeat(loc) => {
                     let ref mut statement = blocks[loc.block].statements[loc.statement_index];
                     match statement.kind {
-                        StatementKind::Assign(_, box Rvalue::Repeat(ref mut operand, _)) => {
+                        StatementKind::Assign(box(_, Rvalue::Repeat(ref mut operand, _))) => {
                             let ty = operand.ty(local_decls, self.tcx);
                             let span = statement.source_info.span;
                             mem::replace(
@@ -420,10 +419,10 @@ pub fn promote_candidates<'tcx>(
             Candidate::Repeat(Location { block, statement_index }) |
             Candidate::Ref(Location { block, statement_index }) => {
                 match body[block].statements[statement_index].kind {
-                    StatementKind::Assign(Place {
+                    StatementKind::Assign(box(Place {
                         base: PlaceBase::Local(local),
                         projection: box [],
-                    }, _) => {
+                    }, _)) => {
                         if temps[local] == TempState::PromotedOut {
                             // Already promoted.
                             continue;
@@ -473,10 +472,10 @@ pub fn promote_candidates<'tcx>(
     for block in body.basic_blocks_mut() {
         block.statements.retain(|statement| {
             match statement.kind {
-                StatementKind::Assign(Place {
+                StatementKind::Assign(box(Place {
                     base: PlaceBase::Local(index),
                     projection: box [],
-                }, _) |
+                }, _)) |
                 StatementKind::StorageLive(index) |
                 StatementKind::StorageDead(index) => {
                     !promoted(index)
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index e05b0c9662056..7cc1e634cf812 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -982,23 +982,25 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
         for candidate in &self.promotion_candidates {
             match *candidate {
                 Candidate::Repeat(Location { block: bb, statement_index: stmt_idx }) => {
-                    if let StatementKind::Assign(_, box Rvalue::Repeat(
+                    if let StatementKind::Assign(box(_, Rvalue::Repeat(
                         Operand::Move(Place {
                             base: PlaceBase::Local(index),
                             projection: box [],
                         }),
                         _
-                    )) = self.body[bb].statements[stmt_idx].kind {
+                    ))) = self.body[bb].statements[stmt_idx].kind {
                         promoted_temps.insert(index);
                     }
                 }
                 Candidate::Ref(Location { block: bb, statement_index: stmt_idx }) => {
                     if let StatementKind::Assign(
-                        _,
-                        box Rvalue::Ref(_, _, Place {
-                            base: PlaceBase::Local(index),
-                            projection: box [],
-                        })
+                        box(
+                            _,
+                            Rvalue::Ref(_, _, Place {
+                                base: PlaceBase::Local(index),
+                                projection: box [],
+                            })
+                        )
                     ) = self.body[bb].statements[stmt_idx].kind {
                         promoted_temps.insert(index);
                     }
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index cb2da1d5ff916..80e020a9eb7e6 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -206,7 +206,7 @@ fn check_statement(
 ) -> McfResult {
     let span = statement.source_info.span;
     match &statement.kind {
-        StatementKind::Assign(place, rval) => {
+        StatementKind::Assign(box(place, rval)) => {
             check_place(place, span)?;
             check_rvalue(tcx, body, rval, span)
         }
diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs
index 07669e2c0c986..70b11944e2fbc 100644
--- a/src/librustc_mir/transform/remove_noop_landing_pads.rs
+++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs
@@ -41,10 +41,10 @@ impl RemoveNoopLandingPads {
                     // These are all nops in a landing pad
                 }
 
-                StatementKind::Assign(Place {
+                StatementKind::Assign(box(Place {
                     base: PlaceBase::Local(_),
                     projection: box [],
-                }, box Rvalue::Use(_)) => {
+                }, Rvalue::Use(_))) => {
                     // Writing to a local (e.g., a drop flag) does not
                     // turn a landing pad to a non-nop
                 }
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index 208407bb9a5e0..68fa082d29407 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -150,7 +150,7 @@ fn each_block<'tcx, O>(
     for (j, stmt) in statements.iter().enumerate() {
         debug!("rustc_peek: ({:?},{}) {:?}", bb, j, stmt);
         let (place, rvalue) = match stmt.kind {
-            mir::StatementKind::Assign(ref place, ref rvalue) => {
+            mir::StatementKind::Assign(box(ref place, ref rvalue)) => {
                 (place, rvalue)
             }
             mir::StatementKind::FakeRead(..) |
@@ -166,7 +166,7 @@ fn each_block<'tcx, O>(
         };
 
         if place == peek_arg_place {
-            if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, ref peeking_at_place) = **rvalue {
+            if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, ref peeking_at_place) = *rvalue {
                 // Okay, our search is over.
                 match move_data.rev_lookup.find(peeking_at_place.as_ref()) {
                     LookupResult::Exact(peek_mpi) => {
diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs
index 2f900f2638f48..34ad5cb5dc787 100644
--- a/src/librustc_mir/transform/uniform_array_move_out.rs
+++ b/src/librustc_mir/transform/uniform_array_move_out.rs
@@ -200,8 +200,8 @@ impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut {
 
             for candidate in &visitor.candidates {
                 let statement = &body[candidate.block].statements[candidate.statement_index];
-                if let StatementKind::Assign(ref dst_place, ref rval) = statement.kind {
-                    if let Rvalue::Aggregate(box AggregateKind::Array(_), ref items) = **rval {
+                if let StatementKind::Assign(box(ref dst_place, ref rval)) = statement.kind {
+                    if let Rvalue::Aggregate(box AggregateKind::Array(_), ref items) = *rval {
                         let items : Vec<_> = items.iter().map(|item| {
                             if let Operand::Move(Place {
                                 base: PlaceBase::Local(local),
@@ -293,24 +293,28 @@ impl RestoreSubsliceArrayMoveOut {
             if block.statements.len() > location.statement_index {
                 let statement = &block.statements[location.statement_index];
                 if let StatementKind::Assign(
-                    Place {
-                        base: PlaceBase::Local(_),
-                        projection: box [],
-                    },
-                    box Rvalue::Use(Operand::Move(Place {
-                        base: _,
-                        projection: box [.., ProjectionElem::ConstantIndex {
+                    box(
+                        Place {
+                            base: PlaceBase::Local(_),
+                            projection: box [],
+                        },
+                        Rvalue::Use(Operand::Move(Place {
+                            base: _,
+                            projection: box [.., ProjectionElem::ConstantIndex {
                                 offset, min_length: _, from_end: false
-                        }],
-                    })),
+                            }],
+                        })),
+                    )
                 ) = &statement.kind {
                     // FIXME remove once we can use slices patterns
                     if let StatementKind::Assign(
-                        _,
-                        box Rvalue::Use(Operand::Move(Place {
-                            base,
-                            projection: box [proj_base @ .., _],
-                        })),
+                        box(
+                            _,
+                            Rvalue::Use(Operand::Move(Place {
+                                base,
+                                projection: box [proj_base @ .., _],
+                            })),
+                        )
                     ) = &statement.kind {
                         return Some((*offset, PlaceRef {
                             base,
diff --git a/src/librustc_mir/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs
index 98e70671ab715..b3565d40b8e21 100644
--- a/src/librustc_mir/util/aggregate.rs
+++ b/src/librustc_mir/util/aggregate.rs
@@ -24,7 +24,7 @@ pub fn expand_aggregate<'tcx>(
             if adt_def.is_enum() {
                 set_discriminant = Some(Statement {
                     kind: StatementKind::SetDiscriminant {
-                        place: lhs.clone(),
+                        place: box(lhs.clone()),
                         variant_index,
                     },
                     source_info,
@@ -39,7 +39,7 @@ pub fn expand_aggregate<'tcx>(
             let variant_index = VariantIdx::new(0);
             set_discriminant = Some(Statement {
                 kind: StatementKind::SetDiscriminant {
-                    place: lhs.clone(),
+                    place: box(lhs.clone()),
                     variant_index,
                 },
                 source_info,
@@ -70,7 +70,7 @@ pub fn expand_aggregate<'tcx>(
         };
         Statement {
             source_info,
-            kind: StatementKind::Assign(lhs_field, box Rvalue::Use(op)),
+            kind: StatementKind::Assign(box(lhs_field, Rvalue::Use(op))),
         }
     }).chain(set_discriminant)
 }
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index c60af70712d1b..52ad97bbde1d7 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -978,7 +978,7 @@ where
     fn assign(&self, lhs: &Place<'tcx>, rhs: Rvalue<'tcx>) -> Statement<'tcx> {
         Statement {
             source_info: self.source_info,
-            kind: StatementKind::Assign(lhs.clone(), box rhs)
+            kind: StatementKind::Assign(box(lhs.clone(), rhs))
         }
     }
 }
diff --git a/src/librustc_mir/util/patch.rs b/src/librustc_mir/util/patch.rs
index eb457dacf8467..2ea9924af7f28 100644
--- a/src/librustc_mir/util/patch.rs
+++ b/src/librustc_mir/util/patch.rs
@@ -120,7 +120,7 @@ impl<'tcx> MirPatch<'tcx> {
     }
 
     pub fn add_assign(&mut self, loc: Location, place: Place<'tcx>, rv: Rvalue<'tcx>) {
-        self.add_statement(loc, StatementKind::Assign(place, box rv));
+        self.add_statement(loc, StatementKind::Assign(box(place, rv)));
     }
 
     pub fn make_nop(&mut self, loc: Location) {

From 2fcd870711ce267c79408ec631f7eba8e0afcdf6 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Thu, 12 Sep 2019 08:29:17 +1000
Subject: [PATCH 694/943] Box `DiagnosticBuilder`.

It's a large type -- 176 bytes on 64-bit. And it's passed around and
returned from a lot of functions, including within PResult.

This commit boxes it, which reduces memory traffic. In particular,
`PResult` shrinks to 16 bytes in the best case; this reduces instruction
counts by up to 2% on various workloads.
---
 .../annotate_snippet_emitter_writer.rs        |  2 +-
 src/librustc_errors/diagnostic_builder.rs     | 81 +++++++++++--------
 src/librustc_errors/emitter.rs                |  2 +-
 src/libsyntax/parse/mod.rs                    |  7 ++
 4 files changed, 55 insertions(+), 37 deletions(-)

diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs
index 39b906141f74c..c626dd0434d52 100644
--- a/src/librustc_errors/annotate_snippet_emitter_writer.rs
+++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs
@@ -37,7 +37,7 @@ impl Emitter for AnnotateSnippetEmitterWriter {
                                           &mut primary_span,
                                           &mut children,
                                           &db.level,
-                                          db.handler.flags.external_macro_backtrace);
+                                          db.handler().flags.external_macro_backtrace);
 
         self.emit_messages_default(&db.level,
                                    db.message(),
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index 41d0638f7c6bd..7b8902f125aee 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -18,8 +18,17 @@ use log::debug;
 /// extending `HandlerFlags`, accessed via `self.handler.flags`.
 #[must_use]
 #[derive(Clone)]
-pub struct DiagnosticBuilder<'a> {
-    pub handler: &'a Handler,
+pub struct DiagnosticBuilder<'a>(Box<DiagnosticBuilderInner<'a>>);
+
+/// This is a large type, and often used as a return value, especially within
+/// the frequently-used `PResult` type. In theory, return value optimization
+/// (RVO) should avoid unnecessary copying. In practice, it does not (at the
+/// time of writing). The split between `DiagnosticBuilder` and
+/// `DiagnosticBuilderInner` exists to avoid many `memcpy` calls.
+#[must_use]
+#[derive(Clone)]
+struct DiagnosticBuilderInner<'a> {
+    handler: &'a Handler,
     diagnostic: Diagnostic,
     allow_suggestions: bool,
 }
@@ -52,7 +61,7 @@ macro_rules! forward {
     ) => {
         $(#[$attrs])*
         pub fn $n(&mut self, $($name: $ty),*) -> &mut Self {
-            self.diagnostic.$n($($name),*);
+            self.0.diagnostic.$n($($name),*);
             self
         }
     };
@@ -69,7 +78,7 @@ macro_rules! forward {
     ) => {
         $(#[$attrs])*
         pub fn $n<S: Into<MultiSpan>>(&mut self, $($name: $ty),*) -> &mut Self {
-            self.diagnostic.$n($($name),*);
+            self.0.diagnostic.$n($($name),*);
             self
         }
     };
@@ -79,24 +88,28 @@ impl<'a> Deref for DiagnosticBuilder<'a> {
     type Target = Diagnostic;
 
     fn deref(&self) -> &Diagnostic {
-        &self.diagnostic
+        &self.0.diagnostic
     }
 }
 
 impl<'a> DerefMut for DiagnosticBuilder<'a> {
     fn deref_mut(&mut self) -> &mut Diagnostic {
-        &mut self.diagnostic
+        &mut self.0.diagnostic
     }
 }
 
 impl<'a> DiagnosticBuilder<'a> {
+    pub fn handler(&self) -> &'a Handler{
+        self.0.handler
+    }
+
     /// Emit the diagnostic.
     pub fn emit(&mut self) {
         if self.cancelled() {
             return;
         }
 
-        self.handler.emit_db(&self);
+        self.0.handler.emit_db(&self);
         self.cancel();
     }
 
@@ -115,8 +128,8 @@ impl<'a> DiagnosticBuilder<'a> {
     /// Buffers the diagnostic for later emission, unless handler
     /// has disabled such buffering.
     pub fn buffer(mut self, buffered_diagnostics: &mut Vec<Diagnostic>) {
-        if self.handler.flags.dont_buffer_diagnostics ||
-            self.handler.flags.treat_err_as_bug.is_some()
+        if self.0.handler.flags.dont_buffer_diagnostics ||
+            self.0.handler.flags.treat_err_as_bug.is_some()
         {
             self.emit();
             return;
@@ -126,7 +139,7 @@ impl<'a> DiagnosticBuilder<'a> {
         // implements `Drop`.
         let diagnostic;
         unsafe {
-            diagnostic = std::ptr::read(&self.diagnostic);
+            diagnostic = std::ptr::read(&self.0.diagnostic);
             std::mem::forget(self);
         };
         // Logging here is useful to help track down where in logs an error was
@@ -144,7 +157,7 @@ impl<'a> DiagnosticBuilder<'a> {
         span: Option<S>,
     ) -> &mut Self {
         let span = span.map(|s| s.into()).unwrap_or_else(|| MultiSpan::new());
-        self.diagnostic.sub(level, message, span, None);
+        self.0.diagnostic.sub(level, message, span, None);
         self
     }
 
@@ -160,7 +173,7 @@ impl<'a> DiagnosticBuilder<'a> {
     /// locally in whichever way makes the most sense.
     pub fn delay_as_bug(&mut self) {
         self.level = Level::Bug;
-        self.handler.delay_as_bug(self.diagnostic.clone());
+        self.0.handler.delay_as_bug(self.0.diagnostic.clone());
         self.cancel();
     }
 
@@ -171,7 +184,7 @@ impl<'a> DiagnosticBuilder<'a> {
     /// then the snippet will just include that `Span`, which is
     /// called the primary span.
     pub fn span_label<T: Into<String>>(&mut self, span: Span, label: T) -> &mut Self {
-        self.diagnostic.span_label(span, label);
+        self.0.diagnostic.span_label(span, label);
         self
     }
 
@@ -208,10 +221,10 @@ impl<'a> DiagnosticBuilder<'a> {
         suggestion: Vec<(Span, String)>,
         applicability: Applicability,
     ) -> &mut Self {
-        if !self.allow_suggestions {
+        if !self.0.allow_suggestions {
             return self
         }
-        self.diagnostic.multipart_suggestion(
+        self.0.diagnostic.multipart_suggestion(
             msg,
             suggestion,
             applicability,
@@ -225,10 +238,10 @@ impl<'a> DiagnosticBuilder<'a> {
         suggestion: Vec<(Span, String)>,
         applicability: Applicability,
     ) -> &mut Self {
-        if !self.allow_suggestions {
+        if !self.0.allow_suggestions {
             return self
         }
-        self.diagnostic.tool_only_multipart_suggestion(
+        self.0.diagnostic.tool_only_multipart_suggestion(
             msg,
             suggestion,
             applicability,
@@ -236,7 +249,6 @@ impl<'a> DiagnosticBuilder<'a> {
         self
     }
 
-
     pub fn span_suggestion(
         &mut self,
         sp: Span,
@@ -244,10 +256,10 @@ impl<'a> DiagnosticBuilder<'a> {
         suggestion: String,
         applicability: Applicability,
     ) -> &mut Self {
-        if !self.allow_suggestions {
+        if !self.0.allow_suggestions {
             return self
         }
-        self.diagnostic.span_suggestion(
+        self.0.diagnostic.span_suggestion(
             sp,
             msg,
             suggestion,
@@ -263,10 +275,10 @@ impl<'a> DiagnosticBuilder<'a> {
         suggestions: impl Iterator<Item = String>,
         applicability: Applicability,
     ) -> &mut Self {
-        if !self.allow_suggestions {
+        if !self.0.allow_suggestions {
             return self
         }
-        self.diagnostic.span_suggestions(
+        self.0.diagnostic.span_suggestions(
             sp,
             msg,
             suggestions,
@@ -282,10 +294,10 @@ impl<'a> DiagnosticBuilder<'a> {
         suggestion: String,
         applicability: Applicability,
     ) -> &mut Self {
-        if !self.allow_suggestions {
+        if !self.0.allow_suggestions {
             return self
         }
-        self.diagnostic.span_suggestion_short(
+        self.0.diagnostic.span_suggestion_short(
             sp,
             msg,
             suggestion,
@@ -301,10 +313,10 @@ impl<'a> DiagnosticBuilder<'a> {
         suggestion: String,
         applicability: Applicability,
     ) -> &mut Self {
-        if !self.allow_suggestions {
+        if !self.0.allow_suggestions {
             return self
         }
-        self.diagnostic.span_suggestion_hidden(
+        self.0.diagnostic.span_suggestion_hidden(
             sp,
             msg,
             suggestion,
@@ -320,10 +332,10 @@ impl<'a> DiagnosticBuilder<'a> {
         suggestion: String,
         applicability: Applicability,
     ) -> &mut Self {
-        if !self.allow_suggestions {
+        if !self.0.allow_suggestions {
             return self
         }
-        self.diagnostic.tool_only_span_suggestion(
+        self.0.diagnostic.tool_only_span_suggestion(
             sp,
             msg,
             suggestion,
@@ -336,7 +348,7 @@ impl<'a> DiagnosticBuilder<'a> {
     forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self);
 
     pub fn allow_suggestions(&mut self, allow: bool) -> &mut Self {
-        self.allow_suggestions = allow;
+        self.0.allow_suggestions = allow;
         self
     }
 
@@ -359,19 +371,18 @@ impl<'a> DiagnosticBuilder<'a> {
 
     /// Creates a new `DiagnosticBuilder` with an already constructed
     /// diagnostic.
-    pub fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic)
-                         -> DiagnosticBuilder<'a> {
-        DiagnosticBuilder {
+    pub fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> DiagnosticBuilder<'a> {
+        DiagnosticBuilder(Box::new(DiagnosticBuilderInner {
             handler,
             diagnostic,
             allow_suggestions: true,
-        }
+        }))
     }
 }
 
 impl<'a> Debug for DiagnosticBuilder<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.diagnostic.fmt(f)
+        self.0.diagnostic.fmt(f)
     }
 }
 
@@ -381,7 +392,7 @@ impl<'a> Drop for DiagnosticBuilder<'a> {
     fn drop(&mut self) {
         if !panicking() && !self.cancelled() {
             let mut db = DiagnosticBuilder::new(
-                self.handler,
+                self.0.handler,
                 Level::Bug,
                 "the following error was constructed but not emitted",
             );
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 0ce69eecc6b1e..66608361c8d44 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -385,7 +385,7 @@ impl Emitter for EmitterWriter {
                                           &mut primary_span,
                                           &mut children,
                                           &db.level,
-                                          db.handler.flags.external_macro_backtrace);
+                                          db.handler().flags.external_macro_backtrace);
 
         self.emit_messages_default(&db.level,
                                    &db.styled_message(),
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index bc1bc00ac8405..2441a027f9940 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -13,6 +13,8 @@ use crate::symbol::Symbol;
 
 use errors::{Applicability, FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder};
 use rustc_data_structures::fx::{FxHashSet, FxHashMap};
+#[cfg(target_arch = "x86_64")]
+use rustc_data_structures::static_assert_size;
 use rustc_data_structures::sync::{Lrc, Lock, Once};
 use syntax_pos::{Span, SourceFile, FileName, MultiSpan};
 use syntax_pos::edition::Edition;
@@ -38,6 +40,11 @@ crate mod unescape_error_reporting;
 
 pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
 
+// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
+// (See also the comment on `DiagnosticBuilderInner`.)
+#[cfg(target_arch = "x86_64")]
+static_assert_size!(PResult<'_, bool>, 16);
+
 /// Collected spans during parsing for places where a certain feature was
 /// used and should be feature gated accordingly in `check_crate`.
 #[derive(Default)]

From 7f0637da5144c7435e88ea3805021882f077d50c Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Thu, 12 Sep 2019 13:29:32 +1000
Subject: [PATCH 695/943] Shrink `SubregionOrigin`.

It's currently 120 bytes on x86-64, due to one oversized variant
(`Subtype`). This commit boxes `Subtype`'s contents, reducing the size
of `SubregionOrigin` to 32 bytes.

The change speeds things up by avoiding lots of `memcpy` calls, mostly
relating to `RegionConstraintData::constraints`, which is a `BTreeMap`
with `SubregionOrigin` values.
---
 src/librustc/infer/equate.rs                       |  2 +-
 .../nice_region_error/placeholder_error.rs         | 14 +++++++-------
 src/librustc/infer/error_reporting/note.rs         |  4 ++--
 src/librustc/infer/glb.rs                          |  2 +-
 src/librustc/infer/lub.rs                          |  2 +-
 src/librustc/infer/mod.rs                          |  6 +++++-
 src/librustc/infer/sub.rs                          |  2 +-
 7 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs
index 5dfa0d29daf1b..96d40bc81add2 100644
--- a/src/librustc/infer/equate.rs
+++ b/src/librustc/infer/equate.rs
@@ -97,7 +97,7 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
                self.tag(),
                a,
                b);
-        let origin = Subtype(self.fields.trace.clone());
+        let origin = Subtype(box self.fields.trace.clone());
         self.fields.infcx.borrow_region_constraints()
                          .make_eqregion(origin, a, b);
         Ok(a)
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 b4fb018920647..5f3c5fed3a3b2 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
@@ -30,7 +30,7 @@ impl NiceRegionError<'me, 'tcx> {
             Some(RegionResolutionError::SubSupConflict(
                 vid,
                 _,
-                SubregionOrigin::Subtype(TypeTrace {
+                SubregionOrigin::Subtype(box TypeTrace {
                     cause,
                     values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
                 }),
@@ -50,7 +50,7 @@ impl NiceRegionError<'me, 'tcx> {
             Some(RegionResolutionError::SubSupConflict(
                 vid,
                 _,
-                SubregionOrigin::Subtype(TypeTrace {
+                SubregionOrigin::Subtype(box TypeTrace {
                     cause,
                     values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
                 }),
@@ -70,7 +70,7 @@ impl NiceRegionError<'me, 'tcx> {
             Some(RegionResolutionError::SubSupConflict(
                 vid,
                 _,
-                SubregionOrigin::Subtype(TypeTrace {
+                SubregionOrigin::Subtype(box TypeTrace {
                     cause,
                     values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
                 }),
@@ -92,7 +92,7 @@ impl NiceRegionError<'me, 'tcx> {
                 _,
                 _,
                 _,
-                SubregionOrigin::Subtype(TypeTrace {
+                SubregionOrigin::Subtype(box TypeTrace {
                     cause,
                     values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
                 }),
@@ -108,7 +108,7 @@ impl NiceRegionError<'me, 'tcx> {
             )),
 
             Some(RegionResolutionError::ConcreteFailure(
-                SubregionOrigin::Subtype(TypeTrace {
+                SubregionOrigin::Subtype(box TypeTrace {
                     cause,
                     values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
                 }),
@@ -125,7 +125,7 @@ impl NiceRegionError<'me, 'tcx> {
             )),
 
             Some(RegionResolutionError::ConcreteFailure(
-                SubregionOrigin::Subtype(TypeTrace {
+                SubregionOrigin::Subtype(box TypeTrace {
                     cause,
                     values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
                 }),
@@ -142,7 +142,7 @@ impl NiceRegionError<'me, 'tcx> {
             )),
 
             Some(RegionResolutionError::ConcreteFailure(
-                SubregionOrigin::Subtype(TypeTrace {
+                SubregionOrigin::Subtype(box TypeTrace {
                     cause,
                     values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
                 }),
diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs
index caed4288892ef..115ffea97bf1a 100644
--- a/src/librustc/infer/error_reporting/note.rs
+++ b/src/librustc/infer/error_reporting/note.rs
@@ -138,7 +138,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                           sup: Region<'tcx>)
                                           -> DiagnosticBuilder<'tcx> {
         match origin {
-            infer::Subtype(trace) => {
+            infer::Subtype(box trace) => {
                 let terr = TypeError::RegionsDoesNotOutlive(sup, sub);
                 let mut err = self.report_and_explain_type_error(trace, &terr);
                 self.tcx.note_and_explain_region(region_scope_tree, &mut err, "", sup, "...");
@@ -450,7 +450,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
     ) -> DiagnosticBuilder<'tcx> {
         // I can't think how to do better than this right now. -nikomatsakis
         match placeholder_origin {
-            infer::Subtype(trace) => {
+            infer::Subtype(box trace) => {
                 let terr = TypeError::RegionsPlaceholderMismatch;
                 self.report_and_explain_type_error(trace, &terr)
             }
diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs
index 2cef521176269..10e45321a6d6a 100644
--- a/src/librustc/infer/glb.rs
+++ b/src/librustc/infer/glb.rs
@@ -57,7 +57,7 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
                a,
                b);
 
-        let origin = Subtype(self.fields.trace.clone());
+        let origin = Subtype(box self.fields.trace.clone());
         Ok(self.fields.infcx.borrow_region_constraints().glb_regions(self.tcx(), origin, a, b))
     }
 
diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs
index e20372f151371..8b64cda7bd26d 100644
--- a/src/librustc/infer/lub.rs
+++ b/src/librustc/infer/lub.rs
@@ -57,7 +57,7 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
                a,
                b);
 
-        let origin = Subtype(self.fields.trace.clone());
+        let origin = Subtype(box self.fields.trace.clone());
         Ok(self.fields.infcx.borrow_region_constraints().lub_regions(self.tcx(), origin, a, b))
     }
 
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 8638f42976f04..a886c44a4792d 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -254,7 +254,7 @@ pub struct TypeTrace<'tcx> {
 #[derive(Clone, Debug)]
 pub enum SubregionOrigin<'tcx> {
     /// Arose from a subtyping relation
-    Subtype(TypeTrace<'tcx>),
+    Subtype(Box<TypeTrace<'tcx>>),
 
     /// Stack-allocated closures cannot outlive innermost loop
     /// or function so as to ensure we only require finite stack
@@ -340,6 +340,10 @@ pub enum SubregionOrigin<'tcx> {
     },
 }
 
+// `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
+#[cfg(target_arch = "x86_64")]
+static_assert_size!(SubregionOrigin<'_>, 32);
+
 /// Places that type/region parameters can appear.
 #[derive(Clone, Copy, Debug)]
 pub enum ParameterOrigin {
diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs
index cd1d206b5fca1..76db55ecfa8ef 100644
--- a/src/librustc/infer/sub.rs
+++ b/src/librustc/infer/sub.rs
@@ -130,7 +130,7 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
         // FIXME -- we have more fine-grained information available
         // from the "cause" field, we could perhaps give more tailored
         // error messages.
-        let origin = SubregionOrigin::Subtype(self.fields.trace.clone());
+        let origin = SubregionOrigin::Subtype(box self.fields.trace.clone());
         self.fields.infcx.borrow_region_constraints()
                          .make_subregion(origin, a, b);
 

From e715d03275cb83a3fd7aeb8f4c62661d4c690464 Mon Sep 17 00:00:00 2001
From: Aleksi Juvani <aleksi@aleksijuvani.com>
Date: Thu, 12 Sep 2019 13:47:17 +0300
Subject: [PATCH 696/943] Remove env vars instead of setting them to an empty
 string

---
 src/librustc_codegen_ssa/back/command.rs        | 16 ++++++++++++++++
 src/librustc_codegen_ssa/back/link.rs           |  3 +++
 src/librustc_target/spec/apple_base.rs          | 12 ++++++------
 src/librustc_target/spec/i686_apple_darwin.rs   |  2 +-
 src/librustc_target/spec/mod.rs                 |  7 ++++++-
 src/librustc_target/spec/x86_64_apple_darwin.rs |  2 +-
 6 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/src/librustc_codegen_ssa/back/command.rs b/src/librustc_codegen_ssa/back/command.rs
index 340cc772e5f07..596978f002b66 100644
--- a/src/librustc_codegen_ssa/back/command.rs
+++ b/src/librustc_codegen_ssa/back/command.rs
@@ -14,6 +14,7 @@ pub struct Command {
     program: Program,
     args: Vec<OsString>,
     env: Vec<(OsString, OsString)>,
+    env_remove: Vec<OsString>,
 }
 
 #[derive(Clone)]
@@ -41,6 +42,7 @@ impl Command {
             program,
             args: Vec::new(),
             env: Vec::new(),
+            env_remove: Vec::new(),
         }
     }
 
@@ -75,6 +77,17 @@ impl Command {
         self.env.push((key.to_owned(), value.to_owned()));
     }
 
+    pub fn env_remove<K>(&mut self, key: K) -> &mut Command
+        where K: AsRef<OsStr>,
+    {
+        self._env_remove(key.as_ref());
+        self
+    }
+
+    fn _env_remove(&mut self, key: &OsStr) {
+        self.env_remove.push(key.to_owned());
+    }
+
     pub fn output(&mut self) -> io::Result<Output> {
         self.command().output()
     }
@@ -100,6 +113,9 @@ impl Command {
         };
         ret.args(&self.args);
         ret.envs(self.env.clone());
+        for k in &self.env_remove {
+            ret.env_remove(k);
+        }
         return ret
     }
 
diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs
index 8603d61fb5453..74cde92974c04 100644
--- a/src/librustc_codegen_ssa/back/link.rs
+++ b/src/librustc_codegen_ssa/back/link.rs
@@ -532,6 +532,9 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
     for &(ref k, ref v) in &sess.target.target.options.link_env {
         cmd.env(k, v);
     }
+    for k in &sess.target.target.options.link_env_remove {
+        cmd.env_remove(k);
+    }
 
     if sess.opts.debugging_opts.print_link_args {
         println!("{:?}", &cmd);
diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs
index e2632fc14148f..f7551aa768dfc 100644
--- a/src/librustc_target/spec/apple_base.rs
+++ b/src/librustc_target/spec/apple_base.rs
@@ -52,18 +52,18 @@ pub fn macos_llvm_target(arch: &str) -> String {
     format!("{}-apple-macosx{}.{}.0", arch, major, minor)
 }
 
-pub fn macos_link_env() -> Vec<(String, String)> {
-    let mut env = Vec::with_capacity(2);
-    // Ignore the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
+pub fn macos_link_env_remove() -> Vec<String> {
+    let mut env_remove = Vec::with_capacity(2);
+    // Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
     // may occur when we're linking a custom build script while targeting iOS for example.
     if let Some(sdkroot) = env::var("SDKROOT").ok() {
         if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform") {
-            env.push(("SDKROOT".to_string(), String::new()))
+            env_remove.push("SDKROOT".to_string())
         }
     }
     // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
     // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
     // although this is apparently ignored when using the linker at "/usr/bin/ld".
-    env.push(("IPHONEOS_DEPLOYMENT_TARGET".to_string(), String::new()));
-    env
+    env_remove.push("IPHONEOS_DEPLOYMENT_TARGET".to_string());
+    env_remove
 }
diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs
index ba44cdccb7c48..27d05823bf21e 100644
--- a/src/librustc_target/spec/i686_apple_darwin.rs
+++ b/src/librustc_target/spec/i686_apple_darwin.rs
@@ -5,7 +5,7 @@ pub fn target() -> TargetResult {
     base.cpu = "yonah".to_string();
     base.max_atomic_width = Some(64);
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
-    base.link_env.extend(super::apple_base::macos_link_env());
+    base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
     base.stack_probes = true;
     base.eliminate_frame_pointer = false;
 
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 503d8a08b6f4f..82e74f317de23 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -580,8 +580,10 @@ pub struct TargetOptions {
     /// user-defined libraries.
     pub post_link_args: LinkArgs,
 
-    /// Environment variables to be set before invoking the linker.
+    /// Environment variables to be set for the linker invocation.
     pub link_env: Vec<(String, String)>,
+    /// Environment variables to be removed for the linker invocation.
+    pub link_env_remove: Vec<String>,
 
     /// Extra arguments to pass to the external assembler (when used)
     pub asm_args: Vec<String>,
@@ -843,6 +845,7 @@ impl Default for TargetOptions {
             post_link_objects_crt: Vec::new(),
             late_link_args: LinkArgs::new(),
             link_env: Vec::new(),
+            link_env_remove: Vec::new(),
             archive_format: "gnu".to_string(),
             custom_unwind_resume: false,
             allow_asm: true,
@@ -1118,6 +1121,7 @@ impl Target {
         key!(post_link_objects_crt, list);
         key!(post_link_args, link_args);
         key!(link_env, env);
+        key!(link_env_remove, list);
         key!(asm_args, list);
         key!(cpu);
         key!(features);
@@ -1334,6 +1338,7 @@ impl ToJson for Target {
         target_option_val!(post_link_objects_crt);
         target_option_val!(link_args - post_link_args);
         target_option_val!(env - link_env);
+        target_option_val!(link_env_remove);
         target_option_val!(asm_args);
         target_option_val!(cpu);
         target_option_val!(features);
diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs
index 442c2650bbba1..d059e44c5c82a 100644
--- a/src/librustc_target/spec/x86_64_apple_darwin.rs
+++ b/src/librustc_target/spec/x86_64_apple_darwin.rs
@@ -6,7 +6,7 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(128); // core2 support cmpxchg16b
     base.eliminate_frame_pointer = false;
     base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
-    base.link_env.extend(super::apple_base::macos_link_env());
+    base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
     base.stack_probes = true;
 
     // Clang automatically chooses a more specific target based on

From 144b8450735f61270cae223c1fd12e2f605c5b34 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Tue, 10 Sep 2019 13:48:30 +0200
Subject: [PATCH 697/943] Add long error explanation for E0312

---
 src/librustc/error_codes.rs | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index eee33846139e6..f6564f1fcd4c1 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -1347,6 +1347,39 @@ struct Foo<T: 'static> {
 ```
 "##,
 
+E0312: r##"
+Reference's lifetime of borrowed content doesn't match the expected lifetime.
+
+Erroneous code example:
+
+```compile_fail,E0312
+pub fn opt_str<'a>(maybestr: &'a Option<String>) -> &'static str {
+    if maybestr.is_none() {
+        "(none)"
+    } else {
+        let s: &'a str = maybestr.as_ref().unwrap();
+        s  // Invalid lifetime!
+    }
+}
+```
+
+To fix this error, either lessen the expected lifetime or find a way to not have
+to use this reference outside of its current scope (by running the code directly
+in the same block for example?):
+
+```
+// In this case, we can fix the issue by switching from "static" lifetime to 'a
+pub fn opt_str<'a>(maybestr: &'a Option<String>) -> &'a str {
+    if maybestr.is_none() {
+        "(none)"
+    } else {
+        let s: &'a str = maybestr.as_ref().unwrap();
+        s  // Ok!
+    }
+}
+```
+"##,
+
 E0317: r##"
 This error occurs when an `if` expression without an `else` block is used in a
 context where a type other than `()` is expected, for example a `let`
@@ -2202,7 +2235,6 @@ static X: u32 = 42;
 //  E0304, // expected signed integer constant
 //  E0305, // expected constant
     E0311, // thing may not live long enough
-    E0312, // lifetime of reference outlives lifetime of borrowed content
     E0313, // lifetime of borrowed pointer outlives lifetime of captured
            // variable
     E0314, // closure outlives stack frame

From cf6a1feda65525b947bfd33279c8b74c00f098c6 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Thu, 12 Sep 2019 13:25:42 +0200
Subject: [PATCH 698/943] update ui tests

---
 src/test/ui/issues/issue-10291.stderr                          | 1 +
 src/test/ui/issues/issue-52533.stderr                          | 1 +
 src/test/ui/lub-if.stderr                                      | 1 +
 src/test/ui/lub-match.stderr                                   | 1 +
 src/test/ui/nll/issue-52742.stderr                             | 1 +
 src/test/ui/nll/issue-55401.stderr                             | 1 +
 .../ui/nll/user-annotations/constant-in-expr-normalize.stderr  | 1 +
 .../nll/user-annotations/constant-in-expr-trait-item-1.stderr  | 1 +
 .../nll/user-annotations/constant-in-expr-trait-item-2.stderr  | 1 +
 src/test/ui/regions/regions-early-bound-error-method.stderr    | 1 +
 src/test/ui/regions/regions-early-bound-error.stderr           | 1 +
 src/test/ui/regions/regions-nested-fns.stderr                  | 1 +
 src/test/ui/regions/regions-static-bound.migrate.stderr        | 3 ++-
 ...ed-closures-infer-argument-types-two-region-pointers.stderr | 1 +
 src/test/ui/wf/wf-static-method.stderr                         | 3 ++-
 15 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/test/ui/issues/issue-10291.stderr b/src/test/ui/issues/issue-10291.stderr
index 5e63469da59f5..a836593e0da10 100644
--- a/src/test/ui/issues/issue-10291.stderr
+++ b/src/test/ui/issues/issue-10291.stderr
@@ -20,3 +20,4 @@ LL | fn test<'x>(x: &'x isize) {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/issues/issue-52533.stderr b/src/test/ui/issues/issue-52533.stderr
index 1ed740c421e0f..586548002072e 100644
--- a/src/test/ui/issues/issue-52533.stderr
+++ b/src/test/ui/issues/issue-52533.stderr
@@ -17,3 +17,4 @@ LL |     foo(|a, b| b)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/lub-if.stderr b/src/test/ui/lub-if.stderr
index bb772d4c6c695..26f756c91833b 100644
--- a/src/test/ui/lub-if.stderr
+++ b/src/test/ui/lub-if.stderr
@@ -26,3 +26,4 @@ LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/lub-match.stderr b/src/test/ui/lub-match.stderr
index 090af25143670..0cb0a23c6f2df 100644
--- a/src/test/ui/lub-match.stderr
+++ b/src/test/ui/lub-match.stderr
@@ -26,3 +26,4 @@ LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/nll/issue-52742.stderr b/src/test/ui/nll/issue-52742.stderr
index b982915800294..90a35177f4c3b 100644
--- a/src/test/ui/nll/issue-52742.stderr
+++ b/src/test/ui/nll/issue-52742.stderr
@@ -20,3 +20,4 @@ LL | |     }
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/nll/issue-55401.stderr b/src/test/ui/nll/issue-55401.stderr
index 50debc6386f6a..4ec16ba055a4c 100644
--- a/src/test/ui/nll/issue-55401.stderr
+++ b/src/test/ui/nll/issue-55401.stderr
@@ -13,3 +13,4 @@ LL | fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr
index f49d68458bea5..0a8ad4221c986 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr
@@ -13,3 +13,4 @@ LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr
index 451bcf41e42a9..d596aaf098f77 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr
@@ -13,3 +13,4 @@ LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr
index d129e55e1e6f6..80ff9a043d4d5 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr
@@ -13,3 +13,4 @@ LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/regions/regions-early-bound-error-method.stderr b/src/test/ui/regions/regions-early-bound-error-method.stderr
index 2e5f55f8742cc..7b9f2c9503b2f 100644
--- a/src/test/ui/regions/regions-early-bound-error-method.stderr
+++ b/src/test/ui/regions/regions-early-bound-error-method.stderr
@@ -17,3 +17,4 @@ LL |     fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/regions/regions-early-bound-error.stderr b/src/test/ui/regions/regions-early-bound-error.stderr
index bc52f4bef7eaa..a68355b78f54c 100644
--- a/src/test/ui/regions/regions-early-bound-error.stderr
+++ b/src/test/ui/regions/regions-early-bound-error.stderr
@@ -17,3 +17,4 @@ LL | fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/regions/regions-nested-fns.stderr b/src/test/ui/regions/regions-nested-fns.stderr
index 15c9c9ca4ddbb..904dee6998c9b 100644
--- a/src/test/ui/regions/regions-nested-fns.stderr
+++ b/src/test/ui/regions/regions-nested-fns.stderr
@@ -57,3 +57,4 @@ LL | fn nested<'x>(x: &'x isize) {
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/regions/regions-static-bound.migrate.stderr b/src/test/ui/regions/regions-static-bound.migrate.stderr
index fc8cca929d389..21ead8b768f47 100644
--- a/src/test/ui/regions/regions-static-bound.migrate.stderr
+++ b/src/test/ui/regions/regions-static-bound.migrate.stderr
@@ -30,4 +30,5 @@ LL |     static_id_indirect(&v);
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0621`.
+Some errors have detailed explanations: E0312, E0621.
+For more information about an error, try `rustc --explain E0312`.
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.stderr
index 728efadf4196e..526055ba04b65 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.stderr
@@ -23,3 +23,4 @@ LL | |     });
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/wf/wf-static-method.stderr b/src/test/ui/wf/wf-static-method.stderr
index f82526aa88ebf..3ec90f00448a9 100644
--- a/src/test/ui/wf/wf-static-method.stderr
+++ b/src/test/ui/wf/wf-static-method.stderr
@@ -105,4 +105,5 @@ LL |     <IndirectEvil>::static_evil(b)
 
 error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0478`.
+Some errors have detailed explanations: E0312, E0478.
+For more information about an error, try `rustc --explain E0312`.

From 612c3947b4550fb093f54ce56b1580685bfe92fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= <matti@marinelayer.io>
Date: Wed, 11 Sep 2019 20:50:53 +0200
Subject: [PATCH 699/943] Trim rustc-workspace-hack

---
 Cargo.lock                                |  4 ----
 src/tools/rustc-workspace-hack/Cargo.toml | 10 ----------
 2 files changed, 14 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 27ee38146097b..bd9dd49eeba13 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3250,13 +3250,9 @@ version = "1.0.0"
 dependencies = [
  "byteorder",
  "crossbeam-utils 0.6.5",
- "parking_lot 0.7.1",
- "rand 0.6.1",
- "scopeguard 0.3.3",
  "serde",
  "serde_json",
  "smallvec",
- "syn 0.15.35",
  "winapi 0.3.6",
 ]
 
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index 4ce411223de43..d068e1cf307b8 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -14,12 +14,6 @@ path = "lib.rs"
 # For documentation about what this is and why in the world these dependencies
 # are appearing, see `README.md`.
 
-[build-dependencies]
-# Currently Cargo/RLS depend on `failure` which depends on `synstructure` which
-# enables this feature. Clippy, however, does not depend on anything that
-# enables this feature. Enable it unconditionally.
-syn = { version = "0.15", features = ['extra-traits'] }
-
 [target.'cfg(windows)'.dependencies.winapi]
 version = "0.3"
 features = [
@@ -65,14 +59,10 @@ features = [
 [dependencies]
 curl-sys = { version = "0.4.13", features = ["http2", "libnghttp2-sys"], optional = true }
 crossbeam-utils = { version = "0.6.5", features = ["nightly"] }
-parking_lot = { version = "0.7", features = ['nightly'] }
-rand = { version = "0.6.1", features = ["i128_support"] }
 serde = { version = "1.0.82", features = ['derive'] }
 serde_json = { version = "1.0.31", features = ["raw_value"] }
 smallvec = { version = "0.6", features = ['union', 'may_dangle'] }
-scopeguard = { version = "0.3.3", features = ["use_std", "default"] }
 byteorder = { version = "1.2.7", features = ["i128"] }
-syn = { version = "0.15.35", features = ["extra-traits", "full"] }
 
 
 [target.'cfg(not(windows))'.dependencies]

From fe6d626abcc6ca994f0554bb78858ccd2b33dcfd Mon Sep 17 00:00:00 2001
From: Aleksi Juvani <aleksi@aleksijuvani.com>
Date: Thu, 12 Sep 2019 15:23:59 +0300
Subject: [PATCH 700/943] Ignore linker env vars set for macOS on iOS targets

---
 src/librustc_target/spec/apple_ios_base.rs | 23 +++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs
index 6d3900c0b203f..fdbb1bd5db34b 100644
--- a/src/librustc_target/spec/apple_ios_base.rs
+++ b/src/librustc_target/spec/apple_ios_base.rs
@@ -38,9 +38,18 @@ pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> {
     // SDKROOT; for rustc, the user or build system can set it, or we
     // can fall back to checking for xcrun on PATH.)
     if let Some(sdkroot) = env::var("SDKROOT").ok() {
-        let sdkroot_path = Path::new(&sdkroot);
-        if sdkroot_path.is_absolute() && sdkroot_path != Path::new("/") && sdkroot_path.exists() {
-            return Ok(sdkroot);
+        let p = Path::new(&sdkroot);
+        match sdk_name {
+            // Ignore `SDKROOT` if it's clearly set for the wrong platform.
+            "iphoneos" if sdkroot.contains("iPhoneSimulator.platform")
+                       || sdkroot.contains("MacOSX.platform") => (),
+            "iphonesimulator" if sdkroot.contains("iPhoneOS.platform")
+                              || sdkroot.contains("MacOSX.platform") => (),
+            "macosx10.15" if sdkroot.contains("iPhoneOS.platform")
+                          || sdkroot.contains("iPhoneSimulator.platform") => (),
+            // Ignore `SDKROOT` if it's not a valid path.
+            _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => (),
+            _ => return Ok(sdkroot),
         }
     }
     let res = Command::new("xcrun")
@@ -100,6 +109,13 @@ fn target_cpu(arch: Arch) -> String {
     }.to_string()
 }
 
+fn link_env_remove(arch: Arch) -> Vec<String> {
+    match arch {
+        Armv7 | Armv7s | Arm64 | I386 | X86_64 => vec!["MACOSX_DEPLOYMENT_TARGET".to_string()],
+        X86_64_macabi => vec!["IPHONEOS_DEPLOYMENT_TARGET".to_string()],
+    }
+}
+
 pub fn opts(arch: Arch) -> Result<TargetOptions, String> {
     let pre_link_args = build_pre_link_args(arch)?;
     Ok(TargetOptions {
@@ -107,6 +123,7 @@ pub fn opts(arch: Arch) -> Result<TargetOptions, String> {
         dynamic_linking: false,
         executables: true,
         pre_link_args,
+        link_env_remove: link_env_remove(arch),
         has_elf_tls: false,
         eliminate_frame_pointer: false,
         .. super::apple_base::opts()

From e9214a147b09f8020f82b450e7c9e16290649909 Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Thu, 12 Sep 2019 19:04:30 +0300
Subject: [PATCH 701/943] codegen: be more explicit about setting giving names
 to allocas.

---
 src/librustc_codegen_llvm/abi.rs           |  2 +-
 src/librustc_codegen_llvm/builder.rs       | 23 +++++--------------
 src/librustc_codegen_llvm/intrinsic.rs     |  2 +-
 src/librustc_codegen_ssa/mir/block.rs      | 18 +++++++--------
 src/librustc_codegen_ssa/mir/mod.rs        | 26 +++++++++++++---------
 src/librustc_codegen_ssa/mir/operand.rs    |  2 +-
 src/librustc_codegen_ssa/mir/place.rs      |  8 ++-----
 src/librustc_codegen_ssa/mir/rvalue.rs     |  2 +-
 src/librustc_codegen_ssa/traits/builder.rs |  5 ++---
 src/test/codegen/personality_lifetimes.rs  |  9 ++++----
 10 files changed, 42 insertions(+), 55 deletions(-)

diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index ff87afe0c444b..2ca517dc3b1a7 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -229,7 +229,7 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
                 // We instead thus allocate some scratch space...
                 let scratch_size = cast.size(bx);
                 let scratch_align = cast.align(bx);
-                let llscratch = bx.alloca(cast.llvm_type(bx), "abi_cast", scratch_align);
+                let llscratch = bx.alloca(cast.llvm_type(bx), scratch_align);
                 bx.lifetime_start(llscratch, scratch_size);
 
                 // ...where we first store the value...
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index e13a5ecc2ebfd..423a01ad1f937 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -387,23 +387,17 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         )
     }
 
-    fn alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
+    fn alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
         let mut bx = Builder::with_cx(self.cx);
         bx.position_at_start(unsafe {
             llvm::LLVMGetFirstBasicBlock(self.llfn())
         });
-        bx.dynamic_alloca(ty, name, align)
+        bx.dynamic_alloca(ty, align)
     }
 
-    fn dynamic_alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
+    fn dynamic_alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
         unsafe {
-            let alloca = if name.is_empty() {
-                llvm::LLVMBuildAlloca(self.llbuilder, ty, UNNAMED)
-            } else {
-                let name = SmallCStr::new(name);
-                llvm::LLVMBuildAlloca(self.llbuilder, ty,
-                                      name.as_ptr())
-            };
+            let alloca = llvm::LLVMBuildAlloca(self.llbuilder, ty, UNNAMED);
             llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
             alloca
         }
@@ -412,16 +406,9 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     fn array_alloca(&mut self,
                         ty: &'ll Type,
                         len: &'ll Value,
-                        name: &str,
                         align: Align) -> &'ll Value {
         unsafe {
-            let alloca = if name.is_empty() {
-                llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, UNNAMED)
-            } else {
-                let name = SmallCStr::new(name);
-                llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len,
-                                           name.as_ptr())
-            };
+            let alloca = llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, UNNAMED);
             llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
             alloca
         }
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index fc0b9ffd11d83..5fbfe9138f2a4 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -871,7 +871,7 @@ fn codegen_msvc_try(
         // More information can be found in libstd's seh.rs implementation.
         let i64p = bx.type_ptr_to(bx.type_i64());
         let ptr_align = bx.tcx().data_layout.pointer_align.abi;
-        let slot = bx.alloca(i64p, "slot", ptr_align);
+        let slot = bx.alloca(i64p, ptr_align);
         bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), None);
 
         normal.ret(bx.const_i32(0));
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index c41e46398467a..d3c59c526c8ad 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -276,7 +276,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let llslot = match op.val {
                     Immediate(_) | Pair(..) => {
                         let scratch =
-                            PlaceRef::alloca(&mut bx, self.fn_ty.ret.layout, "ret");
+                            PlaceRef::alloca(&mut bx, self.fn_ty.ret.layout);
                         op.val.store(&mut bx, scratch);
                         scratch.llval
                     }
@@ -767,7 +767,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             match (arg, op.val) {
                 (&mir::Operand::Copy(_), Ref(_, None, _)) |
                 (&mir::Operand::Constant(_), Ref(_, None, _)) => {
-                    let tmp = PlaceRef::alloca(&mut bx, op.layout, "const");
+                    let tmp = PlaceRef::alloca(&mut bx, op.layout);
                     op.val.store(&mut bx, tmp);
                     op.val = Ref(tmp.llval, None, tmp.align);
                 }
@@ -925,7 +925,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             Immediate(_) | Pair(..) => {
                 match arg.mode {
                     PassMode::Indirect(..) | PassMode::Cast(_) => {
-                        let scratch = PlaceRef::alloca(bx, arg.layout, "arg");
+                        let scratch = PlaceRef::alloca(bx, arg.layout);
                         op.val.store(bx, scratch);
                         (scratch.llval, scratch.align, true)
                     }
@@ -940,7 +940,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     // think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't
                     // have scary latent bugs around.
 
-                    let scratch = PlaceRef::alloca(bx, arg.layout, "arg");
+                    let scratch = PlaceRef::alloca(bx, arg.layout);
                     base::memcpy_ty(bx, scratch.llval, scratch.align, llval, align,
                                     op.layout, MemFlags::empty());
                     (scratch.llval, scratch.align, true)
@@ -1017,7 +1017,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 cx.tcx().mk_mut_ptr(cx.tcx().types.u8),
                 cx.tcx().types.i32
             ]));
-            let slot = PlaceRef::alloca(bx, layout, "personalityslot");
+            let slot = PlaceRef::alloca(bx, layout);
             self.personality_slot = Some(slot);
             slot
         }
@@ -1116,7 +1116,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     return if fn_ret.is_indirect() {
                         // Odd, but possible, case, we have an operand temporary,
                         // but the calling convention has an indirect return.
-                        let tmp = PlaceRef::alloca(bx, fn_ret.layout, "tmp_ret");
+                        let tmp = PlaceRef::alloca(bx, fn_ret.layout);
                         tmp.storage_live(bx);
                         llargs.push(tmp.llval);
                         ReturnDest::IndirectOperand(tmp, index)
@@ -1124,7 +1124,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         // Currently, intrinsics always need a location to store
                         // the result, so we create a temporary `alloca` for the
                         // result.
-                        let tmp = PlaceRef::alloca(bx, fn_ret.layout, "tmp_ret");
+                        let tmp = PlaceRef::alloca(bx, fn_ret.layout);
                         tmp.storage_live(bx);
                         ReturnDest::IndirectOperand(tmp, index)
                     } else {
@@ -1174,7 +1174,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 LocalRef::Operand(None) => {
                     let dst_layout = bx.layout_of(self.monomorphized_place_ty(&dst.as_ref()));
                     assert!(!dst_layout.ty.has_erasable_regions());
-                    let place = PlaceRef::alloca(bx, dst_layout, "transmute_temp");
+                    let place = PlaceRef::alloca(bx, dst_layout);
                     place.storage_live(bx);
                     self.codegen_transmute_into(bx, src, place);
                     let op = bx.load_operand(place);
@@ -1227,7 +1227,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             DirectOperand(index) => {
                 // If there is a cast, we have to store and reload.
                 let op = if let PassMode::Cast(_) = ret_ty.mode {
-                    let tmp = PlaceRef::alloca(bx, ret_ty.layout, "tmp_ret");
+                    let tmp = PlaceRef::alloca(bx, ret_ty.layout);
                     tmp.storage_live(bx);
                     bx.store_arg_ty(&ret_ty, llval, tmp);
                     let op = bx.load_operand(tmp);
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index 00e9ca01f4dd2..df72980383e29 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -268,11 +268,13 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 debug!("alloc: {:?} ({}) -> place", local, name);
                 if layout.is_unsized() {
                     let indirect_place =
-                        PlaceRef::alloca_unsized_indirect(&mut bx, layout, &name.as_str());
+                        PlaceRef::alloca_unsized_indirect(&mut bx, layout);
+                    bx.set_var_name(indirect_place.llval, name);
                     // FIXME: add an appropriate debuginfo
                     LocalRef::UnsizedPlace(indirect_place)
                 } else {
-                    let place = PlaceRef::alloca(&mut bx, layout, &name.as_str());
+                    let place = PlaceRef::alloca(&mut bx, layout);
+                    bx.set_var_name(place.llval, name);
                     if dbg {
                         let (scope, span) = fx.debug_loc(mir::SourceInfo {
                             span: decl.source_info.span,
@@ -293,14 +295,13 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 } else if memory_locals.contains(local) {
                     debug!("alloc: {:?} -> place", local);
                     if layout.is_unsized() {
-                        let indirect_place = PlaceRef::alloca_unsized_indirect(
-                            &mut bx,
-                            layout,
-                            &format!("{:?}", local),
-                        );
+                        let indirect_place = PlaceRef::alloca_unsized_indirect(&mut bx, layout);
+                        bx.set_var_name(indirect_place.llval, format_args!("{:?}", local));
                         LocalRef::UnsizedPlace(indirect_place)
                     } else {
-                        LocalRef::Place(PlaceRef::alloca(&mut bx, layout, &format!("{:?}", local)))
+                        let place = PlaceRef::alloca(&mut bx, layout);
+                        bx.set_var_name(place.llval, format_args!("{:?}", local));
+                        LocalRef::Place(place)
                     }
                 } else {
                     // If this is an immediate local, we do not create an
@@ -470,7 +471,8 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 _ => bug!("spread argument isn't a tuple?!")
             };
 
-            let place = PlaceRef::alloca(bx, bx.layout_of(arg_ty), &name);
+            let place = PlaceRef::alloca(bx, bx.layout_of(arg_ty));
+            bx.set_var_name(place.llval, name);
             for i in 0..tupled_arg_tys.len() {
                 let arg = &fx.fn_ty.args[idx];
                 idx += 1;
@@ -558,11 +560,13 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             llarg_idx += 1;
             let indirect_operand = OperandValue::Pair(llarg, llextra);
 
-            let tmp = PlaceRef::alloca_unsized_indirect(bx, arg.layout, &name);
+            let tmp = PlaceRef::alloca_unsized_indirect(bx, arg.layout);
+            bx.set_var_name(tmp.llval, name);
             indirect_operand.store(bx, tmp);
             tmp
         } else {
-            let tmp = PlaceRef::alloca(bx, arg.layout, &name);
+            let tmp = PlaceRef::alloca(bx, arg.layout);
+            bx.set_var_name(tmp.llval, name);
             if fx.fn_ty.c_variadic && last_arg_idx.map(|idx| arg_index == idx).unwrap_or(false) {
                 let va_list_did = match tcx.lang_items().va_list() {
                     Some(did) => did,
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index a8ab3ea10ed16..aa85d0284f7f9 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -367,7 +367,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
 
         // Allocate an appropriate region on the stack, and copy the value into it
         let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
-        let lldst = bx.array_alloca(bx.cx().type_i8(), llsize, "unsized_tmp", max_align);
+        let lldst = bx.array_alloca(bx.cx().type_i8(), llsize, max_align);
         bx.memcpy(lldst, max_align, llptr, min_align, llsize, flags);
 
         // Store the allocated region and the extra to the indirect place.
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index b8e10d3430292..d3e6cef8195d7 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -71,11 +71,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
     pub fn alloca<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         bx: &mut Bx,
         layout: TyLayout<'tcx>,
-        name: &str
     ) -> Self {
-        debug!("alloca({:?}: {:?})", name, layout);
         assert!(!layout.is_unsized(), "tried to statically allocate unsized place");
-        let tmp = bx.alloca(bx.cx().backend_type(layout), name, layout.align.abi);
+        let tmp = bx.alloca(bx.cx().backend_type(layout), layout.align.abi);
         Self::new_sized(tmp, layout)
     }
 
@@ -83,13 +81,11 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
     pub fn alloca_unsized_indirect<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         bx: &mut Bx,
         layout: TyLayout<'tcx>,
-        name: &str,
     ) -> Self {
-        debug!("alloca_unsized_indirect({:?}: {:?})", name, layout);
         assert!(layout.is_unsized(), "tried to allocate indirect place for sized values");
         let ptr_ty = bx.cx().tcx().mk_mut_ptr(layout.ty);
         let ptr_layout = bx.cx().layout_of(ptr_ty);
-        Self::alloca(bx, ptr_layout, name)
+        Self::alloca(bx, ptr_layout)
     }
 
     pub fn len<Cx: ConstMethods<'tcx, Value = V>>(
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index e0ad2527229ba..da8a7971107be 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -64,7 +64,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         // index into the struct, and this case isn't
                         // important enough for it.
                         debug!("codegen_rvalue: creating ugly alloca");
-                        let scratch = PlaceRef::alloca(&mut bx, operand.layout, "__unsize_temp");
+                        let scratch = PlaceRef::alloca(&mut bx, operand.layout);
                         scratch.storage_live(&mut bx);
                         operand.val.store(&mut bx, scratch);
                         base::coerce_unsized_into(&mut bx, scratch, dest);
diff --git a/src/librustc_codegen_ssa/traits/builder.rs b/src/librustc_codegen_ssa/traits/builder.rs
index 3a144f0b0e0aa..1886701fb3a88 100644
--- a/src/librustc_codegen_ssa/traits/builder.rs
+++ b/src/librustc_codegen_ssa/traits/builder.rs
@@ -109,13 +109,12 @@ pub trait BuilderMethods<'a, 'tcx>:
         rhs: Self::Value,
     ) -> (Self::Value, Self::Value);
 
-    fn alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value;
-    fn dynamic_alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value;
+    fn alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
+    fn dynamic_alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
     fn array_alloca(
         &mut self,
         ty: Self::Type,
         len: Self::Value,
-        name: &str,
         align: Align,
     ) -> Self::Value;
 
diff --git a/src/test/codegen/personality_lifetimes.rs b/src/test/codegen/personality_lifetimes.rs
index 0d3d537a2723d..05888c0e733ad 100644
--- a/src/test/codegen/personality_lifetimes.rs
+++ b/src/test/codegen/personality_lifetimes.rs
@@ -20,12 +20,13 @@ pub fn test() {
     let _s = S;
     // Check that the personality slot alloca gets a lifetime start in each cleanup block, not just
     // in the first one.
+    // CHECK: [[SLOT:%[0-9]+]] = alloca { i8*, i32 }
     // CHECK-LABEL: cleanup:
-    // CHECK: bitcast{{.*}}personalityslot
-    // CHECK-NEXT: call void @llvm.lifetime.start
+    // CHECK: [[BITCAST:%[0-9]+]] = bitcast { i8*, i32 }* [[SLOT]] to i8*
+    // CHECK-NEXT: call void @llvm.lifetime.start.{{.*}}({{.*}}, i8* [[BITCAST]])
     // CHECK-LABEL: cleanup1:
-    // CHECK: bitcast{{.*}}personalityslot
-    // CHECK-NEXT: call void @llvm.lifetime.start
+    // CHECK: [[BITCAST1:%[0-9]+]] = bitcast { i8*, i32 }* [[SLOT]] to i8*
+    // CHECK-NEXT: call void @llvm.lifetime.start.{{.*}}({{.*}}, i8* [[BITCAST1]])
     might_unwind();
     let _t = S;
     might_unwind();

From 9c0bbe09e9e8e621b8fad5c0eab9436ff478fd1d Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Thu, 12 Sep 2019 15:25:33 -0300
Subject: [PATCH 702/943] Use fold

---
 src/librustc/mir/tcx.rs | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index fbe25de0e762c..d776809839743 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -127,13 +127,10 @@ impl<'tcx> Place<'tcx> {
     ) -> PlaceTy<'tcx>
         where D: HasLocalDecls<'tcx>
     {
-        let mut place_ty = base.ty(local_decls);
-
-        for elem in projection.iter() {
-            place_ty = place_ty.projection_ty(tcx, elem);
-        }
-
-        place_ty
+        projection.iter().fold(
+            base.ty(local_decls),
+            |place_ty, elem| place_ty.projection_ty(tcx, elem)
+        )
     }
 
     pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx>

From 232a4a28818d0056677d48932f15d8b0cd17ef32 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Thu, 12 Sep 2019 16:03:38 -0300
Subject: [PATCH 703/943] Destructure instead of using split_at

---
 src/librustc_mir/transform/instcombine.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs
index 2b8e66e3dec1b..da91a8daca368 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/src/librustc_mir/transform/instcombine.rs
@@ -45,7 +45,7 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
                     ref mut base,
                     projection: ref mut projection @ box [.., _],
                 }) => {
-                    let (proj_l, proj_r) = projection.split_at(projection.len() - 1);
+                    let [proj_l @ .., proj_r] = projection;
 
                     let place = Place {
                         // Replace with dummy

From 68b1a8741ebffde9e1bca054569211f66e3deea3 Mon Sep 17 00:00:00 2001
From: Mark Mansi <markm@cs.wisc.edu>
Date: Thu, 12 Sep 2019 16:43:36 -0500
Subject: [PATCH 704/943] Various refactorings to clean up nll diagnostics

- Create ErrorReportingCtx and ErrorConstraintInfo, vasting reducing the
  number of arguments passed around everywhere in the error reporting code
- Create RegionErrorNamingCtx, making a given lifetime have consistent
  numbering thoughout all error messages for that MIR def.
- Make the error reporting code return the DiagnosticBuilder rather than
  directly buffer the Diagnostic. This makes it easier to modify the
  diagnostic later, e.g. to add suggestions.
---
 .../nll/region_infer/error_reporting/mod.rs   | 241 +++++++++---------
 .../error_reporting/region_name.rs            | 198 ++++++++------
 .../borrow_check/nll/region_infer/mod.rs      |  71 ++++--
 3 files changed, 303 insertions(+), 207 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
index efa18587b7ddb..5aaa4bb7b072d 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
@@ -13,7 +13,7 @@ use rustc::infer::NLLRegionVariableOrigin;
 use rustc::mir::{ConstraintCategory, Location, Body};
 use rustc::ty::{self, RegionVid};
 use rustc_data_structures::indexed_vec::IndexVec;
-use rustc_errors::{Diagnostic, DiagnosticBuilder};
+use rustc_errors::DiagnosticBuilder;
 use std::collections::VecDeque;
 use syntax::errors::Applicability;
 use syntax::symbol::kw;
@@ -22,7 +22,7 @@ use syntax_pos::Span;
 mod region_name;
 mod var_name;
 
-crate use self::region_name::{RegionName, RegionNameSource};
+crate use self::region_name::{RegionName, RegionNameSource, RegionErrorNamingCtx};
 
 impl ConstraintDescription for ConstraintCategory {
     fn description(&self) -> &'static str {
@@ -54,6 +54,30 @@ enum Trace {
     NotVisited,
 }
 
+/// Various pieces of state used when reporting borrow checker errors.
+pub struct ErrorReportingCtx<'a, 'b, 'tcx> {
+    rinfcx: &'b RegionInferenceContext<'tcx>,
+    infcx: &'b InferCtxt<'a, 'tcx>,
+
+    mir_def_id: DefId,
+    body: &'b Body<'tcx>,
+    upvars: &'b [Upvar],
+}
+
+/// Information about the various region constraints involved in a borrow checker error.
+#[derive(Clone, Debug)]
+pub struct ErrorConstraintInfo {
+    // fr: outlived_fr
+    fr: RegionVid,
+    fr_is_local: bool,
+    outlived_fr: RegionVid,
+    outlived_fr_is_local: bool,
+
+    // Category and span for best blame constraint
+    category: ConstraintCategory,
+    span: Span,
+}
+
 impl<'tcx> RegionInferenceContext<'tcx> {
     /// Tries to find the best constraint to blame for the fact that
     /// `R: from_region`, where `R` is some region that meets
@@ -257,16 +281,16 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// ```
     ///
     /// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`.
-    pub(super) fn report_error(
-        &self,
+    pub(super) fn report_error<'a>(
+        &'a self,
         body: &Body<'tcx>,
         upvars: &[Upvar],
-        infcx: &InferCtxt<'_, 'tcx>,
+        infcx: &'a InferCtxt<'a, 'tcx>,
         mir_def_id: DefId,
         fr: RegionVid,
         outlived_fr: RegionVid,
-        errors_buffer: &mut Vec<Diagnostic>,
-    ) {
+        renctx: &mut RegionErrorNamingCtx,
+    ) -> DiagnosticBuilder<'a> {
         debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr);
 
         let (category, _, span) = self.best_blame_constraint(body, fr, |r| {
@@ -279,8 +303,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             let tables = infcx.tcx.typeck_tables_of(mir_def_id);
             let nice = NiceRegionError::new_from_span(infcx, span, o, f, Some(tables));
             if let Some(diag) = nice.try_report_from_nll() {
-                diag.buffer(errors_buffer);
-                return;
+                return diag;
             }
         }
 
@@ -293,45 +316,35 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             "report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}",
             fr_is_local, outlived_fr_is_local, category
         );
+
+        let errctx = ErrorReportingCtx {
+            rinfcx: self,
+            infcx,
+            mir_def_id,
+            body,
+            upvars,
+        };
+
+        let errci = ErrorConstraintInfo {
+            fr, outlived_fr, fr_is_local, outlived_fr_is_local, category, span
+        };
+
         match (category, fr_is_local, outlived_fr_is_local) {
             (ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(infcx, fr) => {
-                self.report_fnmut_error(
-                    body,
-                    upvars,
-                    infcx,
-                    mir_def_id,
-                    fr,
-                    outlived_fr,
-                    span,
-                    errors_buffer,
-                )
+                self.report_fnmut_error(&errctx, &errci, renctx)
             }
             (ConstraintCategory::Assignment, true, false)
-            | (ConstraintCategory::CallArgument, true, false) => self.report_escaping_data_error(
-                body,
-                upvars,
-                infcx,
-                mir_def_id,
-                fr,
-                outlived_fr,
-                category,
-                span,
-                errors_buffer,
-            ),
-            _ => self.report_general_error(
-                body,
-                upvars,
-                infcx,
-                mir_def_id,
-                fr,
-                fr_is_local,
-                outlived_fr,
-                outlived_fr_is_local,
-                category,
-                span,
-                errors_buffer,
-            ),
-        };
+            | (ConstraintCategory::CallArgument, true, false) => {
+                let mut db = self.report_escaping_data_error(&errctx, &errci, renctx);
+
+                db
+            }
+            _ => {
+                let mut db = self.report_general_error(&errctx, &errci, renctx);
+
+                db
+            }
+        }
     }
 
     /// We have a constraint `fr1: fr2` that is not satisfied, where
@@ -379,19 +392,19 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// ```
     fn report_fnmut_error(
         &self,
-        body: &Body<'tcx>,
-        upvars: &[Upvar],
-        infcx: &InferCtxt<'_, 'tcx>,
-        mir_def_id: DefId,
-        _fr: RegionVid,
-        outlived_fr: RegionVid,
-        span: Span,
-        errors_buffer: &mut Vec<Diagnostic>,
-    ) {
-        let mut diag = infcx
+        errctx: &ErrorReportingCtx<'_, '_, 'tcx>,
+        errci: &ErrorConstraintInfo,
+        renctx: &mut RegionErrorNamingCtx,
+    ) -> DiagnosticBuilder<'_> {
+        let ErrorConstraintInfo {
+            outlived_fr, span, ..
+        } = errci;
+
+        let mut diag = errctx
+            .infcx
             .tcx
             .sess
-            .struct_span_err(span, "captured variable cannot escape `FnMut` closure body");
+            .struct_span_err(*span, "captured variable cannot escape `FnMut` closure body");
 
         // We should check if the return type of this closure is in fact a closure - in that
         // case, we can special case the error further.
@@ -403,11 +416,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             "returns a reference to a captured variable which escapes the closure body"
         };
 
-        diag.span_label(span, message);
+        diag.span_label(*span, message);
 
-        match self.give_region_a_name(infcx, body, upvars, mir_def_id, outlived_fr, &mut 1)
-            .unwrap().source
-        {
+        match self.give_region_a_name(errctx, renctx, *outlived_fr).unwrap().source {
             RegionNameSource::NamedEarlyBoundRegion(fr_span)
             | RegionNameSource::NamedFreeRegion(fr_span)
             | RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _)
@@ -427,7 +438,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         );
         diag.note("...therefore, they cannot allow references to captured variables to escape");
 
-        diag.buffer(errors_buffer);
+        diag
     }
 
     /// Reports a error specifically for when data is escaping a closure.
@@ -444,20 +455,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// ```
     fn report_escaping_data_error(
         &self,
-        body: &Body<'tcx>,
-        upvars: &[Upvar],
-        infcx: &InferCtxt<'_, 'tcx>,
-        mir_def_id: DefId,
-        fr: RegionVid,
-        outlived_fr: RegionVid,
-        category: ConstraintCategory,
-        span: Span,
-        errors_buffer: &mut Vec<Diagnostic>,
-    ) {
+        errctx: &ErrorReportingCtx<'_, '_, 'tcx>,
+        errci: &ErrorConstraintInfo,
+        renctx: &mut RegionErrorNamingCtx,
+    ) -> DiagnosticBuilder<'_> {
+        let ErrorReportingCtx {
+            infcx, body, upvars, ..
+        } = errctx;
+
+        let ErrorConstraintInfo {
+            span, category, ..
+        } = errci;
+
         let fr_name_and_span =
-            self.get_var_name_and_span_for_region(infcx.tcx, body, upvars, fr);
+            self.get_var_name_and_span_for_region(infcx.tcx, body, upvars, errci.fr);
         let outlived_fr_name_and_span =
-            self.get_var_name_and_span_for_region(infcx.tcx, body, upvars, outlived_fr);
+            self.get_var_name_and_span_for_region(infcx.tcx, body, upvars, errci.outlived_fr);
 
         let escapes_from = match self.universal_regions.defining_ty {
             DefiningTy::Closure(..) => "closure",
@@ -469,27 +482,23 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // Revert to the normal error in these cases.
         // Assignments aren't "escapes" in function items.
         if (fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none())
-            || (category == ConstraintCategory::Assignment && escapes_from == "function")
+            || (*category == ConstraintCategory::Assignment && escapes_from == "function")
             || escapes_from == "const"
         {
             return self.report_general_error(
-                body,
-                upvars,
-                infcx,
-                mir_def_id,
-                fr,
-                true,
-                outlived_fr,
-                false,
-                category,
-                span,
-                errors_buffer,
+                errctx,
+                &ErrorConstraintInfo {
+                    fr_is_local: true,
+                    outlived_fr_is_local: false,
+                    .. *errci
+                },
+                renctx,
             );
         }
 
         let mut diag = borrowck_errors::borrowed_data_escapes_closure(
             infcx.tcx,
-            span,
+            *span,
             escapes_from,
         );
 
@@ -513,12 +522,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             );
 
             diag.span_label(
-                span,
+                *span,
                 format!("`{}` escapes the {} body here", fr_name, escapes_from),
             );
         }
 
-        diag.buffer(errors_buffer);
+        diag
     }
 
     /// Reports a region inference error for the general case with named/synthesized lifetimes to
@@ -538,41 +547,37 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// ```
     fn report_general_error(
         &self,
-        body: &Body<'tcx>,
-        upvars: &[Upvar],
-        infcx: &InferCtxt<'_, 'tcx>,
-        mir_def_id: DefId,
-        fr: RegionVid,
-        fr_is_local: bool,
-        outlived_fr: RegionVid,
-        outlived_fr_is_local: bool,
-        category: ConstraintCategory,
-        span: Span,
-        errors_buffer: &mut Vec<Diagnostic>,
-    ) {
+        errctx: &ErrorReportingCtx<'_, '_, 'tcx>,
+        errci: &ErrorConstraintInfo,
+        renctx: &mut RegionErrorNamingCtx,
+    ) -> DiagnosticBuilder<'_> {
+        let ErrorReportingCtx {
+            infcx, mir_def_id, ..
+        } = errctx;
+        let ErrorConstraintInfo {
+            fr, fr_is_local, outlived_fr, outlived_fr_is_local, span, category, ..
+        } = errci;
+
         let mut diag = infcx.tcx.sess.struct_span_err(
-            span,
+            *span,
             "lifetime may not live long enough"
         );
 
-        let counter = &mut 1;
-        let fr_name = self.give_region_a_name(
-            infcx, body, upvars, mir_def_id, fr, counter).unwrap();
-        fr_name.highlight_region_name(&mut diag);
-        let outlived_fr_name =
-            self.give_region_a_name(infcx, body, upvars, mir_def_id, outlived_fr, counter).unwrap();
-        outlived_fr_name.highlight_region_name(&mut diag);
-
-        let mir_def_name = if infcx.tcx.is_closure(mir_def_id) {
+        let mir_def_name = if infcx.tcx.is_closure(*mir_def_id) {
             "closure"
         } else {
             "function"
         };
 
+        let fr_name = self.give_region_a_name(errctx, renctx, *fr).unwrap();
+        fr_name.highlight_region_name(&mut diag);
+        let outlived_fr_name = self.give_region_a_name(errctx, renctx, *outlived_fr).unwrap();
+        outlived_fr_name.highlight_region_name(&mut diag);
+
         match (category, outlived_fr_is_local, fr_is_local) {
             (ConstraintCategory::Return, true, _) => {
                 diag.span_label(
-                    span,
+                    *span,
                     format!(
                         "{} was supposed to return data with lifetime `{}` but it is returning \
                          data with lifetime `{}`",
@@ -582,7 +587,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             }
             _ => {
                 diag.span_label(
-                    span,
+                    *span,
                     format!(
                         "{}requires that `{}` must outlive `{}`",
                         category.description(),
@@ -593,9 +598,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             }
         }
 
-        self.add_static_impl_trait_suggestion(infcx, &mut diag, fr, fr_name, outlived_fr);
+        self.add_static_impl_trait_suggestion(infcx, &mut diag, *fr, fr_name, *outlived_fr);
 
-        diag.buffer(errors_buffer);
+        diag
     }
 
     /// Adds a suggestion to errors where a `impl Trait` is returned.
@@ -704,8 +709,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             borrow_region,
             |r| self.provides_universal_region(r, borrow_region, outlived_region)
         );
-        let outlived_fr_name =
-            self.give_region_a_name(infcx, body, upvars, mir_def_id, outlived_region, &mut 1);
+
+        let mut renctx = RegionErrorNamingCtx::new();
+        let errctx = ErrorReportingCtx {
+            infcx, body, upvars, mir_def_id,
+            rinfcx: self,
+        };
+        let outlived_fr_name = self.give_region_a_name(&errctx, &mut renctx, outlived_region);
+
         (category, from_closure, span, outlived_fr_name)
     }
 
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index 75a31628a54b6..6fa94269107f5 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -1,5 +1,9 @@
 use std::fmt::{self, Display};
-use crate::borrow_check::nll::region_infer::RegionInferenceContext;
+
+use crate::borrow_check::nll::region_infer::{
+    RegionInferenceContext,
+    error_reporting::ErrorReportingCtx,
+};
 use crate::borrow_check::nll::universal_regions::DefiningTy;
 use crate::borrow_check::nll::ToRegionVid;
 use crate::borrow_check::Upvar;
@@ -13,29 +17,75 @@ use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt};
 use rustc::ty::print::RegionHighlightMode;
 use rustc_errors::DiagnosticBuilder;
 use syntax::symbol::kw;
-use syntax_pos::Span;
-use syntax_pos::symbol::InternedString;
+use rustc_data_structures::fx::FxHashMap;
+use syntax_pos::{Span, symbol::InternedString};
 
-#[derive(Debug)]
+/// A name for a particular region used in emitting diagnostics. This name could be a generated
+/// name like `'1`, a name used by the user like `'a`, or a name like `'static`.
+#[derive(Debug, Clone)]
 crate struct RegionName {
+    /// The name of the region (interned).
     crate name: InternedString,
+    /// Where the region comes from.
     crate source: RegionNameSource,
 }
 
-#[derive(Debug)]
+/// Denotes the source of a region that is named by a `RegionName`. For example, a free region that
+/// was named by the user would get `NamedFreeRegion` and `'static` lifetime would get `Static`.
+/// This helps to print the right kinds of diagnostics.
+#[derive(Debug, Clone)]
 crate enum RegionNameSource {
+    /// A bound (not free) region that was substituted at the def site (not an HRTB).
     NamedEarlyBoundRegion(Span),
+    /// A free region that the user has a name (`'a`) for.
     NamedFreeRegion(Span),
+    /// The `'static` region.
     Static,
+    /// The free region corresponding to the environment of a closure.
     SynthesizedFreeEnvRegion(Span, String),
+    /// The region name corresponds to a region where the type annotation is completely missing
+    /// from the code, e.g. in a closure arguments `|x| { ... }`, where `x` is a reference.
     CannotMatchHirTy(Span, String),
+    /// The region name corresponds a reference that was found by traversing the type in the HIR.
     MatchedHirTy(Span),
+    /// A region name from the generics list of a struct/enum/union.
     MatchedAdtAndSegment(Span),
+    /// The region corresponding to a closure upvar.
     AnonRegionFromUpvar(Span, String),
+    /// The region corresponding to the return type of a closure.
     AnonRegionFromOutput(Span, String, String),
     AnonRegionFromYieldTy(Span, String),
 }
 
+/// Records region names that have been assigned before so that we can use the same ones in later
+/// diagnostics.
+#[derive(Debug, Clone)]
+crate struct RegionErrorNamingCtx {
+    /// Record the region names generated for each region in the given
+    /// MIR def so that we can reuse them later in help/error messages.
+    renctx: FxHashMap<RegionVid, RegionName>,
+
+    /// The counter for generating new region names.
+    counter: usize,
+}
+
+impl RegionErrorNamingCtx {
+    crate fn new() -> Self {
+        Self {
+            counter: 1,
+            renctx: FxHashMap::default(),
+        }
+    }
+
+    crate fn get(&self, region: &RegionVid) -> Option<&RegionName> {
+        self.renctx.get(region)
+    }
+
+    crate fn insert(&mut self, region: RegionVid, name: RegionName) {
+        self.renctx.insert(region, name);
+    }
+}
+
 impl RegionName {
     #[allow(dead_code)]
     crate fn was_named(&self) -> bool {
@@ -63,43 +113,40 @@ impl RegionName {
         self.name
     }
 
-    crate fn highlight_region_name(
-        &self,
-        diag: &mut DiagnosticBuilder<'_>
-    ) {
+    crate fn highlight_region_name(&self, diag: &mut DiagnosticBuilder<'_>) {
         match &self.source {
-            RegionNameSource::NamedFreeRegion(span) |
-            RegionNameSource::NamedEarlyBoundRegion(span) => {
-                diag.span_label(
-                    *span,
-                    format!("lifetime `{}` defined here", self),
-                );
-            },
+            RegionNameSource::NamedFreeRegion(span)
+            | RegionNameSource::NamedEarlyBoundRegion(span) => {
+                diag.span_label(*span, format!("lifetime `{}` defined here", self));
+            }
             RegionNameSource::SynthesizedFreeEnvRegion(span, note) => {
                 diag.span_label(
                     *span,
                     format!("lifetime `{}` represents this closure's body", self),
                 );
                 diag.note(&note);
-            },
+            }
             RegionNameSource::CannotMatchHirTy(span, type_name) => {
                 diag.span_label(*span, format!("has type `{}`", type_name));
-            },
+            }
             RegionNameSource::MatchedHirTy(span) => {
                 diag.span_label(
                     *span,
                     format!("let's call the lifetime of this reference `{}`", self),
                 );
-            },
+            }
             RegionNameSource::MatchedAdtAndSegment(span) => {
                 diag.span_label(*span, format!("let's call this `{}`", self));
-            },
+            }
             RegionNameSource::AnonRegionFromUpvar(span, upvar_name) => {
                 diag.span_label(
                     *span,
-                    format!("lifetime `{}` appears in the type of `{}`", self, upvar_name),
+                    format!(
+                        "lifetime `{}` appears in the type of `{}`",
+                        self, upvar_name
+                    ),
                 );
-            },
+            }
             RegionNameSource::AnonRegionFromOutput(span, mir_description, type_name) => {
                 diag.span_label(
                     *span,
@@ -151,39 +198,49 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// and then return the name `'1` for us to use.
     crate fn give_region_a_name(
         &self,
-        infcx: &InferCtxt<'_, 'tcx>,
-        body: &Body<'tcx>,
-        upvars: &[Upvar],
-        mir_def_id: DefId,
+        errctx: &ErrorReportingCtx<'_, '_, 'tcx>,
+        renctx: &mut RegionErrorNamingCtx,
         fr: RegionVid,
-        counter: &mut usize,
     ) -> Option<RegionName> {
-        debug!("give_region_a_name(fr={:?}, counter={})", fr, counter);
+        let ErrorReportingCtx {
+            infcx, body, mir_def_id, upvars, ..
+        } = errctx;
+
+        debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter);
 
         assert!(self.universal_regions.is_universal_region(fr));
 
-        let value = self.give_name_from_error_region(infcx.tcx, mir_def_id, fr, counter)
+        if let Some(value) = renctx.get(&fr) {
+            return Some(value.clone());
+        }
+
+        let value = self
+            .give_name_from_error_region(infcx.tcx, *mir_def_id, fr, renctx)
             .or_else(|| {
                 self.give_name_if_anonymous_region_appears_in_arguments(
-                    infcx, body, mir_def_id, fr, counter,
+                    infcx, body, *mir_def_id, fr, renctx,
                 )
             })
             .or_else(|| {
                 self.give_name_if_anonymous_region_appears_in_upvars(
-                    infcx.tcx, upvars, fr, counter,
+                    infcx.tcx, upvars, fr, renctx
                 )
             })
             .or_else(|| {
                 self.give_name_if_anonymous_region_appears_in_output(
-                    infcx, body, mir_def_id, fr, counter,
+                    infcx, body, *mir_def_id, fr, renctx,
                 )
             })
             .or_else(|| {
                 self.give_name_if_anonymous_region_appears_in_yield_ty(
-                    infcx, body, mir_def_id, fr, counter,
+                    infcx, body, *mir_def_id, fr, renctx,
                 )
             });
 
+        if let Some(ref value) = value {
+            renctx.insert(fr, value.clone());
+        }
+
         debug!("give_region_a_name: gave name {:?}", value);
         value
     }
@@ -197,7 +254,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         tcx: TyCtxt<'tcx>,
         mir_def_id: DefId,
         fr: RegionVid,
-        counter: &mut usize,
+        renctx: &mut RegionErrorNamingCtx,
     ) -> Option<RegionName> {
         let error_region = self.to_error_region(fr)?;
 
@@ -208,7 +265,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     let span = self.get_named_span(tcx, error_region, ebr.name);
                     Some(RegionName {
                         name: ebr.name,
-                        source: RegionNameSource::NamedEarlyBoundRegion(span)
+                        source: RegionNameSource::NamedEarlyBoundRegion(span),
                     })
                 } else {
                     None
@@ -227,12 +284,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                         name,
                         source: RegionNameSource::NamedFreeRegion(span),
                     })
-                },
+                }
 
                 ty::BoundRegion::BrEnv => {
-                    let mir_hir_id = tcx.hir()
-                                        .as_local_hir_id(mir_def_id)
-                                        .expect("non-local mir");
+                    let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir");
                     let def_ty = self.universal_regions.defining_ty;
 
                     if let DefiningTy::Closure(def_id, substs) = def_ty {
@@ -243,7 +298,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                         } else {
                             bug!("Closure is not defined by a closure expr");
                         };
-                        let region_name = self.synthesize_region_name(counter);
+                        let region_name = self.synthesize_region_name(renctx);
 
                         let closure_kind_ty = substs.closure_kind_ty(def_id, tcx);
                         let note = match closure_kind_ty.to_opt_closure_kind() {
@@ -265,7 +320,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                             name: region_name,
                             source: RegionNameSource::SynthesizedFreeEnvRegion(
                                 args_span,
-                                note.to_string()
+                                note.to_string(),
                             ),
                         })
                     } else {
@@ -335,7 +390,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         body: &Body<'tcx>,
         mir_def_id: DefId,
         fr: RegionVid,
-        counter: &mut usize,
+        renctx: &mut RegionErrorNamingCtx,
     ) -> Option<RegionName> {
         let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
         let argument_index = self.get_argument_index_for_region(infcx.tcx, fr)?;
@@ -349,12 +404,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             fr,
             arg_ty,
             argument_index,
-            counter,
+            renctx,
         ) {
             return Some(region_name);
         }
 
-        self.give_name_if_we_cannot_match_hir_ty(infcx, body, fr, arg_ty, counter)
+        self.give_name_if_we_cannot_match_hir_ty(infcx, body, fr, arg_ty, renctx)
     }
 
     fn give_name_if_we_can_match_hir_ty_from_argument(
@@ -365,7 +420,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         needle_fr: RegionVid,
         argument_ty: Ty<'tcx>,
         argument_index: usize,
-        counter: &mut usize,
+        renctx: &mut RegionErrorNamingCtx,
     ) -> Option<RegionName> {
         let mir_hir_id = infcx.tcx.hir().as_local_hir_id(mir_def_id)?;
         let fn_decl = infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?;
@@ -379,7 +434,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 body,
                 needle_fr,
                 argument_ty,
-                counter,
+                renctx,
             ),
 
             _ => self.give_name_if_we_can_match_hir_ty(
@@ -387,7 +442,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 needle_fr,
                 argument_ty,
                 argument_hir_ty,
-                counter,
+                renctx,
             ),
         }
     }
@@ -409,10 +464,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         body: &Body<'tcx>,
         needle_fr: RegionVid,
         argument_ty: Ty<'tcx>,
-        counter: &mut usize,
+        renctx: &mut RegionErrorNamingCtx,
     ) -> Option<RegionName> {
+        let counter = renctx.counter;
         let mut highlight = RegionHighlightMode::default();
-        highlight.highlighting_region_vid(needle_fr, *counter);
+        highlight.highlighting_region_vid(needle_fr, counter);
         let type_name = infcx.extract_type_name(&argument_ty, Some(highlight)).0;
 
         debug!(
@@ -428,7 +484,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 // This counter value will already have been used, so this function will increment
                 // it so the next value will be used next and return the region name that would
                 // have been used.
-                name: self.synthesize_region_name(counter),
+                name: self.synthesize_region_name(renctx),
                 source: RegionNameSource::CannotMatchHirTy(span, type_name),
             })
         } else {
@@ -455,7 +511,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// type. Once we find that, we can use the span of the `hir::Ty`
     /// to add the highlight.
     ///
-    /// This is a somewhat imperfect process, so long the way we also
+    /// This is a somewhat imperfect process, so along the way we also
     /// keep track of the **closest** type we've found. If we fail to
     /// find the exact `&` or `'_` to highlight, then we may fall back
     /// to highlighting that closest type instead.
@@ -465,7 +521,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         needle_fr: RegionVid,
         argument_ty: Ty<'tcx>,
         argument_hir_ty: &hir::Ty,
-        counter: &mut usize,
+        renctx: &mut RegionErrorNamingCtx,
     ) -> Option<RegionName> {
         let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty)> =
             &mut vec![(argument_ty, argument_hir_ty)];
@@ -483,7 +539,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     hir::TyKind::Rptr(_lifetime, referent_hir_ty),
                 ) => {
                     if region.to_region_vid() == needle_fr {
-                        let region_name = self.synthesize_region_name(counter);
+                        let region_name = self.synthesize_region_name(renctx);
 
                         // Just grab the first character, the `&`.
                         let source_map = tcx.sess.source_map();
@@ -515,7 +571,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                                 substs,
                                 needle_fr,
                                 last_segment,
-                                counter,
+                                renctx,
                                 search_stack,
                             ) {
                                 return Some(name);
@@ -559,18 +615,19 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         substs: SubstsRef<'tcx>,
         needle_fr: RegionVid,
         last_segment: &'hir hir::PathSegment,
-        counter: &mut usize,
+        renctx: &mut RegionErrorNamingCtx,
         search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty)>,
     ) -> Option<RegionName> {
         // Did the user give explicit arguments? (e.g., `Foo<..>`)
         let args = last_segment.args.as_ref()?;
-        let lifetime = self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
+        let lifetime =
+            self.try_match_adt_and_generic_args(substs, needle_fr, args, search_stack)?;
         match lifetime.name {
             hir::LifetimeName::Param(_)
             | hir::LifetimeName::Error
             | hir::LifetimeName::Static
             | hir::LifetimeName::Underscore => {
-                let region_name = self.synthesize_region_name(counter);
+                let region_name = self.synthesize_region_name(renctx);
                 let ampersand_span = lifetime.span;
                 Some(RegionName {
                     name: region_name,
@@ -657,12 +714,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         tcx: TyCtxt<'tcx>,
         upvars: &[Upvar],
         fr: RegionVid,
-        counter: &mut usize,
+        renctx: &mut RegionErrorNamingCtx,
     ) -> Option<RegionName> {
         let upvar_index = self.get_upvar_index_for_region(tcx, fr)?;
         let (upvar_name, upvar_span) =
             self.get_upvar_name_and_span_for_region(tcx, upvars, upvar_index);
-        let region_name = self.synthesize_region_name(counter);
+        let region_name = self.synthesize_region_name(renctx);
 
         Some(RegionName {
             name: region_name,
@@ -680,7 +737,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         body: &Body<'tcx>,
         mir_def_id: DefId,
         fr: RegionVid,
-        counter: &mut usize,
+        renctx: &mut RegionErrorNamingCtx,
     ) -> Option<RegionName> {
         let tcx = infcx.tcx;
 
@@ -694,7 +751,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         }
 
         let mut highlight = RegionHighlightMode::default();
-        highlight.highlighting_region_vid(fr, *counter);
+        highlight.highlighting_region_vid(fr, renctx.counter);
         let type_name = infcx.extract_type_name(&return_ty, Some(highlight)).0;
 
         let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir");
@@ -725,11 +782,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             // This counter value will already have been used, so this function will increment it
             // so the next value will be used next and return the region name that would have been
             // used.
-            name: self.synthesize_region_name(counter),
+            name: self.synthesize_region_name(renctx),
             source: RegionNameSource::AnonRegionFromOutput(
                 return_span,
                 mir_description.to_string(),
-                type_name
+                type_name,
             ),
         })
     }
@@ -740,7 +797,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         body: &Body<'tcx>,
         mir_def_id: DefId,
         fr: RegionVid,
-        counter: &mut usize,
+        renctx: &mut RegionErrorNamingCtx,
     ) -> Option<RegionName> {
         // Note: generators from `async fn` yield `()`, so we don't have to
         // worry about them here.
@@ -757,7 +814,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         }
 
         let mut highlight = RegionHighlightMode::default();
-        highlight.highlighting_region_vid(fr, *counter);
+        highlight.highlighting_region_vid(fr, renctx.counter);
         let type_name = infcx.extract_type_name(&yield_ty, Some(highlight)).0;
 
         let mir_hir_id = tcx.hir().as_local_hir_id(mir_def_id).expect("non-local mir");
@@ -780,16 +837,15 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         );
 
         Some(RegionName {
-            name: self.synthesize_region_name(counter),
+            name: self.synthesize_region_name(renctx),
             source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name),
         })
     }
 
-    /// Creates a synthetic region named `'1`, incrementing the
-    /// counter.
-    fn synthesize_region_name(&self, counter: &mut usize) -> InternedString {
-        let c = *counter;
-        *counter += 1;
+    /// Creates a synthetic region named `'1`, incrementing the counter.
+    fn synthesize_region_name(&self, renctx: &mut RegionErrorNamingCtx) -> InternedString {
+        let c = renctx.counter;
+        renctx.counter += 1;
 
         InternedString::intern(&format!("'{:?}", c))
     }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index 40388722bcac9..7250768699c5f 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -1,15 +1,21 @@
-use super::universal_regions::UniversalRegions;
-use crate::borrow_check::nll::constraints::graph::NormalConstraintGraph;
-use crate::borrow_check::nll::constraints::{
-    ConstraintSccIndex, OutlivesConstraint, OutlivesConstraintSet,
-};
-use crate::borrow_check::nll::member_constraints::{MemberConstraintSet, NllMemberConstraintIndex};
-use crate::borrow_check::nll::region_infer::values::{
-    PlaceholderIndices, RegionElement, ToElementIndex,
+use std::rc::Rc;
+
+use crate::borrow_check::nll::{
+    constraints::{
+        graph::NormalConstraintGraph,
+        ConstraintSccIndex,
+        OutlivesConstraint,
+        OutlivesConstraintSet,
+    },
+    member_constraints::{MemberConstraintSet, NllMemberConstraintIndex},
+    region_infer::values::{
+        PlaceholderIndices, RegionElement, ToElementIndex
+    },
+    region_infer::error_reporting::outlives_suggestion::OutlivesSuggestionBuilder,
+    type_check::{free_region_relations::UniversalRegionRelations, Locations},
 };
-use crate::borrow_check::nll::type_check::free_region_relations::UniversalRegionRelations;
-use crate::borrow_check::nll::type_check::Locations;
 use crate::borrow_check::Upvar;
+
 use rustc::hir::def_id::DefId;
 use rustc::infer::canonical::QueryOutlivesConstraint;
 use rustc::infer::opaque_types;
@@ -31,16 +37,16 @@ use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_errors::{Diagnostic, DiagnosticBuilder};
 use syntax_pos::Span;
 
-use std::rc::Rc;
+crate use self::error_reporting::{RegionName, RegionNameSource, RegionErrorNamingCtx};
+use self::values::{LivenessValues, RegionValueElements, RegionValues};
+use super::universal_regions::UniversalRegions;
+use super::ToRegionVid;
 
 mod dump_mir;
 mod error_reporting;
-crate use self::error_reporting::{RegionName, RegionNameSource};
 mod graphviz;
-pub mod values;
-use self::values::{LivenessValues, RegionValueElements, RegionValues};
 
-use super::ToRegionVid;
+pub mod values;
 
 pub struct RegionInferenceContext<'tcx> {
     /// Contains the definition for every region variable. Region
@@ -487,6 +493,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             errors_buffer,
         );
 
+        // If we produce any errors, we keep track of the names of all regions, so that we can use
+        // the same error names in any suggestions we produce. Note that we need names to be unique
+        // across different errors for the same MIR def so that we can make suggestions that fix
+        // multiple problems.
+        let mut region_naming = RegionErrorNamingCtx::new();
+
         self.check_universal_regions(
             infcx,
             body,
@@ -494,6 +506,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             mir_def_id,
             outlives_requirements.as_mut(),
             errors_buffer,
+            &mut region_naming,
         );
 
         self.check_member_constraints(infcx, mir_def_id, errors_buffer);
@@ -1312,6 +1325,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         mir_def_id: DefId,
         mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
         errors_buffer: &mut Vec<Diagnostic>,
+        region_naming: &mut RegionErrorNamingCtx,
     ) {
         for (fr, fr_definition) in self.definitions.iter_enumerated() {
             match fr_definition.origin {
@@ -1326,7 +1340,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                         mir_def_id,
                         fr,
                         &mut propagated_outlives_requirements,
-                        errors_buffer,
+                        region_naming,
                     );
                 }
 
@@ -1357,7 +1371,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         mir_def_id: DefId,
         longer_fr: RegionVid,
         propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
-        errors_buffer: &mut Vec<Diagnostic>,
+        region_naming: &mut RegionErrorNamingCtx,
     ) {
         debug!("check_universal_region(fr={:?})", longer_fr);
 
@@ -1384,7 +1398,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 upvars,
                 mir_def_id,
                 propagated_outlives_requirements,
-                errors_buffer,
+                region_naming,
             );
             return;
         }
@@ -1400,9 +1414,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 upvars,
                 mir_def_id,
                 propagated_outlives_requirements,
-                errors_buffer,
+                region_naming,
             ) {
                 // continuing to iterate just reports more errors than necessary
+                //
+                // FIXME It would also allow us to report more Outlives Suggestions, though, so
+                // it's not clear that that's a bad thing. Somebody should try commenting out this
+                // line and see it is actually a regression.
                 return;
             }
         }
@@ -1417,7 +1435,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         upvars: &[Upvar],
         mir_def_id: DefId,
         propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
-        errors_buffer: &mut Vec<Diagnostic>,
+        region_naming: &mut RegionErrorNamingCtx,
     ) -> Option<ErrorReported> {
         // If it is known that `fr: o`, carry on.
         if self.universal_region_relations.outlives(longer_fr, shorter_fr) {
@@ -1466,7 +1484,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         //
         // Note: in this case, we use the unapproximated regions to report the
         // error. This gives better error messages in some cases.
-        self.report_error(body, upvars, infcx, mir_def_id, longer_fr, shorter_fr, errors_buffer);
+        let db = self.report_error(
+            body,
+            upvars,
+            infcx,
+            mir_def_id,
+            longer_fr,
+            shorter_fr,
+            region_naming,
+        );
+
+        db.buffer(errors_buffer);
+
         Some(ErrorReported)
     }
 

From 23db4504aa493a5b2670fba1475ac28de6670e59 Mon Sep 17 00:00:00 2001
From: Mark Mansi <markm@cs.wisc.edu>
Date: Thu, 12 Sep 2019 17:42:10 -0500
Subject: [PATCH 705/943] minor fixes

---
 .../borrow_check/nll/region_infer/error_reporting/mod.rs    | 5 +++--
 src/librustc_mir/borrow_check/nll/region_infer/mod.rs       | 6 +++++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
index 5aaa4bb7b072d..660f510ac196e 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
@@ -56,6 +56,7 @@ enum Trace {
 
 /// Various pieces of state used when reporting borrow checker errors.
 pub struct ErrorReportingCtx<'a, 'b, 'tcx> {
+    #[allow(dead_code)] // FIXME(mark-i-m): used by outlives suggestions
     rinfcx: &'b RegionInferenceContext<'tcx>,
     infcx: &'b InferCtxt<'a, 'tcx>,
 
@@ -335,12 +336,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             }
             (ConstraintCategory::Assignment, true, false)
             | (ConstraintCategory::CallArgument, true, false) => {
-                let mut db = self.report_escaping_data_error(&errctx, &errci, renctx);
+                let db = self.report_escaping_data_error(&errctx, &errci, renctx);
 
                 db
             }
             _ => {
-                let mut db = self.report_general_error(&errctx, &errci, renctx);
+                let db = self.report_general_error(&errctx, &errci, renctx);
 
                 db
             }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index 7250768699c5f..78e7943598d68 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -11,7 +11,6 @@ use crate::borrow_check::nll::{
     region_infer::values::{
         PlaceholderIndices, RegionElement, ToElementIndex
     },
-    region_infer::error_reporting::outlives_suggestion::OutlivesSuggestionBuilder,
     type_check::{free_region_relations::UniversalRegionRelations, Locations},
 };
 use crate::borrow_check::Upvar;
@@ -1340,6 +1339,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                         mir_def_id,
                         fr,
                         &mut propagated_outlives_requirements,
+                        errors_buffer,
                         region_naming,
                     );
                 }
@@ -1371,6 +1371,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         mir_def_id: DefId,
         longer_fr: RegionVid,
         propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
+        errors_buffer: &mut Vec<Diagnostic>,
         region_naming: &mut RegionErrorNamingCtx,
     ) {
         debug!("check_universal_region(fr={:?})", longer_fr);
@@ -1398,6 +1399,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 upvars,
                 mir_def_id,
                 propagated_outlives_requirements,
+                errors_buffer,
                 region_naming,
             );
             return;
@@ -1414,6 +1416,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 upvars,
                 mir_def_id,
                 propagated_outlives_requirements,
+                errors_buffer,
                 region_naming,
             ) {
                 // continuing to iterate just reports more errors than necessary
@@ -1435,6 +1438,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         upvars: &[Upvar],
         mir_def_id: DefId,
         propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
+        errors_buffer: &mut Vec<Diagnostic>,
         region_naming: &mut RegionErrorNamingCtx,
     ) -> Option<ErrorReported> {
         // If it is known that `fr: o`, carry on.

From 5b093585922f670ccd0f010c234a325b814d48a9 Mon Sep 17 00:00:00 2001
From: Mark Mansi <markm@cs.wisc.edu>
Date: Thu, 12 Sep 2019 18:56:09 -0500
Subject: [PATCH 706/943] update tests

---
 .../ui/c-variadic/variadic-ffi-4.nll.stderr    | 18 +++++++++---------
 .../ex3-both-anon-regions-3.nll.stderr         |  6 +++---
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr
index 4947d6e529108..ab8398ec5e935 100644
--- a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr
+++ b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr
@@ -37,11 +37,11 @@ error: lifetime may not live long enough
   --> $DIR/variadic-ffi-4.rs:20:5
    |
 LL | pub unsafe extern "C" fn no_escape3(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                               -------                   ------- has type `core::ffi::VaListImpl<'1>`
+   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
    |                                               |
-   |                                               has type `&mut core::ffi::VaListImpl<'2>`
+   |                                               has type `&mut core::ffi::VaListImpl<'1>`
 LL |     *ap0 = ap1;
-   |     ^^^^ assignment requires that `'1` must outlive `'2`
+   |     ^^^^ assignment requires that `'2` must outlive `'1`
 
 error: lifetime may not live long enough
   --> $DIR/variadic-ffi-4.rs:25:5
@@ -57,11 +57,11 @@ error: lifetime may not live long enough
   --> $DIR/variadic-ffi-4.rs:25:5
    |
 LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                               ---                   ------- has type `core::ffi::VaListImpl<'1>`
+   |                                               ---                   ------- has type `core::ffi::VaListImpl<'2>`
    |                                               |
-   |                                               has type `&mut core::ffi::VaListImpl<'2>`
+   |                                               has type `&mut core::ffi::VaListImpl<'1>`
 LL |     ap0 = &mut ap1;
-   |     ^^^^^^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+   |     ^^^^^^^^^^^^^^ assignment requires that `'2` must outlive `'1`
 
 error[E0384]: cannot assign to immutable argument `ap0`
   --> $DIR/variadic-ffi-4.rs:25:5
@@ -99,11 +99,11 @@ error: lifetime may not live long enough
   --> $DIR/variadic-ffi-4.rs:33:12
    |
 LL | pub unsafe extern "C" fn no_escape5(_: usize, mut ap0: &mut VaListImpl, mut ap1: ...) {
-   |                                               -------                   ------- has type `core::ffi::VaListImpl<'1>`
+   |                                               -------                   ------- has type `core::ffi::VaListImpl<'2>`
    |                                               |
-   |                                               has type `&mut core::ffi::VaListImpl<'2>`
+   |                                               has type `&mut core::ffi::VaListImpl<'1>`
 LL |     *ap0 = ap1.clone();
-   |            ^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+   |            ^^^^^^^^^^^ argument requires that `'2` must outlive `'1`
 
 error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr
index 779e2eb8b9205..2ed4d6d4401aa 100644
--- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr
+++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr
@@ -12,11 +12,11 @@ error: lifetime may not live long enough
   --> $DIR/ex3-both-anon-regions-3.rs:2:5
    |
 LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
-   |                         -                    - let's call the lifetime of this reference `'1`
+   |                         -                    - let's call the lifetime of this reference `'3`
    |                         |
-   |                         let's call the lifetime of this reference `'2`
+   |                         let's call the lifetime of this reference `'4`
 LL |     z.push((x,y));
-   |     ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+   |     ^^^^^^^^^^^^^ argument requires that `'3` must outlive `'4`
 
 error: aborting due to 2 previous errors
 

From a2261ad66400c3145f96ebff0d9b75e910fa89dd Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Fri, 13 Sep 2019 10:46:05 +1000
Subject: [PATCH 707/943] Inline `mark_neighbours_as_waiting_from`.

This function is very hot, doesn't get inlined because it's recursive,
and the function calls are significant.

This commit splits it into inlined and uninlined variants, and uses the
inlined variant for the hot call site. This wins several percent on a
few benchmarks.
---
 .../obligation_forest/mod.rs                    | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 04d2b23ab1a1c..6c52e626ababd 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -559,13 +559,20 @@ impl<O: ForestObligation> ObligationForest<O> {
         trace
     }
 
-    #[inline]
-    fn mark_neighbors_as_waiting_from(&self, node: &Node<O>) {
+    // This always-inlined function is for the hot call site.
+    #[inline(always)]
+    fn inlined_mark_neighbors_as_waiting_from(&self, node: &Node<O>) {
         for dependent in node.parent.iter().chain(node.dependents.iter()) {
             self.mark_as_waiting_from(&self.nodes[dependent.get()]);
         }
     }
 
+    // This never-inlined function is for the cold call site.
+    #[inline(never)]
+    fn uninlined_mark_neighbors_as_waiting_from(&self, node: &Node<O>) {
+        self.inlined_mark_neighbors_as_waiting_from(node)
+    }
+
     /// Marks all nodes that depend on a pending node as `NodeState::Waiting`.
     fn mark_as_waiting(&self) {
         for node in &self.nodes {
@@ -576,7 +583,8 @@ impl<O: ForestObligation> ObligationForest<O> {
 
         for node in &self.nodes {
             if node.state.get() == NodeState::Pending {
-                self.mark_neighbors_as_waiting_from(node);
+                // This call site is hot.
+                self.inlined_mark_neighbors_as_waiting_from(node);
             }
         }
     }
@@ -588,7 +596,8 @@ impl<O: ForestObligation> ObligationForest<O> {
             NodeState::Pending | NodeState::Done => {},
         }
 
-        self.mark_neighbors_as_waiting_from(node);
+        // This call site is cold.
+        self.uninlined_mark_neighbors_as_waiting_from(node);
     }
 
     /// Compresses the vector, removing all popped nodes. This adjusts

From a47a5c3a629429526c06f92555394484eedf8277 Mon Sep 17 00:00:00 2001
From: Guanqun Lu <guanqun.lu@gmail.com>
Date: Mon, 9 Sep 2019 23:44:11 +0800
Subject: [PATCH 708/943] typo fix

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

diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index f5e644625729b..2c8590aa4e3fa 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -190,7 +190,7 @@ pub enum ParamName {
     Fresh(usize),
 
     /// Indicates an illegal name was given and an error has been
-    /// repored (so we should squelch other derived errors). Occurs
+    /// reported (so we should squelch other derived errors). Occurs
     /// when, e.g., `'_` is used in the wrong place.
     Error,
 }

From bd25507f0e6501abb8bb1ee79330bf76136d393f Mon Sep 17 00:00:00 2001
From: Oliver Middleton <olliemail27@gmail.com>
Date: Fri, 13 Sep 2019 11:37:29 +0100
Subject: [PATCH 709/943] Remove raw string literal quotes from error index
 descriptions

---
 src/tools/error_index_generator/build.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/error_index_generator/build.rs b/src/tools/error_index_generator/build.rs
index 832aa3b1c8dfd..592b3f14c85af 100644
--- a/src/tools/error_index_generator/build.rs
+++ b/src/tools/error_index_generator/build.rs
@@ -35,7 +35,7 @@ fn register_all() -> Vec<(&'static str, Option<&'static str>)> {
         ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => (
             $(
                 {long_codes.extend([
-                    (stringify!($ecode), Some(stringify!($message))),
+                    (stringify!($ecode), Some($message)),
                 ].iter());}
             )*
             $(

From 69112a27fba9c2b36d6969cf79191045ed780014 Mon Sep 17 00:00:00 2001
From: Oliver Middleton <olliemail27@gmail.com>
Date: Fri, 13 Sep 2019 11:42:31 +0100
Subject: [PATCH 710/943] Add self to .mailmap

---
 .mailmap | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.mailmap b/.mailmap
index da8044de405a6..9587aaab35945 100644
--- a/.mailmap
+++ b/.mailmap
@@ -184,6 +184,7 @@ Neil Pankey <npankey@gmail.com> <neil@wire.im>
 Nick Platt <platt.nicholas@gmail.com>
 Nicole Mazzuca <npmazzuca@gmail.com>
 Nif Ward <nif.ward@gmail.com>
+Oliver Middleton <olliemail27@gmail.com> <ollie27@users.noreply.github.com>
 Oliver Scherer <oliver.schneider@kit.edu> <git-spam-no-reply9815368754983@oli-obk.de>
 Oliver Scherer <oliver.schneider@kit.edu> <git-spam9815368754983@oli-obk.de>
 Oliver Scherer <oliver.schneider@kit.edu> <github333195615777966@oli-obk.de>

From 07a706ecf594e9feca5c57ae5db9e237a080fadf Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Thu, 12 Sep 2019 16:16:43 -0300
Subject: [PATCH 711/943] Avoid math and use patterns to grab projection base

---
 .../borrow_check/conflict_errors.rs           |  5 +----
 src/librustc_mir/borrow_check/mod.rs          |  7 +++---
 .../borrow_check/mutability_errors.rs         |  9 ++------
 src/librustc_mir/build/expr/as_rvalue.rs      | 16 +++++---------
 src/librustc_mir/transform/instcombine.rs     | 22 ++++++++++---------
 5 files changed, 24 insertions(+), 35 deletions(-)

diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index 413f7e2e40635..c901eb2905476 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -1520,10 +1520,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             [] => {
                 StorageDeadOrDrop::LocalStorageDead
             }
-            [.., elem] => {
-                // FIXME(spastorino) revisit when we get rid of Box
-                let base = &place.projection[..place.projection.len() - 1];
-
+            [base @ .., elem] => {
                 // FIXME(spastorino) make this iterate
                 let base_access = self.classify_drop_access_kind(PlaceRef {
                     base: place.base,
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 3b10d8f19668c..5ef70461296c7 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -2324,14 +2324,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let mut place_projection = place_ref.projection;
         let mut by_ref = false;
 
-        if let [.., ProjectionElem::Deref] = place_projection {
-            place_projection = &place_projection[..place_projection.len() - 1];
+        if let [proj_base @ .., ProjectionElem::Deref] = place_projection {
+            place_projection = proj_base;
             by_ref = true;
         }
 
         match place_projection {
-            [.., ProjectionElem::Field(field, _ty)] => {
-                let base = &place_projection[..place_projection.len() - 1];
+            [base @ .., ProjectionElem::Field(field, _ty)] => {
                 let tcx = self.infcx.tcx;
                 let base_ty = Place::ty_from(place_ref.base, base, self.body, tcx).ty;
 
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 12dc2cd1f91c3..9b9dfc3023354 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -82,11 +82,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
             PlaceRef {
                 base: _,
-                projection: [.., ProjectionElem::Deref],
+                projection: [base @ .., ProjectionElem::Deref],
             } => {
-                // FIXME(spastorino) once released use box [base @ .., ProjectionElem::Deref]
-                let base = &the_place_err.projection[..the_place_err.projection.len() - 1];
-
                 if the_place_err.base == &PlaceBase::Local(Local::new(1)) &&
                     base.is_empty() &&
                     !self.upvars.is_empty() {
@@ -243,14 +240,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             // after the field access).
             PlaceRef {
                 base,
-                projection: [..,
+                projection: [base_proj @ ..,
                              ProjectionElem::Deref,
                              ProjectionElem::Field(field, _),
                              ProjectionElem::Deref,
                 ],
             } => {
-                let base_proj = &the_place_err.projection[..the_place_err.projection.len() - 3];
-
                 err.span_label(span, format!("cannot {ACT}", ACT = act));
 
                 if let Some((span, message)) = annotate_struct_field(
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 1371bc5aee82f..6692984524fec 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -514,20 +514,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
             Place {
                 ref base,
-                projection: box [.., ProjectionElem::Field(upvar_index, _)],
+                projection: box [ref base_proj @ .., ProjectionElem::Field(upvar_index, _)],
             }
             | Place {
                 ref base,
-                projection: box [.., ProjectionElem::Field(upvar_index, _), ProjectionElem::Deref],
+                projection: box [
+                    ref base_proj @ ..,
+                    ProjectionElem::Field(upvar_index, _),
+                    ProjectionElem::Deref
+                ],
             } => {
-                let base_proj = if let ProjectionElem::Deref =
-                    arg_place.projection[arg_place.projection.len() - 1]
-                {
-                    &arg_place.projection[..arg_place.projection.len() - 2]
-                } else {
-                    &arg_place.projection[..arg_place.projection.len() - 1]
-                };
-
                 let place = PlaceRef {
                     base,
                     projection: base_proj,
diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs
index da91a8daca368..0e04e63af4522 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/src/librustc_mir/transform/instcombine.rs
@@ -45,16 +45,18 @@ impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor<'tcx> {
                     ref mut base,
                     projection: ref mut projection @ box [.., _],
                 }) => {
-                    let [proj_l @ .., proj_r] = projection;
-
-                    let place = Place {
-                        // Replace with dummy
-                        base: mem::replace(base, PlaceBase::Local(Local::new(0))),
-                        projection: proj_l.to_vec().into_boxed_slice(),
-                    };
-                    *projection = proj_r.to_vec().into_boxed_slice();
-
-                    place
+                    if let box [proj_l @ .., proj_r] = projection {
+                        let place = Place {
+                            // Replace with dummy
+                            base: mem::replace(base, PlaceBase::Local(Local::new(0))),
+                            projection: proj_l.to_vec().into_boxed_slice(),
+                        };
+                        *projection = vec![proj_r.clone()].into_boxed_slice();
+
+                        place
+                    } else {
+                        unreachable!();
+                    }
                 }
                 _ => bug!("Detected `&*` but didn't find `&*`!"),
             };

From 98edaead8249b936a29c53bffb095737643982dc Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Thu, 12 Sep 2019 16:20:20 -0300
Subject: [PATCH 712/943] Fix style in comments

---
 src/librustc_mir/borrow_check/nll/type_check/mod.rs | 10 +++++-----
 src/librustc_mir/borrow_check/prefixes.rs           | 10 +++++-----
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 10c038bc3336f..1d17bae559c59 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -488,16 +488,16 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
                         substs: tcx.mk_substs_trait(place_ty.ty, &[]),
                     };
 
-                    // In order to have a Copy operand, the type T of the
-                    // value must be Copy. Note that we prove that T: Copy,
+                    // To have a `Copy` operand, the type `T` of the
+                    // value must be `Copy`. Note that we prove that `T: Copy`,
                     // rather than using the `is_copy_modulo_regions`
                     // test. This is important because
                     // `is_copy_modulo_regions` ignores the resulting region
                     // obligations and assumes they pass. This can result in
-                    // bounds from Copy impls being unsoundly ignored (e.g.,
-                    // #29149). Note that we decide to use Copy before knowing
+                    // bounds from `Copy` impls being unsoundly ignored (e.g.,
+                    // #29149). Note that we decide to use `Copy` before knowing
                     // whether the bounds fully apply: in effect, the rule is
-                    // that if a value of some type could implement Copy, then
+                    // that if a value of some type could implement `Copy`, then
                     // it must.
                     self.cx.prove_trait_ref(
                         trait_ref,
diff --git a/src/librustc_mir/borrow_check/prefixes.rs b/src/librustc_mir/borrow_check/prefixes.rs
index 819678dfaf255..0a268ec134023 100644
--- a/src/librustc_mir/borrow_check/prefixes.rs
+++ b/src/librustc_mir/borrow_check/prefixes.rs
@@ -118,15 +118,15 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
 
                     match self.kind {
                         PrefixSet::Shallow => {
-                            // shallow prefixes are found by stripping away
+                            // Shallow prefixes are found by stripping away
                             // fields, but stop at *any* dereference.
                             // So we can just stop the traversal now.
                             self.next = None;
                             return Some(cursor);
                         }
                         PrefixSet::All => {
-                            // all prefixes: just blindly enqueue the base
-                            // of the projection
+                            // All prefixes: just blindly enqueue the base
+                            // of the projection.
                             self.next = Some(PlaceRef {
                                 base: cursor.base,
                                 projection: proj_base,
@@ -134,12 +134,12 @@ impl<'cx, 'tcx> Iterator for Prefixes<'cx, 'tcx> {
                             return Some(cursor);
                         }
                         PrefixSet::Supporting => {
-                            // fall through!
+                            // Fall through!
                         }
                     }
 
                     assert_eq!(self.kind, PrefixSet::Supporting);
-                    // supporting prefixes: strip away fields and
+                    // Supporting prefixes: strip away fields and
                     // derefs, except we stop at the deref of a shared
                     // reference.
 

From 6ffc20f6a38ee78b1b496182281e6f5c8ddbaa02 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Thu, 12 Sep 2019 16:21:47 -0300
Subject: [PATCH 713/943] Use if let here

---
 src/librustc_mir/borrow_check/place_ext.rs | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/librustc_mir/borrow_check/place_ext.rs b/src/librustc_mir/borrow_check/place_ext.rs
index 50067345c65ee..411fa5b596765 100644
--- a/src/librustc_mir/borrow_check/place_ext.rs
+++ b/src/librustc_mir/borrow_check/place_ext.rs
@@ -57,7 +57,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
 
             if *elem == ProjectionElem::Deref {
                 let ty = Place::ty_from(&self.base, proj_base, body, tcx).ty;
-                match ty.sty {
+                if let ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) = ty.sty {
                     // For both derefs of raw pointers and `&T`
                     // references, the original path is `Copy` and
                     // therefore not significant.  In particular,
@@ -68,8 +68,7 @@ impl<'tcx> PlaceExt<'tcx> for Place<'tcx> {
                     // original path into a new variable and
                     // borrowed *that* one, leaving the original
                     // path unborrowed.
-                    ty::RawPtr(..) | ty::Ref(_, _, hir::MutImmutable) => return true,
-                    _ => {}
+                    return true;
                 }
             }
         }

From 28db2c9e953f4e1e0f1511193c90b84f4d170d1a Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Thu, 12 Sep 2019 17:33:38 -0300
Subject: [PATCH 714/943] Make all projection base names be proj_base

---
 src/librustc_mir/borrow_check/conflict_errors.rs   | 14 +++++++-------
 src/librustc_mir/borrow_check/mutability_errors.rs | 12 ++++++------
 src/librustc_mir/build/expr/as_rvalue.rs           |  6 +++---
 3 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index c901eb2905476..4b4516d6bf290 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -615,13 +615,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 } = first_borrowed_place;
 
                 for (i, elem) in projection.iter().enumerate().rev() {
-                    let base_proj = &projection[..i];
+                    let proj_base = &projection[..i];
 
                     match elem {
-                        ProjectionElem::Field(field, _) if union_ty(base, base_proj).is_some() => {
+                        ProjectionElem::Field(field, _) if union_ty(base, proj_base).is_some() => {
                             return Some((PlaceRef {
                                 base: base,
-                                projection: base_proj,
+                                projection: proj_base,
                             }, field));
                         },
                         _ => {},
@@ -1520,18 +1520,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             [] => {
                 StorageDeadOrDrop::LocalStorageDead
             }
-            [base @ .., elem] => {
+            [proj_base @ .., elem] => {
                 // FIXME(spastorino) make this iterate
                 let base_access = self.classify_drop_access_kind(PlaceRef {
                     base: place.base,
-                    projection: base,
+                    projection: proj_base,
                 });
                 match elem {
                     ProjectionElem::Deref => match base_access {
                         StorageDeadOrDrop::LocalStorageDead
                         | StorageDeadOrDrop::BoxedStorageDead => {
                             assert!(
-                                Place::ty_from(&place.base, base, self.body, tcx).ty.is_box(),
+                                Place::ty_from(&place.base, proj_base, self.body, tcx).ty.is_box(),
                                 "Drop of value behind a reference or raw pointer"
                             );
                             StorageDeadOrDrop::BoxedStorageDead
@@ -1539,7 +1539,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         StorageDeadOrDrop::Destructor(_) => base_access,
                     },
                     ProjectionElem::Field(..) | ProjectionElem::Downcast(..) => {
-                        let base_ty = Place::ty_from(&place.base, base, self.body, tcx).ty;
+                        let base_ty = Place::ty_from(&place.base, proj_base, self.body, tcx).ty;
                         match base_ty.sty {
                             ty::Adt(def, _) if def.has_dtor(tcx) => {
                                 // Report the outermost adt with a destructor
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 9b9dfc3023354..14b76d97b3e57 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -82,10 +82,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
             PlaceRef {
                 base: _,
-                projection: [base @ .., ProjectionElem::Deref],
+                projection: [proj_base @ .., ProjectionElem::Deref],
             } => {
                 if the_place_err.base == &PlaceBase::Local(Local::new(1)) &&
-                    base.is_empty() &&
+                    proj_base.is_empty() &&
                     !self.upvars.is_empty() {
                     item_msg = format!("`{}`", access_place_desc.unwrap());
                     debug_assert!(self.body.local_decls[Local::new(1)].ty.is_region_ptr());
@@ -106,7 +106,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                             ", as `Fn` closures cannot mutate their captured variables".to_string()
                         }
                 } else if {
-                    if let (PlaceBase::Local(local), []) = (&the_place_err.base, base) {
+                    if let (PlaceBase::Local(local), []) = (&the_place_err.base, proj_base) {
                         self.body.local_decls[*local].is_ref_for_guard()
                     } else {
                         false
@@ -117,7 +117,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 } else {
                     let source = self.borrowed_content_source(PlaceRef {
                         base: the_place_err.base,
-                        projection: base,
+                        projection: proj_base,
                     });
                     let pointer_type = source.describe_for_immutable_place();
                     opt_source = Some(source);
@@ -240,7 +240,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             // after the field access).
             PlaceRef {
                 base,
-                projection: [base_proj @ ..,
+                projection: [proj_base @ ..,
                              ProjectionElem::Deref,
                              ProjectionElem::Field(field, _),
                              ProjectionElem::Deref,
@@ -250,7 +250,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
                 if let Some((span, message)) = annotate_struct_field(
                     self.infcx.tcx,
-                    Place::ty_from(base, base_proj, self.body, self.infcx.tcx).ty,
+                    Place::ty_from(base, proj_base, self.body, self.infcx.tcx).ty,
                     field,
                 ) {
                     err.span_suggestion(
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 6692984524fec..7dfe98cbebfc2 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -514,19 +514,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
             Place {
                 ref base,
-                projection: box [ref base_proj @ .., ProjectionElem::Field(upvar_index, _)],
+                projection: box [ref proj_base @ .., ProjectionElem::Field(upvar_index, _)],
             }
             | Place {
                 ref base,
                 projection: box [
-                    ref base_proj @ ..,
+                    ref proj_base @ ..,
                     ProjectionElem::Field(upvar_index, _),
                     ProjectionElem::Deref
                 ],
             } => {
                 let place = PlaceRef {
                     base,
-                    projection: base_proj,
+                    projection: proj_base,
                 };
 
                 // Not projected from the implicit `self` in a closure.

From ab73b325b0e1288656f69ee24acb822fe91bc6a0 Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Thu, 5 Sep 2019 20:51:22 +0200
Subject: [PATCH 715/943] save-analysis: Nest typeck tables when processing
 functions/methods

Fixes an issue where we did not nest tables correctly when resolving
associated types in formal argument/return type positions
---
 src/librustc_save_analysis/dump_visitor.rs | 80 ++++++++++------------
 1 file changed, 38 insertions(+), 42 deletions(-)

diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 12c5ce12a0e8b..135f13499436c 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -283,36 +283,32 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
     ) {
         debug!("process_method: {}:{}", id, ident);
 
-        if let Some(mut method_data) = self.save_ctxt.get_method_data(id, ident, span) {
-            let sig_str = crate::make_signature(&sig.decl, &generics);
-            if body.is_some() {
-                self.nest_tables(
-                    id,
-                    |v| v.process_formals(&sig.decl.inputs, &method_data.qualname),
-                );
-            }
+        let hir_id = self.tcx.hir().node_to_hir_id(id);
+        self.nest_tables(id, |v| {
+            if let Some(mut method_data) = v.save_ctxt.get_method_data(id, ident, span) {
+                v.process_formals(&sig.decl.inputs, &method_data.qualname);
+                v.process_generic_params(&generics, &method_data.qualname, id);
 
-            self.process_generic_params(&generics, &method_data.qualname, id);
+                method_data.value = crate::make_signature(&sig.decl, &generics);
+                method_data.sig = sig::method_signature(id, ident, generics, sig, &v.save_ctxt);
 
-            method_data.value = sig_str;
-            method_data.sig = sig::method_signature(id, ident, generics, sig, &self.save_ctxt);
-            let hir_id = self.tcx.hir().node_to_hir_id(id);
-            self.dumper.dump_def(&access_from_vis!(self.save_ctxt, vis, hir_id), method_data);
-        }
+                v.dumper.dump_def(&access_from_vis!(v.save_ctxt, vis, hir_id), method_data);
+            }
 
-        // walk arg and return types
-        for arg in &sig.decl.inputs {
-            self.visit_ty(&arg.ty);
-        }
+            // walk arg and return types
+            for arg in &sig.decl.inputs {
+                v.visit_ty(&arg.ty);
+            }
 
-        if let ast::FunctionRetTy::Ty(ref ret_ty) = sig.decl.output {
-            self.visit_ty(ret_ty);
-        }
+            if let ast::FunctionRetTy::Ty(ref ret_ty) = sig.decl.output {
+                v.visit_ty(ret_ty);
+            }
 
-        // walk the fn body
-        if let Some(body) = body {
-            self.nest_tables(id, |v| v.visit_block(body));
-        }
+            // walk the fn body
+            if let Some(body) = body {
+                v.visit_block(body);
+            }
+        });
     }
 
     fn process_struct_field_def(&mut self, field: &ast::StructField, parent_id: NodeId) {
@@ -377,26 +373,26 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         ty_params: &'l ast::Generics,
         body: &'l ast::Block,
     ) {
-        if let Some(fn_data) = self.save_ctxt.get_item_data(item) {
-            down_cast_data!(fn_data, DefData, item.span);
-            self.nest_tables(
-                item.id,
-                |v| v.process_formals(&decl.inputs, &fn_data.qualname),
-            );
-            self.process_generic_params(ty_params, &fn_data.qualname, item.id);
-            let hir_id = self.tcx.hir().node_to_hir_id(item.id);
-            self.dumper.dump_def(&access_from!(self.save_ctxt, item, hir_id), fn_data);
-        }
+        let hir_id = self.tcx.hir().node_to_hir_id(item.id);
+        self.nest_tables(item.id, |v| {
+            if let Some(fn_data) = v.save_ctxt.get_item_data(item) {
+                down_cast_data!(fn_data, DefData, item.span);
+                v.process_formals(&decl.inputs, &fn_data.qualname);
+                v.process_generic_params(ty_params, &fn_data.qualname, item.id);
 
-        for arg in &decl.inputs {
-            self.visit_ty(&arg.ty);
-        }
+                v.dumper.dump_def(&access_from!(v.save_ctxt, item, hir_id), fn_data);
+            }
 
-        if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output {
-            self.visit_ty(&ret_ty);
-        }
+            for arg in &decl.inputs {
+                v.visit_ty(&arg.ty)
+            }
 
-        self.nest_tables(item.id, |v| v.visit_block(&body));
+            if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output {
+                v.visit_ty(&ret_ty);
+            }
+
+            v.visit_block(&body);
+        });
     }
 
     fn process_static_or_const_item(

From b456c820ffe6f19d133f196d3e935071f326094e Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Sun, 8 Sep 2019 21:19:47 +0200
Subject: [PATCH 716/943] Always validate HIR ID for TypeckTables

Performance shouldn't be impacted (see [1] for a perf run) and this
should allow us to catch more bugs, e.g. [2] and [3].

[1]: https://github.com/rust-lang/rust/pull/64262
[2]: https://github.com/rust-lang/rust/pull/64250
[3]: https://github.com/rust-lang/rust/issues/57298
---
 src/librustc/ty/context.rs | 38 ++++++++++++++++++--------------------
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 8e8472a5aacc9..7366037c5eb96 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -205,26 +205,24 @@ pub struct LocalTableInContext<'a, V> {
 fn validate_hir_id_for_typeck_tables(local_id_root: Option<DefId>,
                                      hir_id: hir::HirId,
                                      mut_access: bool) {
-    if cfg!(debug_assertions) {
-        if let Some(local_id_root) = local_id_root {
-            if hir_id.owner != local_id_root.index {
-                ty::tls::with(|tcx| {
-                    bug!("node {} with HirId::owner {:?} cannot be placed in \
-                          TypeckTables with local_id_root {:?}",
-                         tcx.hir().node_to_string(hir_id),
-                         DefId::local(hir_id.owner),
-                         local_id_root)
-                });
-            }
-        } else {
-            // We use "Null Object" TypeckTables in some of the analysis passes.
-            // These are just expected to be empty and their `local_id_root` is
-            // `None`. Therefore we cannot verify whether a given `HirId` would
-            // be a valid key for the given table. Instead we make sure that
-            // nobody tries to write to such a Null Object table.
-            if mut_access {
-                bug!("access to invalid TypeckTables")
-            }
+    if let Some(local_id_root) = local_id_root {
+        if hir_id.owner != local_id_root.index {
+            ty::tls::with(|tcx| {
+                bug!("node {} with HirId::owner {:?} cannot be placed in \
+                        TypeckTables with local_id_root {:?}",
+                        tcx.hir().node_to_string(hir_id),
+                        DefId::local(hir_id.owner),
+                        local_id_root)
+            });
+        }
+    } else {
+        // We use "Null Object" TypeckTables in some of the analysis passes.
+        // These are just expected to be empty and their `local_id_root` is
+        // `None`. Therefore we cannot verify whether a given `HirId` would
+        // be a valid key for the given table. Instead we make sure that
+        // nobody tries to write to such a Null Object table.
+        if mut_access {
+            bug!("access to invalid TypeckTables")
         }
     }
 }

From 6117faa809334136f81c90b6645ae760d50b48cd Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Sun, 8 Sep 2019 21:48:08 +0200
Subject: [PATCH 717/943] save-analysis: Add a related test case

---
 src/test/ui/save-analysis/issue-63663.rs | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 src/test/ui/save-analysis/issue-63663.rs

diff --git a/src/test/ui/save-analysis/issue-63663.rs b/src/test/ui/save-analysis/issue-63663.rs
new file mode 100644
index 0000000000000..ccbe13f1a1b71
--- /dev/null
+++ b/src/test/ui/save-analysis/issue-63663.rs
@@ -0,0 +1,23 @@
+// check-pass
+// compile-flags: -Zsave-analysis
+
+// Check that this doesn't ICE when processing associated const in formal
+// argument and return type of functions defined inside function/method scope.
+
+pub trait Trait {
+    type Assoc;
+}
+
+pub struct A;
+
+pub fn func() {
+    fn _inner1<U: Trait>(_: U::Assoc) {}
+    fn _inner2<U: Trait>() -> U::Assoc { unimplemented!() }
+
+    impl A {
+        fn _inner1<U: Trait>(self, _: U::Assoc) {}
+        fn _inner2<U: Trait>(self) -> U::Assoc { unimplemented!() }
+    }
+}
+
+fn main() {}

From b4151dd3211f4a9e8f980994a094f4b85149cd46 Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Fri, 13 Sep 2019 15:36:38 +0200
Subject: [PATCH 718/943] save-analysis: Use process_bounds when processing
 opaque impl item type

...since the code is literally the same and does the same thing.
---
 src/librustc_save_analysis/dump_visitor.rs | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 135f13499436c..28d8e3a4296ad 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -1109,11 +1109,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
                 // FIXME: uses of the assoc type should ideally point to this
                 // 'def' and the name here should be a ref to the def in the
                 // trait.
-                for bound in bounds.iter() {
-                    if let ast::GenericBound::Trait(trait_ref, _) = bound {
-                        self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
-                    }
-                }
+                self.process_bounds(&bounds);
             }
             ast::ImplItemKind::Macro(_) => {}
         }

From 0fafd615e5f56a98a0c1c21c88fc6352540926b2 Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Fri, 13 Sep 2019 15:41:10 +0200
Subject: [PATCH 719/943] save-analysis: Visit bounds in opaque types

---
 src/librustc_save_analysis/dump_visitor.rs | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 28d8e3a4296ad..fb1003fd7055d 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -1356,10 +1356,10 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
                 self.visit_ty(&ty);
                 self.process_generic_params(ty_params, &qualname, item.id);
             }
-            OpaqueTy(ref _bounds, ref ty_params) => {
+            OpaqueTy(ref bounds, ref ty_params) => {
                 let qualname = format!("::{}",
                     self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
-                // FIXME do something with _bounds
+
                 let value = String::new();
                 if !self.span.filter_generated(item.ident.span) {
                     let span = self.span_from_span(item.ident.span);
@@ -1385,6 +1385,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
                     );
                 }
 
+                self.process_bounds(bounds);
                 self.process_generic_params(ty_params, &qualname, item.id);
             }
             Mac(_) => (),

From b3b671366bc98017fcac7bcfae0d46d038575aa3 Mon Sep 17 00:00:00 2001
From: Christian Veenman <46896178+DevQps@users.noreply.github.com>
Date: Fri, 13 Sep 2019 16:29:06 +0200
Subject: [PATCH 720/943] Update src/libstd/time.rs

Co-Authored-By: Robin Kruppe <robin.kruppe@gmail.com>
---
 src/libstd/time.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index f276ab4200525..ff209785a935d 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -72,7 +72,7 @@ pub use core::time::Duration;
 /// | VXWorks   | [clock_gettime (Monotonic Clock)]                                    |
 /// | WASI      | [__wasi_clock_time_get (Monotonic Clock)]                            |
 /// | Windows   | [QueryPerformanceCounter]                                            |
-
+///
 /// [QueryPerformanceCounter]: https://docs.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter
 /// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time
 /// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode

From 7437f770251f6c3c76f75891d48db4d1e26fc0c2 Mon Sep 17 00:00:00 2001
From: "Felix S. Klock II" <pnkfelix@pnkfx.org>
Date: Fri, 13 Sep 2019 17:06:09 +0200
Subject: [PATCH 721/943] Make fn ptr always structural match, regardless of
 whether formal types are.

Fix #63479.
---
 src/librustc_mir/hair/pattern/mod.rs | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 6caccfddfa422..4aaa5e8ee259a 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -1229,7 +1229,13 @@ fn search_for_adt_without_structural_match<'tcx>(tcx: TyCtxt<'tcx>,
                 ty::RawPtr(..) => {
                     // `#[structural_match]` ignores substructure of
                     // `*const _`/`*mut _`, so skip super_visit_with
-
+                    //
+                    // (But still tell caller to continue search.)
+                    return false;
+                }
+                ty::FnDef(..) | ty::FnPtr(..) => {
+                    // types of formals and return in `fn(_) -> _` are also irrelevant
+                    //
                     // (But still tell caller to continue search.)
                     return false;
                 }

From c529294535fc748f29a9e2182a56e4ef9b4ba000 Mon Sep 17 00:00:00 2001
From: "Felix S. Klock II" <pnkfelix@pnkfx.org>
Date: Fri, 13 Sep 2019 17:08:01 +0200
Subject: [PATCH 722/943] Regression tests for fn ptr and `#[structural_match]`
 as discussed in #63479.

---
 .../fn-ptr-is-structurally-matchable.rs       | 135 ++++++++++++++++++
 .../ui/rfc1445/issue-63479-match-fnptr.rs     |  36 +++++
 2 files changed, 171 insertions(+)
 create mode 100644 src/test/ui/rfc1445/fn-ptr-is-structurally-matchable.rs
 create mode 100644 src/test/ui/rfc1445/issue-63479-match-fnptr.rs

diff --git a/src/test/ui/rfc1445/fn-ptr-is-structurally-matchable.rs b/src/test/ui/rfc1445/fn-ptr-is-structurally-matchable.rs
new file mode 100644
index 0000000000000..5b378fb2a5928
--- /dev/null
+++ b/src/test/ui/rfc1445/fn-ptr-is-structurally-matchable.rs
@@ -0,0 +1,135 @@
+// run-pass
+
+// This file checks that fn ptrs are considered structurally matchable.
+// See also rust-lang/rust#63479.
+
+fn main() {
+    let mut count = 0;
+
+    // A type which is not structurally matchable:
+    struct NotSM;
+
+    // And one that is:
+    #[derive(PartialEq, Eq)]
+    struct SM;
+
+    fn trivial() {}
+
+    fn sm_to(_: SM) {}
+    fn not_sm_to(_: NotSM) {}
+    fn to_sm() -> SM { SM }
+    fn to_not_sm() -> NotSM { NotSM }
+
+    // To recreate the scenario of interest in #63479, we need to add
+    // a ref-level-of-indirection so that we descend into the type.
+
+    fn r_sm_to(_: &SM) {}
+    fn r_not_sm_to(_: &NotSM) {}
+    fn r_to_r_sm(_: &()) -> &SM { &SM }
+    fn r_to_r_not_sm(_: &()) -> &NotSM { &NotSM }
+
+    #[derive(PartialEq, Eq)]
+    struct Wrap<T>(T);
+
+    // In the code below, we put the match input into a local so that
+    // we can assign it an explicit type that is an fn ptr instead of
+    // a singleton type of the fn itself that the type inference would
+    // otherwise assign.
+
+    // Check that fn() is #[structural_match]
+    const CFN1: Wrap<fn()> = Wrap(trivial);
+    let input: Wrap<fn()> = Wrap(trivial);
+    match Wrap(input) {
+        Wrap(CFN1) => count += 1,
+        Wrap(_) => {}
+    };
+
+    // Check that fn(T) is #[structural_match] when T is too.
+    const CFN2: Wrap<fn(SM)> = Wrap(sm_to);
+    let input: Wrap<fn(SM)> = Wrap(sm_to);
+    match Wrap(input) {
+        Wrap(CFN2) => count += 1,
+        Wrap(_) => {}
+    };
+
+    // Check that fn() -> T is #[structural_match] when T is too.
+    const CFN3: Wrap<fn() -> SM> = Wrap(to_sm);
+    let input: Wrap<fn() -> SM> = Wrap(to_sm);
+    match Wrap(input) {
+        Wrap(CFN3) => count += 1,
+        Wrap(_) => {}
+    };
+
+    // Check that fn(T) is #[structural_match] even if T is not.
+    const CFN4: Wrap<fn(NotSM)> = Wrap(not_sm_to);
+    let input: Wrap<fn(NotSM)> = Wrap(not_sm_to);
+    match Wrap(input) {
+        Wrap(CFN4) => count += 1,
+        Wrap(_) => {}
+    };
+
+    // Check that fn() -> T is #[structural_match] even if T is not.
+    const CFN5: Wrap<fn() -> NotSM> = Wrap(to_not_sm);
+    let input: Wrap<fn() -> NotSM> = Wrap(to_not_sm);
+    match Wrap(input) {
+        Wrap(CFN5) => count += 1,
+        Wrap(_) => {}
+    };
+
+    // Check that fn(&T) is #[structural_match] when T is too.
+    const CFN6: Wrap<fn(&SM)> = Wrap(r_sm_to);
+    let input: Wrap<fn(&SM)> = Wrap(r_sm_to);
+    match Wrap(input) {
+        Wrap(CFN6) => count += 1,
+        Wrap(_) => {}
+    };
+
+    // Check that fn() -> &T is #[structural_match] when T is too.
+    const CFN7: Wrap<fn(&()) -> &SM> = Wrap(r_to_r_sm);
+    let input: Wrap<fn(&()) -> &SM> = Wrap(r_to_r_sm);
+    match Wrap(input) {
+        Wrap(CFN7) => count += 1,
+        Wrap(_) => {}
+    };
+
+    // Check that fn(T) is #[structural_match] even if T is not.
+    const CFN8: Wrap<fn(&NotSM)> = Wrap(r_not_sm_to);
+    let input: Wrap<fn(&NotSM)> = Wrap(r_not_sm_to);
+    match Wrap(input) {
+        Wrap(CFN8) => count += 1,
+        Wrap(_) => {}
+    };
+
+    // Check that fn() -> T is #[structural_match] even if T is not.
+    const CFN9: Wrap<fn(&()) -> &NotSM> = Wrap(r_to_r_not_sm);
+    let input: Wrap<fn(&()) -> &NotSM> = Wrap(r_to_r_not_sm);
+    match Wrap(input) {
+        Wrap(CFN9) => count += 1,
+        Wrap(_) => {}
+    };
+
+    // Check that a type which has fn ptrs is `#[structural_match]`.
+    #[derive(PartialEq, Eq)]
+    struct Foo {
+        alpha: fn(NotSM),
+        beta: fn() -> NotSM,
+        gamma: fn(SM),
+        delta: fn() -> SM,
+    }
+
+    const CFOO: Foo = Foo {
+        alpha: not_sm_to,
+        beta: to_not_sm,
+        gamma: sm_to,
+        delta: to_sm,
+    };
+
+    let input = Foo { alpha: not_sm_to, beta: to_not_sm, gamma: sm_to, delta: to_sm };
+    match input {
+        CFOO => count += 1,
+        Foo { .. } => {}
+    };
+
+    // Final count must be 10 now if all
+    assert_eq!(count, 10);
+}
diff --git a/src/test/ui/rfc1445/issue-63479-match-fnptr.rs b/src/test/ui/rfc1445/issue-63479-match-fnptr.rs
new file mode 100644
index 0000000000000..b3c91cec580bf
--- /dev/null
+++ b/src/test/ui/rfc1445/issue-63479-match-fnptr.rs
@@ -0,0 +1,36 @@
+// run-pass
+
+// The actual regression test from #63479. (Including this because my
+// first draft at fn-ptr-is-structurally-matchable.rs failed to actually
+// cover the case this hit; I've since expanded it accordingly, but the
+// experience left me wary of leaving this regression test out.)
+
+#[derive(Eq)]
+struct A {
+  a: i64
+}
+
+impl PartialEq for A {
+    #[inline]
+    fn eq(&self, other: &Self) -> bool {
+        self.a.eq(&other.a)
+    }
+}
+
+type Fn = fn(&[A]);
+
+fn my_fn(_args: &[A]) {
+  println!("hello world");
+}
+
+const TEST: Fn = my_fn;
+
+struct B(Fn);
+
+fn main() {
+  let s = B(my_fn);
+  match s {
+    B(TEST) => println!("matched"),
+    _ => panic!("didn't match")
+  };
+}

From bdad2c52a538206a2f1c154bb5d5c3d7cb6b5d6f Mon Sep 17 00:00:00 2001
From: Eduard-Mihai Burtescu <edy.burt@gmail.com>
Date: Fri, 13 Sep 2019 19:25:05 +0300
Subject: [PATCH 723/943] codegen: use "_N" (like for other locals) instead of
 "argN", for argument names.

---
 src/librustc_codegen_ssa/mir/mod.rs    |  3 ++-
 src/test/codegen/adjustments.rs        |  2 +-
 src/test/codegen/fastcall-inreg.rs     | 12 ++++-----
 src/test/codegen/function-arguments.rs | 28 ++++++++++-----------
 src/test/codegen/refs.rs               |  2 +-
 src/test/codegen/repeat-trusted-len.rs |  2 +-
 src/test/codegen/repr-transparent.rs   | 34 +++++++++++++-------------
 src/test/codegen/scalar-pair-bool.rs   | 12 ++++-----
 src/test/codegen/union-abi.rs          | 16 ++++++------
 9 files changed, 56 insertions(+), 55 deletions(-)

diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index df72980383e29..aa3971a1da81a 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -453,10 +453,11 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     mir.args_iter().enumerate().map(|(arg_index, local)| {
         let arg_decl = &mir.local_decls[local];
 
+        // FIXME(eddyb) don't allocate a `String` unless it gets used.
         let name = if let Some(name) = arg_decl.name {
             name.as_str().to_string()
         } else {
-            format!("arg{}", arg_index)
+            format!("{:?}", local)
         };
 
         if Some(local) == mir.spread_arg {
diff --git a/src/test/codegen/adjustments.rs b/src/test/codegen/adjustments.rs
index ae2ff9994fdf0..ded310d0aebb1 100644
--- a/src/test/codegen/adjustments.rs
+++ b/src/test/codegen/adjustments.rs
@@ -3,7 +3,7 @@
 #![crate_type = "lib"]
 
 // Hack to get the correct size for the length part in slices
-// CHECK: @helper([[USIZE:i[0-9]+]] %arg0)
+// CHECK: @helper([[USIZE:i[0-9]+]] %_1)
 #[no_mangle]
 pub fn helper(_: usize) {
 }
diff --git a/src/test/codegen/fastcall-inreg.rs b/src/test/codegen/fastcall-inreg.rs
index e152e6e9d1333..f67487c83ba23 100644
--- a/src/test/codegen/fastcall-inreg.rs
+++ b/src/test/codegen/fastcall-inreg.rs
@@ -49,27 +49,27 @@
 #![crate_type = "lib"]
 
 pub mod tests {
-    // CHECK: @f1(i32 inreg %arg0, i32 inreg %arg1, i32 %arg2)
+    // CHECK: @f1(i32 inreg %_1, i32 inreg %_2, i32 %_3)
     #[no_mangle]
     pub extern "fastcall" fn f1(_: i32, _: i32, _: i32) {}
 
-    // CHECK: @f2(i32* inreg %arg0, i32* inreg %arg1, i32* %arg2)
+    // CHECK: @f2(i32* inreg %_1, i32* inreg %_2, i32* %_3)
     #[no_mangle]
     pub extern "fastcall" fn f2(_: *const i32, _: *const i32, _: *const i32) {}
 
-    // CHECK: @f3(float %arg0, i32 inreg %arg1, i32 inreg %arg2, i32 %arg3)
+    // CHECK: @f3(float %_1, i32 inreg %_2, i32 inreg %_3, i32 %_4)
     #[no_mangle]
     pub extern "fastcall" fn f3(_: f32, _: i32, _: i32, _: i32) {}
 
-    // CHECK: @f4(i32 inreg %arg0, float %arg1, i32 inreg %arg2, i32 %arg3)
+    // CHECK: @f4(i32 inreg %_1, float %_2, i32 inreg %_3, i32 %_4)
     #[no_mangle]
     pub extern "fastcall" fn f4(_: i32, _: f32, _: i32, _: i32) {}
 
-    // CHECK: @f5(i64 %arg0, i32 %arg1)
+    // CHECK: @f5(i64 %_1, i32 %_2)
     #[no_mangle]
     pub extern "fastcall" fn f5(_: i64, _: i32) {}
 
-    // CHECK: @f6(i1 inreg zeroext %arg0, i32 inreg %arg1, i32 %arg2)
+    // CHECK: @f6(i1 inreg zeroext %_1, i32 inreg %_2, i32 %_3)
     #[no_mangle]
     pub extern "fastcall" fn f6(_: bool, _: i32, _: i32) {}
 }
diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs
index bd121ef24adae..7e1791cd4f296 100644
--- a/src/test/codegen/function-arguments.rs
+++ b/src/test/codegen/function-arguments.rs
@@ -18,48 +18,48 @@ pub fn boolean(x: bool) -> bool {
   x
 }
 
-// CHECK: @readonly_borrow(i32* noalias readonly align 4 dereferenceable(4) %arg0)
+// CHECK: @readonly_borrow(i32* noalias readonly align 4 dereferenceable(4) %_1)
 // FIXME #25759 This should also have `nocapture`
 #[no_mangle]
 pub fn readonly_borrow(_: &i32) {
 }
 
-// CHECK: @static_borrow(i32* noalias readonly align 4 dereferenceable(4) %arg0)
+// CHECK: @static_borrow(i32* noalias readonly align 4 dereferenceable(4) %_1)
 // static borrow may be captured
 #[no_mangle]
 pub fn static_borrow(_: &'static i32) {
 }
 
-// CHECK: @named_borrow(i32* noalias readonly align 4 dereferenceable(4) %arg0)
+// CHECK: @named_borrow(i32* noalias readonly align 4 dereferenceable(4) %_1)
 // borrow with named lifetime may be captured
 #[no_mangle]
 pub fn named_borrow<'r>(_: &'r i32) {
 }
 
-// CHECK: @unsafe_borrow(i16* align 2 dereferenceable(2) %arg0)
+// CHECK: @unsafe_borrow(i16* align 2 dereferenceable(2) %_1)
 // unsafe interior means this isn't actually readonly and there may be aliases ...
 #[no_mangle]
 pub fn unsafe_borrow(_: &UnsafeInner) {
 }
 
-// CHECK: @mutable_unsafe_borrow(i16* align 2 dereferenceable(2) %arg0)
+// CHECK: @mutable_unsafe_borrow(i16* align 2 dereferenceable(2) %_1)
 // ... unless this is a mutable borrow, those never alias
 #[no_mangle]
 pub fn mutable_unsafe_borrow(_: &mut UnsafeInner) {
 }
 
-// CHECK: @mutable_borrow(i32* align 4 dereferenceable(4) %arg0)
+// CHECK: @mutable_borrow(i32* align 4 dereferenceable(4) %_1)
 // FIXME #25759 This should also have `nocapture`
 #[no_mangle]
 pub fn mutable_borrow(_: &mut i32) {
 }
 
-// CHECK: @indirect_struct(%S* noalias nocapture dereferenceable(32) %arg0)
+// CHECK: @indirect_struct(%S* noalias nocapture dereferenceable(32) %_1)
 #[no_mangle]
 pub fn indirect_struct(_: S) {
 }
 
-// CHECK: @borrowed_struct(%S* noalias readonly align 4 dereferenceable(32) %arg0)
+// CHECK: @borrowed_struct(%S* noalias readonly align 4 dereferenceable(32) %_1)
 // FIXME #25759 This should also have `nocapture`
 #[no_mangle]
 pub fn borrowed_struct(_: &S) {
@@ -80,36 +80,36 @@ pub fn struct_return() -> S {
 }
 
 // Hack to get the correct size for the length part in slices
-// CHECK: @helper([[USIZE:i[0-9]+]] %arg0)
+// CHECK: @helper([[USIZE:i[0-9]+]] %_1)
 #[no_mangle]
 pub fn helper(_: usize) {
 }
 
-// CHECK: @slice([0 x i8]* noalias nonnull readonly align 1 %arg0.0, [[USIZE]] %arg0.1)
+// CHECK: @slice([0 x i8]* noalias nonnull readonly align 1 %_1.0, [[USIZE]] %_1.1)
 // FIXME #25759 This should also have `nocapture`
 #[no_mangle]
 pub fn slice(_: &[u8]) {
 }
 
-// CHECK: @mutable_slice([0 x i8]* nonnull align 1 %arg0.0, [[USIZE]] %arg0.1)
+// CHECK: @mutable_slice([0 x i8]* nonnull align 1 %_1.0, [[USIZE]] %_1.1)
 // FIXME #25759 This should also have `nocapture`
 #[no_mangle]
 pub fn mutable_slice(_: &mut [u8]) {
 }
 
-// CHECK: @unsafe_slice([0 x i16]* nonnull align 2 %arg0.0, [[USIZE]] %arg0.1)
+// CHECK: @unsafe_slice([0 x i16]* nonnull align 2 %_1.0, [[USIZE]] %_1.1)
 // unsafe interior means this isn't actually readonly and there may be aliases ...
 #[no_mangle]
 pub fn unsafe_slice(_: &[UnsafeInner]) {
 }
 
-// CHECK: @str([0 x i8]* noalias nonnull readonly align 1 %arg0.0, [[USIZE]] %arg0.1)
+// CHECK: @str([0 x i8]* noalias nonnull readonly align 1 %_1.0, [[USIZE]] %_1.1)
 // FIXME #25759 This should also have `nocapture`
 #[no_mangle]
 pub fn str(_: &[u8]) {
 }
 
-// CHECK: @trait_borrow({}* nonnull align 1 %arg0.0, [3 x [[USIZE]]]* noalias readonly align {{.*}} dereferenceable({{.*}}) %arg0.1)
+// CHECK: @trait_borrow({}* nonnull align 1 %_1.0, [3 x [[USIZE]]]* noalias readonly align {{.*}} dereferenceable({{.*}}) %_1.1)
 // FIXME #25759 This should also have `nocapture`
 #[no_mangle]
 pub fn trait_borrow(_: &Drop) {
diff --git a/src/test/codegen/refs.rs b/src/test/codegen/refs.rs
index cbb9942347673..15f99fd0c22a0 100644
--- a/src/test/codegen/refs.rs
+++ b/src/test/codegen/refs.rs
@@ -3,7 +3,7 @@
 #![crate_type = "lib"]
 
 // Hack to get the correct size for the length part in slices
-// CHECK: @helper([[USIZE:i[0-9]+]] %arg0)
+// CHECK: @helper([[USIZE:i[0-9]+]] %_1)
 #[no_mangle]
 pub fn helper(_: usize) {
 }
diff --git a/src/test/codegen/repeat-trusted-len.rs b/src/test/codegen/repeat-trusted-len.rs
index c348a8f7b8b8f..87f29f6047c6a 100644
--- a/src/test/codegen/repeat-trusted-len.rs
+++ b/src/test/codegen/repeat-trusted-len.rs
@@ -6,7 +6,7 @@
 
 use std::iter;
 
-// CHECK: @helper([[USIZE:i[0-9]+]] %arg0)
+// CHECK: @helper([[USIZE:i[0-9]+]] %_1)
 #[no_mangle]
 pub fn helper(_: usize) {
 }
diff --git a/src/test/codegen/repr-transparent.rs b/src/test/codegen/repr-transparent.rs
index c9f3837565808..e705d5ce3cd72 100644
--- a/src/test/codegen/repr-transparent.rs
+++ b/src/test/codegen/repr-transparent.rs
@@ -14,21 +14,21 @@ pub struct Zst2(());
 #[repr(transparent)]
 pub struct F32(f32);
 
-// CHECK: define float @test_F32(float %arg0)
+// CHECK: define float @test_F32(float %_1)
 #[no_mangle]
 pub extern fn test_F32(_: F32) -> F32 { loop {} }
 
 #[repr(transparent)]
 pub struct Ptr(*mut u8);
 
-// CHECK: define i8* @test_Ptr(i8* %arg0)
+// CHECK: define i8* @test_Ptr(i8* %_1)
 #[no_mangle]
 pub extern fn test_Ptr(_: Ptr) -> Ptr { loop {} }
 
 #[repr(transparent)]
 pub struct WithZst(u64, Zst1);
 
-// CHECK: define i64 @test_WithZst(i64 %arg0)
+// CHECK: define i64 @test_WithZst(i64 %_1)
 #[no_mangle]
 pub extern fn test_WithZst(_: WithZst) -> WithZst { loop {} }
 
@@ -36,14 +36,14 @@ pub extern fn test_WithZst(_: WithZst) -> WithZst { loop {} }
 pub struct WithZeroSizedArray(*const f32, [i8; 0]);
 
 // Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever.
-// CHECK: define i32* @test_WithZeroSizedArray(i32* %arg0)
+// CHECK: define i32* @test_WithZeroSizedArray(i32* %_1)
 #[no_mangle]
 pub extern fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} }
 
 #[repr(transparent)]
 pub struct Generic<T>(T);
 
-// CHECK: define double @test_Generic(double %arg0)
+// CHECK: define double @test_Generic(double %_1)
 #[no_mangle]
 pub extern fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} }
 
@@ -53,14 +53,14 @@ pub struct GenericPlusZst<T>(T, Zst2);
 #[repr(u8)]
 pub enum Bool { True, False, FileNotFound }
 
-// CHECK: define{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %arg0)
+// CHECK: define{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %_1)
 #[no_mangle]
 pub extern fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { loop {} }
 
 #[repr(transparent)]
 pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>);
 
-// CHECK: define i16* @test_LifetimePhantom(i16* %arg0)
+// CHECK: define i16* @test_LifetimePhantom(i16* %_1)
 #[no_mangle]
 pub extern fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} }
 
@@ -70,28 +70,28 @@ pub struct UnitPhantom<T, U> { val: T, unit: PhantomData<U> }
 
 pub struct Px;
 
-// CHECK: define float @test_UnitPhantom(float %arg0)
+// CHECK: define float @test_UnitPhantom(float %_1)
 #[no_mangle]
 pub extern fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} }
 
 #[repr(transparent)]
 pub struct TwoZsts(Zst1, i8, Zst2);
 
-// CHECK: define{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %arg0)
+// CHECK: define{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %_1)
 #[no_mangle]
 pub extern fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} }
 
 #[repr(transparent)]
 pub struct Nested1(Zst2, Generic<f64>);
 
-// CHECK: define double @test_Nested1(double %arg0)
+// CHECK: define double @test_Nested1(double %_1)
 #[no_mangle]
 pub extern fn test_Nested1(_: Nested1) -> Nested1 { loop {} }
 
 #[repr(transparent)]
 pub struct Nested2(Nested1, Zst1);
 
-// CHECK: define double @test_Nested2(double %arg0)
+// CHECK: define double @test_Nested2(double %_1)
 #[no_mangle]
 pub extern fn test_Nested2(_: Nested2) -> Nested2 { loop {} }
 
@@ -101,7 +101,7 @@ struct f32x4(f32, f32, f32, f32);
 #[repr(transparent)]
 pub struct Vector(f32x4);
 
-// CHECK: define <4 x float> @test_Vector(<4 x float> %arg0)
+// CHECK: define <4 x float> @test_Vector(<4 x float> %_1)
 #[no_mangle]
 pub extern fn test_Vector(_: Vector) -> Vector { loop {} }
 
@@ -111,7 +111,7 @@ impl<T: ?Sized> Mirror for T { type It = Self; }
 #[repr(transparent)]
 pub struct StructWithProjection(<f32 as Mirror>::It);
 
-// CHECK: define float @test_Projection(float %arg0)
+// CHECK: define float @test_Projection(float %_1)
 #[no_mangle]
 pub extern fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
 
@@ -120,7 +120,7 @@ pub enum EnumF32 {
     Variant(F32)
 }
 
-// CHECK: define float @test_EnumF32(float %arg0)
+// CHECK: define float @test_EnumF32(float %_1)
 #[no_mangle]
 pub extern fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} }
 
@@ -129,7 +129,7 @@ pub enum EnumF32WithZsts {
     Variant(Zst1, F32, Zst2)
 }
 
-// CHECK: define float @test_EnumF32WithZsts(float %arg0)
+// CHECK: define float @test_EnumF32WithZsts(float %_1)
 #[no_mangle]
 pub extern fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} }
 
@@ -138,7 +138,7 @@ pub union UnionF32 {
     field: F32,
 }
 
-// CHECK: define float @test_UnionF32(float %arg0)
+// CHECK: define float @test_UnionF32(float %_1)
 #[no_mangle]
 pub extern fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} }
 
@@ -149,7 +149,7 @@ pub union UnionF32WithZsts {
     zst2: Zst2,
 }
 
-// CHECK: define float @test_UnionF32WithZsts(float %arg0)
+// CHECK: define float @test_UnionF32WithZsts(float %_1)
 #[no_mangle]
 pub extern fn test_UnionF32WithZsts(_: UnionF32WithZsts) -> UnionF32WithZsts { loop {} }
 
diff --git a/src/test/codegen/scalar-pair-bool.rs b/src/test/codegen/scalar-pair-bool.rs
index 78d1025b13c77..d91ee7f816ded 100644
--- a/src/test/codegen/scalar-pair-bool.rs
+++ b/src/test/codegen/scalar-pair-bool.rs
@@ -20,24 +20,24 @@ pub fn pair_i32_bool(pair: (i32, bool)) -> (i32, bool) {
     pair
 }
 
-// CHECK: define { i8, i8 } @pair_and_or(i1 zeroext %arg0.0, i1 zeroext %arg0.1)
+// CHECK: define { i8, i8 } @pair_and_or(i1 zeroext %_1.0, i1 zeroext %_1.1)
 #[no_mangle]
 pub fn pair_and_or((a, b): (bool, bool)) -> (bool, bool) {
     // Make sure it can operate directly on the unpacked args
-    // CHECK: and i1 %arg0.0, %arg0.1
-    // CHECK: or i1 %arg0.0, %arg0.1
+    // CHECK: and i1 %_1.0, %_1.1
+    // CHECK: or i1 %_1.0, %_1.1
     (a && b, a || b)
 }
 
-// CHECK: define void @pair_branches(i1 zeroext %arg0.0, i1 zeroext %arg0.1)
+// CHECK: define void @pair_branches(i1 zeroext %_1.0, i1 zeroext %_1.1)
 #[no_mangle]
 pub fn pair_branches((a, b): (bool, bool)) {
     // Make sure it can branch directly on the unpacked bool args
-    // CHECK: br i1 %arg0.0
+    // CHECK: br i1 %_1.0
     if a {
         println!("Hello!");
     }
-    // CHECK: br i1 %arg0.1
+    // CHECK: br i1 %_1.1
     if b {
         println!("Goodbye!");
     }
diff --git a/src/test/codegen/union-abi.rs b/src/test/codegen/union-abi.rs
index b7baffe16695a..7339df17b057a 100644
--- a/src/test/codegen/union-abi.rs
+++ b/src/test/codegen/union-abi.rs
@@ -16,38 +16,38 @@ pub struct i64x4(i64, i64, i64, i64);
 #[derive(Copy, Clone)]
 pub union UnionI64x4{ a:(), b: i64x4 }
 
-// CHECK: define void @test_UnionI64x4(<4 x i64>* {{.*}} %arg0)
+// CHECK: define void @test_UnionI64x4(<4 x i64>* {{.*}} %_1)
 #[no_mangle]
 pub fn test_UnionI64x4(_: UnionI64x4) { loop {} }
 
 pub union UnionI64x4_{ a: i64x4, b: (), c:i64x4, d: Unhab, e: ((),()), f: UnionI64x4 }
 
-// CHECK: define void @test_UnionI64x4_(<4 x i64>* {{.*}} %arg0)
+// CHECK: define void @test_UnionI64x4_(<4 x i64>* {{.*}} %_1)
 #[no_mangle]
 pub fn test_UnionI64x4_(_: UnionI64x4_) { loop {} }
 
 pub union UnionI64x4I64{ a: i64x4, b: i64 }
 
-// CHECK: define void @test_UnionI64x4I64(%UnionI64x4I64* {{.*}} %arg0)
+// CHECK: define void @test_UnionI64x4I64(%UnionI64x4I64* {{.*}} %_1)
 #[no_mangle]
 pub fn test_UnionI64x4I64(_: UnionI64x4I64) { loop {} }
 
 pub union UnionI64x4Tuple{ a: i64x4, b: (i64, i64, i64, i64) }
 
-// CHECK: define void @test_UnionI64x4Tuple(%UnionI64x4Tuple* {{.*}} %arg0)
+// CHECK: define void @test_UnionI64x4Tuple(%UnionI64x4Tuple* {{.*}} %_1)
 #[no_mangle]
 pub fn test_UnionI64x4Tuple(_: UnionI64x4Tuple) { loop {} }
 
 
 pub union UnionF32{a:f32}
 
-// CHECK: define float @test_UnionF32(float %arg0)
+// CHECK: define float @test_UnionF32(float %_1)
 #[no_mangle]
 pub fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} }
 
 pub union UnionF32F32{a:f32, b:f32}
 
-// CHECK: define float @test_UnionF32F32(float %arg0)
+// CHECK: define float @test_UnionF32F32(float %_1)
 #[no_mangle]
 pub fn test_UnionF32F32(_: UnionF32F32) -> UnionF32F32 { loop {} }
 
@@ -58,13 +58,13 @@ pub union UnionF32U32{a:f32, b:u32}
 pub fn test_UnionF32U32(_: UnionF32U32) -> UnionF32U32 { loop {} }
 
 pub union UnionU128{a:u128}
-// CHECK: define i128 @test_UnionU128(i128 %arg0)
+// CHECK: define i128 @test_UnionU128(i128 %_1)
 #[no_mangle]
 pub fn test_UnionU128(_: UnionU128) -> UnionU128 { loop {} }
 
 #[repr(C)]
 pub union CUnionU128{a:u128}
-// CHECK: define void @test_CUnionU128(%CUnionU128* {{.*}} %arg0)
+// CHECK: define void @test_CUnionU128(%CUnionU128* {{.*}} %_1)
 #[no_mangle]
 pub fn test_CUnionU128(_: CUnionU128) { loop {} }
 

From 57e82878c0c18d920b5fb0df11bff6aa2e2abca5 Mon Sep 17 00:00:00 2001
From: 12101111 <w12101111@gmail.com>
Date: Sat, 14 Sep 2019 02:40:20 +0800
Subject: [PATCH 724/943] fix #64430

---
 src/librustc/ty/context.rs        |  6 ++---
 src/librustc_typeck/check/expr.rs | 41 ++++++++++++++-----------------
 2 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 8e8472a5aacc9..25d921b7cea4c 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2396,9 +2396,9 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     #[inline]
-    pub fn mk_lang_item(self, ty: Ty<'tcx>, item: lang_items::LangItem)  -> Ty<'tcx> {
-        let def_id = self.require_lang_item(item, None);
-        self.mk_generic_adt(def_id, ty)
+    pub fn mk_lang_item(self, ty: Ty<'tcx>, item: lang_items::LangItem)  -> Option<Ty<'tcx>> {
+        let def_id = self.lang_items().require(item).ok()?;
+        Some(self.mk_generic_adt(def_id, ty))
     }
 
     #[inline]
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index da72dfd155182..56bd903040ab4 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -813,18 +813,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         error: MethodError<'tcx>
     ) {
         let rcvr = &args[0];
-        let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| {
-            if let Ok(pick) = self.lookup_probe(
-                span,
-                segment.ident,
-                new_rcvr_t,
-                rcvr,
-                probe::ProbeScope::AllTraits,
-            ) {
-                err.span_label(
-                    pick.item.ident.span,
-                    &format!("the method is available for `{}` here", new_rcvr_t),
-                );
+        let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, rcvr_t, lang_item| {
+            if let Some(new_rcvr_t) = self.tcx.mk_lang_item(rcvr_t, lang_item) {
+                if let Ok(pick) = self.lookup_probe(
+                    span,
+                    segment.ident,
+                    new_rcvr_t,
+                    rcvr,
+                    probe::ProbeScope::AllTraits,
+                ) {
+                    err.span_label(
+                        pick.item.ident.span,
+                        &format!("the method is available for `{}` here", new_rcvr_t),
+                    );
+                }
             }
         };
 
@@ -840,17 +842,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Try alternative arbitrary self types that could fulfill this call.
                 // FIXME: probe for all types that *could* be arbitrary self-types, not
                 // just this whitelist.
-                let box_rcvr_t = self.tcx.mk_box(rcvr_t);
-                try_alt_rcvr(&mut err, box_rcvr_t);
-                let pin_rcvr_t = self.tcx.mk_lang_item(
-                    rcvr_t,
-                    lang_items::PinTypeLangItem,
-                );
-                try_alt_rcvr(&mut err, pin_rcvr_t);
-                let arc_rcvr_t = self.tcx.mk_lang_item(rcvr_t, lang_items::Arc);
-                try_alt_rcvr(&mut err, arc_rcvr_t);
-                let rc_rcvr_t = self.tcx.mk_lang_item(rcvr_t, lang_items::Rc);
-                try_alt_rcvr(&mut err, rc_rcvr_t);
+                try_alt_rcvr(&mut err, rcvr_t, lang_items::OwnedBoxLangItem);
+                try_alt_rcvr(&mut err, rcvr_t, lang_items::PinTypeLangItem);
+                try_alt_rcvr(&mut err, rcvr_t, lang_items::Arc);
+                try_alt_rcvr(&mut err, rcvr_t, lang_items::Rc);
             }
             err.emit();
         }

From b98a844cf300779d7c103ccf7812e312f021c86f Mon Sep 17 00:00:00 2001
From: 12101111 <w12101111@gmail.com>
Date: Sat, 14 Sep 2019 03:13:51 +0800
Subject: [PATCH 725/943] add ui test for #64430

---
 src/test/ui/issues/issue-64430.rs     | 14 ++++++++++++++
 src/test/ui/issues/issue-64430.stderr | 12 ++++++++++++
 2 files changed, 26 insertions(+)
 create mode 100644 src/test/ui/issues/issue-64430.rs
 create mode 100644 src/test/ui/issues/issue-64430.stderr

diff --git a/src/test/ui/issues/issue-64430.rs b/src/test/ui/issues/issue-64430.rs
new file mode 100644
index 0000000000000..8e58d0dda0e1b
--- /dev/null
+++ b/src/test/ui/issues/issue-64430.rs
@@ -0,0 +1,14 @@
+// compile-flags:-C panic=abort
+
+#![no_std]
+pub struct Foo;
+
+fn main() {
+    Foo.bar()
+    //~^ ERROR E0599
+}
+
+#[panic_handler]
+fn panic(_info: &core::panic::PanicInfo) -> ! {
+    loop{}
+}
\ No newline at end of file
diff --git a/src/test/ui/issues/issue-64430.stderr b/src/test/ui/issues/issue-64430.stderr
new file mode 100644
index 0000000000000..f1b2de8d8b36f
--- /dev/null
+++ b/src/test/ui/issues/issue-64430.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no method named `bar` found for type `Foo` in the current scope
+  --> $DIR/issue-64430.rs:7:9
+   |
+LL | pub struct Foo;
+   | --------------- method `bar` not found for this
+...
+LL |     Foo.bar()
+   |         ^^^ method not found in `Foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.

From e484f213eebd2a61870eb25a6cee0992eab6275c Mon Sep 17 00:00:00 2001
From: 12101111 <w12101111@gmail.com>
Date: Sat, 14 Sep 2019 03:23:58 +0800
Subject: [PATCH 726/943] add trailing newline

---
 src/test/ui/issues/issue-64430.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/ui/issues/issue-64430.rs b/src/test/ui/issues/issue-64430.rs
index 8e58d0dda0e1b..0bc66e06e6731 100644
--- a/src/test/ui/issues/issue-64430.rs
+++ b/src/test/ui/issues/issue-64430.rs
@@ -11,4 +11,4 @@ fn main() {
 #[panic_handler]
 fn panic(_info: &core::panic::PanicInfo) -> ! {
     loop{}
-}
\ No newline at end of file
+}

From 094af9743bd8a2b7cc2ae3b81b8110de9a93ea95 Mon Sep 17 00:00:00 2001
From: Hal Gentz <zegentzy@protonmail.com>
Date: Fri, 13 Sep 2019 20:37:38 -0600
Subject: [PATCH 727/943] Update value.rs

---
 src/librustc/mir/interpret/value.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 811c872968a56..11e7db5804c6a 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -17,8 +17,8 @@ pub struct RawConst<'tcx> {
     pub ty: Ty<'tcx>,
 }
 
-/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations that
-/// match the `LocalState` optimizations for easy conversions between `Operand` and `ConstValue`.
+/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for
+/// array length computations, enum discriminants and the pattern matching logic.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord,
          RustcEncodable, RustcDecodable, Hash, HashStable)]
 pub enum ConstValue<'tcx> {

From 88e755607b0bd65c223fcac40756cb703449c09f Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Fri, 13 Sep 2019 20:59:46 -0700
Subject: [PATCH 728/943] Fix build script sanitizer check.

---
 src/librustc_asan/build.rs | 1 +
 src/librustc_lsan/build.rs | 1 +
 src/librustc_msan/build.rs | 1 +
 src/librustc_tsan/build.rs | 1 +
 4 files changed, 4 insertions(+)

diff --git a/src/librustc_asan/build.rs b/src/librustc_asan/build.rs
index cc856ba68fbb7..645707ccc0338 100644
--- a/src/librustc_asan/build.rs
+++ b/src/librustc_asan/build.rs
@@ -4,6 +4,7 @@ use build_helper::sanitizer_lib_boilerplate;
 use cmake::Config;
 
 fn main() {
+    println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS");
     if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
         return;
     }
diff --git a/src/librustc_lsan/build.rs b/src/librustc_lsan/build.rs
index d5f3e37dea51c..73720d8c2d64e 100644
--- a/src/librustc_lsan/build.rs
+++ b/src/librustc_lsan/build.rs
@@ -4,6 +4,7 @@ use build_helper::sanitizer_lib_boilerplate;
 use cmake::Config;
 
 fn main() {
+    println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS");
     if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
         return;
     }
diff --git a/src/librustc_msan/build.rs b/src/librustc_msan/build.rs
index de1676f489a46..a81786ee36d04 100644
--- a/src/librustc_msan/build.rs
+++ b/src/librustc_msan/build.rs
@@ -4,6 +4,7 @@ use build_helper::sanitizer_lib_boilerplate;
 use cmake::Config;
 
 fn main() {
+    println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS");
     if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
         return;
     }
diff --git a/src/librustc_tsan/build.rs b/src/librustc_tsan/build.rs
index 6df9691257455..f9333e1502327 100644
--- a/src/librustc_tsan/build.rs
+++ b/src/librustc_tsan/build.rs
@@ -4,6 +4,7 @@ use build_helper::sanitizer_lib_boilerplate;
 use cmake::Config;
 
 fn main() {
+    println!("cargo:rerun-if-env-changed=RUSTC_BUILD_SANITIZERS");
     if env::var("RUSTC_BUILD_SANITIZERS") != Ok("1".to_string()) {
         return;
     }

From b60954757eb1acd4069ddbc28a51f4a5bb7d42c9 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 14 Sep 2019 10:23:10 +0200
Subject: [PATCH 729/943] std: always depend on backtrace, but only enable its
 features on demand

---
 src/bootstrap/lib.rs               |  2 +-
 src/libstd/Cargo.toml              | 18 +++++++++---------
 src/libstd/build.rs                |  2 +-
 src/libstd/panicking.rs            |  6 +++---
 src/libstd/rt.rs                   |  4 ++--
 src/libstd/sys_common/backtrace.rs |  5 ++++-
 src/libstd/sys_common/mod.rs       |  1 -
 src/libstd/thread/mod.rs           |  4 ++--
 src/libtest/Cargo.toml             |  2 +-
 9 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 5d7581c8211be..e4f1b773a690d 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -490,7 +490,7 @@ impl Build {
             features.push_str(" llvm-libunwind");
         }
         if self.config.backtrace {
-            features.push_str(" backtrace");
+            features.push_str(" backtrace_support");
         }
         if self.config.profiler {
             features.push_str(" profiler");
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 20442abc58890..2da73c11907de 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -27,15 +27,8 @@ hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] }
 
 [dependencies.backtrace]
 version = "0.3.37"
-default-features = false # don't use coresymbolication on OSX
-features = [
-  "rustc-dep-of-std", # enable build support for integrating into libstd
-  "dbghelp",          # backtrace/symbolize on MSVC
-  "libbacktrace",     # symbolize on most platforms
-  "libunwind",        # backtrace on most platforms
-  "dladdr",           # symbolize on platforms w/o libbacktrace
-]
-optional = true
+default-features = false # without the libstd `backtrace` feature, stub out everything
+features = [ "rustc-dep-of-std" ] # enable build support for integrating into libstd
 
 [dev-dependencies]
 rand = "0.7"
@@ -65,6 +58,13 @@ cc = "1.0"
 [features]
 default = ["std_detect_file_io", "std_detect_dlsym_getauxval"]
 
+backtrace_support = [
+  "backtrace/dbghelp",          # backtrace/symbolize on MSVC
+  "backtrace/libbacktrace",     # symbolize on most platforms
+  "backtrace/libunwind",        # backtrace on most platforms
+  "backtrace/dladdr",           # symbolize on platforms w/o libbacktrace
+]
+
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
 compiler-builtins-c = ["alloc/compiler-builtins-c"]
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index 8db7bc12cd308..3209332eeb622 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -49,7 +49,7 @@ fn main() {
         println!("cargo:rustc-link-lib=zircon");
         println!("cargo:rustc-link-lib=fdio");
     } else if target.contains("cloudabi") {
-        if cfg!(feature = "backtrace") {
+        if cfg!(feature = "backtrace_support") {
             println!("cargo:rustc-link-lib=unwind");
         }
         println!("cargo:rustc-link-lib=c");
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index db4089c294812..93a17d6eea54e 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -157,12 +157,12 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> {
 }
 
 fn default_hook(info: &PanicInfo<'_>) {
-    #[cfg(feature = "backtrace")]
+    #[cfg(feature = "backtrace_support")]
     use crate::sys_common::{backtrace as backtrace_mod};
 
     // If this is a double panic, make sure that we print a backtrace
     // for this panic. Otherwise only print it if logging is enabled.
-    #[cfg(feature = "backtrace")]
+    #[cfg(feature = "backtrace_support")]
     let log_backtrace = {
         let panics = update_panic_count(0);
 
@@ -190,7 +190,7 @@ fn default_hook(info: &PanicInfo<'_>) {
         let _ = writeln!(err, "thread '{}' panicked at '{}', {}",
                          name, msg, location);
 
-        #[cfg(feature = "backtrace")]
+        #[cfg(feature = "backtrace_support")]
         {
             use crate::sync::atomic::{AtomicBool, Ordering};
 
diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs
index cf45eb0daba39..f73bd6c6e74fa 100644
--- a/src/libstd/rt.rs
+++ b/src/libstd/rt.rs
@@ -44,11 +44,11 @@ fn lang_start_internal(main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindS
         sys::args::init(argc, argv);
 
         // Let's run some code!
-        #[cfg(feature = "backtrace")]
+        #[cfg(feature = "backtrace_support")]
         let exit_code = panic::catch_unwind(|| {
             sys_common::backtrace::__rust_begin_short_backtrace(move || main())
         });
-        #[cfg(not(feature = "backtrace"))]
+        #[cfg(not(feature = "backtrace_support"))]
         let exit_code = panic::catch_unwind(move || main());
 
         sys_common::cleanup();
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 1a78abf508620..52890668c35ee 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -7,7 +7,6 @@ use crate::io;
 use crate::borrow::Cow;
 use crate::io::prelude::*;
 use crate::path::{self, Path, PathBuf};
-use crate::sync::atomic::{self, Ordering};
 use crate::sys::mutex::Mutex;
 
 use backtrace::{BacktraceFmt, BytesOrWideString, PrintFmt};
@@ -34,6 +33,7 @@ pub fn lock() -> impl Drop {
 }
 
 /// Prints the current backtrace.
+#[cfg(feature = "backtrace_support")]
 pub fn print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
     // There are issues currently linking libbacktrace into tests, and in
     // general during libstd's own unit tests we're not testing this path. In
@@ -129,7 +129,10 @@ where
 
 // For now logging is turned off by default, and this function checks to see
 // whether the magical environment variable is present to see if it's turned on.
+#[cfg(feature = "backtrace_support")]
 pub fn log_enabled() -> Option<PrintFmt> {
+    use crate::sync::atomic::{self, Ordering};
+
     // Setting environment variables for Fuchsia components isn't a standard
     // or easily supported workflow. For now, always display backtraces.
     if cfg!(target_os = "fuchsia") {
diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs
index 9190a3b0d5fc7..cba3eca538625 100644
--- a/src/libstd/sys_common/mod.rs
+++ b/src/libstd/sys_common/mod.rs
@@ -41,7 +41,6 @@ macro_rules! rtunwrap {
 
 pub mod alloc;
 pub mod at_exit_imp;
-#[cfg(feature = "backtrace")]
 pub mod backtrace;
 pub mod condvar;
 pub mod io;
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 764041d2f4239..85fd80e16afb3 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -465,11 +465,11 @@ impl Builder {
             }
 
             thread_info::set(imp::guard::current(), their_thread);
-            #[cfg(feature = "backtrace")]
+            #[cfg(feature = "backtrace_support")]
             let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
                 crate::sys_common::backtrace::__rust_begin_short_backtrace(f)
             }));
-            #[cfg(not(feature = "backtrace"))]
+            #[cfg(not(feature = "backtrace_support"))]
             let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
             *their_packet.get() = Some(try_result);
         };
diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml
index 170fbb984cf9b..f0041bcf67cb0 100644
--- a/src/libtest/Cargo.toml
+++ b/src/libtest/Cargo.toml
@@ -23,7 +23,7 @@ proc_macro = { path = "../libproc_macro" }
 
 # Forward features to the `std` crate as necessary
 [features]
-backtrace = ["std/backtrace"]
+backtrace_support = ["std/backtrace_support"]
 compiler-builtins-c = ["std/compiler-builtins-c"]
 llvm-libunwind = ["std/llvm-libunwind"]
 panic-unwind = ["std/panic_unwind"]

From 166719ad9fe3137ef4fe18cbf9fed1c050f8855a Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403@users.noreply.github.com>
Date: Sat, 31 Aug 2019 08:50:02 +0200
Subject: [PATCH 730/943] Update installed compiler dependencies

there is a soft-error for older toolchains
from https://reviews.llvm.org/D57264 in preparation for the
hard error in https://reviews.llvm.org/D66188
---
 README.md | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 724bc36ecc6fb..2df9e6a37379d 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ or reading the [rustc guide][rustcguidebuild].
 ### Building on *nix
 1. Make sure you have installed the dependencies:
 
-   * `g++` 4.7 or later or `clang++` 3.x or later
+   * `g++` 5.1 or later or `clang++` 3.5 or later
    * `python` 2.7 (but not 3.x)
    * GNU `make` 3.81 or later
    * `cmake` 3.4.3 or later
@@ -148,6 +148,17 @@ by manually calling the appropriate vcvars file before running the bootstrap.
 > python x.py build
 ```
 
+### Building rustc with older host toolchains
+It is still possible to build Rust with the older toolchain versions listed below, but only if the
+LLVM_TEMPORARILY_ALLOW_OLD_TOOLCHAIN option is set to true in the config.toml file.
+
+* Clang 3.1
+* Apple Clang 3.1
+* GCC 4.8
+* Visual Studio 2015 (Update 3)
+
+Toolchain versions older than what is listed above cannot be used to build rustc.
+
 #### Specifying an ABI
 
 Each specific ABI can also be used from either environment (for example, using

From dac0a158eb78419e3593fa888f9cf1ab81153030 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 14 Sep 2019 12:12:32 +0200
Subject: [PATCH 731/943] rename the crate, not the feature

---
 src/bootstrap/lib.rs               |  2 +-
 src/libstd/Cargo.toml              | 13 +++++++------
 src/libstd/backtrace.rs            |  1 +
 src/libstd/build.rs                |  2 +-
 src/libstd/panicking.rs            |  8 ++++----
 src/libstd/rt.rs                   |  4 ++--
 src/libstd/sys_common/backtrace.rs | 10 +++++-----
 src/libstd/thread/mod.rs           |  4 ++--
 src/libtest/Cargo.toml             |  2 +-
 9 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index e4f1b773a690d..5d7581c8211be 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -490,7 +490,7 @@ impl Build {
             features.push_str(" llvm-libunwind");
         }
         if self.config.backtrace {
-            features.push_str(" backtrace_support");
+            features.push_str(" backtrace");
         }
         if self.config.profiler {
             features.push_str(" profiler");
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 2da73c11907de..af1d2402f88e7 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -25,7 +25,8 @@ profiler_builtins = { path = "../libprofiler_builtins", optional = true }
 unwind = { path = "../libunwind" }
 hashbrown = { version = "0.5.0", features = ['rustc-dep-of-std'] }
 
-[dependencies.backtrace]
+[dependencies.backtrace_rs]
+package = "backtrace"
 version = "0.3.37"
 default-features = false # without the libstd `backtrace` feature, stub out everything
 features = [ "rustc-dep-of-std" ] # enable build support for integrating into libstd
@@ -58,11 +59,11 @@ cc = "1.0"
 [features]
 default = ["std_detect_file_io", "std_detect_dlsym_getauxval"]
 
-backtrace_support = [
-  "backtrace/dbghelp",          # backtrace/symbolize on MSVC
-  "backtrace/libbacktrace",     # symbolize on most platforms
-  "backtrace/libunwind",        # backtrace on most platforms
-  "backtrace/dladdr",           # symbolize on platforms w/o libbacktrace
+backtrace = [
+  "backtrace_rs/dbghelp",          # backtrace/symbolize on MSVC
+  "backtrace_rs/libbacktrace",     # symbolize on most platforms
+  "backtrace_rs/libunwind",        # backtrace on most platforms
+  "backtrace_rs/dladdr",           # symbolize on platforms w/o libbacktrace
 ]
 
 panic-unwind = ["panic_unwind"]
diff --git a/src/libstd/backtrace.rs b/src/libstd/backtrace.rs
index 5d46ef7dbb10a..61c42a56071e6 100644
--- a/src/libstd/backtrace.rs
+++ b/src/libstd/backtrace.rs
@@ -97,6 +97,7 @@ use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
 use crate::sync::Mutex;
 use crate::sys_common::backtrace::{output_filename, lock};
 use crate::vec::Vec;
+use backtrace_rs as backtrace;
 use backtrace::BytesOrWideString;
 
 /// A captured OS thread stack backtrace.
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index 3209332eeb622..8db7bc12cd308 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -49,7 +49,7 @@ fn main() {
         println!("cargo:rustc-link-lib=zircon");
         println!("cargo:rustc-link-lib=fdio");
     } else if target.contains("cloudabi") {
-        if cfg!(feature = "backtrace_support") {
+        if cfg!(feature = "backtrace") {
             println!("cargo:rustc-link-lib=unwind");
         }
         println!("cargo:rustc-link-lib=c");
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 93a17d6eea54e..e7755af7f07da 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -157,17 +157,17 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> {
 }
 
 fn default_hook(info: &PanicInfo<'_>) {
-    #[cfg(feature = "backtrace_support")]
+    #[cfg(feature = "backtrace")]
     use crate::sys_common::{backtrace as backtrace_mod};
 
     // If this is a double panic, make sure that we print a backtrace
     // for this panic. Otherwise only print it if logging is enabled.
-    #[cfg(feature = "backtrace_support")]
+    #[cfg(feature = "backtrace")]
     let log_backtrace = {
         let panics = update_panic_count(0);
 
         if panics >= 2 {
-            Some(backtrace::PrintFmt::Full)
+            Some(backtrace_rs::PrintFmt::Full)
         } else {
             backtrace_mod::log_enabled()
         }
@@ -190,7 +190,7 @@ fn default_hook(info: &PanicInfo<'_>) {
         let _ = writeln!(err, "thread '{}' panicked at '{}', {}",
                          name, msg, location);
 
-        #[cfg(feature = "backtrace_support")]
+        #[cfg(feature = "backtrace")]
         {
             use crate::sync::atomic::{AtomicBool, Ordering};
 
diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs
index f73bd6c6e74fa..cf45eb0daba39 100644
--- a/src/libstd/rt.rs
+++ b/src/libstd/rt.rs
@@ -44,11 +44,11 @@ fn lang_start_internal(main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindS
         sys::args::init(argc, argv);
 
         // Let's run some code!
-        #[cfg(feature = "backtrace_support")]
+        #[cfg(feature = "backtrace")]
         let exit_code = panic::catch_unwind(|| {
             sys_common::backtrace::__rust_begin_short_backtrace(move || main())
         });
-        #[cfg(not(feature = "backtrace_support"))]
+        #[cfg(not(feature = "backtrace"))]
         let exit_code = panic::catch_unwind(move || main());
 
         sys_common::cleanup();
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 52890668c35ee..f49adc01659ff 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -9,7 +9,7 @@ use crate::io::prelude::*;
 use crate::path::{self, Path, PathBuf};
 use crate::sys::mutex::Mutex;
 
-use backtrace::{BacktraceFmt, BytesOrWideString, PrintFmt};
+use backtrace_rs::{BacktraceFmt, BytesOrWideString, PrintFmt};
 
 /// Max number of frames to print.
 const MAX_NB_FRAMES: usize = 100;
@@ -33,7 +33,7 @@ pub fn lock() -> impl Drop {
 }
 
 /// Prints the current backtrace.
-#[cfg(feature = "backtrace_support")]
+#[cfg(feature = "backtrace")]
 pub fn print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
     // There are issues currently linking libbacktrace into tests, and in
     // general during libstd's own unit tests we're not testing this path. In
@@ -74,14 +74,14 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
     bt_fmt.add_context()?;
     let mut idx = 0;
     let mut res = Ok(());
-    backtrace::trace_unsynchronized(|frame| {
+    backtrace_rs::trace_unsynchronized(|frame| {
         if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {
             return false;
         }
 
         let mut hit = false;
         let mut stop = false;
-        backtrace::resolve_frame_unsynchronized(frame, |symbol| {
+        backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
             hit = true;
             if print_fmt == PrintFmt::Short {
                 if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
@@ -129,7 +129,7 @@ where
 
 // For now logging is turned off by default, and this function checks to see
 // whether the magical environment variable is present to see if it's turned on.
-#[cfg(feature = "backtrace_support")]
+#[cfg(feature = "backtrace")]
 pub fn log_enabled() -> Option<PrintFmt> {
     use crate::sync::atomic::{self, Ordering};
 
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 85fd80e16afb3..764041d2f4239 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -465,11 +465,11 @@ impl Builder {
             }
 
             thread_info::set(imp::guard::current(), their_thread);
-            #[cfg(feature = "backtrace_support")]
+            #[cfg(feature = "backtrace")]
             let try_result = panic::catch_unwind(panic::AssertUnwindSafe(|| {
                 crate::sys_common::backtrace::__rust_begin_short_backtrace(f)
             }));
-            #[cfg(not(feature = "backtrace_support"))]
+            #[cfg(not(feature = "backtrace"))]
             let try_result = panic::catch_unwind(panic::AssertUnwindSafe(f));
             *their_packet.get() = Some(try_result);
         };
diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml
index f0041bcf67cb0..170fbb984cf9b 100644
--- a/src/libtest/Cargo.toml
+++ b/src/libtest/Cargo.toml
@@ -23,7 +23,7 @@ proc_macro = { path = "../libproc_macro" }
 
 # Forward features to the `std` crate as necessary
 [features]
-backtrace_support = ["std/backtrace_support"]
+backtrace = ["std/backtrace"]
 compiler-builtins-c = ["std/compiler-builtins-c"]
 llvm-libunwind = ["std/llvm-libunwind"]
 panic-unwind = ["std/panic_unwind"]

From ee83402918b25172665ba5cc09bcf8adc5f55380 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 14 Sep 2019 12:49:04 +0200
Subject: [PATCH 732/943] when BUILD_MANIFEST_DISABLE_SIGNING is set, we don't
 need gpg-password-file

---
 src/bootstrap/dist.rs | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 500d5766a899e..076bcd878df71 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -2000,6 +2000,8 @@ impl Step for HashSign {
     }
 
     fn run(self, builder: &Builder<'_>) {
+        // This gets called by `promote-release`
+        // (https://github.com/rust-lang/rust-central-station/tree/master/promote-release).
         let mut cmd = builder.tool_cmd(Tool::BuildManifest);
         if builder.config.dry_run {
             return;
@@ -2010,10 +2012,14 @@ impl Step for HashSign {
         let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| {
             panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
         });
-        let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
-            panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
-        });
-        let pass = t!(fs::read_to_string(&file));
+        let pass = if env::var("BUILD_MANIFEST_DISABLE_SIGNING").is_err() {
+            let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
+                panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
+            });
+            t!(fs::read_to_string(&file))
+        } else {
+            String::new()
+        };
 
         let today = output(Command::new("date").arg("+%Y-%m-%d"));
 

From 766c4a556e95b4c47f811932a710e326c263634c Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 14 Sep 2019 12:57:39 +0200
Subject: [PATCH 733/943] build-manifest: when Miri tests are not passing, do
 not add Miri component

---
 Cargo.lock                           |  2 ++
 src/tools/build-manifest/Cargo.toml  |  2 ++
 src/tools/build-manifest/src/main.rs | 54 +++++++++++++++++++++++++---
 3 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index f2eaf470658b3..9ec76d6c3cf8b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -201,7 +201,9 @@ dependencies = [
 name = "build-manifest"
 version = "0.1.0"
 dependencies = [
+ "reqwest",
  "serde",
+ "serde_json",
  "toml",
 ]
 
diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml
index c364479d8db13..63ae445f99b60 100644
--- a/src/tools/build-manifest/Cargo.toml
+++ b/src/tools/build-manifest/Cargo.toml
@@ -7,3 +7,5 @@ edition = "2018"
 [dependencies]
 toml = "0.5"
 serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
+reqwest = "0.9"
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 9ffa9391c820b..c2d642bb136be 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -1,12 +1,19 @@
+//! Build a dist manifest, hash and sign everything.
+//! This gets called by `promote-release`
+//! (https://github.com/rust-lang/rust-central-station/tree/master/promote-release)
+//! via `x.py dist hash-and-sign`; the cmdline arguments are set up
+//! by rustbuild (in `src/bootstrap/dist.rs`).
+
 use toml;
 use serde::Serialize;
 
 use std::collections::BTreeMap;
 use std::env;
 use std::fs;
-use std::io::{self, Read, Write};
+use std::io::{self, Read, Write, BufRead, BufReader};
 use std::path::{PathBuf, Path};
 use std::process::{Command, Stdio};
+use std::collections::HashMap;
 
 static HOSTS: &[&str] = &[
     "aarch64-unknown-linux-gnu",
@@ -146,6 +153,9 @@ static MINGW: &[&str] = &[
     "x86_64-pc-windows-gnu",
 ];
 
+static TOOLSTATE: &str =
+    "https://raw.githubusercontent.com/rust-lang-nursery/rust-toolstate/master/history/linux.tsv";
+
 #[derive(Serialize)]
 #[serde(rename_all = "kebab-case")]
 struct Manifest {
@@ -270,6 +280,7 @@ fn main() {
     // Do not ask for a passphrase while manually testing
     let mut passphrase = String::new();
     if should_sign {
+        // `x.py` passes the passphrase via stdin.
         t!(io::stdin().read_to_string(&mut passphrase));
     }
 
@@ -353,6 +364,7 @@ impl Builder {
         self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu");
         self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu");
 
+        self.check_toolstate();
         self.digest_and_sign();
         let manifest = self.build_manifest();
         self.write_channel_files(&self.rust_release, &manifest);
@@ -362,6 +374,37 @@ impl Builder {
         }
     }
 
+    /// If a tool does not pass its tests, don't ship it.
+    /// Right now, we do this only for Miri.
+    fn check_toolstate(&mut self) {
+        // Get the toolstate for this rust revision.
+        let rev = self.rust_git_commit_hash.as_ref().expect("failed to determine rust git hash");
+        let toolstates = reqwest::get(TOOLSTATE).expect("failed to get toolstates");
+        let toolstates = BufReader::new(toolstates);
+        let toolstate = toolstates.lines()
+            .find_map(|line| {
+                let line = line.expect("failed to read toolstate lines");
+                let mut pieces = line.splitn(2, '\t');
+                let commit = pieces.next().expect("malformed toolstate line");
+                if commit != rev {
+                    // Not the right commit.
+                    return None;
+                }
+                // Return the 2nd piece, the JSON.
+                Some(pieces.next().expect("malformed toolstate line").to_owned())
+            })
+            .expect("failed to find toolstate for rust commit");
+        let toolstate: HashMap<String, String> =
+            serde_json::from_str(&toolstate).expect("toolstate is malformed JSON");
+        // Mark some tools as missing based on toolstate.
+        if toolstate.get("miri").map(|s| &*s as &str) != Some("test-pass") {
+            println!("Miri tests are not passing, removing component");
+            self.miri_version = None;
+            self.miri_git_commit_hash = None;
+        }
+    }
+
+    /// Hash all files, compute their signatures, and collect the hashes in `self.digests`.
     fn digest_and_sign(&mut self) {
         for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
             let filename = file.file_name().unwrap().to_str().unwrap();
@@ -532,19 +575,20 @@ impl Builder {
             .as_ref()
             .cloned()
             .map(|version| (version, true))
-            .unwrap_or_default();
+            .unwrap_or_default(); // `is_present` defaults to `false` here.
 
-        // miri needs to build std with xargo, which doesn't allow stable/beta:
-        // <https://github.com/japaric/xargo/pull/204#issuecomment-374888868>
+        // Miri is nightly-only; never ship it for other trains.
         if pkgname == "miri-preview" && self.rust_release != "nightly" {
-            is_present = false; // ignore it
+            is_present = false; // Pretend the component is entirely missing.
         }
 
         let targets = targets.iter().map(|name| {
             if is_present {
+                // The component generally exists, but it might still be missing for this target.
                 let filename = self.filename(pkgname, name);
                 let digest = match self.digests.remove(&filename) {
                     Some(digest) => digest,
+                    // This component does not exist for this target -- skip it.
                     None => return (name.to_string(), Target::unavailable()),
                 };
                 let xz_filename = filename.replace(".tar.gz", ".tar.xz");

From 58a26c8fc0200c29bd753cf6fcfd80ee34a98920 Mon Sep 17 00:00:00 2001
From: Alexander Regueiro <alex@noldorin.com>
Date: Sat, 14 Sep 2019 15:26:50 +0100
Subject: [PATCH 734/943] Update src/liballoc/raw_vec.rs

Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
---
 src/liballoc/raw_vec.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index f1c5904afe6fc..cf025eee4358b 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -172,7 +172,7 @@ impl<T> RawVec<T, Global> {
     /// # Undefined Behavior
     ///
     /// The `ptr` must be allocated (on the system heap), and with the given `capacity`.
-    /// Th `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems).
+    /// The `capacity` cannot exceed `isize::MAX` (only a concern on 32-bit systems).
     /// If the `ptr` and `capacity` come from a `RawVec`, then this is guaranteed.
     pub unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self {
         RawVec {

From fc9f13e42470da7e3b1e2f870d1719895484292f Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sat, 14 Sep 2019 13:56:44 +0300
Subject: [PATCH 735/943] def_collector: Do not ICE on attributes on unnamed
 fields

---
 src/librustc/hir/map/def_collector.rs             | 15 +++++++++++++--
 src/librustc/hir/map/definitions.rs               |  2 ++
 .../ui/attributes/unnamed-field-attributes.rs     |  9 +++++++++
 3 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 src/test/ui/attributes/unnamed-field-attributes.rs

diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index bffb4df836e3b..b42fbd5c0a1ae 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -170,9 +170,13 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
     }
 
     fn visit_variant_data(&mut self, data: &'a VariantData) {
+        // The assumption here is that non-`cfg` macro expansion cannot change field indices.
+        // It currently holds because only inert attributes are accepted on fields,
+        // and every such attribute expands into a single field after it's resolved.
         for (index, field) in data.fields().iter().enumerate() {
             if field.is_placeholder {
                 self.visit_macro_invoc(field.id);
+                self.definitions.placeholder_field_indices.insert(field.id, index);
                 continue;
             }
             let name = field.ident.map(|ident| ident.name)
@@ -338,12 +342,19 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
         }
     }
 
+    // This method is called only when we are visiting an individual field
+    // after expanding an attribute on it.
     fn visit_struct_field(&mut self, sf: &'a StructField) {
         if sf.is_placeholder {
             self.visit_macro_invoc(sf.id)
         } else {
-            let name = sf.ident.map(|ident| ident.name)
-                .unwrap_or_else(|| panic!("don't know the field number in this context"));
+            let name = sf.ident.map_or_else(
+                || {
+                    let expn_id = NodeId::placeholder_from_expn_id(self.expansion);
+                    sym::integer(self.definitions.placeholder_field_indices[&expn_id])
+                },
+                |ident| ident.name,
+            );
             let def = self.create_def(sf.id,
                                         DefPathData::ValueNs(name.as_interned_str()),
                                         sf.span);
diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs
index 651fe8449ac93..187bc59332460 100644
--- a/src/librustc/hir/map/definitions.rs
+++ b/src/librustc/hir/map/definitions.rs
@@ -104,6 +104,8 @@ pub struct Definitions {
     /// When collecting definitions from an AST fragment produced by a macro invocation `ExpnId`
     /// we know what parent node that fragment should be attached to thanks to this table.
     invocation_parents: FxHashMap<ExpnId, DefIndex>,
+    /// Indices of unnamed struct or variant fields with unresolved attributes.
+    pub(super) placeholder_field_indices: NodeMap<usize>,
 }
 
 /// A unique identifier that we can use to lookup a definition
diff --git a/src/test/ui/attributes/unnamed-field-attributes.rs b/src/test/ui/attributes/unnamed-field-attributes.rs
new file mode 100644
index 0000000000000..93f364047e9a5
--- /dev/null
+++ b/src/test/ui/attributes/unnamed-field-attributes.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+struct S(
+    #[rustfmt::skip] u8,
+    u16,
+    #[rustfmt::skip] u32,
+);
+
+fn main() {}

From c681cf781b440620aca8cad4be9b76a477fc6c1a Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sat, 14 Sep 2019 17:36:27 +0300
Subject: [PATCH 736/943] def_collector: Factor out common field handling code

---
 src/librustc/hir/map/def_collector.rs | 47 ++++++++++++---------------
 1 file changed, 21 insertions(+), 26 deletions(-)

diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index b42fbd5c0a1ae..d1cc7a8ce988f 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -31,7 +31,7 @@ impl<'a> DefCollector<'a> {
         self.definitions.create_def_with_parent(parent_def, node_id, data, self.expansion, span)
     }
 
-    pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
+    fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
         let orig_parent_def = std::mem::replace(&mut self.parent_def, parent_def);
         f(self);
         self.parent_def = orig_parent_def;
@@ -74,6 +74,22 @@ impl<'a> DefCollector<'a> {
         })
     }
 
+    fn collect_field(&mut self, field: &'a StructField, index: Option<usize>) {
+        if field.is_placeholder {
+            self.visit_macro_invoc(field.id);
+        } else {
+            let name = field.ident.map(|ident| ident.name)
+                .or_else(|| index.map(sym::integer))
+                .unwrap_or_else(|| {
+                    let node_id = NodeId::placeholder_from_expn_id(self.expansion);
+                    sym::integer(self.definitions.placeholder_field_indices[&node_id])
+                })
+                .as_interned_str();
+            let def = self.create_def(field.id, DefPathData::ValueNs(name), field.span);
+            self.with_parent(def, |this| visit::walk_struct_field(this, field));
+        }
+    }
+
     pub fn visit_macro_invoc(&mut self, id: NodeId) {
         self.definitions.set_invocation_parent(id.placeholder_to_expn_id(), self.parent_def);
     }
@@ -174,17 +190,10 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
         // It currently holds because only inert attributes are accepted on fields,
         // and every such attribute expands into a single field after it's resolved.
         for (index, field) in data.fields().iter().enumerate() {
-            if field.is_placeholder {
-                self.visit_macro_invoc(field.id);
+            self.collect_field(field, Some(index));
+            if field.is_placeholder && field.ident.is_none() {
                 self.definitions.placeholder_field_indices.insert(field.id, index);
-                continue;
             }
-            let name = field.ident.map(|ident| ident.name)
-                .unwrap_or_else(|| sym::integer(index));
-            let def = self.create_def(field.id,
-                                      DefPathData::ValueNs(name.as_interned_str()),
-                                      field.span);
-            self.with_parent(def, |this| visit::walk_struct_field(this, field));
         }
     }
 
@@ -344,21 +353,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
 
     // This method is called only when we are visiting an individual field
     // after expanding an attribute on it.
-    fn visit_struct_field(&mut self, sf: &'a StructField) {
-        if sf.is_placeholder {
-            self.visit_macro_invoc(sf.id)
-        } else {
-            let name = sf.ident.map_or_else(
-                || {
-                    let expn_id = NodeId::placeholder_from_expn_id(self.expansion);
-                    sym::integer(self.definitions.placeholder_field_indices[&expn_id])
-                },
-                |ident| ident.name,
-            );
-            let def = self.create_def(sf.id,
-                                        DefPathData::ValueNs(name.as_interned_str()),
-                                        sf.span);
-            self.with_parent(def, |this| visit::walk_struct_field(this, sf));
-        }
+    fn visit_struct_field(&mut self, field: &'a StructField) {
+        self.collect_field(field, None);
     }
 }

From b7f20d06ea40d13834bd04ad32d098d3626f11c7 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sun, 8 Sep 2019 13:06:49 -0400
Subject: [PATCH 737/943] Provide a span if main function is not present in
 crate

Unfortunately, the diagnotic machinery does not cope well with an empty
span which can happen if the crate is empty, in which case we merely set
a spanless note.
---
 src/librustc/middle/entry.rs                  | 74 +++++++++++--------
 .../ui-fulldeps/hash-stable-is-unstable.rs    |  2 +
 .../hash-stable-is-unstable.stderr            |  9 +--
 .../ui/associated-type-bounds/inside-adt.rs   |  2 +
 .../associated-type-bounds/inside-adt.stderr  |  7 +-
 .../cfg-attr-cfg-2.stderr                     |  5 +-
 .../cfg-in-crate-1.stderr                     |  4 +-
 .../ui/continue-after-missing-main.nll.stderr | 10 ++-
 .../ui/continue-after-missing-main.stderr     | 10 ++-
 src/test/ui/elided-test.stderr                |  6 +-
 src/test/ui/error-codes/E0138.stderr          |  2 +-
 src/test/ui/error-codes/E0601.rs              |  2 +-
 src/test/ui/error-codes/E0601.stderr          |  4 +-
 src/test/ui/issues/issue-46101.rs             |  2 +
 src/test/ui/issues/issue-46101.stderr         |  9 +--
 src/test/ui/issues/issue-49040.rs             |  1 +
 src/test/ui/issues/issue-49040.stderr         |  6 +-
 src/test/ui/issues/issue-60057.rs             |  2 +
 src/test/ui/issues/issue-60057.stderr         |  9 +--
 src/test/ui/json-short.stderr                 |  2 +-
 src/test/ui/lifetime-before-type-params.rs    |  2 +
 .../ui/lifetime-before-type-params.stderr     |  7 +-
 src/test/ui/main-wrong-location.rs            |  1 +
 src/test/ui/main-wrong-location.stderr        | 16 +++-
 src/test/ui/missing/missing-main.stderr       |  4 +-
 src/test/ui/parser-recovery-1.rs              |  1 +
 src/test/ui/parser-recovery-1.stderr          | 19 +++--
 src/test/ui/parser/issue-2354.rs              |  5 +-
 src/test/ui/parser/issue-2354.stderr          | 20 ++++-
 src/test/ui/parser/lex-bad-char-literals-2.rs |  2 +
 .../ui/parser/lex-bad-char-literals-2.stderr  |  7 +-
 .../parser/unclosed-delimiter-in-dep.stderr   |  2 +-
 src/test/ui/parser/unclosed_delim_mod.rs      |  2 +
 src/test/ui/parser/unclosed_delim_mod.stderr  |  9 +--
 .../ui/resolve/visibility-indeterminate.rs    |  2 +
 .../resolve/visibility-indeterminate.stderr   |  7 +-
 .../ui/tool-attributes/diagnostic_item.rs     |  1 +
 .../ui/tool-attributes/diagnostic_item.stderr |  9 +--
 .../ui/type-alias-impl-trait/issue-60564.rs   |  2 +
 .../type-alias-impl-trait/issue-60564.stderr  |  7 +-
 src/test/ui/type/ascription/issue-34255-1.rs  |  1 +
 .../ui/type/ascription/issue-34255-1.stderr   |  8 +-
 42 files changed, 176 insertions(+), 126 deletions(-)

diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
index 93bb301f0951a..ba27d332e43f7 100644
--- a/src/librustc/middle/entry.rs
+++ b/src/librustc/middle/entry.rs
@@ -16,16 +16,16 @@ struct EntryContext<'a, 'tcx> {
 
     map: &'a hir_map::Map<'tcx>,
 
-    /// The top-level function called 'main'.
+    /// The top-level function called `main`.
     main_fn: Option<(HirId, Span)>,
 
-    /// The function that has attribute named 'main'.
+    /// The function that has attribute named `main`.
     attr_main_fn: Option<(HirId, Span)>,
 
     /// The function that has the attribute 'start' on it.
     start_fn: Option<(HirId, Span)>,
 
-    /// The functions that one might think are 'main' but aren't, e.g.
+    /// The functions that one might think are `main` but aren't, e.g.
     /// main functions not defined at the top level. For diagnostics.
     non_main_fns: Vec<(HirId, Span)> ,
 }
@@ -88,7 +88,7 @@ fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType {
                 EntryPointType::MainAttr
             } else if item.ident.name == sym::main {
                 if at_root {
-                    // This is a top-level function so can be 'main'.
+                    // This is a top-level function so can be `main`.
                     EntryPointType::MainNamed
                 } else {
                     EntryPointType::OtherMain
@@ -109,7 +109,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
                 ctxt.main_fn = Some((item.hir_id, item.span));
             } else {
                 span_err!(ctxt.session, item.span, E0136,
-                          "multiple 'main' functions");
+                          "multiple `main` functions");
             }
         },
         EntryPointType::OtherMain => {
@@ -130,7 +130,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
             if ctxt.start_fn.is_none() {
                 ctxt.start_fn = Some((item.hir_id, item.span));
             } else {
-                struct_span_err!(ctxt.session, item.span, E0138, "multiple 'start' functions")
+                struct_span_err!(ctxt.session, item.span, E0138, "multiple `start` functions")
                     .span_label(ctxt.start_fn.unwrap().1, "previous `start` function here")
                     .span_label(item.span, "multiple `start` functions")
                     .emit();
@@ -148,34 +148,48 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De
     } else if let Some((hir_id, _)) = visitor.main_fn {
         Some((tcx.hir().local_def_id(hir_id), EntryFnType::Main))
     } else {
-        // There is no main function.
-        let mut err = struct_err!(tcx.sess, E0601,
-            "`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE));
-        if !visitor.non_main_fns.is_empty() {
-            // There were some functions named 'main' though. Try to give the user a hint.
-            err.note("the main function must be defined at the crate level \
-                      but you have one or more functions named 'main' that are not \
-                      defined at the crate level. Either move the definition or \
-                      attach the `#[main]` attribute to override this behavior.");
-            for &(_, span) in &visitor.non_main_fns {
-                err.span_note(span, "here is a function named 'main'");
-            }
-            err.emit();
-        } else {
-            if let Some(ref filename) = tcx.sess.local_crate_source_file {
-                err.note(&format!("consider adding a `main` function to `{}`", filename.display()));
-            }
-            if tcx.sess.teach(&err.get_code().unwrap()) {
-                err.note("If you don't know the basics of Rust, you can go look to the Rust Book \
-                          to get started: https://doc.rust-lang.org/book/");
-            }
-            err.emit();
-        }
-
+        no_main_err(tcx, visitor);
         None
     }
 }
 
+fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
+    // There is no main function.
+    let mut err = struct_err!(tcx.sess, E0601,
+        "`main` function not found in crate `{}`", tcx.crate_name(LOCAL_CRATE));
+    let filename = &tcx.sess.local_crate_source_file;
+    let note = if !visitor.non_main_fns.is_empty() {
+        for &(_, span) in &visitor.non_main_fns {
+            err.span_note(span, "here is a function named `main`");
+        }
+        err.note("you have one or more functions named `main` not defined at the crate level");
+        err.help("either move the `main` function definitions or attach the `#[main]` attribute \
+                  to one of them");
+        // There were some functions named `main` though. Try to give the user a hint.
+        format!("the main function must be defined at the crate level{}",
+                 filename.as_ref().map(|f| format!(" (in `{}`)", f.display())).unwrap_or_default())
+    } else if let Some(filename) = filename {
+        format!("consider adding a `main` function to `{}`", filename.display())
+    } else {
+        String::from("consider adding a `main` function at the crate level")
+    };
+    let sp = tcx.hir().krate().span;
+    // The file may be empty, which leads to the diagnostic machinery not emitting this
+    // note. This is a relatively simple way to detect that case and emit a span-less
+    // note instead.
+    if let Ok(_) = tcx.sess.source_map().lookup_line(sp.lo()) {
+        err.set_span(sp);
+        err.span_label(sp, &note);
+    } else {
+        err.note(&note);
+    }
+    if tcx.sess.teach(&err.get_code().unwrap()) {
+        err.note("If you don't know the basics of Rust, you can go look to the Rust Book \
+                  to get started: https://doc.rust-lang.org/book/");
+    }
+    err.emit();
+}
+
 pub fn find_entry_point(tcx: TyCtxt<'_>) -> Option<(DefId, EntryFnType)> {
     tcx.entry_fn(LOCAL_CRATE)
 }
diff --git a/src/test/ui-fulldeps/hash-stable-is-unstable.rs b/src/test/ui-fulldeps/hash-stable-is-unstable.rs
index 9f67f642df1ce..d79ef62c31207 100644
--- a/src/test/ui-fulldeps/hash-stable-is-unstable.rs
+++ b/src/test/ui-fulldeps/hash-stable-is-unstable.rs
@@ -13,3 +13,5 @@ use rustc_macros::HashStable;
 #[derive(HashStable)]
 //~^ use of unstable library feature 'rustc_private'
 struct Test;
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/hash-stable-is-unstable.stderr b/src/test/ui-fulldeps/hash-stable-is-unstable.stderr
index 02056d30eae9c..e2dc0c3be725f 100644
--- a/src/test/ui-fulldeps/hash-stable-is-unstable.stderr
+++ b/src/test/ui-fulldeps/hash-stable-is-unstable.stderr
@@ -1,7 +1,3 @@
-error[E0601]: `main` function not found in crate `hash_stable_is_unstable`
-   |
-   = note: consider adding a `main` function to `$DIR/hash-stable-is-unstable.rs`
-
 error[E0658]: use of unstable library feature 'rustc_private': this crate is being loaded from the sysroot, an unstable location; did you mean to load this crate from crates.io via `Cargo.toml` instead?
   --> $DIR/hash-stable-is-unstable.rs:3:1
    |
@@ -47,7 +43,6 @@ LL | #[derive(HashStable)]
    = note: for more information, see https://github.com/rust-lang/rust/issues/27812
    = help: add `#![feature(rustc_private)]` to the crate attributes to enable
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0601, E0658.
-For more information about an error, try `rustc --explain E0601`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/associated-type-bounds/inside-adt.rs b/src/test/ui/associated-type-bounds/inside-adt.rs
index 83a60825d84cd..59ce9496d28f0 100644
--- a/src/test/ui/associated-type-bounds/inside-adt.rs
+++ b/src/test/ui/associated-type-bounds/inside-adt.rs
@@ -31,3 +31,5 @@ union U2 { f: Box<dyn Iterator<Item: Copy>> }
 union U3 { f: dyn Iterator<Item: 'static> }
 //~^ ERROR associated type bounds are not allowed within structs, enums, or unions
 //~| ERROR could not find defining uses
+
+fn main() {}
diff --git a/src/test/ui/associated-type-bounds/inside-adt.stderr b/src/test/ui/associated-type-bounds/inside-adt.stderr
index d0e0ceccd3725..9c4d03e900940 100644
--- a/src/test/ui/associated-type-bounds/inside-adt.stderr
+++ b/src/test/ui/associated-type-bounds/inside-adt.stderr
@@ -52,10 +52,6 @@ error: associated type bounds are not allowed within structs, enums, or unions
 LL | union U3 { f: dyn Iterator<Item: 'static> }
    |                            ^^^^^^^^^^^^^
 
-error[E0601]: `main` function not found in crate `inside_adt`
-   |
-   = note: consider adding a `main` function to `$DIR/inside-adt.rs`
-
 error: could not find defining uses
   --> $DIR/inside-adt.rs:5:29
    |
@@ -110,6 +106,5 @@ error: could not find defining uses
 LL | union U3 { f: dyn Iterator<Item: 'static> }
    |                            ^^^^^^^^^^^^^
 
-error: aborting due to 19 previous errors
+error: aborting due to 18 previous errors
 
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/conditional-compilation/cfg-attr-cfg-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-cfg-2.stderr
index db3c7acff151c..e9df780def5df 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-cfg-2.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-cfg-2.stderr
@@ -1,6 +1,9 @@
 error[E0601]: `main` function not found in crate `cfg_attr_cfg_2`
+  --> $DIR/cfg-attr-cfg-2.rs:8:1
    |
-   = note: consider adding a `main` function to `$DIR/cfg-attr-cfg-2.rs`
+LL | / #[cfg_attr(foo, cfg(bar))]
+LL | | fn main() { }
+   | |_____________^ consider adding a `main` function to `$DIR/cfg-attr-cfg-2.rs`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/conditional-compilation/cfg-in-crate-1.stderr b/src/test/ui/conditional-compilation/cfg-in-crate-1.stderr
index c6d42c732c934..0b5c3e0335586 100644
--- a/src/test/ui/conditional-compilation/cfg-in-crate-1.stderr
+++ b/src/test/ui/conditional-compilation/cfg-in-crate-1.stderr
@@ -1,6 +1,8 @@
 error[E0601]: `main` function not found in crate `cfg_in_crate_1`
+  --> $DIR/cfg-in-crate-1.rs:3:1
    |
-   = note: consider adding a `main` function to `$DIR/cfg-in-crate-1.rs`
+LL | #![cfg(bar)]
+   | ^^^^^^^^^^^^ consider adding a `main` function to `$DIR/cfg-in-crate-1.rs`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/continue-after-missing-main.nll.stderr b/src/test/ui/continue-after-missing-main.nll.stderr
index aceabf3316479..b94c365f2539a 100644
--- a/src/test/ui/continue-after-missing-main.nll.stderr
+++ b/src/test/ui/continue-after-missing-main.nll.stderr
@@ -1,6 +1,14 @@
 error[E0601]: `main` function not found in crate `continue_after_missing_main`
+  --> $DIR/continue-after-missing-main.rs:1:1
    |
-   = note: consider adding a `main` function to `$DIR/continue-after-missing-main.rs`
+LL | / #![allow(dead_code)]
+LL | |
+LL | | // error-pattern:`main` function not found in crate
+LL | |
+...  |
+LL | |
+LL | | }
+   | |_^ consider adding a `main` function to `$DIR/continue-after-missing-main.rs`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/continue-after-missing-main.stderr b/src/test/ui/continue-after-missing-main.stderr
index cc5f87659079e..d764e7d860af6 100644
--- a/src/test/ui/continue-after-missing-main.stderr
+++ b/src/test/ui/continue-after-missing-main.stderr
@@ -1,6 +1,14 @@
 error[E0601]: `main` function not found in crate `continue_after_missing_main`
+  --> $DIR/continue-after-missing-main.rs:1:1
    |
-   = note: consider adding a `main` function to `$DIR/continue-after-missing-main.rs`
+LL | / #![allow(dead_code)]
+LL | |
+LL | | // error-pattern:`main` function not found in crate
+LL | |
+...  |
+LL | |
+LL | | }
+   | |_^ consider adding a `main` function to `$DIR/continue-after-missing-main.rs`
 
 error[E0623]: lifetime mismatch
   --> $DIR/continue-after-missing-main.rs:30:56
diff --git a/src/test/ui/elided-test.stderr b/src/test/ui/elided-test.stderr
index d22eee4e8bde7..175bd033067bc 100644
--- a/src/test/ui/elided-test.stderr
+++ b/src/test/ui/elided-test.stderr
@@ -1,6 +1,10 @@
 error[E0601]: `main` function not found in crate `elided_test`
+  --> $DIR/elided-test.rs:5:1
    |
-   = note: consider adding a `main` function to `$DIR/elided-test.rs`
+LL | / #[test]
+LL | | fn main() {
+LL | | }
+   | |_^ consider adding a `main` function to `$DIR/elided-test.rs`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0138.stderr b/src/test/ui/error-codes/E0138.stderr
index 745dccfb17571..445053a4a89e3 100644
--- a/src/test/ui/error-codes/E0138.stderr
+++ b/src/test/ui/error-codes/E0138.stderr
@@ -1,4 +1,4 @@
-error[E0138]: multiple 'start' functions
+error[E0138]: multiple `start` functions
   --> $DIR/E0138.rs:7:1
    |
 LL | fn foo(argc: isize, argv: *const *const u8) -> isize { 0 }
diff --git a/src/test/ui/error-codes/E0601.rs b/src/test/ui/error-codes/E0601.rs
index 47feb7f836722..4380ddeac0aac 100644
--- a/src/test/ui/error-codes/E0601.rs
+++ b/src/test/ui/error-codes/E0601.rs
@@ -1 +1 @@
-// Test for main function not found.
+//~ ERROR `main` function not found
diff --git a/src/test/ui/error-codes/E0601.stderr b/src/test/ui/error-codes/E0601.stderr
index cbc20db35da77..a687f575615d7 100644
--- a/src/test/ui/error-codes/E0601.stderr
+++ b/src/test/ui/error-codes/E0601.stderr
@@ -1,6 +1,8 @@
 error[E0601]: `main` function not found in crate `E0601`
+  --> $DIR/E0601.rs:1:37
    |
-   = note: consider adding a `main` function to `$DIR/E0601.rs`
+LL |
+   |                                     ^ consider adding a `main` function to `$DIR/E0601.rs`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-46101.rs b/src/test/ui/issues/issue-46101.rs
index 2d9111e9b3a98..8b1343b1326b4 100644
--- a/src/test/ui/issues/issue-46101.rs
+++ b/src/test/ui/issues/issue-46101.rs
@@ -2,3 +2,5 @@
 trait Foo {}
 #[derive(Foo::Anything)] //~ ERROR failed to resolve: partially resolved path in a derive macro
 struct S;
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-46101.stderr b/src/test/ui/issues/issue-46101.stderr
index 772d4bfeb30a7..9c88d3b87c907 100644
--- a/src/test/ui/issues/issue-46101.stderr
+++ b/src/test/ui/issues/issue-46101.stderr
@@ -4,11 +4,6 @@ error[E0433]: failed to resolve: partially resolved path in a derive macro
 LL | #[derive(Foo::Anything)]
    |          ^^^^^^^^^^^^^ partially resolved path in a derive macro
 
-error[E0601]: `main` function not found in crate `issue_46101`
-   |
-   = note: consider adding a `main` function to `$DIR/issue-46101.rs`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0433, E0601.
-For more information about an error, try `rustc --explain E0433`.
+For more information about this error, try `rustc --explain E0433`.
diff --git a/src/test/ui/issues/issue-49040.rs b/src/test/ui/issues/issue-49040.rs
index a5f05d2824eb8..b7a541dd6642a 100644
--- a/src/test/ui/issues/issue-49040.rs
+++ b/src/test/ui/issues/issue-49040.rs
@@ -1,2 +1,3 @@
 #![allow(unused_variables)]; //~ ERROR expected item, found `;`
+//~^ ERROR `main` function
 fn foo() {}
diff --git a/src/test/ui/issues/issue-49040.stderr b/src/test/ui/issues/issue-49040.stderr
index de78b8d3c14af..4134d6aa54468 100644
--- a/src/test/ui/issues/issue-49040.stderr
+++ b/src/test/ui/issues/issue-49040.stderr
@@ -5,8 +5,12 @@ LL | #![allow(unused_variables)];
    |                            ^ help: remove this semicolon
 
 error[E0601]: `main` function not found in crate `issue_49040`
+  --> $DIR/issue-49040.rs:1:1
    |
-   = note: consider adding a `main` function to `$DIR/issue-49040.rs`
+LL | / #![allow(unused_variables)];
+LL | |
+LL | | fn foo() {}
+   | |__^ consider adding a `main` function to `$DIR/issue-49040.rs`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-60057.rs b/src/test/ui/issues/issue-60057.rs
index 3027d01c5325b..b52343adaee71 100644
--- a/src/test/ui/issues/issue-60057.rs
+++ b/src/test/ui/issues/issue-60057.rs
@@ -15,3 +15,5 @@ impl A {
         }
     }
 }
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-60057.stderr b/src/test/ui/issues/issue-60057.stderr
index 6b967204ce6fb..4d915fcd9fe3d 100644
--- a/src/test/ui/issues/issue-60057.stderr
+++ b/src/test/ui/issues/issue-60057.stderr
@@ -10,11 +10,6 @@ error[E0425]: cannot find value `banana` in this scope
 LL |             banana: banana
    |                     ^^^^^^ help: you might have meant to use the available field: `self.banana`
 
-error[E0601]: `main` function not found in crate `issue_60057`
-   |
-   = note: consider adding a `main` function to `$DIR/issue-60057.rs`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0425, E0601.
-For more information about an error, try `rustc --explain E0425`.
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/json-short.stderr b/src/test/ui/json-short.stderr
index dffbdb7e4802d..86cb2f0a3a813 100644
--- a/src/test/ui/json-short.stderr
+++ b/src/test/ui/json-short.stderr
@@ -11,7 +11,7 @@ fn main() {
 
 If you don't know the basics of Rust, you can go look to the Rust Book to get
 started: https://doc.rust-lang.org/book/
-"},"level":"error","spans":[],"children":[{"message":"consider adding a `main` function to `$DIR/json-short.rs`","code":null,"level":"note","spans":[],"children":[],"rendered":null}],"rendered":"error[E0601]: `main` function not found in crate `json_short`
+"},"level":"error","spans":[{"file_name":"$DIR/json-short.rs","byte_start":76,"byte_end":76,"line_start":2,"line_end":2,"column_start":63,"column_end":63,"is_primary":true,"text":[{"text":"// compile-flags: --json=diagnostic-short --error-format=json","highlight_start":63,"highlight_end":63}],"label":"consider adding a `main` function to `$DIR/json-short.rs`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-short.rs:2:63: error[E0601]: `main` function not found in crate `json_short`
 "}
 {"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error
 "}
diff --git a/src/test/ui/lifetime-before-type-params.rs b/src/test/ui/lifetime-before-type-params.rs
index 9b905d4883a16..5a71d6efeda62 100644
--- a/src/test/ui/lifetime-before-type-params.rs
+++ b/src/test/ui/lifetime-before-type-params.rs
@@ -7,3 +7,5 @@ fn third<T, U, 'a>() {}
 //~^ ERROR lifetime parameters must be declared prior to type parameters
 fn fourth<'a, T, 'b, U, 'c, V>() {}
 //~^ ERROR lifetime parameters must be declared prior to type parameters
+
+fn main() {}
diff --git a/src/test/ui/lifetime-before-type-params.stderr b/src/test/ui/lifetime-before-type-params.stderr
index ffc6784bafed8..76d7d0f024d65 100644
--- a/src/test/ui/lifetime-before-type-params.stderr
+++ b/src/test/ui/lifetime-before-type-params.stderr
@@ -22,10 +22,5 @@ error: lifetime parameters must be declared prior to type parameters
 LL | fn fourth<'a, T, 'b, U, 'c, V>() {}
    |          --------^^-----^^---- help: reorder the parameters: lifetimes, then types: `<'a, 'b, 'c, T, U, V>`
 
-error[E0601]: `main` function not found in crate `lifetime_before_type_params`
-   |
-   = note: consider adding a `main` function to `$DIR/lifetime-before-type-params.rs`
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/main-wrong-location.rs b/src/test/ui/main-wrong-location.rs
index d7ed5128195e9..f75d08813cdcd 100644
--- a/src/test/ui/main-wrong-location.rs
+++ b/src/test/ui/main-wrong-location.rs
@@ -1,4 +1,5 @@
 mod m {
+//~^ ERROR `main` function not found
     // An inferred main entry point (that doesn't use #[main])
     // must appear at the top of the crate
     fn main() { }
diff --git a/src/test/ui/main-wrong-location.stderr b/src/test/ui/main-wrong-location.stderr
index b30931f2f2301..e301c2ff09ad7 100644
--- a/src/test/ui/main-wrong-location.stderr
+++ b/src/test/ui/main-wrong-location.stderr
@@ -1,11 +1,21 @@
 error[E0601]: `main` function not found in crate `main_wrong_location`
+  --> $DIR/main-wrong-location.rs:1:1
    |
-   = note: the main function must be defined at the crate level but you have one or more functions named 'main' that are not defined at the crate level. Either move the definition or attach the `#[main]` attribute to override this behavior.
-note: here is a function named 'main'
-  --> $DIR/main-wrong-location.rs:4:5
+LL | / mod m {
+LL | |
+LL | |     // An inferred main entry point (that doesn't use #[main])
+LL | |     // must appear at the top of the crate
+LL | |     fn main() { }
+LL | | }
+   | |_^ the main function must be defined at the crate level (in `$DIR/main-wrong-location.rs`)
+   |
+note: here is a function named `main`
+  --> $DIR/main-wrong-location.rs:5:5
    |
 LL |     fn main() { }
    |     ^^^^^^^^^^^^^
+   = note: you have one or more functions named `main` not defined at the crate level
+   = help: either move the `main` function definitions or attach the `#[main]` attribute to one of them
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/missing/missing-main.stderr b/src/test/ui/missing/missing-main.stderr
index 34b03ada3d295..6a35f5117efd6 100644
--- a/src/test/ui/missing/missing-main.stderr
+++ b/src/test/ui/missing/missing-main.stderr
@@ -1,6 +1,8 @@
 error[E0601]: `main` function not found in crate `missing_main`
+  --> $DIR/missing-main.rs:2:1
    |
-   = note: consider adding a `main` function to `$DIR/missing-main.rs`
+LL | fn mian() { }
+   | ^^^^^^^^^^^^^ consider adding a `main` function to `$DIR/missing-main.rs`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser-recovery-1.rs b/src/test/ui/parser-recovery-1.rs
index 21d36048e6703..8126525c34f95 100644
--- a/src/test/ui/parser-recovery-1.rs
+++ b/src/test/ui/parser-recovery-1.rs
@@ -3,6 +3,7 @@
 // Test that we can recover from missing braces in the parser.
 
 trait Foo {
+//~^ ERROR `main` function not found
     fn bar() {
         let x = foo();
         //~^ ERROR cannot find function `foo` in this scope
diff --git a/src/test/ui/parser-recovery-1.stderr b/src/test/ui/parser-recovery-1.stderr
index c29f42759178e..ffe2b3322fc81 100644
--- a/src/test/ui/parser-recovery-1.stderr
+++ b/src/test/ui/parser-recovery-1.stderr
@@ -1,8 +1,9 @@
 error: this file contains an un-closed delimiter
-  --> $DIR/parser-recovery-1.rs:15:55
+  --> $DIR/parser-recovery-1.rs:16:55
    |
 LL | trait Foo {
    |           - un-closed delimiter
+LL |
 LL |     fn bar() {
    |              - this delimiter might not be properly closed...
 ...
@@ -13,26 +14,34 @@ LL | }
    |                                                       ^
 
 error: unexpected token: `;`
-  --> $DIR/parser-recovery-1.rs:12:15
+  --> $DIR/parser-recovery-1.rs:13:15
    |
 LL |     let x = y.;
    |               ^
 
 error[E0425]: cannot find function `foo` in this scope
-  --> $DIR/parser-recovery-1.rs:7:17
+  --> $DIR/parser-recovery-1.rs:8:17
    |
 LL |         let x = foo();
    |                 ^^^ not found in this scope
 
 error[E0425]: cannot find value `y` in this scope
-  --> $DIR/parser-recovery-1.rs:12:13
+  --> $DIR/parser-recovery-1.rs:13:13
    |
 LL |     let x = y.;
    |             ^ not found in this scope
 
 error[E0601]: `main` function not found in crate `parser_recovery_1`
+  --> $DIR/parser-recovery-1.rs:5:1
    |
-   = note: consider adding a `main` function to `$DIR/parser-recovery-1.rs`
+LL | / trait Foo {
+LL | |
+LL | |     fn bar() {
+LL | |         let x = foo();
+...  |
+LL | |
+LL | | }
+   | |______________________________________________________^ consider adding a `main` function to `$DIR/parser-recovery-1.rs`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/parser/issue-2354.rs b/src/test/ui/parser/issue-2354.rs
index 565f84822f7d6..a14eb6e32fc91 100644
--- a/src/test/ui/parser/issue-2354.rs
+++ b/src/test/ui/parser/issue-2354.rs
@@ -1,4 +1,7 @@
 fn foo() { //~ NOTE un-closed delimiter
+//~^ ERROR `main` function not found
+//~^^ NOTE main function must be defined
+//~^^^ NOTE you have one or more functions
   match Some(10) {
   //~^ NOTE this delimiter might not be properly closed...
       Some(y) => { panic!(); }
@@ -11,5 +14,5 @@ fn bar() {
     while (i < 1000) {}
 }
 
-fn main() {} //~ NOTE here is a function named 'main'
+fn main() {} //~ NOTE here is a function named `main`
              //~ ERROR this file contains an un-closed delimiter
diff --git a/src/test/ui/parser/issue-2354.stderr b/src/test/ui/parser/issue-2354.stderr
index 7098da738b8df..038e3dcfa40a9 100644
--- a/src/test/ui/parser/issue-2354.stderr
+++ b/src/test/ui/parser/issue-2354.stderr
@@ -1,8 +1,9 @@
 error: this file contains an un-closed delimiter
-  --> $DIR/issue-2354.rs:15:66
+  --> $DIR/issue-2354.rs:18:66
    |
 LL | fn foo() {
    |          - un-closed delimiter
+...
 LL |   match Some(10) {
    |                  - this delimiter might not be properly closed...
 ...
@@ -13,13 +14,24 @@ LL |
    |                                                                  ^
 
 error[E0601]: `main` function not found in crate `issue_2354`
+  --> $DIR/issue-2354.rs:1:1
+   |
+LL | / fn foo() {
+LL | |
+LL | |
+LL | |
+...  |
+LL | | fn main() {}
+LL | |
+   | |_________________________________________________________________^ the main function must be defined at the crate level (in `$DIR/issue-2354.rs`)
    |
-   = note: the main function must be defined at the crate level but you have one or more functions named 'main' that are not defined at the crate level. Either move the definition or attach the `#[main]` attribute to override this behavior.
-note: here is a function named 'main'
-  --> $DIR/issue-2354.rs:14:1
+note: here is a function named `main`
+  --> $DIR/issue-2354.rs:17:1
    |
 LL | fn main() {}
    | ^^^^^^^^^^^^
+   = note: you have one or more functions named `main` not defined at the crate level
+   = help: either move the `main` function definitions or attach the `#[main]` attribute to one of them
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/parser/lex-bad-char-literals-2.rs b/src/test/ui/parser/lex-bad-char-literals-2.rs
index 1e180f87fc186..d35dafd9a3443 100644
--- a/src/test/ui/parser/lex-bad-char-literals-2.rs
+++ b/src/test/ui/parser/lex-bad-char-literals-2.rs
@@ -2,3 +2,5 @@
 static c: char =
     'nope' //~ ERROR: character literal may only contain one codepoint
 ;
+
+fn main() {}
diff --git a/src/test/ui/parser/lex-bad-char-literals-2.stderr b/src/test/ui/parser/lex-bad-char-literals-2.stderr
index b0a4ed02434b4..5653d4ea672af 100644
--- a/src/test/ui/parser/lex-bad-char-literals-2.stderr
+++ b/src/test/ui/parser/lex-bad-char-literals-2.stderr
@@ -8,10 +8,5 @@ help: if you meant to write a `str` literal, use double quotes
 LL |     "nope"
    |     ^^^^^^
 
-error[E0601]: `main` function not found in crate `lex_bad_char_literals_2`
-   |
-   = note: consider adding a `main` function to `$DIR/lex-bad-char-literals-2.rs`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/parser/unclosed-delimiter-in-dep.stderr b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr
index 633c63bea9105..818f61b4d2229 100644
--- a/src/test/ui/parser/unclosed-delimiter-in-dep.stderr
+++ b/src/test/ui/parser/unclosed-delimiter-in-dep.stderr
@@ -1,5 +1,5 @@
 error: incorrect close delimiter: `}`
-  --> $DIR/unclosed_delim_mod.rs:5:1
+  --> $DIR/unclosed_delim_mod.rs:7:1
    |
 LL | pub fn new() -> Result<Value, ()> {
    |                                   - close delimiter possibly meant for this
diff --git a/src/test/ui/parser/unclosed_delim_mod.rs b/src/test/ui/parser/unclosed_delim_mod.rs
index b1664f49dc591..486e23312819d 100644
--- a/src/test/ui/parser/unclosed_delim_mod.rs
+++ b/src/test/ui/parser/unclosed_delim_mod.rs
@@ -1,3 +1,5 @@
+fn main() {}
+
 pub struct Value {}
 pub fn new() -> Result<Value, ()> {
     Ok(Value {
diff --git a/src/test/ui/parser/unclosed_delim_mod.stderr b/src/test/ui/parser/unclosed_delim_mod.stderr
index cc04eb531cbea..fe2d968af0f32 100644
--- a/src/test/ui/parser/unclosed_delim_mod.stderr
+++ b/src/test/ui/parser/unclosed_delim_mod.stderr
@@ -1,5 +1,5 @@
 error: incorrect close delimiter: `}`
-  --> $DIR/unclosed_delim_mod.rs:5:1
+  --> $DIR/unclosed_delim_mod.rs:7:1
    |
 LL | pub fn new() -> Result<Value, ()> {
    |                                   - close delimiter possibly meant for this
@@ -9,10 +9,5 @@ LL |     }
 LL | }
    | ^ incorrect close delimiter
 
-error[E0601]: `main` function not found in crate `unclosed_delim_mod`
-   |
-   = note: consider adding a `main` function to `$DIR/unclosed_delim_mod.rs`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/resolve/visibility-indeterminate.rs b/src/test/ui/resolve/visibility-indeterminate.rs
index 595eaf440c9f4..198ea752881f1 100644
--- a/src/test/ui/resolve/visibility-indeterminate.rs
+++ b/src/test/ui/resolve/visibility-indeterminate.rs
@@ -3,3 +3,5 @@
 foo!(); //~ ERROR cannot find macro `foo!` in this scope
 
 pub(in ::bar) struct Baz {} //~ ERROR cannot determine resolution for the visibility
+
+fn main() {}
diff --git a/src/test/ui/resolve/visibility-indeterminate.stderr b/src/test/ui/resolve/visibility-indeterminate.stderr
index a259c8090b35d..17927a5967dcb 100644
--- a/src/test/ui/resolve/visibility-indeterminate.stderr
+++ b/src/test/ui/resolve/visibility-indeterminate.stderr
@@ -10,10 +10,5 @@ error: cannot find macro `foo!` in this scope
 LL | foo!();
    | ^^^
 
-error[E0601]: `main` function not found in crate `visibility_indeterminate`
-   |
-   = note: consider adding a `main` function to `$DIR/visibility-indeterminate.rs`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/tool-attributes/diagnostic_item.rs b/src/test/ui/tool-attributes/diagnostic_item.rs
index 1d35422ed6241..26a52ce60cfd8 100644
--- a/src/test/ui/tool-attributes/diagnostic_item.rs
+++ b/src/test/ui/tool-attributes/diagnostic_item.rs
@@ -1,2 +1,3 @@
 #[rustc_diagnostic_item = "foomp"] //~ ERROR compiler internal support for linting
 struct Foomp;
+fn main() {}
diff --git a/src/test/ui/tool-attributes/diagnostic_item.stderr b/src/test/ui/tool-attributes/diagnostic_item.stderr
index deff4da6b8052..5432f8dea8606 100644
--- a/src/test/ui/tool-attributes/diagnostic_item.stderr
+++ b/src/test/ui/tool-attributes/diagnostic_item.stderr
@@ -7,11 +7,6 @@ LL | #[rustc_diagnostic_item = "foomp"]
    = note: for more information, see https://github.com/rust-lang/rust/issues/29642
    = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
 
-error[E0601]: `main` function not found in crate `diagnostic_item`
-   |
-   = note: consider adding a `main` function to `$DIR/diagnostic_item.rs`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0601, E0658.
-For more information about an error, try `rustc --explain E0601`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs
index 91c4576597ea4..9e96b1cf7b05f 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60564.rs
+++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs
@@ -24,3 +24,5 @@ where
             .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
     }
 }
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr
index ebb13fca1da92..b838c06cadee3 100644
--- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr
+++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr
@@ -1,7 +1,3 @@
-error[E0601]: `main` function not found in crate `issue_60564`
-   |
-   = note: consider adding a `main` function to `$DIR/issue-60564.rs`
-
 error: type parameter `E` is part of concrete type but not used in parameter list for the `impl Trait` type alias
   --> $DIR/issue-60564.rs:20:49
    |
@@ -20,6 +16,5 @@ error: could not find defining uses
 LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0601`.
diff --git a/src/test/ui/type/ascription/issue-34255-1.rs b/src/test/ui/type/ascription/issue-34255-1.rs
index c11a248d3c7d1..c21d9f3d97cbb 100644
--- a/src/test/ui/type/ascription/issue-34255-1.rs
+++ b/src/test/ui/type/ascription/issue-34255-1.rs
@@ -13,3 +13,4 @@ impl Reactor {
 }
 
 // This case isn't currently being handled gracefully, including for completeness.
+fn main() {}
diff --git a/src/test/ui/type/ascription/issue-34255-1.stderr b/src/test/ui/type/ascription/issue-34255-1.stderr
index 531455b82b424..195b393b2f609 100644
--- a/src/test/ui/type/ascription/issue-34255-1.stderr
+++ b/src/test/ui/type/ascription/issue-34255-1.stderr
@@ -14,17 +14,13 @@ LL |         input_cells: Vec::new()
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
 
-error[E0601]: `main` function not found in crate `issue_34255_1`
-   |
-   = note: consider adding a `main` function to `$DIR/issue-34255-1.rs`
-
 error[E0107]: wrong number of type arguments: expected 1, found 0
   --> $DIR/issue-34255-1.rs:7:22
    |
 LL |         input_cells: Vec::new()
    |                      ^^^^^^^^^^ expected 1 type argument
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0107, E0425, E0601.
+Some errors have detailed explanations: E0107, E0425.
 For more information about an error, try `rustc --explain E0107`.

From 7b3adc289eb84f21199d1f2aeac9d88779b7369b Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Thu, 12 Sep 2019 10:46:49 -0400
Subject: [PATCH 738/943] Ban non-extern rust intrinsics

Intrinsics can only be defined by the compiler.
---
 src/librustc_typeck/check/mod.rs              |  20 +-
 .../incremental/hashes/function_interfaces.rs |  12 --
 src/test/incremental/hashes/trait_defs.rs     |   5 +-
 src/test/ui/feature-gates/feature-gate-abi.rs |  10 +-
 .../ui/feature-gates/feature-gate-abi.stderr  | 187 ++++++++++--------
 .../feature-gates/feature-gate-intrinsics.rs  |   1 +
 .../feature-gate-intrinsics.stderr            |   8 +-
 src/test/ui/intrinsics-always-extern.rs       |  16 ++
 src/test/ui/intrinsics-always-extern.stderr   |  24 +++
 9 files changed, 186 insertions(+), 97 deletions(-)
 create mode 100644 src/test/ui/intrinsics-always-extern.rs
 create mode 100644 src/test/ui/intrinsics-always-extern.stderr

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 02e7d97ccdf7b..ae7ab0a771754 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1088,6 +1088,8 @@ fn check_fn<'a, 'tcx>(
 
     let span = body.value.span;
 
+    fn_maybe_err(fcx.tcx, span, fn_sig.abi);
+
     if body.generator_kind.is_some() && can_be_generator.is_some() {
         let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
             kind: TypeVariableOriginKind::TypeInference,
@@ -1439,6 +1441,14 @@ fn check_opaque_for_cycles<'tcx>(
     }
 }
 
+// Forbid defining intrinsics in Rust code,
+// as they must always be defined by the compiler.
+fn fn_maybe_err(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
+    if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
+        tcx.sess.span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
+    }
+}
+
 pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
     debug!(
         "check_item_type(it.hir_id={}, it.name={})",
@@ -1475,9 +1485,17 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item) {
                 check_on_unimplemented(tcx, trait_def_id, it);
             }
         }
-        hir::ItemKind::Trait(..) => {
+        hir::ItemKind::Trait(_, _, _, _, ref items) => {
             let def_id = tcx.hir().local_def_id(it.hir_id);
             check_on_unimplemented(tcx, def_id, it);
+
+            for item in items.iter() {
+                let item = tcx.hir().trait_item(item.id);
+                if let hir::TraitItemKind::Method(sig, _) = &item.node {
+                    let abi = sig.header.abi;
+                    fn_maybe_err(tcx, item.ident.span, abi);
+                }
+            }
         }
         hir::ItemKind::Struct(..) => {
             check_struct(tcx, it.hir_id, it.span);
diff --git a/src/test/incremental/hashes/function_interfaces.rs b/src/test/incremental/hashes/function_interfaces.rs
index 4515e36166eb8..9cc2d3bcf6045 100644
--- a/src/test/incremental/hashes/function_interfaces.rs
+++ b/src/test/incremental/hashes/function_interfaces.rs
@@ -11,7 +11,6 @@
 
 
 #![allow(warnings)]
-#![feature(intrinsics)]
 #![feature(linkage)]
 #![feature(rustc_attrs)]
 #![crate_type = "rlib"]
@@ -99,17 +98,6 @@ pub fn make_extern() {}
 pub extern "C" fn make_extern() {}
 
 
-// Extern C Extern Rust-Intrinsic ----------------------------------------------
-
-#[cfg(cfail1)]
-pub extern "C" fn make_intrinsic() {}
-
-#[cfg(not(cfail1))]
-#[rustc_clean(cfg = "cfail2", except = "Hir, HirBody, typeck_tables_of, fn_sig")]
-#[rustc_clean(cfg = "cfail3")]
-pub extern "rust-intrinsic" fn make_intrinsic() {}
-
-
 // Type Parameter --------------------------------------------------------------
 
 #[cfg(cfail1)]
diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs
index 81ff99533fc91..3006cdccfbb55 100644
--- a/src/test/incremental/hashes/trait_defs.rs
+++ b/src/test/incremental/hashes/trait_defs.rs
@@ -18,7 +18,6 @@
 #![feature(rustc_attrs)]
 #![crate_type="rlib"]
 #![feature(associated_type_defaults)]
-#![feature(intrinsics)]
 
 
 // Change trait visibility
@@ -318,7 +317,7 @@ trait TraitAddExternModifier {
 
 
 
-// Change extern "C" to extern "rust-intrinsic"
+// Change extern "C" to extern "stdcall"
 #[cfg(cfail1)]
 trait TraitChangeExternCToRustIntrinsic {
     extern "C" fn method();
@@ -330,7 +329,7 @@ trait TraitChangeExternCToRustIntrinsic {
 trait TraitChangeExternCToRustIntrinsic {
     #[rustc_dirty(label="Hir", cfg="cfail2")]
     #[rustc_clean(label="Hir", cfg="cfail3")]
-    extern "rust-intrinsic" fn method();
+    extern "stdcall" fn method();
 }
 
 
diff --git a/src/test/ui/feature-gates/feature-gate-abi.rs b/src/test/ui/feature-gates/feature-gate-abi.rs
index 41c9f79bfe3ed..61da38eea74b3 100644
--- a/src/test/ui/feature-gates/feature-gate-abi.rs
+++ b/src/test/ui/feature-gates/feature-gate-abi.rs
@@ -10,7 +10,9 @@
 
 // Functions
 extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change
+//~^ ERROR intrinsic must be in
 extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental
+//~^ ERROR intrinsic must be in
 extern "vectorcall" fn f3() {} //~ ERROR vectorcall is experimental and subject to change
 extern "rust-call" fn f4() {} //~ ERROR rust-call ABI is subject to change
 extern "msp430-interrupt" fn f5() {} //~ ERROR msp430-interrupt ABI is experimental
@@ -22,7 +24,9 @@ extern "amdgpu-kernel" fn f9() {} //~ ERROR amdgpu-kernel ABI is experimental an
 // Methods in trait definition
 trait Tr {
     extern "rust-intrinsic" fn m1(); //~ ERROR intrinsics are subject to change
+    //~^ ERROR intrinsic must be in
     extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental
+    //~^ ERROR intrinsic must be in
     extern "vectorcall" fn m3(); //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn m4(); //~ ERROR rust-call ABI is subject to change
     extern "msp430-interrupt" fn m5(); //~ ERROR msp430-interrupt ABI is experimental
@@ -31,8 +35,6 @@ trait Tr {
     extern "thiscall" fn m8(); //~ ERROR thiscall is experimental and subject to change
     extern "amdgpu-kernel" fn m9(); //~ ERROR amdgpu-kernel ABI is experimental and subject to change
 
-    extern "rust-intrinsic" fn dm1() {} //~ ERROR intrinsics are subject to change
-    extern "platform-intrinsic" fn dm2() {} //~ ERROR platform intrinsics are experimental
     extern "vectorcall" fn dm3() {} //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn dm4() {} //~ ERROR rust-call ABI is subject to change
     extern "msp430-interrupt" fn dm5() {} //~ ERROR msp430-interrupt ABI is experimental
@@ -47,7 +49,9 @@ struct S;
 // Methods in trait impl
 impl Tr for S {
     extern "rust-intrinsic" fn m1() {} //~ ERROR intrinsics are subject to change
+    //~^ ERROR intrinsic must be in
     extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental
+    //~^ ERROR intrinsic must be in
     extern "vectorcall" fn m3() {} //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn m4() {} //~ ERROR rust-call ABI is subject to change
     extern "msp430-interrupt" fn m5() {} //~ ERROR msp430-interrupt ABI is experimental
@@ -60,7 +64,9 @@ impl Tr for S {
 // Methods in inherent impl
 impl S {
     extern "rust-intrinsic" fn im1() {} //~ ERROR intrinsics are subject to change
+    //~^ ERROR intrinsic must be in
     extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental
+    //~^ ERROR intrinsic must be in
     extern "vectorcall" fn im3() {} //~ ERROR vectorcall is experimental and subject to change
     extern "rust-call" fn im4() {} //~ ERROR rust-call ABI is subject to change
     extern "msp430-interrupt" fn im5() {} //~ ERROR msp430-interrupt ABI is experimental
diff --git a/src/test/ui/feature-gates/feature-gate-abi.stderr b/src/test/ui/feature-gates/feature-gate-abi.stderr
index 88e0b8667be54..afda76dc2b0aa 100644
--- a/src/test/ui/feature-gates/feature-gate-abi.stderr
+++ b/src/test/ui/feature-gates/feature-gate-abi.stderr
@@ -7,7 +7,7 @@ LL | extern "rust-intrinsic" fn f1() {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:13:1
+  --> $DIR/feature-gate-abi.rs:14:1
    |
 LL | extern "platform-intrinsic" fn f2() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL | extern "platform-intrinsic" fn f2() {}
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:14:1
+  --> $DIR/feature-gate-abi.rs:16:1
    |
 LL | extern "vectorcall" fn f3() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ LL | extern "vectorcall" fn f3() {}
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:15:1
+  --> $DIR/feature-gate-abi.rs:17:1
    |
 LL | extern "rust-call" fn f4() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL | extern "rust-call" fn f4() {}
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:16:1
+  --> $DIR/feature-gate-abi.rs:18:1
    |
 LL | extern "msp430-interrupt" fn f5() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +42,7 @@ LL | extern "msp430-interrupt" fn f5() {}
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:17:1
+  --> $DIR/feature-gate-abi.rs:19:1
    |
 LL | extern "ptx-kernel" fn f6() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -51,7 +51,7 @@ LL | extern "ptx-kernel" fn f6() {}
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:18:1
+  --> $DIR/feature-gate-abi.rs:20:1
    |
 LL | extern "x86-interrupt" fn f7() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -60,7 +60,7 @@ LL | extern "x86-interrupt" fn f7() {}
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:19:1
+  --> $DIR/feature-gate-abi.rs:21:1
    |
 LL | extern "thiscall" fn f8() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -68,7 +68,7 @@ LL | extern "thiscall" fn f8() {}
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:20:1
+  --> $DIR/feature-gate-abi.rs:22:1
    |
 LL | extern "amdgpu-kernel" fn f9() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -77,7 +77,7 @@ LL | extern "amdgpu-kernel" fn f9() {}
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:24:5
+  --> $DIR/feature-gate-abi.rs:26:5
    |
 LL |     extern "rust-intrinsic" fn m1();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -85,7 +85,7 @@ LL |     extern "rust-intrinsic" fn m1();
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:25:5
+  --> $DIR/feature-gate-abi.rs:28:5
    |
 LL |     extern "platform-intrinsic" fn m2();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -94,7 +94,7 @@ LL |     extern "platform-intrinsic" fn m2();
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:26:5
+  --> $DIR/feature-gate-abi.rs:30:5
    |
 LL |     extern "vectorcall" fn m3();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -102,7 +102,7 @@ LL |     extern "vectorcall" fn m3();
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:27:5
+  --> $DIR/feature-gate-abi.rs:31:5
    |
 LL |     extern "rust-call" fn m4();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -111,7 +111,7 @@ LL |     extern "rust-call" fn m4();
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:28:5
+  --> $DIR/feature-gate-abi.rs:32:5
    |
 LL |     extern "msp430-interrupt" fn m5();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -120,7 +120,7 @@ LL |     extern "msp430-interrupt" fn m5();
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:29:5
+  --> $DIR/feature-gate-abi.rs:33:5
    |
 LL |     extern "ptx-kernel" fn m6();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -129,7 +129,7 @@ LL |     extern "ptx-kernel" fn m6();
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:30:5
+  --> $DIR/feature-gate-abi.rs:34:5
    |
 LL |     extern "x86-interrupt" fn m7();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -138,7 +138,7 @@ LL |     extern "x86-interrupt" fn m7();
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:31:5
+  --> $DIR/feature-gate-abi.rs:35:5
    |
 LL |     extern "thiscall" fn m8();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -146,7 +146,7 @@ LL |     extern "thiscall" fn m8();
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:32:5
+  --> $DIR/feature-gate-abi.rs:36:5
    |
 LL |     extern "amdgpu-kernel" fn m9();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -154,25 +154,8 @@ LL |     extern "amdgpu-kernel" fn m9();
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
-error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:34:5
-   |
-LL |     extern "rust-intrinsic" fn dm1() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add `#![feature(intrinsics)]` to the crate attributes to enable
-
-error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:35:5
-   |
-LL |     extern "platform-intrinsic" fn dm2() {}
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/27731
-   = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
-
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:36:5
+  --> $DIR/feature-gate-abi.rs:38:5
    |
 LL |     extern "vectorcall" fn dm3() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -180,7 +163,7 @@ LL |     extern "vectorcall" fn dm3() {}
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:37:5
+  --> $DIR/feature-gate-abi.rs:39:5
    |
 LL |     extern "rust-call" fn dm4() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -189,7 +172,7 @@ LL |     extern "rust-call" fn dm4() {}
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:38:5
+  --> $DIR/feature-gate-abi.rs:40:5
    |
 LL |     extern "msp430-interrupt" fn dm5() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -198,7 +181,7 @@ LL |     extern "msp430-interrupt" fn dm5() {}
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:39:5
+  --> $DIR/feature-gate-abi.rs:41:5
    |
 LL |     extern "ptx-kernel" fn dm6() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -207,7 +190,7 @@ LL |     extern "ptx-kernel" fn dm6() {}
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:40:5
+  --> $DIR/feature-gate-abi.rs:42:5
    |
 LL |     extern "x86-interrupt" fn dm7() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -216,7 +199,7 @@ LL |     extern "x86-interrupt" fn dm7() {}
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:41:5
+  --> $DIR/feature-gate-abi.rs:43:5
    |
 LL |     extern "thiscall" fn dm8() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -224,7 +207,7 @@ LL |     extern "thiscall" fn dm8() {}
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:42:5
+  --> $DIR/feature-gate-abi.rs:44:5
    |
 LL |     extern "amdgpu-kernel" fn dm9() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -233,7 +216,7 @@ LL |     extern "amdgpu-kernel" fn dm9() {}
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:49:5
+  --> $DIR/feature-gate-abi.rs:51:5
    |
 LL |     extern "rust-intrinsic" fn m1() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -241,7 +224,7 @@ LL |     extern "rust-intrinsic" fn m1() {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:50:5
+  --> $DIR/feature-gate-abi.rs:53:5
    |
 LL |     extern "platform-intrinsic" fn m2() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -250,7 +233,7 @@ LL |     extern "platform-intrinsic" fn m2() {}
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:51:5
+  --> $DIR/feature-gate-abi.rs:55:5
    |
 LL |     extern "vectorcall" fn m3() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -258,7 +241,7 @@ LL |     extern "vectorcall" fn m3() {}
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:52:5
+  --> $DIR/feature-gate-abi.rs:56:5
    |
 LL |     extern "rust-call" fn m4() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -267,7 +250,7 @@ LL |     extern "rust-call" fn m4() {}
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:53:5
+  --> $DIR/feature-gate-abi.rs:57:5
    |
 LL |     extern "msp430-interrupt" fn m5() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -276,7 +259,7 @@ LL |     extern "msp430-interrupt" fn m5() {}
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:54:5
+  --> $DIR/feature-gate-abi.rs:58:5
    |
 LL |     extern "ptx-kernel" fn m6() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -285,7 +268,7 @@ LL |     extern "ptx-kernel" fn m6() {}
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:55:5
+  --> $DIR/feature-gate-abi.rs:59:5
    |
 LL |     extern "x86-interrupt" fn m7() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -294,7 +277,7 @@ LL |     extern "x86-interrupt" fn m7() {}
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:56:5
+  --> $DIR/feature-gate-abi.rs:60:5
    |
 LL |     extern "thiscall" fn m8() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -302,7 +285,7 @@ LL |     extern "thiscall" fn m8() {}
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:57:5
+  --> $DIR/feature-gate-abi.rs:61:5
    |
 LL |     extern "amdgpu-kernel" fn m9() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -311,7 +294,7 @@ LL |     extern "amdgpu-kernel" fn m9() {}
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:62:5
+  --> $DIR/feature-gate-abi.rs:66:5
    |
 LL |     extern "rust-intrinsic" fn im1() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -319,7 +302,7 @@ LL |     extern "rust-intrinsic" fn im1() {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:63:5
+  --> $DIR/feature-gate-abi.rs:68:5
    |
 LL |     extern "platform-intrinsic" fn im2() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -328,7 +311,7 @@ LL |     extern "platform-intrinsic" fn im2() {}
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:64:5
+  --> $DIR/feature-gate-abi.rs:70:5
    |
 LL |     extern "vectorcall" fn im3() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -336,7 +319,7 @@ LL |     extern "vectorcall" fn im3() {}
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:65:5
+  --> $DIR/feature-gate-abi.rs:71:5
    |
 LL |     extern "rust-call" fn im4() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -345,7 +328,7 @@ LL |     extern "rust-call" fn im4() {}
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:66:5
+  --> $DIR/feature-gate-abi.rs:72:5
    |
 LL |     extern "msp430-interrupt" fn im5() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -354,7 +337,7 @@ LL |     extern "msp430-interrupt" fn im5() {}
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:67:5
+  --> $DIR/feature-gate-abi.rs:73:5
    |
 LL |     extern "ptx-kernel" fn im6() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -363,7 +346,7 @@ LL |     extern "ptx-kernel" fn im6() {}
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:68:5
+  --> $DIR/feature-gate-abi.rs:74:5
    |
 LL |     extern "x86-interrupt" fn im7() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -372,7 +355,7 @@ LL |     extern "x86-interrupt" fn im7() {}
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:69:5
+  --> $DIR/feature-gate-abi.rs:75:5
    |
 LL |     extern "thiscall" fn im8() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -380,7 +363,7 @@ LL |     extern "thiscall" fn im8() {}
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:70:5
+  --> $DIR/feature-gate-abi.rs:76:5
    |
 LL |     extern "amdgpu-kernel" fn im9() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -389,7 +372,7 @@ LL |     extern "amdgpu-kernel" fn im9() {}
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:74:11
+  --> $DIR/feature-gate-abi.rs:80:11
    |
 LL | type A1 = extern "rust-intrinsic" fn();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -397,7 +380,7 @@ LL | type A1 = extern "rust-intrinsic" fn();
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:75:11
+  --> $DIR/feature-gate-abi.rs:81:11
    |
 LL | type A2 = extern "platform-intrinsic" fn();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -406,7 +389,7 @@ LL | type A2 = extern "platform-intrinsic" fn();
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:76:11
+  --> $DIR/feature-gate-abi.rs:82:11
    |
 LL | type A3 = extern "vectorcall" fn();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -414,7 +397,7 @@ LL | type A3 = extern "vectorcall" fn();
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:77:11
+  --> $DIR/feature-gate-abi.rs:83:11
    |
 LL | type A4 = extern "rust-call" fn();
    |           ^^^^^^^^^^^^^^^^^^^^^^^
@@ -423,7 +406,7 @@ LL | type A4 = extern "rust-call" fn();
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:78:11
+  --> $DIR/feature-gate-abi.rs:84:11
    |
 LL | type A5 = extern "msp430-interrupt" fn();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -432,7 +415,7 @@ LL | type A5 = extern "msp430-interrupt" fn();
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:79:11
+  --> $DIR/feature-gate-abi.rs:85:11
    |
 LL | type A6 = extern "ptx-kernel" fn ();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -441,7 +424,7 @@ LL | type A6 = extern "ptx-kernel" fn ();
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:80:11
+  --> $DIR/feature-gate-abi.rs:86:11
    |
 LL | type A7 = extern "x86-interrupt" fn();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -450,7 +433,7 @@ LL | type A7 = extern "x86-interrupt" fn();
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:81:11
+  --> $DIR/feature-gate-abi.rs:87:11
    |
 LL | type A8 = extern "thiscall" fn();
    |           ^^^^^^^^^^^^^^^^^^^^^^
@@ -458,7 +441,7 @@ LL | type A8 = extern "thiscall" fn();
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:82:11
+  --> $DIR/feature-gate-abi.rs:88:11
    |
 LL | type A9 = extern "amdgpu-kernel" fn();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -467,7 +450,7 @@ LL | type A9 = extern "amdgpu-kernel" fn();
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:85:1
+  --> $DIR/feature-gate-abi.rs:91:1
    |
 LL | extern "rust-intrinsic" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -475,7 +458,7 @@ LL | extern "rust-intrinsic" {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
 
 error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:86:1
+  --> $DIR/feature-gate-abi.rs:92:1
    |
 LL | extern "platform-intrinsic" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -484,7 +467,7 @@ LL | extern "platform-intrinsic" {}
    = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
 
 error[E0658]: vectorcall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:87:1
+  --> $DIR/feature-gate-abi.rs:93:1
    |
 LL | extern "vectorcall" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
@@ -492,7 +475,7 @@ LL | extern "vectorcall" {}
    = help: add `#![feature(abi_vectorcall)]` to the crate attributes to enable
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:88:1
+  --> $DIR/feature-gate-abi.rs:94:1
    |
 LL | extern "rust-call" {}
    | ^^^^^^^^^^^^^^^^^^^^^
@@ -501,7 +484,7 @@ LL | extern "rust-call" {}
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0658]: msp430-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:89:1
+  --> $DIR/feature-gate-abi.rs:95:1
    |
 LL | extern "msp430-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -510,7 +493,7 @@ LL | extern "msp430-interrupt" {}
    = help: add `#![feature(abi_msp430_interrupt)]` to the crate attributes to enable
 
 error[E0658]: PTX ABIs are experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:90:1
+  --> $DIR/feature-gate-abi.rs:96:1
    |
 LL | extern "ptx-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^
@@ -519,7 +502,7 @@ LL | extern "ptx-kernel" {}
    = help: add `#![feature(abi_ptx)]` to the crate attributes to enable
 
 error[E0658]: x86-interrupt ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:91:1
+  --> $DIR/feature-gate-abi.rs:97:1
    |
 LL | extern "x86-interrupt" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -528,7 +511,7 @@ LL | extern "x86-interrupt" {}
    = help: add `#![feature(abi_x86_interrupt)]` to the crate attributes to enable
 
 error[E0658]: thiscall is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:92:1
+  --> $DIR/feature-gate-abi.rs:98:1
    |
 LL | extern "thiscall" {}
    | ^^^^^^^^^^^^^^^^^^^^
@@ -536,7 +519,7 @@ LL | extern "thiscall" {}
    = help: add `#![feature(abi_thiscall)]` to the crate attributes to enable
 
 error[E0658]: amdgpu-kernel ABI is experimental and subject to change
-  --> $DIR/feature-gate-abi.rs:93:1
+  --> $DIR/feature-gate-abi.rs:99:1
    |
 LL | extern "amdgpu-kernel" {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -544,6 +527,54 @@ LL | extern "amdgpu-kernel" {}
    = note: for more information, see https://github.com/rust-lang/rust/issues/51575
    = help: add `#![feature(abi_amdgpu_kernel)]` to the crate attributes to enable
 
-error: aborting due to 63 previous errors
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/feature-gate-abi.rs:26:32
+   |
+LL |     extern "rust-intrinsic" fn m1();
+   |                                ^^
+
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/feature-gate-abi.rs:28:36
+   |
+LL |     extern "platform-intrinsic" fn m2();
+   |                                    ^^
+
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/feature-gate-abi.rs:12:33
+   |
+LL | extern "rust-intrinsic" fn f1() {}
+   |                                 ^^
+
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/feature-gate-abi.rs:14:37
+   |
+LL | extern "platform-intrinsic" fn f2() {}
+   |                                     ^^
+
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/feature-gate-abi.rs:51:37
+   |
+LL |     extern "rust-intrinsic" fn m1() {}
+   |                                     ^^
+
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/feature-gate-abi.rs:53:41
+   |
+LL |     extern "platform-intrinsic" fn m2() {}
+   |                                         ^^
+
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/feature-gate-abi.rs:66:38
+   |
+LL |     extern "rust-intrinsic" fn im1() {}
+   |                                      ^^
+
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/feature-gate-abi.rs:68:42
+   |
+LL |     extern "platform-intrinsic" fn im2() {}
+   |                                          ^^
+
+error: aborting due to 69 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-intrinsics.rs b/src/test/ui/feature-gates/feature-gate-intrinsics.rs
index d1da94338283b..e0dc3cc579d79 100644
--- a/src/test/ui/feature-gates/feature-gate-intrinsics.rs
+++ b/src/test/ui/feature-gates/feature-gate-intrinsics.rs
@@ -3,5 +3,6 @@ extern "rust-intrinsic" {   //~ ERROR intrinsics are subject to change
 }
 
 extern "rust-intrinsic" fn baz() {} //~ ERROR intrinsics are subject to change
+//~^ ERROR intrinsic must be in
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-intrinsics.stderr b/src/test/ui/feature-gates/feature-gate-intrinsics.stderr
index 09843f05af1b9..101a10e8df71f 100644
--- a/src/test/ui/feature-gates/feature-gate-intrinsics.stderr
+++ b/src/test/ui/feature-gates/feature-gate-intrinsics.stderr
@@ -22,7 +22,13 @@ error[E0093]: unrecognized intrinsic function: `bar`
 LL |     fn bar();
    |     ^^^^^^^^^ unrecognized intrinsic
 
-error: aborting due to 3 previous errors
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/feature-gate-intrinsics.rs:5:34
+   |
+LL | extern "rust-intrinsic" fn baz() {}
+   |                                  ^^
+
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0093, E0658.
 For more information about an error, try `rustc --explain E0093`.
diff --git a/src/test/ui/intrinsics-always-extern.rs b/src/test/ui/intrinsics-always-extern.rs
new file mode 100644
index 0000000000000..22951147d7d87
--- /dev/null
+++ b/src/test/ui/intrinsics-always-extern.rs
@@ -0,0 +1,16 @@
+#![feature(intrinsics)]
+
+trait Foo {
+    extern "rust-intrinsic" fn foo(&self); //~ ERROR intrinsic must
+}
+
+impl Foo for () {
+    extern "rust-intrinsic" fn foo(&self) { //~ ERROR intrinsic must
+    }
+}
+
+extern "rust-intrinsic" fn hello() {//~ ERROR intrinsic must
+}
+
+fn main() {
+}
diff --git a/src/test/ui/intrinsics-always-extern.stderr b/src/test/ui/intrinsics-always-extern.stderr
new file mode 100644
index 0000000000000..24b6da16096e6
--- /dev/null
+++ b/src/test/ui/intrinsics-always-extern.stderr
@@ -0,0 +1,24 @@
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/intrinsics-always-extern.rs:4:32
+   |
+LL |     extern "rust-intrinsic" fn foo(&self);
+   |                                ^^^
+
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/intrinsics-always-extern.rs:8:43
+   |
+LL |       extern "rust-intrinsic" fn foo(&self) {
+   |  ___________________________________________^
+LL | |     }
+   | |_____^
+
+error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/intrinsics-always-extern.rs:12:36
+   |
+LL |   extern "rust-intrinsic" fn hello() {
+   |  ____________________________________^
+LL | | }
+   | |_^
+
+error: aborting due to 3 previous errors
+

From 2a774b1e6bfda649f75dcc6d32502100f8420a3a Mon Sep 17 00:00:00 2001
From: mark <markm@cs.wisc.edu>
Date: Sat, 14 Sep 2019 11:26:59 -0500
Subject: [PATCH 739/943] address Centril's comments

---
 .../nll/region_infer/error_reporting/mod.rs   | 27 ++++++++++---------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
index 660f510ac196e..26a89b4e7a8d1 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
@@ -56,12 +56,20 @@ enum Trace {
 
 /// Various pieces of state used when reporting borrow checker errors.
 pub struct ErrorReportingCtx<'a, 'b, 'tcx> {
+    /// The region inference context used for borrow chekcing this MIR body.
     #[allow(dead_code)] // FIXME(mark-i-m): used by outlives suggestions
-    rinfcx: &'b RegionInferenceContext<'tcx>,
+    region_infcx: &'b RegionInferenceContext<'tcx>,
+
+    /// The inference context used for type checking.
     infcx: &'b InferCtxt<'a, 'tcx>,
 
+    /// The MIR def we are reporting errors on.
     mir_def_id: DefId,
+
+    /// The MIR body we are reporting errors on (for convenience).
     body: &'b Body<'tcx>,
+
+    /// Any upvars for the MIR body we have kept track of during borrow checking.
     upvars: &'b [Upvar],
 }
 
@@ -319,7 +327,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         );
 
         let errctx = ErrorReportingCtx {
-            rinfcx: self,
+            region_infcx: self,
             infcx,
             mir_def_id,
             body,
@@ -335,16 +343,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 self.report_fnmut_error(&errctx, &errci, renctx)
             }
             (ConstraintCategory::Assignment, true, false)
-            | (ConstraintCategory::CallArgument, true, false) => {
-                let db = self.report_escaping_data_error(&errctx, &errci, renctx);
-
-                db
-            }
-            _ => {
-                let db = self.report_general_error(&errctx, &errci, renctx);
-
-                db
-            }
+            | (ConstraintCategory::CallArgument, true, false) =>
+                self.report_escaping_data_error(&errctx, &errci, renctx),
+            _ => self.report_general_error(&errctx, &errci, renctx),
         }
     }
 
@@ -714,7 +715,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         let mut renctx = RegionErrorNamingCtx::new();
         let errctx = ErrorReportingCtx {
             infcx, body, upvars, mir_def_id,
-            rinfcx: self,
+            region_infcx: self,
         };
         let outlived_fr_name = self.give_region_a_name(&errctx, &mut renctx, outlived_region);
 

From 966d96c9d2f16fd66eefda2eac25126a353bbb3a Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sat, 14 Sep 2019 19:36:41 +0300
Subject: [PATCH 740/943] feature_gate: Remove dead code from attribute
 checking

Same checks are performed during name resolution, and all attributes go through name resolution now
---
 src/librustc_interface/passes.rs    | 11 ++-----
 src/libsyntax/feature_gate/check.rs | 50 +++++------------------------
 2 files changed, 10 insertions(+), 51 deletions(-)

diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 3cfae1686dfdf..e8e8da6733471 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -41,7 +41,6 @@ use syntax::mut_visit::MutVisitor;
 use syntax::parse::{self, PResult};
 use syntax::util::node_count::NodeCounter;
 use syntax::symbol::Symbol;
-use syntax::feature_gate::AttributeType;
 use syntax_pos::FileName;
 use syntax_ext;
 
@@ -219,7 +218,6 @@ impl BoxedResolver {
 
 pub struct PluginInfo {
     syntax_exts: Vec<NamedSyntaxExtension>,
-    attributes: Vec<(Symbol, AttributeType)>,
 }
 
 pub fn register_plugins<'a>(
@@ -312,12 +310,9 @@ pub fn register_plugins<'a>(
     }
 
     *sess.plugin_llvm_passes.borrow_mut() = llvm_passes;
-    *sess.plugin_attributes.borrow_mut() = attributes.clone();
+    *sess.plugin_attributes.borrow_mut() = attributes;
 
-    Ok((krate, PluginInfo {
-        syntax_exts,
-        attributes,
-    }))
+    Ok((krate, PluginInfo { syntax_exts }))
 }
 
 fn configure_and_expand_inner<'a>(
@@ -329,7 +324,6 @@ fn configure_and_expand_inner<'a>(
     crate_loader: &'a mut CrateLoader<'a>,
     plugin_info: PluginInfo,
 ) -> Result<(ast::Crate, Resolver<'a>)> {
-    let attributes = plugin_info.attributes;
     time(sess, "pre ast expansion lint checks", || {
         lint::check_ast_crate(
             sess,
@@ -522,7 +516,6 @@ fn configure_and_expand_inner<'a>(
             &krate,
             &sess.parse_sess,
             &sess.features_untracked(),
-            &attributes,
             sess.opts.unstable_features,
         );
     });
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 5711b269ff092..ddf847ca3a34c 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -1,7 +1,7 @@
 use super::{active::{ACTIVE_FEATURES, Features}, Feature, State as FeatureState};
 use super::accepted::ACCEPTED_FEATURES;
 use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
-use super::builtin_attrs::{AttributeGate, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
+use super::builtin_attrs::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 
 use crate::ast::{
     self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind,
@@ -33,9 +33,8 @@ pub enum Stability {
 }
 
 struct Context<'a> {
-    features: &'a Features,
     parse_sess: &'a ParseSess,
-    plugin_attributes: &'a [(Symbol, AttributeType)],
+    features: &'a Features,
 }
 
 macro_rules! gate_feature_fn {
@@ -67,7 +66,6 @@ impl<'a> Context<'a> {
         &self,
         attr: &ast::Attribute,
         attr_info: Option<&BuiltinAttribute>,
-        is_macro: bool
     ) {
         debug!("check_attribute(attr = {:?})", attr);
         if let Some(&(name, ty, _template, ref gateage)) = attr_info {
@@ -87,42 +85,15 @@ impl<'a> Context<'a> {
                 }
             }
             debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
-            return;
-        } else {
-            for segment in &attr.path.segments {
-                if segment.ident.as_str().starts_with("rustc") {
-                    let msg = "attributes starting with `rustc` are \
-                               reserved for use by the `rustc` compiler";
-                    gate_feature!(self, rustc_attrs, segment.ident.span, msg);
-                }
-            }
-        }
-        for &(n, ty) in self.plugin_attributes {
-            if attr.path == n {
-                // Plugins can't gate attributes, so we don't check for it
-                // unlike the code above; we only use this loop to
-                // short-circuit to avoid the checks below.
-                debug!("check_attribute: {:?} is registered by a plugin, {:?}", attr.path, ty);
-                return;
-            }
-        }
-        if !is_macro && !attr::is_known(attr) {
-            // Only run the custom attribute lint during regular feature gate
-            // checking. Macro gating runs before the plugin attributes are
-            // registered, so we skip this in that case.
-            let msg = format!("the attribute `{}` is currently unknown to the compiler and \
-                               may have meaning added to it in the future", attr.path);
-            gate_feature!(self, custom_attribute, attr.span, &msg);
         }
     }
 }
 
 pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) {
-    let cx = Context { features, parse_sess, plugin_attributes: &[] };
+    let cx = Context { parse_sess, features };
     cx.check_attribute(
         attr,
         attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name).map(|a| *a)),
-        true
     );
 }
 
@@ -321,7 +292,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
         });
 
         // Check for gated attributes.
-        self.context.check_attribute(attr, attr_info, false);
+        self.context.check_attribute(attr, attr_info);
 
         if attr.check_name(sym::doc) {
             if let Some(content) = attr.meta_item_list() {
@@ -872,21 +843,16 @@ fn active_features_up_to(edition: Edition) -> impl Iterator<Item=&'static Featur
 }
 
 pub fn check_crate(krate: &ast::Crate,
-                   sess: &ParseSess,
+                   parse_sess: &ParseSess,
                    features: &Features,
-                   plugin_attributes: &[(Symbol, AttributeType)],
                    unstable: UnstableFeatures) {
-    maybe_stage_features(&sess.span_diagnostic, krate, unstable);
-    let ctx = Context {
-        features,
-        parse_sess: sess,
-        plugin_attributes,
-    };
+    maybe_stage_features(&parse_sess.span_diagnostic, krate, unstable);
+    let ctx = Context { parse_sess, features };
 
     macro_rules! gate_all {
         ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); };
         ($spans:ident, $gate:ident, $msg:literal) => {
-            for span in &*sess.gated_spans.$spans.borrow() {
+            for span in &*parse_sess.gated_spans.$spans.borrow() {
                 gate_feature!(&ctx, $gate, *span, $msg);
             }
         }

From a01ba39b4b47e8dd397ccb5b6c0363ee168107b2 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sat, 14 Sep 2019 21:29:59 +0300
Subject: [PATCH 741/943] feature_gate: Merge various attribute gating
 functions

---
 src/libsyntax/ext/expand.rs                   |  15 +--
 src/libsyntax/feature_gate/builtin_attrs.rs   |   1 +
 src/libsyntax/feature_gate/check.rs           | 122 ++++++------------
 src/libsyntax/feature_gate/mod.rs             |   3 +-
 .../feature-gates/feature-gate-doc_alias.rs   |   2 +-
 .../feature-gate-doc_alias.stderr             |   2 +-
 .../ui/feature-gates/feature-gate-doc_cfg.rs  |   2 +-
 .../feature-gates/feature-gate-doc_cfg.stderr |   2 +-
 .../feature-gates/feature-gate-doc_keyword.rs |   2 +-
 .../feature-gate-doc_keyword.stderr           |   2 +-
 .../feature-gate-external_doc.rs              |   2 +-
 .../feature-gate-external_doc.stderr          |   2 +-
 12 files changed, 54 insertions(+), 103 deletions(-)

diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 87e2d721f89a0..b80c530731dfc 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -26,7 +26,7 @@ use syntax_pos::{Span, DUMMY_SP, FileName};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
 use std::io::ErrorKind;
-use std::{iter, mem};
+use std::{iter, mem, slice};
 use std::ops::DerefMut;
 use std::rc::Rc;
 use std::path::PathBuf;
@@ -1019,7 +1019,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
     fn check_attributes(&mut self, attrs: &[ast::Attribute]) {
         let features = self.cx.ecfg.features.unwrap();
         for attr in attrs.iter() {
-            self.check_attribute_inner(attr, features);
+            feature_gate::check_attribute(attr, self.cx.parse_sess, features);
 
             // macros are expanded before any lint passes so this warning has to be hardcoded
             if attr.path == sym::derive {
@@ -1029,15 +1029,6 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
             }
         }
     }
-
-    fn check_attribute(&mut self, at: &ast::Attribute) {
-        let features = self.cx.ecfg.features.unwrap();
-        self.check_attribute_inner(at, features);
-    }
-
-    fn check_attribute_inner(&mut self, at: &ast::Attribute, features: &Features) {
-        feature_gate::check_attribute(at, self.cx.parse_sess, features);
-    }
 }
 
 impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
@@ -1445,7 +1436,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
 
                 if let Some(file) = it.value_str() {
                     let err_count = self.cx.parse_sess.span_diagnostic.err_count();
-                    self.check_attribute(&at);
+                    self.check_attributes(slice::from_ref(at));
                     if self.cx.parse_sess.span_diagnostic.err_count() > err_count {
                         // avoid loading the file if they haven't enabled the feature
                         return noop_visit_attribute(at, self);
diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs
index 763c3ffd782df..b6e13200f32af 100644
--- a/src/libsyntax/feature_gate/builtin_attrs.rs
+++ b/src/libsyntax/feature_gate/builtin_attrs.rs
@@ -79,6 +79,7 @@ pub enum AttributeType {
     CrateLevel,
 }
 
+#[derive(Clone, Copy)]
 pub enum AttributeGate {
     /// Is gated by a given feature gate, reason
     /// and function to check if enabled
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index ddf847ca3a34c..3a9dae5a8b217 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -1,7 +1,7 @@
 use super::{active::{ACTIVE_FEATURES, Features}, Feature, State as FeatureState};
 use super::accepted::ACCEPTED_FEATURES;
 use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES};
-use super::builtin_attrs::{AttributeGate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
+use super::builtin_attrs::{AttributeGate, BUILTIN_ATTRIBUTE_MAP};
 
 use crate::ast::{
     self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind,
@@ -61,40 +61,46 @@ macro_rules! gate_feature {
     };
 }
 
-impl<'a> Context<'a> {
-    fn check_attribute(
-        &self,
-        attr: &ast::Attribute,
-        attr_info: Option<&BuiltinAttribute>,
-    ) {
-        debug!("check_attribute(attr = {:?})", attr);
-        if let Some(&(name, ty, _template, ref gateage)) = attr_info {
-            if let AttributeGate::Gated(_, name, desc, ref has_feature) = *gateage {
-                if !attr.span.allows_unstable(name) {
-                    gate_feature_fn!(
-                        self, has_feature, attr.span, name, desc, GateStrength::Hard
-                    );
-                }
-            } else if name == sym::doc {
-                if let Some(content) = attr.meta_item_list() {
-                    if content.iter().any(|c| c.check_name(sym::include)) {
-                        gate_feature!(self, external_doc, attr.span,
-                            "`#[doc(include = \"...\")]` is experimental"
-                        );
-                    }
-                }
+crate fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) {
+    let cx = &Context { parse_sess, features };
+    let attr_info =
+        attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);
+    // Check feature gates for built-in attributes.
+    if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info {
+        gate_feature_fn!(cx, has_feature, attr.span, name, descr, GateStrength::Hard);
+    }
+    // Check input tokens for built-in and key-value attributes.
+    match attr_info {
+        // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
+        Some((name, _, template, _)) if name != sym::rustc_dummy =>
+            check_builtin_attribute(parse_sess, attr, name, template),
+        _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
+            if token == token::Eq {
+                // All key-value attributes are restricted to meta-item syntax.
+                attr.parse_meta(parse_sess).map_err(|mut err| err.emit()).ok();
             }
-            debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage);
         }
     }
-}
-
-pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) {
-    let cx = Context { parse_sess, features };
-    cx.check_attribute(
-        attr,
-        attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name).map(|a| *a)),
-    );
+    // Check unstable flavors of the `#[doc]` attribute.
+    if attr.check_name(sym::doc) {
+        for nested_meta in attr.meta_item_list().unwrap_or_default() {
+            macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => {
+                $(if nested_meta.check_name(sym::$name) {
+                    let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental");
+                    gate_feature!(cx, $feature, attr.span, msg);
+                })*
+            }}
+
+            gate_doc!(
+                include => external_doc
+                cfg => doc_cfg
+                masked => doc_masked
+                spotlight => doc_spotlight
+                alias => doc_alias
+                keyword => doc_keyword
+            );
+        }
+    }
 }
 
 fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
@@ -210,7 +216,6 @@ pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str =
 
 struct PostExpansionVisitor<'a> {
     context: &'a Context<'a>,
-    builtin_attributes: &'static FxHashMap<Symbol, &'static BuiltinAttribute>,
 }
 
 macro_rules! gate_feature_post {
@@ -287,50 +292,7 @@ impl<'a> PostExpansionVisitor<'a> {
 
 impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_attribute(&mut self, attr: &ast::Attribute) {
-        let attr_info = attr.ident().and_then(|ident| {
-            self.builtin_attributes.get(&ident.name).map(|a| *a)
-        });
-
-        // Check for gated attributes.
-        self.context.check_attribute(attr, attr_info);
-
-        if attr.check_name(sym::doc) {
-            if let Some(content) = attr.meta_item_list() {
-                if content.len() == 1 && content[0].check_name(sym::cfg) {
-                    gate_feature_post!(&self, doc_cfg, attr.span,
-                        "`#[doc(cfg(...))]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::masked)) {
-                    gate_feature_post!(&self, doc_masked, attr.span,
-                        "`#[doc(masked)]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::spotlight)) {
-                    gate_feature_post!(&self, doc_spotlight, attr.span,
-                        "`#[doc(spotlight)]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::alias)) {
-                    gate_feature_post!(&self, doc_alias, attr.span,
-                        "`#[doc(alias = \"...\")]` is experimental"
-                    );
-                } else if content.iter().any(|c| c.check_name(sym::keyword)) {
-                    gate_feature_post!(&self, doc_keyword, attr.span,
-                        "`#[doc(keyword = \"...\")]` is experimental"
-                    );
-                }
-            }
-        }
-
-        match attr_info {
-            // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
-            Some(&(name, _, template, _)) if name != sym::rustc_dummy =>
-                check_builtin_attribute(self.context.parse_sess, attr, name, template),
-            _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
-                if token == token::Eq {
-                    // All key-value attributes are restricted to meta-item syntax.
-                    attr.parse_meta(self.context.parse_sess).map_err(|mut err| err.emit()).ok();
-                }
-            }
-        }
+        check_attribute(attr, self.context.parse_sess, self.context.features);
     }
 
     fn visit_name(&mut self, sp: Span, name: ast::Name) {
@@ -864,11 +826,7 @@ pub fn check_crate(krate: &ast::Crate,
     gate_all!(yields, generators, "yield syntax is experimental");
     gate_all!(or_patterns, "or-patterns syntax is experimental");
 
-    let visitor = &mut PostExpansionVisitor {
-        context: &ctx,
-        builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP,
-    };
-    visit::walk_crate(visitor, krate);
+    visit::walk_crate(&mut PostExpansionVisitor { context: &ctx }, krate);
 }
 
 #[derive(Clone, Copy, Hash)]
diff --git a/src/libsyntax/feature_gate/mod.rs b/src/libsyntax/feature_gate/mod.rs
index 1e41667ea411e..ca13ab3620508 100644
--- a/src/libsyntax/feature_gate/mod.rs
+++ b/src/libsyntax/feature_gate/mod.rs
@@ -58,7 +58,8 @@ pub use builtin_attrs::{
     deprecated_attributes, is_builtin_attr,  is_builtin_attr_name,
 };
 pub use check::{
-    check_attribute, check_crate, get_features, feature_err, emit_feature_err,
+    check_crate, get_features, feature_err, emit_feature_err,
     Stability, GateIssue, UnstableFeatures,
     EXPLAIN_STMT_ATTR_SYNTAX, EXPLAIN_UNSIZED_TUPLE_COERCION,
 };
+crate use check::check_attribute;
diff --git a/src/test/ui/feature-gates/feature-gate-doc_alias.rs b/src/test/ui/feature-gates/feature-gate-doc_alias.rs
index adb6fc217a329..c95722102d9b6 100644
--- a/src/test/ui/feature-gates/feature-gate-doc_alias.rs
+++ b/src/test/ui/feature-gates/feature-gate-doc_alias.rs
@@ -1,4 +1,4 @@
-#[doc(alias = "foo")] //~ ERROR: `#[doc(alias = "...")]` is experimental
+#[doc(alias = "foo")] //~ ERROR: `#[doc(alias)]` is experimental
 pub struct Foo;
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-doc_alias.stderr b/src/test/ui/feature-gates/feature-gate-doc_alias.stderr
index dddaa45de8ff8..540b1f5ccbe43 100644
--- a/src/test/ui/feature-gates/feature-gate-doc_alias.stderr
+++ b/src/test/ui/feature-gates/feature-gate-doc_alias.stderr
@@ -1,4 +1,4 @@
-error[E0658]: `#[doc(alias = "...")]` is experimental
+error[E0658]: `#[doc(alias)]` is experimental
   --> $DIR/feature-gate-doc_alias.rs:1:1
    |
 LL | #[doc(alias = "foo")]
diff --git a/src/test/ui/feature-gates/feature-gate-doc_cfg.rs b/src/test/ui/feature-gates/feature-gate-doc_cfg.rs
index bb3846e7f6b55..b12b8a1057182 100644
--- a/src/test/ui/feature-gates/feature-gate-doc_cfg.rs
+++ b/src/test/ui/feature-gates/feature-gate-doc_cfg.rs
@@ -1,2 +1,2 @@
-#[doc(cfg(unix))] //~ ERROR: `#[doc(cfg(...))]` is experimental
+#[doc(cfg(unix))] //~ ERROR: `#[doc(cfg)]` is experimental
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr b/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr
index 7b0a231df4c3e..eaa908d0037ae 100644
--- a/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr
+++ b/src/test/ui/feature-gates/feature-gate-doc_cfg.stderr
@@ -1,4 +1,4 @@
-error[E0658]: `#[doc(cfg(...))]` is experimental
+error[E0658]: `#[doc(cfg)]` is experimental
   --> $DIR/feature-gate-doc_cfg.rs:1:1
    |
 LL | #[doc(cfg(unix))]
diff --git a/src/test/ui/feature-gates/feature-gate-doc_keyword.rs b/src/test/ui/feature-gates/feature-gate-doc_keyword.rs
index 6cdcfa67c3a9b..4bb9a40deb0dd 100644
--- a/src/test/ui/feature-gates/feature-gate-doc_keyword.rs
+++ b/src/test/ui/feature-gates/feature-gate-doc_keyword.rs
@@ -1,4 +1,4 @@
-#[doc(keyword = "match")] //~ ERROR: `#[doc(keyword = "...")]` is experimental
+#[doc(keyword = "match")] //~ ERROR: `#[doc(keyword)]` is experimental
 /// wonderful
 mod foo{}
 
diff --git a/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr b/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr
index abde0bea9b230..15a41d9ffa4ea 100644
--- a/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr
+++ b/src/test/ui/feature-gates/feature-gate-doc_keyword.stderr
@@ -1,4 +1,4 @@
-error[E0658]: `#[doc(keyword = "...")]` is experimental
+error[E0658]: `#[doc(keyword)]` is experimental
   --> $DIR/feature-gate-doc_keyword.rs:1:1
    |
 LL | #[doc(keyword = "match")]
diff --git a/src/test/ui/feature-gates/feature-gate-external_doc.rs b/src/test/ui/feature-gates/feature-gate-external_doc.rs
index dec3fa185791c..9d68d3ec4f52a 100644
--- a/src/test/ui/feature-gates/feature-gate-external_doc.rs
+++ b/src/test/ui/feature-gates/feature-gate-external_doc.rs
@@ -1,2 +1,2 @@
-#[doc(include="asdf.md")] //~ ERROR: `#[doc(include = "...")]` is experimental
+#[doc(include="asdf.md")] //~ ERROR: `#[doc(include)]` is experimental
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-external_doc.stderr b/src/test/ui/feature-gates/feature-gate-external_doc.stderr
index a5a874374d1eb..683c0ad217426 100644
--- a/src/test/ui/feature-gates/feature-gate-external_doc.stderr
+++ b/src/test/ui/feature-gates/feature-gate-external_doc.stderr
@@ -1,4 +1,4 @@
-error[E0658]: `#[doc(include = "...")]` is experimental
+error[E0658]: `#[doc(include)]` is experimental
   --> $DIR/feature-gate-external_doc.rs:1:1
    |
 LL | #[doc(include="asdf.md")]

From cb771fdd6c927a4308440cad1607570140f058d6 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sat, 14 Sep 2019 21:54:16 +0300
Subject: [PATCH 742/943] feature_gate: Eliminate `check::Context`

Use `PostExpansionVisitor` directly instead
---
 src/libsyntax/feature_gate/check.rs | 110 +++++++++++++---------------
 1 file changed, 51 insertions(+), 59 deletions(-)

diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index 3a9dae5a8b217..b4491a87f0600 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -32,15 +32,10 @@ pub enum Stability {
     Deprecated(&'static str, Option<&'static str>),
 }
 
-struct Context<'a> {
-    parse_sess: &'a ParseSess,
-    features: &'a Features,
-}
-
 macro_rules! gate_feature_fn {
     ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => {{
         let (cx, has_feature, span,
-             name, explain, level) = ($cx, $has_feature, $span, $name, $explain, $level);
+             name, explain, level) = (&*$cx, $has_feature, $span, $name, $explain, $level);
         let has_feature: bool = has_feature(&$cx.features);
         debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
         if !has_feature && !span.allows_unstable($name) {
@@ -62,45 +57,7 @@ macro_rules! gate_feature {
 }
 
 crate fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) {
-    let cx = &Context { parse_sess, features };
-    let attr_info =
-        attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);
-    // Check feature gates for built-in attributes.
-    if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info {
-        gate_feature_fn!(cx, has_feature, attr.span, name, descr, GateStrength::Hard);
-    }
-    // Check input tokens for built-in and key-value attributes.
-    match attr_info {
-        // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
-        Some((name, _, template, _)) if name != sym::rustc_dummy =>
-            check_builtin_attribute(parse_sess, attr, name, template),
-        _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
-            if token == token::Eq {
-                // All key-value attributes are restricted to meta-item syntax.
-                attr.parse_meta(parse_sess).map_err(|mut err| err.emit()).ok();
-            }
-        }
-    }
-    // Check unstable flavors of the `#[doc]` attribute.
-    if attr.check_name(sym::doc) {
-        for nested_meta in attr.meta_item_list().unwrap_or_default() {
-            macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => {
-                $(if nested_meta.check_name(sym::$name) {
-                    let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental");
-                    gate_feature!(cx, $feature, attr.span, msg);
-                })*
-            }}
-
-            gate_doc!(
-                include => external_doc
-                cfg => doc_cfg
-                masked => doc_masked
-                spotlight => doc_spotlight
-                alias => doc_alias
-                keyword => doc_keyword
-            );
-        }
-    }
+    PostExpansionVisitor { parse_sess, features }.visit_attribute(attr)
 }
 
 fn find_lang_feature_issue(feature: Symbol) -> Option<u32> {
@@ -215,20 +172,21 @@ pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str =
     "unsized tuple coercion is not stable enough for use and is subject to change";
 
 struct PostExpansionVisitor<'a> {
-    context: &'a Context<'a>,
+    parse_sess: &'a ParseSess,
+    features: &'a Features,
 }
 
 macro_rules! gate_feature_post {
     ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{
         let (cx, span) = ($cx, $span);
         if !span.allows_unstable(sym::$feature) {
-            gate_feature!(cx.context, $feature, span, $explain)
+            gate_feature!(cx, $feature, span, $explain)
         }
     }};
     ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{
         let (cx, span) = ($cx, $span);
         if !span.allows_unstable(sym::$feature) {
-            gate_feature!(cx.context, $feature, span, $explain, $level)
+            gate_feature!(cx, $feature, span, $explain, $level)
         }
     }}
 }
@@ -292,7 +250,44 @@ impl<'a> PostExpansionVisitor<'a> {
 
 impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     fn visit_attribute(&mut self, attr: &ast::Attribute) {
-        check_attribute(attr, self.context.parse_sess, self.context.features);
+        let attr_info =
+            attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);
+        // Check feature gates for built-in attributes.
+        if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info {
+            gate_feature_fn!(self, has_feature, attr.span, name, descr, GateStrength::Hard);
+        }
+        // Check input tokens for built-in and key-value attributes.
+        match attr_info {
+            // `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
+            Some((name, _, template, _)) if name != sym::rustc_dummy =>
+                check_builtin_attribute(self.parse_sess, attr, name, template),
+            _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() {
+                if token == token::Eq {
+                    // All key-value attributes are restricted to meta-item syntax.
+                    attr.parse_meta(self.parse_sess).map_err(|mut err| err.emit()).ok();
+                }
+            }
+        }
+        // Check unstable flavors of the `#[doc]` attribute.
+        if attr.check_name(sym::doc) {
+            for nested_meta in attr.meta_item_list().unwrap_or_default() {
+                macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => {
+                    $(if nested_meta.check_name(sym::$name) {
+                        let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental");
+                        gate_feature!(self, $feature, attr.span, msg);
+                    })*
+                }}
+
+                gate_doc!(
+                    include => external_doc
+                    cfg => doc_cfg
+                    masked => doc_masked
+                    spotlight => doc_spotlight
+                    alias => doc_alias
+                    keyword => doc_keyword
+                );
+            }
+        }
     }
 
     fn visit_name(&mut self, sp: Span, name: ast::Name) {
@@ -300,7 +295,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             gate_feature_post!(
                 &self,
                 non_ascii_idents,
-                self.context.parse_sess.source_map().def_span(sp),
+                self.parse_sess.source_map().def_span(sp),
                 "non-ascii idents are not fully supported"
             );
         }
@@ -356,12 +351,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                     }
                 }
 
-                let has_feature = self.context.features.arbitrary_enum_discriminant;
+                let has_feature = self.features.arbitrary_enum_discriminant;
                 if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) {
-                    Parser::maybe_report_invalid_custom_discriminants(
-                        self.context.parse_sess,
-                        &variants,
-                    );
+                    Parser::maybe_report_invalid_custom_discriminants(self.parse_sess, &variants);
                 }
             }
 
@@ -471,7 +463,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             ast::ExprKind::Type(..) => {
                 // To avoid noise about type ascription in common syntax errors, only emit if it
                 // is the *only* error.
-                if self.context.parse_sess.span_diagnostic.err_count() == 0 {
+                if self.parse_sess.span_diagnostic.err_count() == 0 {
                     gate_feature_post!(&self, type_ascription, e.span,
                                        "type ascription is experimental");
                 }
@@ -809,13 +801,13 @@ pub fn check_crate(krate: &ast::Crate,
                    features: &Features,
                    unstable: UnstableFeatures) {
     maybe_stage_features(&parse_sess.span_diagnostic, krate, unstable);
-    let ctx = Context { parse_sess, features };
+    let mut visitor = PostExpansionVisitor { parse_sess, features };
 
     macro_rules! gate_all {
         ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); };
         ($spans:ident, $gate:ident, $msg:literal) => {
             for span in &*parse_sess.gated_spans.$spans.borrow() {
-                gate_feature!(&ctx, $gate, *span, $msg);
+                gate_feature!(&visitor, $gate, *span, $msg);
             }
         }
     }
@@ -826,7 +818,7 @@ pub fn check_crate(krate: &ast::Crate,
     gate_all!(yields, generators, "yield syntax is experimental");
     gate_all!(or_patterns, "or-patterns syntax is experimental");
 
-    visit::walk_crate(&mut PostExpansionVisitor { context: &ctx }, krate);
+    visit::walk_crate(&mut visitor, krate);
 }
 
 #[derive(Clone, Copy, Hash)]

From f6a5b29d197ba3f64007e51b948b427232173f2f Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sat, 14 Sep 2019 22:36:58 +0300
Subject: [PATCH 743/943] resolve: Tweak some expected/found wording

---
 src/librustc_resolve/macros.rs               | 5 +++--
 src/test/ui/issues/issue-49934-errors.rs     | 4 ++--
 src/test/ui/issues/issue-49934-errors.stderr | 4 ++--
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index bd8b5e13c6205..9096d14645100 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -237,7 +237,8 @@ impl<'a> base::Resolver for Resolver<'a> {
                 if let Res::Def(..) = res {
                     self.session.span_err(
                         span,
-                        "expected an inert attribute, found an attribute macro"
+                        &format!("expected an inert attribute, found {} {}",
+                                 res.article(), res.descr()),
                     );
                     return Ok(InvocationRes::Single(self.dummy_ext(kind)));
                 }
@@ -322,7 +323,7 @@ impl<'a> Resolver<'a> {
         self.check_stability_and_deprecation(&ext, path);
 
         Ok(if ext.macro_kind() != kind {
-            let expected = if kind == MacroKind::Attr { "attribute" } else  { kind.descr() };
+            let expected = if kind == MacroKind::Attr { "attribute" } else { kind.descr() };
             let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path);
             self.session.struct_span_err(path.span, &msg)
                         .span_label(path.span, format!("not {} {}", kind.article(), expected))
diff --git a/src/test/ui/issues/issue-49934-errors.rs b/src/test/ui/issues/issue-49934-errors.rs
index 58f64d137b9f9..6fa5f01ffd926 100644
--- a/src/test/ui/issues/issue-49934-errors.rs
+++ b/src/test/ui/issues/issue-49934-errors.rs
@@ -1,10 +1,10 @@
 fn foo<#[derive(Debug)] T>() {
 //~^ ERROR `derive` may only be applied to structs, enums and unions
-//~| ERROR expected an inert attribute, found an attribute macro
+//~| ERROR expected an inert attribute, found a derive macro
     match 0 {
         #[derive(Debug)]
         //~^ ERROR `derive` may only be applied to structs, enums and unions
-        //~| ERROR expected an inert attribute, found an attribute macro
+        //~| ERROR expected an inert attribute, found a derive macro
         _ => (),
     }
 }
diff --git a/src/test/ui/issues/issue-49934-errors.stderr b/src/test/ui/issues/issue-49934-errors.stderr
index fce1f65881266..8778d88d0ebec 100644
--- a/src/test/ui/issues/issue-49934-errors.stderr
+++ b/src/test/ui/issues/issue-49934-errors.stderr
@@ -4,7 +4,7 @@ error: `derive` may only be applied to structs, enums and unions
 LL | fn foo<#[derive(Debug)] T>() {
    |        ^^^^^^^^^^^^^^^^
 
-error: expected an inert attribute, found an attribute macro
+error: expected an inert attribute, found a derive macro
   --> $DIR/issue-49934-errors.rs:1:17
    |
 LL | fn foo<#[derive(Debug)] T>() {
@@ -16,7 +16,7 @@ error: `derive` may only be applied to structs, enums and unions
 LL |         #[derive(Debug)]
    |         ^^^^^^^^^^^^^^^^
 
-error: expected an inert attribute, found an attribute macro
+error: expected an inert attribute, found a derive macro
   --> $DIR/issue-49934-errors.rs:5:18
    |
 LL |         #[derive(Debug)]

From 6e5ada43bf84b15a8dd4d55f5bee3ba1a9939bfe Mon Sep 17 00:00:00 2001
From: Tim Vermeulen <tvermeulen@me.com>
Date: Sat, 31 Aug 2019 23:00:15 +0200
Subject: [PATCH 744/943] Add cmp::{min_by, min_by_key, max_by, max_by_key}

---
 src/libcore/cmp.rs       | 90 +++++++++++++++++++++++++++++++++++++++-
 src/libcore/tests/cmp.rs | 24 ++++++++++-
 src/libcore/tests/lib.rs |  1 +
 3 files changed, 112 insertions(+), 3 deletions(-)

diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 7ec2295f97e36..4e2b1627e15ef 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -570,7 +570,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
     #[inline]
     fn max(self, other: Self) -> Self
     where Self: Sized {
-        if other >= self { other } else { self }
+        max_by(self, other, Ord::cmp)
     }
 
     /// Compares and returns the minimum of two values.
@@ -587,7 +587,7 @@ pub trait Ord: Eq + PartialOrd<Self> {
     #[inline]
     fn min(self, other: Self) -> Self
     where Self: Sized {
-        if self <= other { self } else { other }
+        min_by(self, other, Ord::cmp)
     }
 
     /// Restrict a value to a certain interval.
@@ -898,6 +898,49 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
     v1.min(v2)
 }
 
+/// Returns the minimum of two values with respect to the specified comparison function.
+///
+/// Returns the first argument if the comparison determines them to be equal.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(cmp_min_max_by)]
+///
+/// use std::cmp;
+///
+/// assert_eq!(cmp::min_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 1);
+/// assert_eq!(cmp::min_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
+/// ```
+#[inline]
+#[unstable(feature = "cmp_min_max_by", issue = "64460")]
+pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
+    match compare(&v1, &v2) {
+        Ordering::Less | Ordering::Equal => v1,
+        Ordering::Greater => v2,
+    }
+}
+
+/// Returns the element that gives the minimum value from the specified function.
+///
+/// Returns the first argument if the comparison determines them to be equal.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(cmp_min_max_by)]
+///
+/// use std::cmp;
+///
+/// assert_eq!(cmp::min_by_key(-2, 1, |x: &i32| x.abs()), 1);
+/// assert_eq!(cmp::min_by_key(-2, 2, |x: &i32| x.abs()), -2);
+/// ```
+#[inline]
+#[unstable(feature = "cmp_min_max_by", issue = "64460")]
+pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
+    min_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
+}
+
 /// Compares and returns the maximum of two values.
 ///
 /// Returns the second argument if the comparison determines them to be equal.
@@ -918,6 +961,49 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
     v1.max(v2)
 }
 
+/// Returns the maximum of two values with respect to the specified comparison function.
+///
+/// Returns the second argument if the comparison determines them to be equal.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(cmp_min_max_by)]
+///
+/// use std::cmp;
+///
+/// assert_eq!(cmp::max_by(-2, 1, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), -2);
+/// assert_eq!(cmp::max_by(-2, 2, |x: &i32, y: &i32| x.abs().cmp(&y.abs())), 2);
+/// ```
+#[inline]
+#[unstable(feature = "cmp_min_max_by", issue = "64460")]
+pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
+    match compare(&v1, &v2) {
+        Ordering::Less | Ordering::Equal => v2,
+        Ordering::Greater => v1,
+    }
+}
+
+/// Returns the element that gives the maximum value from the specified function.
+///
+/// Returns the second argument if the comparison determines them to be equal.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(cmp_min_max_by)]
+///
+/// use std::cmp;
+///
+/// assert_eq!(cmp::max_by_key(-2, 1, |x: &i32| x.abs()), -2);
+/// assert_eq!(cmp::max_by_key(-2, 2, |x: &i32| x.abs()), 2);
+/// ```
+#[inline]
+#[unstable(feature = "cmp_min_max_by", issue = "64460")]
+pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
+    max_by(v1, v2, |v1, v2| f(v1).cmp(&f(v2)))
+}
+
 // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
 mod impls {
     use crate::cmp::Ordering::{self, Less, Greater, Equal};
diff --git a/src/libcore/tests/cmp.rs b/src/libcore/tests/cmp.rs
index 4e624e5eb126e..5e6778e222a29 100644
--- a/src/libcore/tests/cmp.rs
+++ b/src/libcore/tests/cmp.rs
@@ -1,4 +1,4 @@
-use core::cmp::Ordering::{Less, Greater, Equal};
+use core::cmp::{self, Ordering::*};
 
 #[test]
 fn test_int_totalord() {
@@ -28,6 +28,28 @@ fn test_ord_max_min() {
     assert_eq!(1.min(1), 1);
 }
 
+#[test]
+fn test_ord_min_max_by() {
+    let f = |x: &i32, y: &i32| x.abs().cmp(&y.abs());
+    assert_eq!(cmp::min_by(1, -1, f), 1);
+    assert_eq!(cmp::min_by(1, -2, f), 1);
+    assert_eq!(cmp::min_by(2, -1, f), -1);
+    assert_eq!(cmp::max_by(1, -1, f), -1);
+    assert_eq!(cmp::max_by(1, -2, f), -2);
+    assert_eq!(cmp::max_by(2, -1, f), 2);
+}
+
+#[test]
+fn test_ord_min_max_by_key() {
+    let f = |x: &i32| x.abs();
+    assert_eq!(cmp::min_by_key(1, -1, f), 1);
+    assert_eq!(cmp::min_by_key(1, -2, f), 1);
+    assert_eq!(cmp::min_by_key(2, -1, f), -1);
+    assert_eq!(cmp::max_by_key(1, -1, f), -1);
+    assert_eq!(cmp::max_by_key(1, -2, f), -2);
+    assert_eq!(cmp::max_by_key(2, -1, f), 2);
+}
+
 #[test]
 fn test_ordering_reverse() {
     assert_eq!(Less.reverse(), Greater);
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 050195cd2ef51..35661356028cb 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -34,6 +34,7 @@
 #![feature(iter_partition_in_place)]
 #![feature(iter_is_partitioned)]
 #![feature(iter_order_by)]
+#![feature(cmp_min_max_by)]
 
 extern crate test;
 

From 72175915d6ae5abbc45cf2860a90508d2b4a38ea Mon Sep 17 00:00:00 2001
From: Tim Vermeulen <tvermeulen@me.com>
Date: Sat, 14 Sep 2019 21:24:50 +0200
Subject: [PATCH 745/943] Simplify Iterator::{min_by, max_by} using
 cmp::{min_by, max_by}

---
 src/libcore/iter/traits/iterator.rs | 48 ++++++++++-------------------
 1 file changed, 17 insertions(+), 31 deletions(-)

diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs
index c09df3f7f22cb..da49223dfb285 100644
--- a/src/libcore/iter/traits/iterator.rs
+++ b/src/libcore/iter/traits/iterator.rs
@@ -1,4 +1,4 @@
-use crate::cmp::Ordering;
+use crate::cmp::{self, Ordering};
 use crate::ops::{Add, Try};
 
 use super::super::LoopState;
@@ -2223,13 +2223,12 @@ pub trait Iterator {
             move |x| (f(&x), x)
         }
 
-        // switch to y even if it is only equal, to preserve stability.
         #[inline]
-        fn select<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> bool {
-            x_p <= y_p
+        fn compare<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering {
+            x_p.cmp(y_p)
         }
 
-        let (_, x) = select_fold1(self.map(key(f)), select)?;
+        let (_, x) = self.map(key(f)).max_by(compare)?;
         Some(x)
     }
 
@@ -2252,13 +2251,12 @@ pub trait Iterator {
     fn max_by<F>(self, compare: F) -> Option<Self::Item>
         where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
     {
-        // switch to y even if it is only equal, to preserve stability.
         #[inline]
-        fn select<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(&T, &T) -> bool {
-            move |x, y| compare(x, y) != Ordering::Greater
+        fn fold<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T {
+            move |x, y| cmp::max_by(x, y, &mut compare)
         }
 
-        select_fold1(self, select(compare))
+        fold1(self, fold(compare))
     }
 
     /// Returns the element that gives the minimum value from the
@@ -2285,13 +2283,12 @@ pub trait Iterator {
             move |x| (f(&x), x)
         }
 
-        // only switch to y if it is strictly smaller, to preserve stability.
         #[inline]
-        fn select<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> bool {
-            x_p > y_p
+        fn compare<T, B: Ord>((x_p, _): &(B, T), (y_p, _): &(B, T)) -> Ordering {
+            x_p.cmp(y_p)
         }
 
-        let (_, x) = select_fold1(self.map(key(f)), select)?;
+        let (_, x) = self.map(key(f)).min_by(compare)?;
         Some(x)
     }
 
@@ -2314,13 +2311,12 @@ pub trait Iterator {
     fn min_by<F>(self, compare: F) -> Option<Self::Item>
         where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering,
     {
-        // only switch to y if it is strictly smaller, to preserve stability.
         #[inline]
-        fn select<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(&T, &T) -> bool {
-            move |x, y| compare(x, y) == Ordering::Greater
+        fn fold<T>(mut compare: impl FnMut(&T, &T) -> Ordering) -> impl FnMut(T, T) -> T {
+            move |x, y| cmp::min_by(x, y, &mut compare)
         }
 
-        select_fold1(self, select(compare))
+        fold1(self, fold(compare))
     }
 
 
@@ -2958,28 +2954,18 @@ pub trait Iterator {
     }
 }
 
-/// Select an element from an iterator based on the given "comparison"
-/// function.
-///
-/// This is an idiosyncratic helper to try to factor out the
-/// commonalities of {max,min}{,_by}. In particular, this avoids
-/// having to implement optimizations several times.
+/// Fold an iterator without having to provide an initial value.
 #[inline]
-fn select_fold1<I, F>(mut it: I, f: F) -> Option<I::Item>
+fn fold1<I, F>(mut it: I, f: F) -> Option<I::Item>
     where
         I: Iterator,
-        F: FnMut(&I::Item, &I::Item) -> bool,
+        F: FnMut(I::Item, I::Item) -> I::Item,
 {
-    #[inline]
-    fn select<T>(mut f: impl FnMut(&T, &T) -> bool) -> impl FnMut(T, T) -> T {
-        move |sel, x| if f(&sel, &x) { x } else { sel }
-    }
-
     // start with the first element as our selection. This avoids
     // having to use `Option`s inside the loop, translating to a
     // sizeable performance gain (6x in one case).
     let first = it.next()?;
-    Some(it.fold(first, select(f)))
+    Some(it.fold(first, f))
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]

From dab68131d314e6608c547311dfca1655ac8da886 Mon Sep 17 00:00:00 2001
From: Jonas Schievink <jonasschievink@gmail.com>
Date: Sat, 14 Sep 2019 23:02:22 +0200
Subject: [PATCH 746/943] Try to fix the test output normalization

---
 src/test/ui/proc-macro/invalid-punct-ident-1.rs | 10 +++++-----
 src/test/ui/proc-macro/invalid-punct-ident-2.rs | 10 +++++-----
 src/test/ui/proc-macro/invalid-punct-ident-3.rs | 10 +++++-----
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.rs b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
index 3b6498b4b0ee9..94a4b403d5a3f 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-1.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
@@ -3,11 +3,11 @@
 // FIXME https://github.com/rust-lang/rust/issues/59998
 // normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> ""
 // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
-// normalize-stderr-test "error: internal compiler error.*\n" -> ""
-// normalize-stderr-test "note:.*unexpectedly panicked.*\n" -> ""
-// normalize-stderr-test "note: we would appreciate a bug report.*\n" -> ""
-// normalize-stderr-test "note: compiler flags.*\n" -> ""
-// normalize-stderr-test "note: rustc.*running on.*\n" -> ""
+// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
 
 #[macro_use]
 extern crate invalid_punct_ident;
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-2.rs b/src/test/ui/proc-macro/invalid-punct-ident-2.rs
index ee57752e2be27..778b7eeecd7a9 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-2.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-2.rs
@@ -3,11 +3,11 @@
 // FIXME https://github.com/rust-lang/rust/issues/59998
 // normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> ""
 // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
-// normalize-stderr-test "error: internal compiler error.*\n" -> ""
-// normalize-stderr-test "note:.*unexpectedly panicked.*\n" -> ""
-// normalize-stderr-test "note: we would appreciate a bug report.*\n" -> ""
-// normalize-stderr-test "note: compiler flags.*\n" -> ""
-// normalize-stderr-test "note: rustc.*running on.*\n" -> ""
+// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
 
 #[macro_use]
 extern crate invalid_punct_ident;
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.rs b/src/test/ui/proc-macro/invalid-punct-ident-3.rs
index efcd6801ecbdd..f68ee3de7f456 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-3.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-3.rs
@@ -3,11 +3,11 @@
 // FIXME https://github.com/rust-lang/rust/issues/59998
 // normalize-stderr-test "thread.*panicked.*proc_macro_server.rs.*\n" -> ""
 // normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
-// normalize-stderr-test "error: internal compiler error.*\n" -> ""
-// normalize-stderr-test "note:.*unexpectedly panicked.*\n" -> ""
-// normalize-stderr-test "note: we would appreciate a bug report.*\n" -> ""
-// normalize-stderr-test "note: compiler flags.*\n" -> ""
-// normalize-stderr-test "note: rustc.*running on.*\n" -> ""
+// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
 
 #[macro_use]
 extern crate invalid_punct_ident;

From 30e39e871fa9064f310d05a295a6c197d9b0da78 Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Sat, 14 Sep 2019 20:53:42 +0200
Subject: [PATCH 747/943] save-analysis: Deduplicate lookup_{d,r}ef_id
 functions

---
 src/librustc_save_analysis/dump_visitor.rs | 11 ++++-------
 src/librustc_save_analysis/lib.rs          |  8 ++++----
 2 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index fb1003fd7055d..c43e07a8c7480 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -130,6 +130,10 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         self.save_ctxt.span_from_span(span)
     }
 
+    fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
+        self.save_ctxt.lookup_def_id(ref_id)
+    }
+
     pub fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) {
         let source_file = self.tcx.sess.local_crate_source_file.as_ref();
         let crate_root = source_file.map(|source_file| {
@@ -223,13 +227,6 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         }
     }
 
-    fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
-        match self.save_ctxt.get_path_res(ref_id) {
-            Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => None,
-            def => Some(def.def_id()),
-        }
-    }
-
     fn process_formals(&mut self, formals: &'l [ast::Param], qualname: &str) {
         for arg in formals {
             self.visit_pat(&arg.pat);
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 4bc098db68611..055ccf6c2c4f8 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -312,7 +312,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
                     let impl_id = self.next_impl_id();
                     let span = self.span_from_span(sub_span);
 
-                    let type_data = self.lookup_ref_id(typ.id);
+                    let type_data = self.lookup_def_id(typ.id);
                     type_data.map(|type_data| {
                         Data::RelationData(Relation {
                             kind: RelationKind::Impl {
@@ -322,7 +322,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
                             from: id_from_def_id(type_data),
                             to: trait_ref
                                 .as_ref()
-                                .and_then(|t| self.lookup_ref_id(t.ref_id))
+                                .and_then(|t| self.lookup_def_id(t.ref_id))
                                 .map(id_from_def_id)
                                 .unwrap_or_else(|| null_id()),
                         },
@@ -495,7 +495,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
     }
 
     pub fn get_trait_ref_data(&self, trait_ref: &ast::TraitRef) -> Option<Ref> {
-        self.lookup_ref_id(trait_ref.ref_id).and_then(|def_id| {
+        self.lookup_def_id(trait_ref.ref_id).and_then(|def_id| {
             let span = trait_ref.path.span;
             if generated_code(span) {
                 return None;
@@ -870,7 +870,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
         })
     }
 
-    fn lookup_ref_id(&self, ref_id: NodeId) -> Option<DefId> {
+    fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
         match self.get_path_res(ref_id) {
             Res::PrimTy(_) | Res::SelfTy(..) | Res::Err => None,
             def => Some(def.def_id()),

From a946b8d6e1ff39f22e3f9f1c46ba81898901d907 Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Sun, 15 Sep 2019 00:42:18 +0200
Subject: [PATCH 748/943] save-analysis: Process bounds in impl trait only in
 argument position

---
 src/librustc_save_analysis/dump_visitor.rs | 19 ++++++++++++++++++-
 src/test/ui/save-analysis/issue-63663.rs   | 11 ++++++++---
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index c43e07a8c7480..55f6b91e71431 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -385,7 +385,12 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
             }
 
             if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output {
-                v.visit_ty(&ret_ty);
+                if let ast::TyKind::ImplTrait(..) = ret_ty.node {
+                    // FIXME: Opaque type desugaring prevents us from easily
+                    // processing trait bounds. See `visit_ty` for more details.
+                } else {
+                    v.visit_ty(&ret_ty);
+                }
             }
 
             v.visit_block(&body);
@@ -1439,6 +1444,18 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
                 self.visit_ty(element);
                 self.nest_tables(length.id, |v| v.visit_expr(&length.value));
             }
+            ast::TyKind::ImplTrait(id, ref bounds) => {
+                // FIXME: As of writing, the opaque type lowering introduces
+                // another DefPath scope/segment (used to declare the resulting
+                // opaque type item).
+                // However, the synthetic scope does *not* have associated
+                // typeck tables, which means we can't nest it and we fire an
+                // assertion when resolving the qualified type paths in trait
+                // bounds...
+                // This will panic if called on return type `impl Trait`, which
+                // we guard against in `process_fn`.
+                self.nest_tables(id, |v| v.process_bounds(bounds));
+            }
             _ => visit::walk_ty(self, t),
         }
     }
diff --git a/src/test/ui/save-analysis/issue-63663.rs b/src/test/ui/save-analysis/issue-63663.rs
index ccbe13f1a1b71..92e85884f664d 100644
--- a/src/test/ui/save-analysis/issue-63663.rs
+++ b/src/test/ui/save-analysis/issue-63663.rs
@@ -1,15 +1,20 @@
 // check-pass
 // compile-flags: -Zsave-analysis
 
-// Check that this doesn't ICE when processing associated const in formal
-// argument and return type of functions defined inside function/method scope.
-
 pub trait Trait {
     type Assoc;
 }
 
 pub struct A;
 
+trait Generic<T> {}
+impl<T> Generic<T> for () {}
+
+// Don't ICE when resolving type paths in return type `impl Trait`
+fn assoc_in_opaque_type_bounds<U: Trait>() -> impl Generic<U::Assoc> {}
+
+// Check that this doesn't ICE when processing associated const in formal
+// argument and return type of functions defined inside function/method scope.
 pub fn func() {
     fn _inner1<U: Trait>(_: U::Assoc) {}
     fn _inner2<U: Trait>() -> U::Assoc { unimplemented!() }

From 1d33f06de80ce6b473460cdf87566d57f53a0b4e Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 14 Sep 2019 18:41:46 -0400
Subject: [PATCH 749/943] Don't mark expression with attributes as not needing
 parentheses

This is not perfectly correct as `#[attr] (5)` will still not lint, but
it does seem good enough, in particular as the parentheses in that case
are not unambiguously incorrect.
---
 src/librustc_lint/unused.rs                   |  3 +-
 .../ui/lint/issue-54538-unused-parens-lint.rs |  6 +++-
 .../issue-54538-unused-parens-lint.stderr     | 36 +++++++++----------
 3 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 561bf202dfeff..20c05800889cf 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -370,7 +370,8 @@ impl UnusedParens {
                                      right_pos: Option<BytePos>) {
         match value.node {
             ast::ExprKind::Paren(ref inner) => {
-                if !Self::is_expr_parens_necessary(inner, followed_by_block) {
+                if !Self::is_expr_parens_necessary(inner, followed_by_block) &&
+                    value.attrs.is_empty() {
                     let expr_text = if let Ok(snippet) = cx.sess().source_map()
                         .span_to_snippet(value.span) {
                             snippet
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
index 1d8cce5228116..7dcbdd0863cbd 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
@@ -1,4 +1,4 @@
-#![feature(box_patterns)]
+#![feature(box_patterns, stmt_expr_attributes)]
 
 #![feature(or_patterns)]
 //~^ WARN the feature `or_patterns` is incomplete
@@ -17,6 +17,10 @@ fn lint_on_top_level() {
     let _ = |(a): u8| 0; //~ ERROR unnecessary parentheses around pattern
 }
 
+fn _no_lint_attr() {
+    let _x = #[allow(dead_code)] (1 + 2);
+}
+
 // Don't lint in these cases (#64106).
 fn or_patterns_no_lint() {
     match Box::new(0) {
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
index 7d5e286416fe2..675dd4f07def6 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
@@ -49,109 +49,109 @@ LL |     let _ = |(a): u8| 0;
    |              ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:41:12
+  --> $DIR/issue-54538-unused-parens-lint.rs:45:12
    |
 LL |     if let (0 | 1) = 0 {}
    |            ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:42:13
+  --> $DIR/issue-54538-unused-parens-lint.rs:46:13
    |
 LL |     if let ((0 | 1),) = (0,) {}
    |             ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:43:13
+  --> $DIR/issue-54538-unused-parens-lint.rs:47:13
    |
 LL |     if let [(0 | 1)] = [0] {}
    |             ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:44:16
+  --> $DIR/issue-54538-unused-parens-lint.rs:48:16
    |
 LL |     if let 0 | (1 | 2) = 0 {}
    |                ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:46:15
+  --> $DIR/issue-54538-unused-parens-lint.rs:50:15
    |
 LL |     if let TS((0 | 1)) = TS(0) {}
    |               ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:48:20
+  --> $DIR/issue-54538-unused-parens-lint.rs:52:20
    |
 LL |     if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
    |                    ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:58:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:62:9
    |
 LL |         (_) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:59:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:63:9
    |
 LL |         (y) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:60:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:64:9
    |
 LL |         (ref r) => {}
    |         ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:61:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:65:9
    |
 LL |         (e @ 1...2) => {}
    |         ^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:67:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:71:9
    |
 LL |         (e @ &(1...2)) => {}
    |         ^^^^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:68:10
+  --> $DIR/issue-54538-unused-parens-lint.rs:72:10
    |
 LL |         &(_) => {}
    |          ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:79:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:83:9
    |
 LL |         (_) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:80:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:84:9
    |
 LL |         (y) => {}
    |         ^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:81:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:85:9
    |
 LL |         (ref r) => {}
    |         ^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:82:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:86:9
    |
 LL |         (e @ 1..=2) => {}
    |         ^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:88:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:92:9
    |
 LL |         (e @ &(1..=2)) => {}
    |         ^^^^^^^^^^^^^^ help: remove these parentheses
 
 error: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:89:10
+  --> $DIR/issue-54538-unused-parens-lint.rs:93:10
    |
 LL |         &(_) => {}
    |          ^^^ help: remove these parentheses

From 8ee77a268f1f90b6e99e31cd3c4d03f893b73a76 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Sat, 14 Sep 2019 19:51:40 -0300
Subject: [PATCH 750/943] Use try_fold instead of manually carrying an
 accumulator

---
 src/librustc_mir/interpret/operand.rs | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 06b7206f4292c..9ad1542905b68 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -477,7 +477,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
         use rustc::mir::PlaceBase;
 
-        let mut op = match &place.base {
+        let base_op = match &place.base {
             PlaceBase::Local(mir::RETURN_PLACE) =>
                 throw_unsup!(ReadFromReturnPointer),
             PlaceBase::Local(local) => {
@@ -497,9 +497,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             }
         };
 
-        for elem in place.projection.iter() {
-            op = self.operand_projection(op, elem)?
-        }
+        let op = place.projection.iter().try_fold(
+            base_op,
+            |op, elem| self.operand_projection(op, elem)
+        )?;
 
         trace!("eval_place_to_op: got {:?}", *op);
         Ok(op)

From 71d45499a5cf1556220769174424f9f1ad94e1f5 Mon Sep 17 00:00:00 2001
From: Guanqun Lu <guanqun.lu@gmail.com>
Date: Tue, 10 Sep 2019 22:18:24 +0800
Subject: [PATCH 751/943] simply the initialization

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

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 02e7d97ccdf7b..0799acc730bf7 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -400,7 +400,7 @@ pub struct UnsafetyState {
 
 impl UnsafetyState {
     pub fn function(unsafety: hir::Unsafety, def: hir::HirId) -> UnsafetyState {
-        UnsafetyState { def: def, unsafety: unsafety, unsafe_push_count: 0, from_fn: true }
+        UnsafetyState { def, unsafety, unsafe_push_count: 0, from_fn: true }
     }
 
     pub fn recurse(&mut self, blk: &hir::Block) -> UnsafetyState {

From a0e48b6d256368574aa130c55851ec18746d98a3 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 14 Sep 2019 17:53:14 -0400
Subject: [PATCH 752/943] Warn on no_start, crate_id attribute use

These attributes are now deprecated; they don't have any use anymore.
---
 src/librustc_lint/builtin.rs                  | 29 ++++++++++++++-----
 src/test/ui/attributes/item-attributes.rs     |  2 --
 .../issue-43106-gating-of-builtin-attrs.rs    |  4 +--
 ...issue-43106-gating-of-builtin-attrs.stderr | 14 +++++++++
 src/test/ui/issues/issue-1251.rs              |  2 --
 src/test/ui/issues/issue-6919.rs              |  1 -
 6 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index aecf5c5b52dba..cf19a9eb147a8 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -669,6 +669,22 @@ impl DeprecatedAttr {
     }
 }
 
+fn lint_deprecated_attr(
+    cx: &EarlyContext<'_>,
+    attr: &ast::Attribute,
+    msg: &str,
+    suggestion: Option<&str>,
+) {
+    cx.struct_span_lint(DEPRECATED, attr.span, &msg)
+        .span_suggestion_short(
+            attr.span,
+            suggestion.unwrap_or("remove this attribute"),
+            String::new(),
+            Applicability::MachineApplicable
+        )
+        .emit();
+}
+
 impl EarlyLintPass for DeprecatedAttr {
     fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) {
         for &&(n, _, _, ref g) in &self.depr_attrs {
@@ -679,18 +695,15 @@ impl EarlyLintPass for DeprecatedAttr {
                                              _) = g {
                     let msg = format!("use of deprecated attribute `{}`: {}. See {}",
                                       name, reason, link);
-                    let mut err = cx.struct_span_lint(DEPRECATED, attr.span, &msg);
-                    err.span_suggestion_short(
-                        attr.span,
-                        suggestion.unwrap_or("remove this attribute"),
-                        String::new(),
-                        Applicability::MachineApplicable
-                    );
-                    err.emit();
+                    lint_deprecated_attr(cx, attr, &msg, suggestion);
                 }
                 return;
             }
         }
+        if attr.check_name(sym::no_start) || attr.check_name(sym::crate_id) {
+            let msg = format!("use of deprecated attribute `{}`: no longer used.", attr.path);
+            lint_deprecated_attr(cx, attr, &msg, None);
+        }
     }
 }
 
diff --git a/src/test/ui/attributes/item-attributes.rs b/src/test/ui/attributes/item-attributes.rs
index c760a28ecf0ba..79cd0f5fbc358 100644
--- a/src/test/ui/attributes/item-attributes.rs
+++ b/src/test/ui/attributes/item-attributes.rs
@@ -11,8 +11,6 @@
 #![rustc_dummy]
 #![rustc_dummy(attr5)]
 
-#![crate_id="foobar#0.1"]
-
 // These are attributes of the following mod
 #[rustc_dummy = "val"]
 #[rustc_dummy = "val"]
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
index 6d51bb3f8ada8..68ff95e420895 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs
@@ -84,12 +84,12 @@
 #![crate_name = "0900"]
 #![crate_type = "bin"] // cannot pass "0800" here
 
-// For #![crate_id], see issue #43142. (I cannot bear to enshrine current behavior in a test)
+#![crate_id = "10"] //~ WARN use of deprecated attribute
 
 // FIXME(#44232) we should warn that this isn't used.
 #![feature(rust1)]
 
-// For #![no_start], see issue #43144. (I cannot bear to enshrine current behavior in a test)
+#![no_start] //~ WARN use of deprecated attribute
 
 // (cannot easily gating state of crate-level #[no_main]; but non crate-level is below at "0400")
 #![no_builtins]
diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
index 864df35a79fe3..b2a6018b5354d 100644
--- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
+++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr
@@ -186,6 +186,20 @@ LL |     mod inner { #![macro_escape] }
    |
    = help: consider an outer attribute, `#[macro_use]` mod ...
 
+warning: use of deprecated attribute `crate_id`: no longer used.
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:87:1
+   |
+LL | #![crate_id = "10"]
+   | ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
+   |
+   = note: `#[warn(deprecated)]` on by default
+
+warning: use of deprecated attribute `no_start`: no longer used.
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:92:1
+   |
+LL | #![no_start]
+   | ^^^^^^^^^^^^ help: remove this attribute
+
 warning: the feature `rust1` has been stable since 1.0.0 and no longer requires an attribute to enable
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:90:12
    |
diff --git a/src/test/ui/issues/issue-1251.rs b/src/test/ui/issues/issue-1251.rs
index 63b5a4dd1b31a..77278ecda6ecb 100644
--- a/src/test/ui/issues/issue-1251.rs
+++ b/src/test/ui/issues/issue-1251.rs
@@ -6,8 +6,6 @@
 
 #![feature(rustc_private)]
 
-#![crate_id="rust_get_test_int"]
-
 mod rustrt {
     extern crate libc;
 
diff --git a/src/test/ui/issues/issue-6919.rs b/src/test/ui/issues/issue-6919.rs
index 11aed12087313..6f1e1f97708ef 100644
--- a/src/test/ui/issues/issue-6919.rs
+++ b/src/test/ui/issues/issue-6919.rs
@@ -4,7 +4,6 @@
 
 // pretty-expanded FIXME #23616
 
-#![crate_id="issue-6919"]
 extern crate issue6919_3;
 
 pub fn main() {

From e8d2f629245f956ec63da04ca672f4cab3a928ef Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sat, 14 Sep 2019 21:10:12 +0100
Subject: [PATCH 753/943] Prefer `Symbol` to `Ident` when there's no sensible
 `Span`

---
 src/librustc_lint/unused.rs             | 17 +++++--------
 src/librustc_resolve/lib.rs             | 34 ++++++++++++-------------
 src/librustc_resolve/resolve_imports.rs | 10 +++++---
 3 files changed, 28 insertions(+), 33 deletions(-)

diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 561bf202dfeff..21ea4766d8e52 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -618,24 +618,19 @@ impl UnusedImportBraces {
             }
 
             // Trigger the lint if the nested item is a non-self single item
-            let node_ident;
-            match items[0].0.kind {
+            let node_name = match items[0].0.kind {
                 ast::UseTreeKind::Simple(rename, ..) => {
                     let orig_ident = items[0].0.prefix.segments.last().unwrap().ident;
                     if orig_ident.name == kw::SelfLower {
                         return;
                     }
-                    node_ident = rename.unwrap_or(orig_ident);
+                    rename.unwrap_or(orig_ident).name
                 }
-                ast::UseTreeKind::Glob => {
-                    node_ident = ast::Ident::from_str("*");
-                }
-                ast::UseTreeKind::Nested(_) => {
-                    return;
-                }
-            }
+                ast::UseTreeKind::Glob => Symbol::intern("*"),
+                ast::UseTreeKind::Nested(_) => return,
+            };
 
-            let msg = format!("braces around {} is unnecessary", node_ident.name);
+            let msg = format!("braces around {} is unnecessary", node_name);
             cx.span_lint(UNUSED_IMPORT_BRACES, item.span, &msg);
         }
     }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index f97fcb0a035a2..74f68e5147126 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -40,7 +40,7 @@ use rustc_metadata::cstore::CStore;
 use syntax::ext::hygiene::{ExpnId, Transparency, SyntaxContext};
 use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
 use syntax::ext::base::{SyntaxExtension, MacroKind, SpecialDerives};
-use syntax::symbol::{Symbol, kw, sym};
+use syntax::symbol::{kw, sym};
 
 use syntax::visit::{self, Visitor};
 use syntax::attr;
@@ -241,7 +241,7 @@ impl Segment {
 
     fn names_to_string(segments: &[Segment]) -> String {
         names_to_string(&segments.iter()
-                            .map(|seg| seg.ident)
+                            .map(|seg| seg.ident.name)
                             .collect::<Vec<_>>())
     }
 }
@@ -951,7 +951,7 @@ pub struct Resolver<'a> {
     struct_constructors: DefIdMap<(Res, ty::Visibility)>,
 
     /// Features enabled for this crate.
-    active_features: FxHashSet<Symbol>,
+    active_features: FxHashSet<Name>,
 
     /// Stores enum visibilities to properly build a reduced graph
     /// when visiting the correspondent variants.
@@ -1018,8 +1018,8 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
     fn resolve_str_path(
         &mut self,
         span: Span,
-        crate_root: Option<Symbol>,
-        components: &[Symbol],
+        crate_root: Option<Name>,
+        components: &[Name],
         ns: Namespace,
     ) -> (ast::Path, Res) {
         let root = if crate_root.is_some() {
@@ -2555,7 +2555,7 @@ impl<'a> Resolver<'a> {
     fn add_suggestion_for_rename_of_use(
         &self,
         err: &mut DiagnosticBuilder<'_>,
-        name: Symbol,
+        name: Name,
         directive: &ImportDirective<'_>,
         binding_span: Span,
     ) {
@@ -2770,22 +2770,22 @@ impl<'a> Resolver<'a> {
     }
 }
 
-fn names_to_string(idents: &[Ident]) -> String {
+fn names_to_string(names: &[Name]) -> String {
     let mut result = String::new();
-    for (i, ident) in idents.iter()
-                            .filter(|ident| ident.name != kw::PathRoot)
+    for (i, name) in names.iter()
+                            .filter(|name| **name != kw::PathRoot)
                             .enumerate() {
         if i > 0 {
             result.push_str("::");
         }
-        result.push_str(&ident.as_str());
+        result.push_str(&name.as_str());
     }
     result
 }
 
 fn path_names_to_string(path: &Path) -> String {
     names_to_string(&path.segments.iter()
-                        .map(|seg| seg.ident)
+                        .map(|seg| seg.ident.name)
                         .collect::<Vec<_>>())
 }
 
@@ -2793,15 +2793,14 @@ fn path_names_to_string(path: &Path) -> String {
 fn module_to_string(module: Module<'_>) -> Option<String> {
     let mut names = Vec::new();
 
-    fn collect_mod(names: &mut Vec<Ident>, module: Module<'_>) {
+    fn collect_mod(names: &mut Vec<Name>, module: Module<'_>) {
         if let ModuleKind::Def(.., name) = module.kind {
             if let Some(parent) = module.parent {
-                names.push(Ident::with_dummy_span(name));
+                names.push(name);
                 collect_mod(names, parent);
             }
         } else {
-            // danger, shouldn't be ident?
-            names.push(Ident::from_str("<opaque>"));
+            names.push(Name::intern("<opaque>"));
             collect_mod(names, module.parent.unwrap());
         }
     }
@@ -2810,9 +2809,8 @@ fn module_to_string(module: Module<'_>) -> Option<String> {
     if names.is_empty() {
         return None;
     }
-    Some(names_to_string(&names.into_iter()
-                        .rev()
-                        .collect::<Vec<_>>()))
+    names.reverse();
+    Some(names_to_string(&names))
 }
 
 #[derive(Copy, Clone, Debug)]
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index eb509f1a01d67..e77e8290f1faa 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -1433,15 +1433,17 @@ fn import_path_to_string(names: &[Ident],
     let global = !names.is_empty() && names[0].name == kw::PathRoot;
     if let Some(pos) = pos {
         let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] };
-        names_to_string(names)
+        names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>())
     } else {
         let names = if global { &names[1..] } else { names };
         if names.is_empty() {
             import_directive_subclass_to_string(subclass)
         } else {
-            format!("{}::{}",
-                    names_to_string(names),
-                    import_directive_subclass_to_string(subclass))
+            format!(
+                "{}::{}",
+                names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>()),
+                import_directive_subclass_to_string(subclass),
+            )
         }
     }
 }

From 57a45e9cbd951efd8224c3535431890b7bef9e6a Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sat, 14 Sep 2019 21:14:03 +0100
Subject: [PATCH 754/943] Avoid some unnecessary `&str` to `Ident` conversions

---
 src/librustc_metadata/cstore_impl.rs      |  3 ++-
 src/libsyntax/ext/build.rs                |  2 +-
 src/libsyntax_ext/deriving/generic/mod.rs |  2 +-
 src/libsyntax_ext/deriving/generic/ty.rs  | 26 +++++++++++------------
 src/libsyntax_ext/test_harness.rs         |  2 +-
 5 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index d6450f00c8b6a..a1e3bbcbf8ea9 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -444,7 +444,8 @@ impl cstore::CStore {
             .insert(local_span, (name.to_string(), data.get_span(id.index, sess)));
 
         LoadedMacro::MacroDef(ast::Item {
-            ident: ast::Ident::from_str(&name.as_str()),
+            // FIXME: cross-crate hygiene
+            ident: ast::Ident::with_dummy_span(name.as_symbol()),
             id: ast::DUMMY_NODE_ID,
             span: local_span,
             attrs: attrs.iter().cloned().collect(),
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 06a55316f31d6..eea66f9147d93 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -363,7 +363,7 @@ impl<'a> ExtCtxt<'a> {
         self.expr(sp, ast::ExprKind::Field(expr, ident.with_span_pos(sp)))
     }
     pub fn expr_tup_field_access(&self, sp: Span, expr: P<ast::Expr>, idx: usize) -> P<ast::Expr> {
-        let ident = Ident::from_str(&idx.to_string()).with_span_pos(sp);
+        let ident = Ident::new(sym::integer(idx), sp);
         self.expr(sp, ast::ExprKind::Field(expr, ident))
     }
     pub fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index c53fa7dc706e7..da16ee7a54434 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -237,7 +237,7 @@ pub struct MethodDef<'a> {
     /// Whether there is a self argument (outer Option) i.e., whether
     /// this is a static function, and whether it is a pointer (inner
     /// Option)
-    pub explicit_self: Option<Option<PtrTy<'a>>>,
+    pub explicit_self: Option<Option<PtrTy>>,
 
     /// Arguments other than the self argument
     pub args: Vec<(Ty<'a>, &'a str)>,
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index cb1c7b21fee0d..d47ef2c5d5959 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -13,9 +13,9 @@ use syntax_pos::symbol::kw;
 
 /// The types of pointers
 #[derive(Clone)]
-pub enum PtrTy<'a> {
+pub enum PtrTy {
     /// &'lifetime mut
-    Borrowed(Option<&'a str>, ast::Mutability),
+    Borrowed(Option<Ident>, ast::Mutability),
     /// *mut
     #[allow(dead_code)]
     Raw(ast::Mutability),
@@ -26,7 +26,7 @@ pub enum PtrTy<'a> {
 #[derive(Clone)]
 pub struct Path<'a> {
     path: Vec<&'a str>,
-    lifetime: Option<&'a str>,
+    lifetime: Option<Ident>,
     params: Vec<Box<Ty<'a>>>,
     kind: PathKind,
 }
@@ -46,7 +46,7 @@ impl<'a> Path<'a> {
         Path::new_(vec![path], None, Vec::new(), PathKind::Local)
     }
     pub fn new_<'r>(path: Vec<&'r str>,
-                    lifetime: Option<&'r str>,
+                    lifetime: Option<Ident>,
                     params: Vec<Box<Ty<'r>>>,
                     kind: PathKind)
                     -> Path<'r> {
@@ -99,7 +99,7 @@ impl<'a> Path<'a> {
 pub enum Ty<'a> {
     Self_,
     /// &/Box/ Ty
-    Ptr(Box<Ty<'a>>, PtrTy<'a>),
+    Ptr(Box<Ty<'a>>, PtrTy),
     /// mod::mod::Type<[lifetime], [Params...]>, including a plain type
     /// parameter, and things like `i32`
     Literal(Path<'a>),
@@ -107,14 +107,14 @@ pub enum Ty<'a> {
     Tuple(Vec<Ty<'a>>),
 }
 
-pub fn borrowed_ptrty<'r>() -> PtrTy<'r> {
+pub fn borrowed_ptrty() -> PtrTy {
     Borrowed(None, ast::Mutability::Immutable)
 }
 pub fn borrowed(ty: Box<Ty<'_>>) -> Ty<'_> {
     Ptr(ty, borrowed_ptrty())
 }
 
-pub fn borrowed_explicit_self<'r>() -> Option<Option<PtrTy<'r>>> {
+pub fn borrowed_explicit_self() -> Option<Option<PtrTy>> {
     Some(Some(borrowed_ptrty()))
 }
 
@@ -126,13 +126,11 @@ pub fn nil_ty<'r>() -> Ty<'r> {
     Tuple(Vec::new())
 }
 
-fn mk_lifetime(cx: &ExtCtxt<'_>, span: Span, lt: &Option<&str>) -> Option<ast::Lifetime> {
-    lt.map(|s|
-        cx.lifetime(span, Ident::from_str(s))
-    )
+fn mk_lifetime(cx: &ExtCtxt<'_>, span: Span, lt: &Option<Ident>) -> Option<ast::Lifetime> {
+    lt.map(|ident| cx.lifetime(span, ident))
 }
 
-fn mk_lifetimes(cx: &ExtCtxt<'_>, span: Span, lt: &Option<&str>) -> Vec<ast::Lifetime> {
+fn mk_lifetimes(cx: &ExtCtxt<'_>, span: Span, lt: &Option<Ident>) -> Vec<ast::Lifetime> {
     mk_lifetime(cx, span, lt).into_iter().collect()
 }
 
@@ -265,7 +263,7 @@ impl<'a> LifetimeBounds<'a> {
 
 pub fn get_explicit_self(cx: &ExtCtxt<'_>,
                          span: Span,
-                         self_ptr: &Option<PtrTy<'_>>)
+                         self_ptr: &Option<PtrTy>)
                          -> (P<Expr>, ast::ExplicitSelf) {
     // this constructs a fresh `self` path
     let self_path = cx.expr_self(span);
@@ -276,7 +274,7 @@ pub fn get_explicit_self(cx: &ExtCtxt<'_>,
                 respan(span,
                        match *ptr {
                            Borrowed(ref lt, mutbl) => {
-                               let lt = lt.map(|s| cx.lifetime(span, Ident::from_str(s)));
+                               let lt = lt.map(|s| cx.lifetime(span, s));
                                SelfKind::Region(lt, mutbl)
                            }
                            Raw(_) => {
diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index b93c11fad3823..257c967d0d02f 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -288,7 +288,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     // Honor the reexport_test_harness_main attribute
     let main_id = match cx.reexport_test_harness_main {
         Some(sym) => Ident::new(sym, sp.with_ctxt(SyntaxContext::root())),
-        None => Ident::from_str_and_span("main", sp),
+        None => Ident::new(sym::main, sp),
     };
 
     let main = P(ast::Item {

From 5ae3830d589ec75494ff26bd9c92e9f77e49173f Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sat, 14 Sep 2019 21:16:51 +0100
Subject: [PATCH 755/943] Give more `Idents` spans

---
 src/librustc/hir/lowering.rs                  |  2 +-
 src/libsyntax/ext/base.rs                     |  4 ++--
 src/libsyntax/ext/build.rs                    |  2 +-
 src/libsyntax/parse/parser/item.rs            |  2 +-
 src/libsyntax_ext/deriving/cmp/partial_ord.rs |  2 +-
 src/libsyntax_ext/deriving/debug.rs           |  8 +++----
 src/libsyntax_ext/deriving/decodable.rs       | 20 ++++++++++-------
 src/libsyntax_ext/deriving/encodable.rs       | 18 +++++++--------
 src/libsyntax_ext/deriving/generic/mod.rs     | 14 ++++++------
 src/libsyntax_ext/deriving/generic/ty.rs      |  4 ++--
 src/libsyntax_ext/env.rs                      |  4 ++--
 src/libsyntax_ext/format.rs                   | 22 +++++++++----------
 src/libsyntax_ext/global_allocator.rs         | 12 +++++-----
 src/libsyntax_ext/proc_macro_harness.rs       | 14 ++++++------
 src/libsyntax_ext/test.rs                     |  8 +++----
 src/libsyntax_ext/test_harness.rs             |  2 +-
 src/libsyntax_pos/symbol.rs                   |  2 +-
 17 files changed, 72 insertions(+), 68 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index b50cfa00f09ef..58789a10609b7 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -1316,7 +1316,7 @@ impl<'a> LoweringContext<'a> {
                             ImplTraitContext::Universal(in_band_ty_params),
                         );
                         // Set the name to `impl Bound1 + Bound2`.
-                        let ident = Ident::from_str(&pprust::ty_to_string(t)).with_span_pos(span);
+                        let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span);
                         in_band_ty_params.push(hir::GenericParam {
                             hir_id: self.lower_node_id(def_node_id),
                             name: ParamName::Plain(ident),
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 7759a985d6134..d3f6717ee875d 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -1081,8 +1081,8 @@ impl<'a> ExtCtxt<'a> {
     pub fn set_trace_macros(&mut self, x: bool) {
         self.ecfg.trace_mac = x
     }
-    pub fn ident_of(&self, st: &str) -> ast::Ident {
-        ast::Ident::from_str(st)
+    pub fn ident_of(&self, st: &str, sp: Span) -> ast::Ident {
+        ast::Ident::from_str_and_span(st, sp)
     }
     pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> {
         let def_site = self.with_def_site_ctxt(DUMMY_SP);
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index eea66f9147d93..f1d0e0b68f735 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -525,7 +525,7 @@ impl<'a> ExtCtxt<'a> {
         let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
         let err_path = self.path_global(sp, err);
 
-        let binding_variable = self.ident_of("__try_var");
+        let binding_variable = self.ident_of("__try_var", sp);
         let binding_pat = self.pat_ident(sp, binding_variable);
         let binding_expr = self.expr_ident(sp, binding_variable);
 
diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index baae6155f3478..cf196645e4f7b 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -1256,7 +1256,7 @@ impl<'a> Parser<'a> {
             for part in idents {
                 fixed_name.push_str(&format!("_{}", part.name));
             }
-            ident = Ident::from_str(&fixed_name).with_span_pos(fixed_name_sp);
+            ident = Ident::from_str_and_span(&fixed_name, fixed_name_sp);
 
             self.struct_span_err(fixed_name_sp, error_msg)
                 .span_label(fixed_name_sp, "dash-separated idents are not valid")
diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
index debdc300e6495..13d63aaf2a80c 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs
@@ -109,7 +109,7 @@ pub fn some_ordering_collapsed(
         GtOp => "gt",
         GeOp => "ge",
     };
-    cx.expr_method_call(span, lft, ast::Ident::from_str_and_span(op_str, span), vec![rgt])
+    cx.expr_method_call(span, lft, cx.ident_of(op_str, span), vec![rgt])
 }
 
 pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> P<Expr> {
diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs
index 781645a574e9a..088b61be8b81b 100644
--- a/src/libsyntax_ext/deriving/debug.rs
+++ b/src/libsyntax_ext/deriving/debug.rs
@@ -62,7 +62,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
     // We want to make sure we have the ctxt set so that we can use unstable methods
     let span = cx.with_def_site_ctxt(span);
     let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked));
-    let builder = Ident::from_str_and_span("debug_trait_builder", span);
+    let builder = cx.ident_of("debug_trait_builder", span);
     let builder_expr = cx.expr_ident(span, builder.clone());
 
     let fmt = substr.nonself_args[0].clone();
@@ -72,7 +72,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
         ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => {
             // tuple struct/"normal" variant
             let expr =
-                cx.expr_method_call(span, fmt, Ident::from_str("debug_tuple"), vec![name]);
+                cx.expr_method_call(span, fmt, cx.ident_of("debug_tuple", span), vec![name]);
             stmts.push(cx.stmt_let(span, true, builder, expr));
 
             for field in fields {
@@ -93,7 +93,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
         ast::VariantData::Struct(..) => {
             // normal struct/struct variant
             let expr =
-                cx.expr_method_call(span, fmt, Ident::from_str("debug_struct"), vec![name]);
+                cx.expr_method_call(span, fmt, cx.ident_of("debug_struct", span), vec![name]);
             stmts.push(cx.stmt_let(DUMMY_SP, true, builder, expr));
 
             for field in fields {
@@ -113,7 +113,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>
         }
     }
 
-    let expr = cx.expr_method_call(span, builder_expr, Ident::from_str("finish"), vec![]);
+    let expr = cx.expr_method_call(span, builder_expr, cx.ident_of("finish", span), vec![]);
 
     stmts.push(cx.stmt_expr(expr));
     let block = cx.block(span, stmts);
diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs
index d3d604b72521d..cde72abbdef6a 100644
--- a/src/libsyntax_ext/deriving/decodable.rs
+++ b/src/libsyntax_ext/deriving/decodable.rs
@@ -66,10 +66,14 @@ fn decodable_substructure(cx: &mut ExtCtxt<'_>,
                           krate: &str)
                           -> P<Expr> {
     let decoder = substr.nonself_args[0].clone();
-    let recurse = vec![cx.ident_of(krate), cx.ident_of("Decodable"), cx.ident_of("decode")];
+    let recurse = vec![
+        cx.ident_of(krate, trait_span),
+        cx.ident_of("Decodable", trait_span),
+        cx.ident_of("decode", trait_span),
+    ];
     let exprdecode = cx.expr_path(cx.path_global(trait_span, recurse));
     // throw an underscore in front to suppress unused variable warnings
-    let blkarg = cx.ident_of("_d");
+    let blkarg = cx.ident_of("_d", trait_span);
     let blkdecoder = cx.expr_ident(trait_span, blkarg);
 
     return match *substr.fields {
@@ -78,7 +82,7 @@ fn decodable_substructure(cx: &mut ExtCtxt<'_>,
                 Unnamed(ref fields, _) => fields.len(),
                 Named(ref fields) => fields.len(),
             };
-            let read_struct_field = cx.ident_of("read_struct_field");
+            let read_struct_field = cx.ident_of("read_struct_field", trait_span);
 
             let path = cx.path_ident(trait_span, substr.type_ident);
             let result =
@@ -94,17 +98,17 @@ fn decodable_substructure(cx: &mut ExtCtxt<'_>,
             let result = cx.expr_ok(trait_span, result);
             cx.expr_method_call(trait_span,
                                 decoder,
-                                cx.ident_of("read_struct"),
+                                cx.ident_of("read_struct", trait_span),
                                 vec![cx.expr_str(trait_span, substr.type_ident.name),
                                      cx.expr_usize(trait_span, nfields),
                                      cx.lambda1(trait_span, result, blkarg)])
         }
         StaticEnum(_, ref fields) => {
-            let variant = cx.ident_of("i");
+            let variant = cx.ident_of("i", trait_span);
 
             let mut arms = Vec::with_capacity(fields.len() + 1);
             let mut variants = Vec::with_capacity(fields.len());
-            let rvariant_arg = cx.ident_of("read_enum_variant_arg");
+            let rvariant_arg = cx.ident_of("read_enum_variant_arg", trait_span);
 
             for (i, &(ident, v_span, ref parts)) in fields.iter().enumerate() {
                 variants.push(cx.expr_str(v_span, ident.name));
@@ -132,11 +136,11 @@ fn decodable_substructure(cx: &mut ExtCtxt<'_>,
             let variant_vec = cx.expr_addr_of(trait_span, variant_vec);
             let result = cx.expr_method_call(trait_span,
                                              blkdecoder,
-                                             cx.ident_of("read_enum_variant"),
+                                             cx.ident_of("read_enum_variant", trait_span),
                                              vec![variant_vec, lambda]);
             cx.expr_method_call(trait_span,
                                 decoder,
-                                cx.ident_of("read_enum"),
+                                cx.ident_of("read_enum", trait_span),
                                 vec![cx.expr_str(trait_span, substr.type_ident.name),
                                      cx.lambda1(trait_span, result, blkarg)])
         }
diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs
index 8b18fb25e90c1..655d3bb7c4ab8 100644
--- a/src/libsyntax_ext/deriving/encodable.rs
+++ b/src/libsyntax_ext/deriving/encodable.rs
@@ -153,16 +153,16 @@ fn encodable_substructure(cx: &mut ExtCtxt<'_>,
                           -> P<Expr> {
     let encoder = substr.nonself_args[0].clone();
     // throw an underscore in front to suppress unused variable warnings
-    let blkarg = cx.ident_of("_e");
+    let blkarg = cx.ident_of("_e", trait_span);
     let blkencoder = cx.expr_ident(trait_span, blkarg);
     let fn_path = cx.expr_path(cx.path_global(trait_span,
-                                              vec![cx.ident_of(krate),
-                                                   cx.ident_of("Encodable"),
-                                                   cx.ident_of("encode")]));
+                                              vec![cx.ident_of(krate, trait_span),
+                                                   cx.ident_of("Encodable", trait_span),
+                                                   cx.ident_of("encode", trait_span)]));
 
     return match *substr.fields {
         Struct(_, ref fields) => {
-            let emit_struct_field = cx.ident_of("emit_struct_field");
+            let emit_struct_field = cx.ident_of("emit_struct_field", trait_span);
             let mut stmts = Vec::new();
             for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() {
                 let name = match name {
@@ -201,7 +201,7 @@ fn encodable_substructure(cx: &mut ExtCtxt<'_>,
 
             cx.expr_method_call(trait_span,
                                 encoder,
-                                cx.ident_of("emit_struct"),
+                                cx.ident_of("emit_struct", trait_span),
                                 vec![cx.expr_str(trait_span, substr.type_ident.name),
                                      cx.expr_usize(trait_span, fields.len()),
                                      blk])
@@ -214,7 +214,7 @@ fn encodable_substructure(cx: &mut ExtCtxt<'_>,
             // actually exist.
             let me = cx.stmt_let(trait_span, false, blkarg, encoder);
             let encoder = cx.expr_ident(trait_span, blkarg);
-            let emit_variant_arg = cx.ident_of("emit_enum_variant_arg");
+            let emit_variant_arg = cx.ident_of("emit_enum_variant_arg", trait_span);
             let mut stmts = Vec::new();
             if !fields.is_empty() {
                 let last = fields.len() - 1;
@@ -244,7 +244,7 @@ fn encodable_substructure(cx: &mut ExtCtxt<'_>,
             let name = cx.expr_str(trait_span, variant.ident.name);
             let call = cx.expr_method_call(trait_span,
                                            blkencoder,
-                                           cx.ident_of("emit_enum_variant"),
+                                           cx.ident_of("emit_enum_variant", trait_span),
                                            vec![name,
                                                 cx.expr_usize(trait_span, idx),
                                                 cx.expr_usize(trait_span, fields.len()),
@@ -252,7 +252,7 @@ fn encodable_substructure(cx: &mut ExtCtxt<'_>,
             let blk = cx.lambda1(trait_span, call, blkarg);
             let ret = cx.expr_method_call(trait_span,
                                           encoder,
-                                          cx.ident_of("emit_enum"),
+                                          cx.ident_of("emit_enum", trait_span),
                                           vec![cx.expr_str(trait_span ,substr.type_ident.name),
                                                blk]);
             cx.expr_block(cx.block(trait_span, vec![me, cx.stmt_expr(ret)]))
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index da16ee7a54434..aceee62e89b0c 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -843,7 +843,7 @@ impl<'a> MethodDef<'a> {
                                 -> P<Expr> {
         let substructure = Substructure {
             type_ident,
-            method_ident: cx.ident_of(self.name),
+            method_ident: cx.ident_of(self.name, trait_.span),
             self_args,
             nonself_args,
             fields,
@@ -890,7 +890,7 @@ impl<'a> MethodDef<'a> {
 
         for (ty, name) in self.args.iter() {
             let ast_ty = ty.to_ty(cx, trait_.span, type_ident, generics);
-            let ident = ast::Ident::from_str_and_span(name, trait_.span);
+            let ident = cx.ident_of(name, trait_.span);
             arg_tys.push((ident, ast_ty));
 
             let arg_expr = cx.expr_ident(trait_.span, ident);
@@ -938,7 +938,7 @@ impl<'a> MethodDef<'a> {
 
         let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident);
 
-        let method_ident = cx.ident_of(self.name);
+        let method_ident = cx.ident_of(self.name, trait_.span);
         let fn_decl = cx.fn_decl(args, ast::FunctionRetTy::Ty(ret_type));
         let body_block = cx.block_expr(body);
 
@@ -1201,7 +1201,7 @@ impl<'a> MethodDef<'a> {
             ).collect::<Vec<String>>();
 
         let self_arg_idents = self_arg_names.iter()
-            .map(|name| cx.ident_of(&name[..]))
+            .map(|name| cx.ident_of(name, sp))
             .collect::<Vec<ast::Ident>>();
 
         // The `vi_idents` will be bound, solely in the catch-all, to
@@ -1210,7 +1210,7 @@ impl<'a> MethodDef<'a> {
         let vi_idents = self_arg_names.iter()
             .map(|name| {
                 let vi_suffix = format!("{}_vi", &name[..]);
-                ast::Ident::from_str_and_span(&vi_suffix[..], trait_.span)
+                cx.ident_of(&vi_suffix[..], trait_.span)
             })
             .collect::<Vec<ast::Ident>>();
 
@@ -1389,7 +1389,7 @@ impl<'a> MethodDef<'a> {
 
                 let target_ty = cx.ty_ident(
                     sp,
-                    ast::Ident::from_str_and_span(target_type_name, sp),
+                    cx.ident_of(target_type_name, sp),
                 );
                 let variant_disr = cx.expr_cast(sp, variant_value, target_ty);
                 let let_stmt = cx.stmt_let(sp, false, ident, variant_disr);
@@ -1591,7 +1591,7 @@ impl<'a> TraitDef<'a> {
         let mut ident_exprs = Vec::new();
         for (i, struct_field) in struct_def.fields().iter().enumerate() {
             let sp = struct_field.span.with_ctxt(self.span.ctxt());
-            let ident = ast::Ident::from_str_and_span(&format!("{}_{}", prefix, i), self.span);
+            let ident = cx.ident_of(&format!("{}_{}", prefix, i), self.span);
             paths.push(ident.with_span_pos(sp));
             let val = cx.expr_path(cx.path_ident(sp, ident));
             let val = if use_temporaries {
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index d47ef2c5d5959..b341a07675206 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -72,7 +72,7 @@ impl<'a> Path<'a> {
                    self_ty: Ident,
                    self_generics: &Generics)
                    -> ast::Path {
-        let mut idents = self.path.iter().map(|s| Ident::from_str_and_span(*s, span)).collect();
+        let mut idents = self.path.iter().map(|s| cx.ident_of(*s, span)).collect();
         let lt = mk_lifetimes(cx, span, &self.lifetime);
         let tys: Vec<P<ast::Ty>> =
             self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
@@ -207,7 +207,7 @@ fn mk_ty_param(cx: &ExtCtxt<'_>,
             cx.trait_bound(path)
         })
         .collect();
-    cx.typaram(span, ast::Ident::from_str_and_span(name, span), attrs.to_owned(), bounds, None)
+    cx.typaram(span, cx.ident_of(name, span), attrs.to_owned(), bounds, None)
 }
 
 fn mk_generics(params: Vec<ast::GenericParam>, span: Span) -> Generics {
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 179b7fe00a97a..3b0ddeeea2d95 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -23,13 +23,13 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
     let sp = cx.with_legacy_ctxt(sp);
     let e = match env::var(&*var.as_str()) {
         Err(..) => {
-            let lt = cx.lifetime(sp, Ident::with_dummy_span(kw::StaticLifetime));
+            let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp));
             cx.expr_path(cx.path_all(sp,
                                      true,
                                      cx.std_path(&[sym::option, sym::Option, sym::None]),
                                      vec![GenericArg::Type(cx.ty_rptr(sp,
                                                      cx.ty_ident(sp,
-                                                                 Ident::with_dummy_span(sym::str)),
+                                                                 Ident::new(sym::str, sp)),
                                                      Some(lt),
                                                      ast::Mutability::Immutable))],
                                      vec![]))
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 5bfbdc999174d..46c7cbb83de90 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -486,7 +486,7 @@ impl<'a, 'b> Context<'a, 'b> {
         let sp = self.macsp;
         let count = |c, arg| {
             let mut path = Context::rtpath(self.ecx, "Count");
-            path.push(self.ecx.ident_of(c));
+            path.push(self.ecx.ident_of(c, sp));
             match arg {
                 Some(arg) => self.ecx.expr_call_global(sp, path, vec![arg]),
                 None => self.ecx.expr_path(self.ecx.path_global(sp, path)),
@@ -534,7 +534,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 let pos = {
                     let pos = |c, arg| {
                         let mut path = Context::rtpath(self.ecx, "Position");
-                        path.push(self.ecx.ident_of(c));
+                        path.push(self.ecx.ident_of(c, sp));
                         match arg {
                             Some(i) => {
                                 let arg = self.ecx.expr_usize(sp, i);
@@ -603,7 +603,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 let fill = self.ecx.expr_lit(sp, ast::LitKind::Char(fill));
                 let align = |name| {
                     let mut p = Context::rtpath(self.ecx, "Alignment");
-                    p.push(self.ecx.ident_of(name));
+                    p.push(self.ecx.ident_of(name, sp));
                     self.ecx.path_global(sp, p)
                 };
                 let align = match arg.format.align {
@@ -621,11 +621,11 @@ impl<'a, 'b> Context<'a, 'b> {
                     sp,
                     path,
                     vec![
-                        self.ecx.field_imm(sp, self.ecx.ident_of("fill"), fill),
-                        self.ecx.field_imm(sp, self.ecx.ident_of("align"), align),
-                        self.ecx.field_imm(sp, self.ecx.ident_of("flags"), flags),
-                        self.ecx.field_imm(sp, self.ecx.ident_of("precision"), prec),
-                        self.ecx.field_imm(sp, self.ecx.ident_of("width"), width),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("fill", sp), fill),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("align", sp), align),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("flags", sp), flags),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("precision", sp), prec),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("width", sp), width),
                     ],
                 );
 
@@ -634,8 +634,8 @@ impl<'a, 'b> Context<'a, 'b> {
                     sp,
                                           path,
                     vec![
-                        self.ecx.field_imm(sp, self.ecx.ident_of("position"), pos),
-                        self.ecx.field_imm(sp, self.ecx.ident_of("format"), fmt),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("position", sp), pos),
+                        self.ecx.field_imm(sp, self.ecx.ident_of("format", sp), fmt),
                     ],
                 ))
             }
@@ -653,7 +653,7 @@ impl<'a, 'b> Context<'a, 'b> {
         let mut heads = Vec::with_capacity(self.args.len());
 
         let names_pos: Vec<_> = (0..self.args.len())
-            .map(|i| ast::Ident::from_str_and_span(&format!("arg{}", i), self.macsp))
+            .map(|i| self.ecx.ident_of(&format!("arg{}", i), self.macsp))
             .collect();
 
         // First, build up the static array which will become our precompiled
diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs
index f4af1699cd683..c57e5eec0b6b8 100644
--- a/src/libsyntax_ext/global_allocator.rs
+++ b/src/libsyntax_ext/global_allocator.rs
@@ -43,7 +43,7 @@ pub fn expand(
     let const_ty = ecx.ty(span, TyKind::Tup(Vec::new()));
     let const_body = ecx.expr_block(ecx.block(span, stmts));
     let const_item =
-        ecx.item_const(span, Ident::with_dummy_span(kw::Underscore), const_ty, const_body);
+        ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body);
 
     // Return the original item and the new methods.
     vec![Annotatable::Item(item), Annotatable::Item(const_item)]
@@ -61,7 +61,7 @@ impl AllocFnFactory<'_, '_> {
         let mut abi_args = Vec::new();
         let mut i = 0;
         let ref mut mk = || {
-            let name = Ident::from_str(&format!("arg{}", i));
+            let name = self.cx.ident_of(&format!("arg{}", i), self.span);
             i += 1;
             name
         };
@@ -83,7 +83,7 @@ impl AllocFnFactory<'_, '_> {
         );
         let item = self.cx.item(
             self.span,
-            Ident::from_str(&self.kind.fn_name(method.name)),
+            self.cx.ident_of(&self.kind.fn_name(method.name), self.span),
             self.attrs(),
             kind,
         );
@@ -119,7 +119,7 @@ impl AllocFnFactory<'_, '_> {
     ) -> P<Expr> {
         match *ty {
             AllocatorTy::Layout => {
-                let usize = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::usize));
+                let usize = self.cx.path_ident(self.span, Ident::new(sym::usize, self.span));
                 let ty_usize = self.cx.ty_path(usize);
                 let size = ident();
                 let align = ident();
@@ -177,12 +177,12 @@ impl AllocFnFactory<'_, '_> {
     }
 
     fn usize(&self) -> P<Ty> {
-        let usize = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::usize));
+        let usize = self.cx.path_ident(self.span, Ident::new(sym::usize, self.span));
         self.cx.ty_path(usize)
     }
 
     fn ptr_u8(&self) -> P<Ty> {
-        let u8 = self.cx.path_ident(self.span, Ident::with_dummy_span(sym::u8));
+        let u8 = self.cx.path_ident(self.span, Ident::new(sym::u8, self.span));
         let ty_u8 = self.cx.ty_path(u8);
         self.cx.ty_ptr(self.span, ty_u8, Mutability::Mutable)
     }
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index 31d32d23a645e..a5dcfb9840aca 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -340,12 +340,12 @@ fn mk_decls(
                         Vec::new(),
                         ast::ItemKind::ExternCrate(None));
 
-    let bridge = Ident::from_str_and_span("bridge", span);
-    let client = Ident::from_str_and_span("client", span);
-    let proc_macro_ty = Ident::from_str_and_span("ProcMacro", span);
-    let custom_derive = Ident::from_str_and_span("custom_derive", span);
-    let attr = Ident::from_str_and_span("attr", span);
-    let bang = Ident::from_str_and_span("bang", span);
+    let bridge = cx.ident_of("bridge", span);
+    let client = cx.ident_of("client", span);
+    let proc_macro_ty = cx.ident_of("ProcMacro", span);
+    let custom_derive = cx.ident_of("custom_derive", span);
+    let attr = cx.ident_of("attr", span);
+    let bang = cx.ident_of("bang", span);
 
     let decls = {
         let local_path = |sp: Span, name| {
@@ -378,7 +378,7 @@ fn mk_decls(
 
     let decls_static = cx.item_static(
         span,
-        Ident::from_str_and_span("_DECLS", span),
+        cx.ident_of("_DECLS", span),
         cx.ty_rptr(span,
             cx.ty(span, ast::TyKind::Slice(
                 cx.ty_path(cx.path(span,
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index be5aca73f5cb1..0910c00a8a2a9 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -98,20 +98,20 @@ pub fn expand_test_or_bench(
 
     // creates test::$name
     let test_path = |name| {
-        cx.path(sp, vec![test_id, cx.ident_of(name)])
+        cx.path(sp, vec![test_id, cx.ident_of(name, sp)])
     };
 
     // creates test::ShouldPanic::$name
     let should_panic_path = |name| {
-        cx.path(sp, vec![test_id, cx.ident_of("ShouldPanic"), cx.ident_of(name)])
+        cx.path(sp, vec![test_id, cx.ident_of("ShouldPanic", sp), cx.ident_of(name, sp)])
     };
 
     // creates $name: $expr
-    let field = |name, expr| cx.field_imm(sp, cx.ident_of(name), expr);
+    let field = |name, expr| cx.field_imm(sp, cx.ident_of(name, sp), expr);
 
     let test_fn = if is_bench {
         // A simple ident for a lambda
-        let b = ast::Ident::from_str_and_span("b", attr_sp);
+        let b = cx.ident_of("b", attr_sp);
 
         cx.expr_call(sp, cx.expr_path(test_path("StaticBenchFn")), vec![
             // |b| self::test::assert_test_result(
diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs
index 257c967d0d02f..56de0c97f81c0 100644
--- a/src/libsyntax_ext/test_harness.rs
+++ b/src/libsyntax_ext/test_harness.rs
@@ -250,7 +250,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
 
     // test::test_main_static(...)
     let mut test_runner = cx.test_runner.clone().unwrap_or(
-        ecx.path(sp, vec![test_id, Ident::from_str_and_span("test_main_static", sp)]));
+        ecx.path(sp, vec![test_id, ecx.ident_of("test_main_static", sp)]));
 
     test_runner.span = sp;
 
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index ab32d4461ef87..597ae83572cee 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -765,7 +765,7 @@ impl Ident {
         Ident::with_dummy_span(string.as_symbol())
     }
 
-    /// Maps a string to an identifier with an empty span.
+    /// Maps a string to an identifier with a dummy span.
     pub fn from_str(string: &str) -> Ident {
         Ident::with_dummy_span(Symbol::intern(string))
     }

From 8ab67c8f560a730b8978f4a42deb70d01ca1cdfc Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sat, 14 Sep 2019 21:17:11 +0100
Subject: [PATCH 756/943] Remove `with_legacy_ctxt`

---
 src/libsyntax/ext/base.rs                 |  7 -----
 src/libsyntax_ext/asm.rs                  |  2 +-
 src/libsyntax_ext/assert.rs               |  4 ++-
 src/libsyntax_ext/cfg.rs                  |  2 +-
 src/libsyntax_ext/concat.rs               |  2 +-
 src/libsyntax_ext/concat_idents.rs        |  2 +-
 src/libsyntax_ext/env.rs                  |  2 +-
 src/libsyntax_ext/global_allocator.rs     |  2 +-
 src/libsyntax_ext/global_asm.rs           |  2 +-
 src/libsyntax_pos/lib.rs                  |  7 -----
 src/test/ui/allocator/hygiene.rs          | 31 +++++++++++++++++++++++
 src/test/ui/syntax-extension-minor.rs     |  6 ++---
 src/test/ui/syntax-extension-minor.stderr |  9 -------
 13 files changed, 44 insertions(+), 34 deletions(-)
 create mode 100644 src/test/ui/allocator/hygiene.rs
 delete mode 100644 src/test/ui/syntax-extension-minor.stderr

diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index d3f6717ee875d..384c0555c85bd 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -977,13 +977,6 @@ impl<'a> ExtCtxt<'a> {
         span.with_call_site_ctxt(self.current_expansion.id)
     }
 
-    /// Span with a context reproducing `macro_rules` hygiene (hygienic locals, unhygienic items).
-    /// FIXME: This should be eventually replaced either with `with_def_site_ctxt` (preferably),
-    /// or with `with_call_site_ctxt` (where necessary).
-    pub fn with_legacy_ctxt(&self, span: Span) -> Span {
-        span.with_legacy_ctxt(self.current_expansion.id)
-    }
-
     /// Returns span for the macro which originally caused the current expansion to happen.
     ///
     /// Stops backtracing at include! boundary.
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 328b307361d9e..75d727b9fb60b 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -62,7 +62,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
     MacEager::expr(P(ast::Expr {
         id: ast::DUMMY_NODE_ID,
         node: ast::ExprKind::InlineAsm(P(inline_asm)),
-        span: cx.with_legacy_ctxt(sp),
+        span: cx.with_def_site_ctxt(sp),
         attrs: ThinVec::new(),
     }))
 }
diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs
index 001996e1db718..cbfe14fa439be 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -23,7 +23,9 @@ pub fn expand_assert<'cx>(
         }
     };
 
-    let sp = cx.with_legacy_ctxt(sp);
+    // `core::panic` and `std::panic` are different macros, so we use call-site
+    // context to pick up whichever is currently in scope.
+    let sp = cx.with_call_site_ctxt(sp);
     let panic_call = Mac {
         path: Path::from_ident(Ident::new(sym::panic, sp)),
         tts: custom_message.unwrap_or_else(|| {
diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs
index 0342e442df2e9..3c33baf95a597 100644
--- a/src/libsyntax_ext/cfg.rs
+++ b/src/libsyntax_ext/cfg.rs
@@ -16,7 +16,7 @@ pub fn expand_cfg(
     sp: Span,
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
-    let sp = cx.with_legacy_ctxt(sp);
+    let sp = cx.with_def_site_ctxt(sp);
 
     match parse_cfg(cx, sp, tts) {
         Ok(cfg) => {
diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs
index fc56dff65e4e2..16f016036ea5e 100644
--- a/src/libsyntax_ext/concat.rs
+++ b/src/libsyntax_ext/concat.rs
@@ -59,6 +59,6 @@ pub fn expand_concat(
     } else if has_errors {
         return DummyResult::any(sp);
     }
-    let sp = cx.with_legacy_ctxt(sp);
+    let sp = cx.with_def_site_ctxt(sp);
     base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
 }
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index 6391b62b58dc9..f344706d4ebf5 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -39,7 +39,7 @@ pub fn expand_concat_idents<'cx>(cx: &'cx mut ExtCtxt<'_>,
         }
     }
 
-    let ident = ast::Ident::new(Symbol::intern(&res_str), cx.with_legacy_ctxt(sp));
+    let ident = ast::Ident::new(Symbol::intern(&res_str), cx.with_call_site_ctxt(sp));
 
     struct ConcatIdentsResult { ident: ast::Ident }
 
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 3b0ddeeea2d95..70e1fbe6af78a 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -20,7 +20,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
         Some(v) => v,
     };
 
-    let sp = cx.with_legacy_ctxt(sp);
+    let sp = cx.with_def_site_ctxt(sp);
     let e = match env::var(&*var.as_str()) {
         Err(..) => {
             let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp));
diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs
index c57e5eec0b6b8..19a87e6dc6d74 100644
--- a/src/libsyntax_ext/global_allocator.rs
+++ b/src/libsyntax_ext/global_allocator.rs
@@ -28,7 +28,7 @@ pub fn expand(
     };
 
     // Generate a bunch of new items using the AllocFnFactory
-    let span = ecx.with_legacy_ctxt(item.span);
+    let span = ecx.with_def_site_ctxt(item.span);
     let f = AllocFnFactory {
         span,
         kind: AllocatorKind::Global,
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index 6140f0df58af9..c56b3f3fc808f 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -30,7 +30,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                 id: ast::DUMMY_NODE_ID,
                 node: ast::ItemKind::GlobalAsm(P(global_asm)),
                 vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited),
-                span: cx.with_legacy_ctxt(sp),
+                span: cx.with_def_site_ctxt(sp),
                 tokens: None,
             })])
         }
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 9a296f17aaf4a..ca177eb4a3616 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -526,13 +526,6 @@ impl Span {
         self.with_ctxt_from_mark(expn_id, Transparency::Transparent)
     }
 
-    /// Span with a context reproducing `macro_rules` hygiene (hygienic locals, unhygienic items).
-    /// FIXME: This should be eventually replaced either with `with_def_site_ctxt` (preferably),
-    /// or with `with_call_site_ctxt` (where necessary).
-    pub fn with_legacy_ctxt(&self, expn_id: ExpnId) -> Span {
-        self.with_ctxt_from_mark(expn_id, Transparency::SemiTransparent)
-    }
-
     /// Produces a span with the same location as `self` and context produced by a macro with the
     /// given ID and transparency, assuming that macro was defined directly and not produced by
     /// some other macro (which is the case for built-in and procedural macros).
diff --git a/src/test/ui/allocator/hygiene.rs b/src/test/ui/allocator/hygiene.rs
new file mode 100644
index 0000000000000..9bd8406a27608
--- /dev/null
+++ b/src/test/ui/allocator/hygiene.rs
@@ -0,0 +1,31 @@
+// run-pass
+// no-prefer-dynamic
+// aux-build:custom.rs
+// aux-build:helper.rs
+
+#![allow(nonstandard_style)]
+
+extern crate custom;
+extern crate helper;
+
+use custom::A;
+use std::sync::atomic::{AtomicUsize, Ordering};
+
+#[allow(dead_code)]
+struct u8;
+#[allow(dead_code)]
+struct usize;
+#[allow(dead_code)]
+static arg0: () = ();
+
+#[global_allocator]
+pub static GLOBAL: A = A(AtomicUsize::new(0));
+
+fn main() {
+    let n = GLOBAL.0.load(Ordering::SeqCst);
+    let s = Box::new(0);
+    helper::work_with(&s);
+    assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1);
+    drop(s);
+    assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
+}
diff --git a/src/test/ui/syntax-extension-minor.rs b/src/test/ui/syntax-extension-minor.rs
index 0206a769937e4..2d6710af39270 100644
--- a/src/test/ui/syntax-extension-minor.rs
+++ b/src/test/ui/syntax-extension-minor.rs
@@ -1,3 +1,5 @@
+// run-pass
+
 #![feature(concat_idents)]
 
 pub fn main() {
@@ -5,10 +7,8 @@ pub fn main() {
     let _: concat_idents!(F, oo) = Foo; // Test that `concat_idents!` can be used in type positions
 
     let asdf_fdsa = "<.<".to_string();
-    // this now fails (correctly, I claim) because hygiene prevents
-    // the assembled identifier from being a reference to the binding.
+    // concat_idents should have call-site hygiene.
     assert!(concat_idents!(asd, f_f, dsa) == "<.<".to_string());
-    //~^ ERROR cannot find value `asdf_fdsa` in this scope
 
     assert_eq!(stringify!(use_mention_distinction), "use_mention_distinction");
 }
diff --git a/src/test/ui/syntax-extension-minor.stderr b/src/test/ui/syntax-extension-minor.stderr
deleted file mode 100644
index 2d8056da527c6..0000000000000
--- a/src/test/ui/syntax-extension-minor.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0425]: cannot find value `asdf_fdsa` in this scope
-  --> $DIR/syntax-extension-minor.rs:10:13
-   |
-LL |     assert!(concat_idents!(asd, f_f, dsa) == "<.<".to_string());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0425`.

From b4ef99f4a61aa14f860c37eecbd04791005effc2 Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sun, 14 Jul 2019 20:16:16 +0100
Subject: [PATCH 757/943] Print visibility of `macro` items

---
 src/libsyntax/ast.rs          | 2 +-
 src/libsyntax/print/pprust.rs | 8 ++++++--
 src/test/pretty/macro.rs      | 2 +-
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index bcbc0a19ce768..b634dcca7fca2 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -2387,7 +2387,7 @@ pub enum ItemKind {
     ),
     /// A macro invocation.
     ///
-    /// E.g., `macro_rules! foo { .. }` or `foo!(..)`.
+    /// E.g., `foo!(..)`.
     Mac(Mac),
 
     /// A macro definition.
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 5d8498f8b5d26..dd8c76342e35b 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1369,8 +1369,12 @@ impl<'a> State<'a> {
                 }
             }
             ast::ItemKind::MacroDef(ref macro_def) => {
-                let (kw, has_bang) =
-                    if macro_def.legacy { ("macro_rules", true) } else { ("macro", false) };
+                let (kw, has_bang) = if macro_def.legacy {
+                    ("macro_rules", true)
+                } else {
+                    self.print_visibility(&item.vis);
+                    ("macro", false)
+                };
                 self.print_mac_common(
                     Some(MacHeader::Keyword(kw)),
                     has_bang,
diff --git a/src/test/pretty/macro.rs b/src/test/pretty/macro.rs
index 39677d1dc2da3..1e1e1dbfb3ea5 100644
--- a/src/test/pretty/macro.rs
+++ b/src/test/pretty/macro.rs
@@ -2,6 +2,6 @@
 
 #![feature(decl_macro)]
 
-macro mac { ($ arg : expr) => { $ arg + $ arg } }
+pub(crate) macro mac { ($ arg : expr) => { $ arg + $ arg } }
 
 fn main() { }

From 42a19dde82a55b65f18566d54dbbb033a22e08d9 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sun, 15 Sep 2019 12:55:18 +0300
Subject: [PATCH 758/943] resolve: Tweak "cannot find" wording for attributes

---
 src/librustc_resolve/macros.rs                |  6 ++--
 src/libsyntax_pos/hygiene.rs                  |  7 ++++
 src/test/ui/attributes/obsolete-attr.rs       |  4 +--
 src/test/ui/attributes/obsolete-attr.stderr   |  4 +--
 src/test/ui/attributes/unknown-attr.rs        |  6 ++--
 src/test/ui/attributes/unknown-attr.stderr    |  6 ++--
 ...-attr-unknown-attribute-macro-expansion.rs |  2 +-
 ...r-unknown-attribute-macro-expansion.stderr |  2 +-
 .../cfg-generic-params.rs                     | 10 +++---
 .../cfg-generic-params.stderr                 | 10 +++---
 src/test/ui/custom_attribute.rs               |  6 ++--
 src/test/ui/custom_attribute.stderr           |  6 ++--
 .../feature-gate-custom_attribute.rs          | 26 +++++++-------
 .../feature-gate-custom_attribute.stderr      | 26 +++++++-------
 .../feature-gate-custom_attribute2.rs         | 34 +++++++++----------
 .../feature-gate-custom_attribute2.stderr     | 34 +++++++++----------
 .../feature-gates/feature-gate-rustc-attrs.rs |  2 +-
 .../feature-gate-rustc-attrs.stderr           |  2 +-
 src/test/ui/issues/issue-32655.rs             |  4 +--
 src/test/ui/issues/issue-32655.stderr         |  4 +--
 src/test/ui/issues/issue-49074.rs             |  2 +-
 src/test/ui/issues/issue-49074.stderr         |  2 +-
 src/test/ui/macros/macro-reexport-removed.rs  |  2 +-
 .../ui/macros/macro-reexport-removed.stderr   |  2 +-
 src/test/ui/proc-macro/derive-still-gated.rs  |  2 +-
 .../ui/proc-macro/derive-still-gated.stderr   |  2 +-
 .../proc-macro/macro-namespace-reserved-2.rs  |  2 +-
 .../macro-namespace-reserved-2.stderr         |  2 +-
 .../ui/proc-macro/proc-macro-attributes.rs    |  2 +-
 .../proc-macro/proc-macro-attributes.stderr   |  2 +-
 src/test/ui/proc-macro/resolve-error.rs       |  4 +--
 src/test/ui/proc-macro/resolve-error.stderr   |  4 +--
 .../ui/reserved/reserved-attr-on-macro.rs     |  2 +-
 .../ui/reserved/reserved-attr-on-macro.stderr |  2 +-
 src/test/ui/suggestions/attribute-typos.rs    |  6 ++--
 .../ui/suggestions/attribute-typos.stderr     |  6 ++--
 .../tool-attributes-misplaced-1.rs            |  2 +-
 .../tool-attributes-misplaced-1.stderr        |  2 +-
 38 files changed, 128 insertions(+), 121 deletions(-)

diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 9096d14645100..734ae8d94d86d 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -323,7 +323,7 @@ impl<'a> Resolver<'a> {
         self.check_stability_and_deprecation(&ext, path);
 
         Ok(if ext.macro_kind() != kind {
-            let expected = if kind == MacroKind::Attr { "attribute" } else { kind.descr() };
+            let expected = kind.descr_expected();
             let msg = format!("expected {}, found {} `{}`", expected, res.descr(), path);
             self.session.struct_span_err(path.span, &msg)
                         .span_label(path.span, format!("not {} {}", kind.article(), expected))
@@ -775,8 +775,8 @@ impl<'a> Resolver<'a> {
                 Err(..) => {
                     assert!(initial_binding.is_none());
                     let bang = if kind == MacroKind::Bang { "!" } else { "" };
-                    let msg =
-                        format!("cannot find {} `{}{}` in this scope", kind.descr(), ident, bang);
+                    let expected = kind.descr_expected();
+                    let msg = format!("cannot find {} `{}{}` in this scope", expected, ident, bang);
                     let mut err = self.session.struct_span_err(ident.span, &msg);
                     self.unresolved_macro_suggestions(&mut err, kind, &parent_scope, ident);
                     err.emit();
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index f0e7344c1b986..8971638d0ffe0 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -677,6 +677,13 @@ impl MacroKind {
         }
     }
 
+    pub fn descr_expected(self) -> &'static str {
+        match self {
+            MacroKind::Attr => "attribute",
+            _ => self.descr(),
+        }
+    }
+
     pub fn article(self) -> &'static str {
         match self {
             MacroKind::Attr => "an",
diff --git a/src/test/ui/attributes/obsolete-attr.rs b/src/test/ui/attributes/obsolete-attr.rs
index cf6dd338552b8..42f90eda166b6 100644
--- a/src/test/ui/attributes/obsolete-attr.rs
+++ b/src/test/ui/attributes/obsolete-attr.rs
@@ -1,9 +1,9 @@
 // Obsolete attributes fall back to unstable custom attributes.
 
 #[ab_isize="stdcall"] extern {}
-//~^ ERROR cannot find attribute macro `ab_isize` in this scope
+//~^ ERROR cannot find attribute `ab_isize` in this scope
 
 #[fixed_stack_segment] fn f() {}
-//~^ ERROR cannot find attribute macro `fixed_stack_segment` in this scope
+//~^ ERROR cannot find attribute `fixed_stack_segment` in this scope
 
 fn main() {}
diff --git a/src/test/ui/attributes/obsolete-attr.stderr b/src/test/ui/attributes/obsolete-attr.stderr
index 9c6909f65f3ea..2d7c257c6208c 100644
--- a/src/test/ui/attributes/obsolete-attr.stderr
+++ b/src/test/ui/attributes/obsolete-attr.stderr
@@ -1,10 +1,10 @@
-error: cannot find attribute macro `fixed_stack_segment` in this scope
+error: cannot find attribute `fixed_stack_segment` in this scope
   --> $DIR/obsolete-attr.rs:6:3
    |
 LL | #[fixed_stack_segment] fn f() {}
    |   ^^^^^^^^^^^^^^^^^^^
 
-error: cannot find attribute macro `ab_isize` in this scope
+error: cannot find attribute `ab_isize` in this scope
   --> $DIR/obsolete-attr.rs:3:3
    |
 LL | #[ab_isize="stdcall"] extern {}
diff --git a/src/test/ui/attributes/unknown-attr.rs b/src/test/ui/attributes/unknown-attr.rs
index 544a6e2a7e78a..70fef04e95c67 100644
--- a/src/test/ui/attributes/unknown-attr.rs
+++ b/src/test/ui/attributes/unknown-attr.rs
@@ -3,10 +3,10 @@
 #![feature(custom_inner_attributes)]
 
 #![mutable_doc]
-//~^ ERROR cannot find attribute macro `mutable_doc` in this scope
+//~^ ERROR cannot find attribute `mutable_doc` in this scope
 
 #[dance] mod a {}
-//~^ ERROR cannot find attribute macro `dance` in this scope
+//~^ ERROR cannot find attribute `dance` in this scope
 
 #[dance] fn main() {}
-//~^ ERROR cannot find attribute macro `dance` in this scope
+//~^ ERROR cannot find attribute `dance` in this scope
diff --git a/src/test/ui/attributes/unknown-attr.stderr b/src/test/ui/attributes/unknown-attr.stderr
index 4d463874d669e..85c227dc83aa6 100644
--- a/src/test/ui/attributes/unknown-attr.stderr
+++ b/src/test/ui/attributes/unknown-attr.stderr
@@ -1,16 +1,16 @@
-error: cannot find attribute macro `mutable_doc` in this scope
+error: cannot find attribute `mutable_doc` in this scope
   --> $DIR/unknown-attr.rs:5:4
    |
 LL | #![mutable_doc]
    |    ^^^^^^^^^^^
 
-error: cannot find attribute macro `dance` in this scope
+error: cannot find attribute `dance` in this scope
   --> $DIR/unknown-attr.rs:8:3
    |
 LL | #[dance] mod a {}
    |   ^^^^^
 
-error: cannot find attribute macro `dance` in this scope
+error: cannot find attribute `dance` in this scope
   --> $DIR/unknown-attr.rs:11:3
    |
 LL | #[dance] fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs
index 22dbac766707d..45b757e928302 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs
+++ b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.rs
@@ -1,7 +1,7 @@
 macro_rules! foo {
     () => {
         #[cfg_attr(all(), unknown)]
-        //~^ ERROR cannot find attribute macro `unknown` in this scope
+        //~^ ERROR cannot find attribute `unknown` in this scope
         fn foo() {}
     }
 }
diff --git a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr
index c7c52a2923a59..ef434ec82610e 100644
--- a/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr
+++ b/src/test/ui/conditional-compilation/cfg-attr-unknown-attribute-macro-expansion.stderr
@@ -1,4 +1,4 @@
-error: cannot find attribute macro `unknown` in this scope
+error: cannot find attribute `unknown` in this scope
   --> $DIR/cfg-attr-unknown-attribute-macro-expansion.rs:3:27
    |
 LL |         #[cfg_attr(all(), unknown)]
diff --git a/src/test/ui/conditional-compilation/cfg-generic-params.rs b/src/test/ui/conditional-compilation/cfg-generic-params.rs
index faf01957c7e4f..53aa3556362f9 100644
--- a/src/test/ui/conditional-compilation/cfg-generic-params.rs
+++ b/src/test/ui/conditional-compilation/cfg-generic-params.rs
@@ -17,22 +17,22 @@ struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy;
 
 fn f_lt_no<#[cfg_attr(no, unknown)] 'a>() {} // OK
 fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {}
-//~^ ERROR cannot find attribute macro `unknown` in this scope
+//~^ ERROR cannot find attribute `unknown` in this scope
 fn f_ty_no<#[cfg_attr(no, unknown)] T>() {} // OK
 fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {}
-//~^ ERROR cannot find attribute macro `unknown` in this scope
+//~^ ERROR cannot find attribute `unknown` in this scope
 
 type FnNo = for<#[cfg_attr(no, unknown)] 'a> fn(); // OK
 type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn();
-//~^ ERROR cannot find attribute macro `unknown` in this scope
+//~^ ERROR cannot find attribute `unknown` in this scope
 
 type PolyNo = dyn for<#[cfg_attr(no, unknown)] 'a> Copy; // OK
 type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
-//~^ ERROR cannot find attribute macro `unknown` in this scope
+//~^ ERROR cannot find attribute `unknown` in this scope
 
 struct WhereNo where for<#[cfg_attr(no, unknown)] 'a> u8: Copy; // OK
 struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
-//~^ ERROR cannot find attribute macro `unknown` in this scope
+//~^ ERROR cannot find attribute `unknown` in this scope
 
 fn main() {
     f_lt::<'static>();
diff --git a/src/test/ui/conditional-compilation/cfg-generic-params.stderr b/src/test/ui/conditional-compilation/cfg-generic-params.stderr
index f6e5732916b91..d9e29c8262c63 100644
--- a/src/test/ui/conditional-compilation/cfg-generic-params.stderr
+++ b/src/test/ui/conditional-compilation/cfg-generic-params.stderr
@@ -16,31 +16,31 @@ error: only lifetime parameters can be used in this context
 LL | struct WhereBad where for<#[cfg(no)] 'a, #[cfg(yes)] T> u8: Copy;
    |                                                      ^
 
-error: cannot find attribute macro `unknown` in this scope
+error: cannot find attribute `unknown` in this scope
   --> $DIR/cfg-generic-params.rs:34:43
    |
 LL | struct WhereYes where for<#[cfg_attr(yes, unknown)] 'a> u8: Copy;
    |                                           ^^^^^^^
 
-error: cannot find attribute macro `unknown` in this scope
+error: cannot find attribute `unknown` in this scope
   --> $DIR/cfg-generic-params.rs:30:40
    |
 LL | type PolyYes = dyn for<#[cfg_attr(yes, unknown)] 'a> Copy;
    |                                        ^^^^^^^
 
-error: cannot find attribute macro `unknown` in this scope
+error: cannot find attribute `unknown` in this scope
   --> $DIR/cfg-generic-params.rs:26:34
    |
 LL | type FnYes = for<#[cfg_attr(yes, unknown)] 'a> fn();
    |                                  ^^^^^^^
 
-error: cannot find attribute macro `unknown` in this scope
+error: cannot find attribute `unknown` in this scope
   --> $DIR/cfg-generic-params.rs:22:29
    |
 LL | fn f_ty_yes<#[cfg_attr(yes, unknown)] T>() {}
    |                             ^^^^^^^
 
-error: cannot find attribute macro `unknown` in this scope
+error: cannot find attribute `unknown` in this scope
   --> $DIR/cfg-generic-params.rs:19:29
    |
 LL | fn f_lt_yes<#[cfg_attr(yes, unknown)] 'a>() {}
diff --git a/src/test/ui/custom_attribute.rs b/src/test/ui/custom_attribute.rs
index 13c873c3b7e48..4957184229da0 100644
--- a/src/test/ui/custom_attribute.rs
+++ b/src/test/ui/custom_attribute.rs
@@ -1,9 +1,9 @@
 #![feature(stmt_expr_attributes)]
 
-#[foo] //~ ERROR cannot find attribute macro `foo` in this scope
+#[foo] //~ ERROR cannot find attribute `foo` in this scope
 fn main() {
-    #[foo] //~ ERROR cannot find attribute macro `foo` in this scope
+    #[foo] //~ ERROR cannot find attribute `foo` in this scope
     let x = ();
-    #[foo] //~ ERROR cannot find attribute macro `foo` in this scope
+    #[foo] //~ ERROR cannot find attribute `foo` in this scope
     x
 }
diff --git a/src/test/ui/custom_attribute.stderr b/src/test/ui/custom_attribute.stderr
index b4f9f3f49b235..4023892d29466 100644
--- a/src/test/ui/custom_attribute.stderr
+++ b/src/test/ui/custom_attribute.stderr
@@ -1,16 +1,16 @@
-error: cannot find attribute macro `foo` in this scope
+error: cannot find attribute `foo` in this scope
   --> $DIR/custom_attribute.rs:3:3
    |
 LL | #[foo]
    |   ^^^
 
-error: cannot find attribute macro `foo` in this scope
+error: cannot find attribute `foo` in this scope
   --> $DIR/custom_attribute.rs:5:7
    |
 LL |     #[foo]
    |       ^^^
 
-error: cannot find attribute macro `foo` in this scope
+error: cannot find attribute `foo` in this scope
   --> $DIR/custom_attribute.rs:7:7
    |
 LL |     #[foo]
diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute.rs b/src/test/ui/feature-gates/feature-gate-custom_attribute.rs
index d34936b42a6ff..936cab268d2c9 100644
--- a/src/test/ui/feature-gates/feature-gate-custom_attribute.rs
+++ b/src/test/ui/feature-gates/feature-gate-custom_attribute.rs
@@ -1,18 +1,18 @@
 // Check that literals in attributes parse just fine.
 
-#[fake_attr] //~ ERROR cannot find attribute macro `fake_attr` in this scope
-#[fake_attr(100)] //~ ERROR cannot find attribute macro `fake_attr` in this scope
-#[fake_attr(1, 2, 3)] //~ ERROR cannot find attribute macro `fake_attr` in this scope
-#[fake_attr("hello")] //~ ERROR cannot find attribute macro `fake_attr` in this scope
-#[fake_attr(name = "hello")] //~ ERROR cannot find attribute macro `fake_attr` in this scope
-#[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR cannot find attribute macro `fake_attr` in th
-#[fake_attr(key = "hello", val = 10)] //~ ERROR cannot find attribute macro `fake_attr` in this scop
-#[fake_attr(key("hello"), val(10))] //~ ERROR cannot find attribute macro `fake_attr` in this scope
-#[fake_attr(enabled = true, disabled = false)] //~ ERROR cannot find attribute macro `fake_attr` in
-#[fake_attr(true)] //~ ERROR cannot find attribute macro `fake_attr` in this scope
-#[fake_attr(pi = 3.14159)] //~ ERROR cannot find attribute macro `fake_attr` in this scope
-#[fake_attr(b"hi")] //~ ERROR cannot find attribute macro `fake_attr` in this scope
-#[fake_doc(r"doc")] //~ ERROR cannot find attribute macro `fake_doc` in this scope
+#[fake_attr] //~ ERROR cannot find attribute `fake_attr` in this scope
+#[fake_attr(100)] //~ ERROR cannot find attribute `fake_attr` in this scope
+#[fake_attr(1, 2, 3)] //~ ERROR cannot find attribute `fake_attr` in this scope
+#[fake_attr("hello")] //~ ERROR cannot find attribute `fake_attr` in this scope
+#[fake_attr(name = "hello")] //~ ERROR cannot find attribute `fake_attr` in this scope
+#[fake_attr(1, "hi", key = 12, true, false)] //~ ERROR cannot find attribute `fake_attr` in th
+#[fake_attr(key = "hello", val = 10)] //~ ERROR cannot find attribute `fake_attr` in this scop
+#[fake_attr(key("hello"), val(10))] //~ ERROR cannot find attribute `fake_attr` in this scope
+#[fake_attr(enabled = true, disabled = false)] //~ ERROR cannot find attribute `fake_attr` in
+#[fake_attr(true)] //~ ERROR cannot find attribute `fake_attr` in this scope
+#[fake_attr(pi = 3.14159)] //~ ERROR cannot find attribute `fake_attr` in this scope
+#[fake_attr(b"hi")] //~ ERROR cannot find attribute `fake_attr` in this scope
+#[fake_doc(r"doc")] //~ ERROR cannot find attribute `fake_doc` in this scope
 struct Q {}
 
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr b/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr
index efdc2d1cd31ed..b7c45ec1fb7ea 100644
--- a/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr
+++ b/src/test/ui/feature-gates/feature-gate-custom_attribute.stderr
@@ -1,76 +1,76 @@
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:3:3
    |
 LL | #[fake_attr]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:4:3
    |
 LL | #[fake_attr(100)]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:5:3
    |
 LL | #[fake_attr(1, 2, 3)]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:6:3
    |
 LL | #[fake_attr("hello")]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:7:3
    |
 LL | #[fake_attr(name = "hello")]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:8:3
    |
 LL | #[fake_attr(1, "hi", key = 12, true, false)]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:9:3
    |
 LL | #[fake_attr(key = "hello", val = 10)]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:10:3
    |
 LL | #[fake_attr(key("hello"), val(10))]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:11:3
    |
 LL | #[fake_attr(enabled = true, disabled = false)]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:12:3
    |
 LL | #[fake_attr(true)]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:13:3
    |
 LL | #[fake_attr(pi = 3.14159)]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_attr` in this scope
+error: cannot find attribute `fake_attr` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:14:3
    |
 LL | #[fake_attr(b"hi")]
    |   ^^^^^^^^^
 
-error: cannot find attribute macro `fake_doc` in this scope
+error: cannot find attribute `fake_doc` in this scope
   --> $DIR/feature-gate-custom_attribute.rs:15:3
    |
 LL | #[fake_doc(r"doc")]
diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs b/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs
index 51b5bf5387b5f..e4c80141aa2a5 100644
--- a/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs
+++ b/src/test/ui/feature-gates/feature-gate-custom_attribute2.rs
@@ -4,54 +4,54 @@
 // gate-test-custom_attribute
 
 struct StLt<#[lt_struct] 'a>(&'a u32);
-//~^ ERROR cannot find attribute macro `lt_struct` in this scope
+//~^ ERROR cannot find attribute `lt_struct` in this scope
 struct StTy<#[ty_struct] I>(I);
-//~^ ERROR cannot find attribute macro `ty_struct` in this scope
+//~^ ERROR cannot find attribute `ty_struct` in this scope
 
 enum EnLt<#[lt_enum] 'b> { A(&'b u32), B }
-//~^ ERROR cannot find attribute macro `lt_enum` in this scope
+//~^ ERROR cannot find attribute `lt_enum` in this scope
 enum EnTy<#[ty_enum] J> { A(J), B }
-//~^ ERROR cannot find attribute macro `ty_enum` in this scope
+//~^ ERROR cannot find attribute `ty_enum` in this scope
 
 trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
-//~^ ERROR cannot find attribute macro `lt_trait` in this scope
+//~^ ERROR cannot find attribute `lt_trait` in this scope
 trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); }
-//~^ ERROR cannot find attribute macro `ty_trait` in this scope
+//~^ ERROR cannot find attribute `ty_trait` in this scope
 
 type TyLt<#[lt_type] 'd> = &'d u32;
-//~^ ERROR cannot find attribute macro `lt_type` in this scope
+//~^ ERROR cannot find attribute `lt_type` in this scope
 type TyTy<#[ty_type] L> = (L, );
-//~^ ERROR cannot find attribute macro `ty_type` in this scope
+//~^ ERROR cannot find attribute `ty_type` in this scope
 
 impl<#[lt_inherent] 'e> StLt<'e> { }
-//~^ ERROR cannot find attribute macro `lt_inherent` in this scope
+//~^ ERROR cannot find attribute `lt_inherent` in this scope
 impl<#[ty_inherent] M> StTy<M> { }
-//~^ ERROR cannot find attribute macro `ty_inherent` in this scope
+//~^ ERROR cannot find attribute `ty_inherent` in this scope
 
 impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
-    //~^ ERROR cannot find attribute macro `lt_impl_for` in this scope
+    //~^ ERROR cannot find attribute `lt_impl_for` in this scope
     fn foo(&self, _: &'f [u32]) -> &'f u32 { loop { } }
 }
 impl<#[ty_impl_for] N> TrTy<N> for StTy<N> {
-    //~^ ERROR cannot find attribute macro `ty_impl_for` in this scope
+    //~^ ERROR cannot find attribute `ty_impl_for` in this scope
     fn foo(&self, _: N) { }
 }
 
 fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
-//~^ ERROR cannot find attribute macro `lt_fn` in this scope
+//~^ ERROR cannot find attribute `lt_fn` in this scope
 fn f_ty<#[ty_fn] O>(_: O) { }
-//~^ ERROR cannot find attribute macro `ty_fn` in this scope
+//~^ ERROR cannot find attribute `ty_fn` in this scope
 
 impl<I> StTy<I> {
     fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
-    //~^ ERROR cannot find attribute macro `lt_meth` in this scope
+    //~^ ERROR cannot find attribute `lt_meth` in this scope
     fn m_ty<#[ty_meth] P>(_: P) { }
-    //~^ ERROR cannot find attribute macro `ty_meth` in this scope
+    //~^ ERROR cannot find attribute `ty_meth` in this scope
 }
 
 fn hof_lt<Q>(_: Q)
     where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
-    //~^ ERROR cannot find attribute macro `lt_hof` in this scope
+    //~^ ERROR cannot find attribute `lt_hof` in this scope
 {
 }
 
diff --git a/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr b/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr
index 9250616127f3d..bc89caddb4439 100644
--- a/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr
+++ b/src/test/ui/feature-gates/feature-gate-custom_attribute2.stderr
@@ -1,100 +1,100 @@
-error: cannot find attribute macro `lt_hof` in this scope
+error: cannot find attribute `lt_hof` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:53:21
    |
 LL |     where Q: for <#[lt_hof] 'i> Fn(&'i [u32]) -> &'i u32
    |                     ^^^^^^
 
-error: cannot find attribute macro `ty_meth` in this scope
+error: cannot find attribute `ty_meth` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:48:15
    |
 LL |     fn m_ty<#[ty_meth] P>(_: P) { }
    |               ^^^^^^^
 
-error: cannot find attribute macro `lt_meth` in this scope
+error: cannot find attribute `lt_meth` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:46:15
    |
 LL |     fn m_lt<#[lt_meth] 'h>(_: &'h [u32]) -> &'h u32 { loop { } }
    |               ^^^^^^^
 
-error: cannot find attribute macro `ty_fn` in this scope
+error: cannot find attribute `ty_fn` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:42:11
    |
 LL | fn f_ty<#[ty_fn] O>(_: O) { }
    |           ^^^^^
 
-error: cannot find attribute macro `lt_fn` in this scope
+error: cannot find attribute `lt_fn` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:40:11
    |
 LL | fn f_lt<#[lt_fn] 'g>(_: &'g [u32]) -> &'g u32 { loop { } }
    |           ^^^^^
 
-error: cannot find attribute macro `ty_impl_for` in this scope
+error: cannot find attribute `ty_impl_for` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:35:8
    |
 LL | impl<#[ty_impl_for] N> TrTy<N> for StTy<N> {
    |        ^^^^^^^^^^^
 
-error: cannot find attribute macro `lt_impl_for` in this scope
+error: cannot find attribute `lt_impl_for` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:31:8
    |
 LL | impl<#[lt_impl_for] 'f> TrLt<'f> for StLt<'f> {
    |        ^^^^^^^^^^^
 
-error: cannot find attribute macro `ty_inherent` in this scope
+error: cannot find attribute `ty_inherent` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:28:8
    |
 LL | impl<#[ty_inherent] M> StTy<M> { }
    |        ^^^^^^^^^^^
 
-error: cannot find attribute macro `lt_inherent` in this scope
+error: cannot find attribute `lt_inherent` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:26:8
    |
 LL | impl<#[lt_inherent] 'e> StLt<'e> { }
    |        ^^^^^^^^^^^
 
-error: cannot find attribute macro `ty_type` in this scope
+error: cannot find attribute `ty_type` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:23:13
    |
 LL | type TyTy<#[ty_type] L> = (L, );
    |             ^^^^^^^
 
-error: cannot find attribute macro `lt_type` in this scope
+error: cannot find attribute `lt_type` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:21:13
    |
 LL | type TyLt<#[lt_type] 'd> = &'d u32;
    |             ^^^^^^^
 
-error: cannot find attribute macro `ty_trait` in this scope
+error: cannot find attribute `ty_trait` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:18:14
    |
 LL | trait TrTy<#[ty_trait] K> { fn foo(&self, _: K); }
    |              ^^^^^^^^
 
-error: cannot find attribute macro `lt_trait` in this scope
+error: cannot find attribute `lt_trait` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:16:14
    |
 LL | trait TrLt<#[lt_trait] 'c> { fn foo(&self, _: &'c [u32]) -> &'c u32; }
    |              ^^^^^^^^
 
-error: cannot find attribute macro `ty_enum` in this scope
+error: cannot find attribute `ty_enum` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:13:13
    |
 LL | enum EnTy<#[ty_enum] J> { A(J), B }
    |             ^^^^^^^
 
-error: cannot find attribute macro `lt_enum` in this scope
+error: cannot find attribute `lt_enum` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:11:13
    |
 LL | enum EnLt<#[lt_enum] 'b> { A(&'b u32), B }
    |             ^^^^^^^
 
-error: cannot find attribute macro `ty_struct` in this scope
+error: cannot find attribute `ty_struct` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:8:15
    |
 LL | struct StTy<#[ty_struct] I>(I);
    |               ^^^^^^^^^
 
-error: cannot find attribute macro `lt_struct` in this scope
+error: cannot find attribute `lt_struct` in this scope
   --> $DIR/feature-gate-custom_attribute2.rs:6:15
    |
 LL | struct StLt<#[lt_struct] 'a>(&'a u32);
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs
index 4044fd2b895e4..c985298a30aed 100644
--- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs
+++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs
@@ -19,5 +19,5 @@ fn g() {}
 //~^ ERROR the `#[rustc_dummy]` attribute is just used for rustc unit tests
 #[rustc_unknown]
 //~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
-//~| ERROR cannot find attribute macro `rustc_unknown` in this scope
+//~| ERROR cannot find attribute `rustc_unknown` in this scope
 fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
index c1063027fa444..d6fdab2b0412d 100644
--- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
+++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr
@@ -37,7 +37,7 @@ LL | #[rustc_unknown]
    = note: for more information, see https://github.com/rust-lang/rust/issues/29642
    = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
 
-error: cannot find attribute macro `rustc_unknown` in this scope
+error: cannot find attribute `rustc_unknown` in this scope
   --> $DIR/feature-gate-rustc-attrs.rs:20:3
    |
 LL | #[rustc_unknown]
diff --git a/src/test/ui/issues/issue-32655.rs b/src/test/ui/issues/issue-32655.rs
index fad7bf55cf4ea..f52e092312968 100644
--- a/src/test/ui/issues/issue-32655.rs
+++ b/src/test/ui/issues/issue-32655.rs
@@ -1,6 +1,6 @@
 macro_rules! foo (
     () => (
-        #[derive_Clone] //~ ERROR cannot find attribute macro `derive_Clone` in this scope
+        #[derive_Clone] //~ ERROR cannot find attribute `derive_Clone` in this scope
         struct T;
     );
 );
@@ -12,7 +12,7 @@ macro_rules! bar (
 foo!();
 
 bar!(
-    #[derive_Clone] //~ ERROR cannot find attribute macro `derive_Clone` in this scope
+    #[derive_Clone] //~ ERROR cannot find attribute `derive_Clone` in this scope
     struct S;
 );
 
diff --git a/src/test/ui/issues/issue-32655.stderr b/src/test/ui/issues/issue-32655.stderr
index e13bed0fbfd66..ca085b25c2ddf 100644
--- a/src/test/ui/issues/issue-32655.stderr
+++ b/src/test/ui/issues/issue-32655.stderr
@@ -1,4 +1,4 @@
-error: cannot find attribute macro `derive_Clone` in this scope
+error: cannot find attribute `derive_Clone` in this scope
   --> $DIR/issue-32655.rs:3:11
    |
 LL |         #[derive_Clone]
@@ -7,7 +7,7 @@ LL |         #[derive_Clone]
 LL | foo!();
    | ------- in this macro invocation
 
-error: cannot find attribute macro `derive_Clone` in this scope
+error: cannot find attribute `derive_Clone` in this scope
   --> $DIR/issue-32655.rs:15:7
    |
 LL |     #[derive_Clone]
diff --git a/src/test/ui/issues/issue-49074.rs b/src/test/ui/issues/issue-49074.rs
index 38074d5b05ca2..f909add5f5891 100644
--- a/src/test/ui/issues/issue-49074.rs
+++ b/src/test/ui/issues/issue-49074.rs
@@ -1,7 +1,7 @@
 // Check that unknown attribute error is shown even if there are unresolved macros.
 
 #[marco_use] // typo
-//~^ ERROR cannot find attribute macro `marco_use` in this scope
+//~^ ERROR cannot find attribute `marco_use` in this scope
 mod foo {
     macro_rules! bar {
         () => ();
diff --git a/src/test/ui/issues/issue-49074.stderr b/src/test/ui/issues/issue-49074.stderr
index e0d3bb3ecc2e1..42d0b511fc5e4 100644
--- a/src/test/ui/issues/issue-49074.stderr
+++ b/src/test/ui/issues/issue-49074.stderr
@@ -6,7 +6,7 @@ LL |    bar!();
    |
    = help: have you added the `#[macro_use]` on the module/import?
 
-error: cannot find attribute macro `marco_use` in this scope
+error: cannot find attribute `marco_use` in this scope
   --> $DIR/issue-49074.rs:3:3
    |
 LL | #[marco_use] // typo
diff --git a/src/test/ui/macros/macro-reexport-removed.rs b/src/test/ui/macros/macro-reexport-removed.rs
index b69a1fa4df08a..874c94d08e06a 100644
--- a/src/test/ui/macros/macro-reexport-removed.rs
+++ b/src/test/ui/macros/macro-reexport-removed.rs
@@ -2,7 +2,7 @@
 
 #![feature(macro_reexport)] //~ ERROR feature has been removed
 
-#[macro_reexport(macro_one)] //~ ERROR cannot find attribute macro `macro_reexport` in this scope
+#[macro_reexport(macro_one)] //~ ERROR cannot find attribute `macro_reexport` in this scope
 extern crate two_macros;
 
 fn main() {}
diff --git a/src/test/ui/macros/macro-reexport-removed.stderr b/src/test/ui/macros/macro-reexport-removed.stderr
index 25778fba68f7c..4bec70850aff7 100644
--- a/src/test/ui/macros/macro-reexport-removed.stderr
+++ b/src/test/ui/macros/macro-reexport-removed.stderr
@@ -10,7 +10,7 @@ note: subsumed by `pub use`
 LL | #![feature(macro_reexport)]
    |            ^^^^^^^^^^^^^^
 
-error: cannot find attribute macro `macro_reexport` in this scope
+error: cannot find attribute `macro_reexport` in this scope
   --> $DIR/macro-reexport-removed.rs:5:3
    |
 LL | #[macro_reexport(macro_one)]
diff --git a/src/test/ui/proc-macro/derive-still-gated.rs b/src/test/ui/proc-macro/derive-still-gated.rs
index 4e6f9b072205d..3f8d6f0716b3a 100644
--- a/src/test/ui/proc-macro/derive-still-gated.rs
+++ b/src/test/ui/proc-macro/derive-still-gated.rs
@@ -3,7 +3,7 @@
 #[macro_use]
 extern crate test_macros;
 
-#[derive_Empty] //~ ERROR cannot find attribute macro `derive_Empty` in this scope
+#[derive_Empty] //~ ERROR cannot find attribute `derive_Empty` in this scope
 struct A;
 
 fn main() {}
diff --git a/src/test/ui/proc-macro/derive-still-gated.stderr b/src/test/ui/proc-macro/derive-still-gated.stderr
index 4df1715db9467..99289fdfe7fd5 100644
--- a/src/test/ui/proc-macro/derive-still-gated.stderr
+++ b/src/test/ui/proc-macro/derive-still-gated.stderr
@@ -1,4 +1,4 @@
-error: cannot find attribute macro `derive_Empty` in this scope
+error: cannot find attribute `derive_Empty` in this scope
   --> $DIR/derive-still-gated.rs:6:3
    |
 LL | #[derive_Empty]
diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs
index 8a26df9e76ade..bc46a07dd3f4b 100644
--- a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs
+++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs
@@ -35,7 +35,7 @@ fn check_bang3() {
                        //~| ERROR expected macro, found derive macro `crate::MyTrait`
 }
 
-#[my_macro] //~ ERROR cannot find attribute macro `my_macro` in this scope
+#[my_macro] //~ ERROR cannot find attribute `my_macro` in this scope
 #[crate::my_macro] //~ ERROR can't use a procedural macro from the same crate that defines it
                    //~| ERROR expected attribute, found macro `crate::my_macro`
 fn check_attr1() {}
diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
index 0c863e919670d..9616e80fa64c7 100644
--- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
+++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
@@ -100,7 +100,7 @@ error: cannot find macro `MyTrait!` in this scope
 LL |     MyTrait!();
    |     ^^^^^^^
 
-error: cannot find attribute macro `my_macro` in this scope
+error: cannot find attribute `my_macro` in this scope
   --> $DIR/macro-namespace-reserved-2.rs:38:3
    |
 LL | #[my_macro]
diff --git a/src/test/ui/proc-macro/proc-macro-attributes.rs b/src/test/ui/proc-macro/proc-macro-attributes.rs
index 04215226c6d41..6401522bdf89c 100644
--- a/src/test/ui/proc-macro/proc-macro-attributes.rs
+++ b/src/test/ui/proc-macro/proc-macro-attributes.rs
@@ -4,7 +4,7 @@
 extern crate derive_b;
 
 #[B] //~ ERROR `B` is ambiguous
-#[C] //~ ERROR cannot find attribute macro `C` in this scope
+#[C] //~ ERROR cannot find attribute `C` in this scope
 #[B(D)] //~ ERROR `B` is ambiguous
 #[B(E = "foo")] //~ ERROR `B` is ambiguous
 #[B(arbitrary tokens)] //~ ERROR `B` is ambiguous
diff --git a/src/test/ui/proc-macro/proc-macro-attributes.stderr b/src/test/ui/proc-macro/proc-macro-attributes.stderr
index b068c6bc83bf3..3ac93a748523a 100644
--- a/src/test/ui/proc-macro/proc-macro-attributes.stderr
+++ b/src/test/ui/proc-macro/proc-macro-attributes.stderr
@@ -1,4 +1,4 @@
-error: cannot find attribute macro `C` in this scope
+error: cannot find attribute `C` in this scope
   --> $DIR/proc-macro-attributes.rs:7:3
    |
 LL | #[C]
diff --git a/src/test/ui/proc-macro/resolve-error.rs b/src/test/ui/proc-macro/resolve-error.rs
index 088f39c6665ff..d2282af27f543 100644
--- a/src/test/ui/proc-macro/resolve-error.rs
+++ b/src/test/ui/proc-macro/resolve-error.rs
@@ -24,11 +24,11 @@ macro_rules! attr_proc_mac {
 struct Foo;
 
 // Interpreted as an unstable custom attribute
-#[attr_proc_macra] //~ ERROR cannot find attribute macro `attr_proc_macra` in this scope
+#[attr_proc_macra] //~ ERROR cannot find attribute `attr_proc_macra` in this scope
 struct Bar;
 
 // Interpreted as an unstable custom attribute
-#[FooWithLongNan] //~ ERROR cannot find attribute macro `FooWithLongNan` in this scope
+#[FooWithLongNan] //~ ERROR cannot find attribute `FooWithLongNan` in this scope
 struct Asdf;
 
 #[derive(Dlone)]
diff --git a/src/test/ui/proc-macro/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr
index 2a5f2b883813d..6c242cf45d64c 100644
--- a/src/test/ui/proc-macro/resolve-error.stderr
+++ b/src/test/ui/proc-macro/resolve-error.stderr
@@ -40,13 +40,13 @@ error: cannot find derive macro `Dlone` in this scope
 LL | #[derive(Dlone)]
    |          ^^^^^ help: a derive macro with a similar name exists: `Clone`
 
-error: cannot find attribute macro `FooWithLongNan` in this scope
+error: cannot find attribute `FooWithLongNan` in this scope
   --> $DIR/resolve-error.rs:31:3
    |
 LL | #[FooWithLongNan]
    |   ^^^^^^^^^^^^^^
 
-error: cannot find attribute macro `attr_proc_macra` in this scope
+error: cannot find attribute `attr_proc_macra` in this scope
   --> $DIR/resolve-error.rs:27:3
    |
 LL | #[attr_proc_macra]
diff --git a/src/test/ui/reserved/reserved-attr-on-macro.rs b/src/test/ui/reserved/reserved-attr-on-macro.rs
index fddb991da822c..2630db0d09785 100644
--- a/src/test/ui/reserved/reserved-attr-on-macro.rs
+++ b/src/test/ui/reserved/reserved-attr-on-macro.rs
@@ -1,5 +1,5 @@
 #[rustc_attribute_should_be_reserved]
-//~^ ERROR cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope
+//~^ ERROR cannot find attribute `rustc_attribute_should_be_reserved` in this scope
 //~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
 
 macro_rules! foo {
diff --git a/src/test/ui/reserved/reserved-attr-on-macro.stderr b/src/test/ui/reserved/reserved-attr-on-macro.stderr
index 856162b318dea..685960588a2cb 100644
--- a/src/test/ui/reserved/reserved-attr-on-macro.stderr
+++ b/src/test/ui/reserved/reserved-attr-on-macro.stderr
@@ -15,7 +15,7 @@ LL |     foo!();
    |
    = note: import resolution is stuck, try simplifying macro imports
 
-error: cannot find attribute macro `rustc_attribute_should_be_reserved` in this scope
+error: cannot find attribute `rustc_attribute_should_be_reserved` in this scope
   --> $DIR/reserved-attr-on-macro.rs:1:3
    |
 LL | #[rustc_attribute_should_be_reserved]
diff --git a/src/test/ui/suggestions/attribute-typos.rs b/src/test/ui/suggestions/attribute-typos.rs
index 74f63f2b0ed07..7c8231bbb24f8 100644
--- a/src/test/ui/suggestions/attribute-typos.rs
+++ b/src/test/ui/suggestions/attribute-typos.rs
@@ -1,11 +1,11 @@
-#[deprcated] //~ ERROR cannot find attribute macro `deprcated` in this scope
+#[deprcated] //~ ERROR cannot find attribute `deprcated` in this scope
 fn foo() {}
 
-#[tests] //~ ERROR cannot find attribute macro `tests` in this scope
+#[tests] //~ ERROR cannot find attribute `tests` in this scope
 fn bar() {}
 
 #[rustc_err]
-//~^ ERROR cannot find attribute macro `rustc_err` in this scope
+//~^ ERROR cannot find attribute `rustc_err` in this scope
 //~| ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler
 
 fn main() {}
diff --git a/src/test/ui/suggestions/attribute-typos.stderr b/src/test/ui/suggestions/attribute-typos.stderr
index 6b2f591b9e7d9..e40329382fd40 100644
--- a/src/test/ui/suggestions/attribute-typos.stderr
+++ b/src/test/ui/suggestions/attribute-typos.stderr
@@ -7,19 +7,19 @@ LL | #[rustc_err]
    = note: for more information, see https://github.com/rust-lang/rust/issues/29642
    = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
 
-error: cannot find attribute macro `rustc_err` in this scope
+error: cannot find attribute `rustc_err` in this scope
   --> $DIR/attribute-typos.rs:7:3
    |
 LL | #[rustc_err]
    |   ^^^^^^^^^ help: a built-in attribute with a similar name exists: `rustc_error`
 
-error: cannot find attribute macro `tests` in this scope
+error: cannot find attribute `tests` in this scope
   --> $DIR/attribute-typos.rs:4:3
    |
 LL | #[tests]
    |   ^^^^^ help: an attribute macro with a similar name exists: `test`
 
-error: cannot find attribute macro `deprcated` in this scope
+error: cannot find attribute `deprcated` in this scope
   --> $DIR/attribute-typos.rs:1:3
    |
 LL | #[deprcated]
diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs
index c07da4345f7d9..72929c5e80590 100644
--- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs
+++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs
@@ -5,7 +5,7 @@ type B = rustfmt::skip; //~ ERROR expected type, found tool attribute `rustfmt::
 struct S;
 
 // Interpreted as an unstable custom attribute
-#[rustfmt] //~ ERROR cannot find attribute macro `rustfmt` in this scope
+#[rustfmt] //~ ERROR cannot find attribute `rustfmt` in this scope
 fn check() {}
 
 #[rustfmt::skip] // OK
diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr
index 33581a170822b..393ad0949cc4b 100644
--- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr
+++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr
@@ -4,7 +4,7 @@ error: cannot find derive macro `rustfmt` in this scope
 LL | #[derive(rustfmt)]
    |          ^^^^^^^
 
-error: cannot find attribute macro `rustfmt` in this scope
+error: cannot find attribute `rustfmt` in this scope
   --> $DIR/tool-attributes-misplaced-1.rs:8:3
    |
 LL | #[rustfmt]

From f7f8d6584bf342cdc22eb06888f7cb674b73b3b5 Mon Sep 17 00:00:00 2001
From: Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
Date: Sun, 15 Sep 2019 13:12:14 +0300
Subject: [PATCH 759/943] resolve: Remove `!` from "cannot find" diagnostics
 for macros

---
 src/librustc_resolve/macros.rs                            | 3 +--
 src/test/ui/empty/empty-macro-use.stderr                  | 2 +-
 src/test/ui/ext-nonexistent.stderr                        | 2 +-
 src/test/ui/hygiene/no_implicit_prelude-2018.rs           | 2 +-
 src/test/ui/hygiene/no_implicit_prelude-2018.stderr       | 2 +-
 src/test/ui/hygiene/no_implicit_prelude.rs                | 2 +-
 src/test/ui/hygiene/no_implicit_prelude.stderr            | 2 +-
 src/test/ui/issues/issue-11692-1.rs                       | 2 +-
 src/test/ui/issues/issue-11692-1.stderr                   | 2 +-
 src/test/ui/issues/issue-11692-2.rs                       | 2 +-
 src/test/ui/issues/issue-11692-2.stderr                   | 2 +-
 src/test/ui/issues/issue-19734.rs                         | 2 +-
 src/test/ui/issues/issue-19734.stderr                     | 2 +-
 src/test/ui/issues/issue-40845.rs                         | 4 ++--
 src/test/ui/issues/issue-40845.stderr                     | 4 ++--
 src/test/ui/issues/issue-49074.rs                         | 2 +-
 src/test/ui/issues/issue-49074.stderr                     | 2 +-
 src/test/ui/macros/macro-expansion-tests.stderr           | 4 ++--
 src/test/ui/macros/macro-name-typo.stderr                 | 2 +-
 src/test/ui/macros/macro-path-prelude-fail-3.rs           | 2 +-
 src/test/ui/macros/macro-path-prelude-fail-3.stderr       | 2 +-
 src/test/ui/macros/macro-use-wrong-name.stderr            | 2 +-
 src/test/ui/macros/macro_undefined.stderr                 | 2 +-
 src/test/ui/missing/missing-macro-use.rs                  | 2 +-
 src/test/ui/missing/missing-macro-use.stderr              | 2 +-
 src/test/ui/proc-macro/macro-namespace-reserved-2.rs      | 4 ++--
 src/test/ui/proc-macro/macro-namespace-reserved-2.stderr  | 4 ++--
 src/test/ui/proc-macro/resolve-error.stderr               | 8 ++++----
 src/test/ui/resolve/visibility-indeterminate.rs           | 2 +-
 src/test/ui/resolve/visibility-indeterminate.stderr       | 2 +-
 src/test/ui/self/self_type_keyword.rs                     | 2 +-
 src/test/ui/self/self_type_keyword.stderr                 | 2 +-
 .../ui/tool-attributes/tool-attributes-misplaced-1.rs     | 2 +-
 .../ui/tool-attributes/tool-attributes-misplaced-1.stderr | 2 +-
 34 files changed, 42 insertions(+), 43 deletions(-)

diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 734ae8d94d86d..3900a3dbb3872 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -774,9 +774,8 @@ impl<'a> Resolver<'a> {
                 }
                 Err(..) => {
                     assert!(initial_binding.is_none());
-                    let bang = if kind == MacroKind::Bang { "!" } else { "" };
                     let expected = kind.descr_expected();
-                    let msg = format!("cannot find {} `{}{}` in this scope", expected, ident, bang);
+                    let msg = format!("cannot find {} `{}` in this scope", expected, ident);
                     let mut err = self.session.struct_span_err(ident.span, &msg);
                     self.unresolved_macro_suggestions(&mut err, kind, &parent_scope, ident);
                     err.emit();
diff --git a/src/test/ui/empty/empty-macro-use.stderr b/src/test/ui/empty/empty-macro-use.stderr
index 16300411c8cef..8e3e06896ee78 100644
--- a/src/test/ui/empty/empty-macro-use.stderr
+++ b/src/test/ui/empty/empty-macro-use.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `macro_two!` in this scope
+error: cannot find macro `macro_two` in this scope
   --> $DIR/empty-macro-use.rs:7:5
    |
 LL |     macro_two!();
diff --git a/src/test/ui/ext-nonexistent.stderr b/src/test/ui/ext-nonexistent.stderr
index 3fbbb4952649f..f3aa83fd50806 100644
--- a/src/test/ui/ext-nonexistent.stderr
+++ b/src/test/ui/ext-nonexistent.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `iamnotanextensionthatexists!` in this scope
+error: cannot find macro `iamnotanextensionthatexists` in this scope
   --> $DIR/ext-nonexistent.rs:2:13
    |
 LL | fn main() { iamnotanextensionthatexists!(""); }
diff --git a/src/test/ui/hygiene/no_implicit_prelude-2018.rs b/src/test/ui/hygiene/no_implicit_prelude-2018.rs
index 3ad7435fecf29..83ca28167a468 100644
--- a/src/test/ui/hygiene/no_implicit_prelude-2018.rs
+++ b/src/test/ui/hygiene/no_implicit_prelude-2018.rs
@@ -4,7 +4,7 @@
 mod bar {
     fn f() {
         ::std::print!(""); // OK
-        print!(); //~ ERROR cannot find macro `print!` in this scope
+        print!(); //~ ERROR cannot find macro `print` in this scope
     }
 }
 
diff --git a/src/test/ui/hygiene/no_implicit_prelude-2018.stderr b/src/test/ui/hygiene/no_implicit_prelude-2018.stderr
index 0fdb18d967a6c..f31b75238dffe 100644
--- a/src/test/ui/hygiene/no_implicit_prelude-2018.stderr
+++ b/src/test/ui/hygiene/no_implicit_prelude-2018.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `print!` in this scope
+error: cannot find macro `print` in this scope
   --> $DIR/no_implicit_prelude-2018.rs:7:9
    |
 LL |         print!();
diff --git a/src/test/ui/hygiene/no_implicit_prelude.rs b/src/test/ui/hygiene/no_implicit_prelude.rs
index 890c8307543f3..204e7b248797a 100644
--- a/src/test/ui/hygiene/no_implicit_prelude.rs
+++ b/src/test/ui/hygiene/no_implicit_prelude.rs
@@ -13,7 +13,7 @@ mod bar {
     }
     fn f() {
         ::foo::m!();
-        assert_eq!(0, 0); //~ ERROR cannot find macro `panic!` in this scope
+        assert_eq!(0, 0); //~ ERROR cannot find macro `panic` in this scope
     }
 }
 
diff --git a/src/test/ui/hygiene/no_implicit_prelude.stderr b/src/test/ui/hygiene/no_implicit_prelude.stderr
index 8fa55d05bddcb..bc0ce746be925 100644
--- a/src/test/ui/hygiene/no_implicit_prelude.stderr
+++ b/src/test/ui/hygiene/no_implicit_prelude.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `panic!` in this scope
+error: cannot find macro `panic` in this scope
   --> $DIR/no_implicit_prelude.rs:16:9
    |
 LL |         assert_eq!(0, 0);
diff --git a/src/test/ui/issues/issue-11692-1.rs b/src/test/ui/issues/issue-11692-1.rs
index 70b712c560830..b6f3bb8ef0549 100644
--- a/src/test/ui/issues/issue-11692-1.rs
+++ b/src/test/ui/issues/issue-11692-1.rs
@@ -1,3 +1,3 @@
 fn main() {
-    print!(testo!()); //~ ERROR cannot find macro `testo!` in this scope
+    print!(testo!()); //~ ERROR cannot find macro `testo` in this scope
 }
diff --git a/src/test/ui/issues/issue-11692-1.stderr b/src/test/ui/issues/issue-11692-1.stderr
index bfd1647e8bee4..386463436b8e6 100644
--- a/src/test/ui/issues/issue-11692-1.stderr
+++ b/src/test/ui/issues/issue-11692-1.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `testo!` in this scope
+error: cannot find macro `testo` in this scope
   --> $DIR/issue-11692-1.rs:2:12
    |
 LL |     print!(testo!());
diff --git a/src/test/ui/issues/issue-11692-2.rs b/src/test/ui/issues/issue-11692-2.rs
index 61be284d7320e..5957ed338f4e7 100644
--- a/src/test/ui/issues/issue-11692-2.rs
+++ b/src/test/ui/issues/issue-11692-2.rs
@@ -1,3 +1,3 @@
 fn main() {
-    concat!(test!()); //~ ERROR cannot find macro `test!` in this scope
+    concat!(test!()); //~ ERROR cannot find macro `test` in this scope
 }
diff --git a/src/test/ui/issues/issue-11692-2.stderr b/src/test/ui/issues/issue-11692-2.stderr
index 740c3555e52f0..f021943da32da 100644
--- a/src/test/ui/issues/issue-11692-2.stderr
+++ b/src/test/ui/issues/issue-11692-2.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `test!` in this scope
+error: cannot find macro `test` in this scope
   --> $DIR/issue-11692-2.rs:2:13
    |
 LL |     concat!(test!());
diff --git a/src/test/ui/issues/issue-19734.rs b/src/test/ui/issues/issue-19734.rs
index b730e19a1e632..fe4a327aef49c 100644
--- a/src/test/ui/issues/issue-19734.rs
+++ b/src/test/ui/issues/issue-19734.rs
@@ -4,5 +4,5 @@ struct Type;
 
 impl Type {
     undef!();
-    //~^ ERROR cannot find macro `undef!` in this scope
+    //~^ ERROR cannot find macro `undef` in this scope
 }
diff --git a/src/test/ui/issues/issue-19734.stderr b/src/test/ui/issues/issue-19734.stderr
index fc1a7d0381be2..81757974de9dd 100644
--- a/src/test/ui/issues/issue-19734.stderr
+++ b/src/test/ui/issues/issue-19734.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `undef!` in this scope
+error: cannot find macro `undef` in this scope
   --> $DIR/issue-19734.rs:6:5
    |
 LL |     undef!();
diff --git a/src/test/ui/issues/issue-40845.rs b/src/test/ui/issues/issue-40845.rs
index c9102f4417c17..a4ede6adfa3c2 100644
--- a/src/test/ui/issues/issue-40845.rs
+++ b/src/test/ui/issues/issue-40845.rs
@@ -1,6 +1,6 @@
-trait T { m!(); } //~ ERROR cannot find macro `m!` in this scope
+trait T { m!(); } //~ ERROR cannot find macro `m` in this scope
 
 struct S;
-impl S { m!(); } //~ ERROR cannot find macro `m!` in this scope
+impl S { m!(); } //~ ERROR cannot find macro `m` in this scope
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-40845.stderr b/src/test/ui/issues/issue-40845.stderr
index a8be38ebf0657..2744330a4e58e 100644
--- a/src/test/ui/issues/issue-40845.stderr
+++ b/src/test/ui/issues/issue-40845.stderr
@@ -1,10 +1,10 @@
-error: cannot find macro `m!` in this scope
+error: cannot find macro `m` in this scope
   --> $DIR/issue-40845.rs:4:10
    |
 LL | impl S { m!(); }
    |          ^
 
-error: cannot find macro `m!` in this scope
+error: cannot find macro `m` in this scope
   --> $DIR/issue-40845.rs:1:11
    |
 LL | trait T { m!(); }
diff --git a/src/test/ui/issues/issue-49074.rs b/src/test/ui/issues/issue-49074.rs
index f909add5f5891..752bb345b703e 100644
--- a/src/test/ui/issues/issue-49074.rs
+++ b/src/test/ui/issues/issue-49074.rs
@@ -9,5 +9,5 @@ mod foo {
 }
 
 fn main() {
-   bar!(); //~ ERROR cannot find macro `bar!` in this scope
+   bar!(); //~ ERROR cannot find macro `bar` in this scope
 }
diff --git a/src/test/ui/issues/issue-49074.stderr b/src/test/ui/issues/issue-49074.stderr
index 42d0b511fc5e4..bbfeb4ea9483a 100644
--- a/src/test/ui/issues/issue-49074.stderr
+++ b/src/test/ui/issues/issue-49074.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `bar!` in this scope
+error: cannot find macro `bar` in this scope
   --> $DIR/issue-49074.rs:12:4
    |
 LL |    bar!();
diff --git a/src/test/ui/macros/macro-expansion-tests.stderr b/src/test/ui/macros/macro-expansion-tests.stderr
index 4ad9ade95a052..8b3f7ca88171c 100644
--- a/src/test/ui/macros/macro-expansion-tests.stderr
+++ b/src/test/ui/macros/macro-expansion-tests.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `m!` in this scope
+error: cannot find macro `m` in this scope
   --> $DIR/macro-expansion-tests.rs:7:21
    |
 LL |     fn g() -> i32 { m!() }
@@ -6,7 +6,7 @@ LL |     fn g() -> i32 { m!() }
    |
    = help: have you added the `#[macro_use]` on the module/import?
 
-error: cannot find macro `m!` in this scope
+error: cannot find macro `m` in this scope
   --> $DIR/macro-expansion-tests.rs:15:21
    |
 LL |     fn g() -> i32 { m!() }
diff --git a/src/test/ui/macros/macro-name-typo.stderr b/src/test/ui/macros/macro-name-typo.stderr
index 967f4f3c4ac4a..ce2e1985b38ce 100644
--- a/src/test/ui/macros/macro-name-typo.stderr
+++ b/src/test/ui/macros/macro-name-typo.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `printlx!` in this scope
+error: cannot find macro `printlx` in this scope
   --> $DIR/macro-name-typo.rs:2:5
    |
 LL |     printlx!("oh noes!");
diff --git a/src/test/ui/macros/macro-path-prelude-fail-3.rs b/src/test/ui/macros/macro-path-prelude-fail-3.rs
index 597053d625134..68eb350a95614 100644
--- a/src/test/ui/macros/macro-path-prelude-fail-3.rs
+++ b/src/test/ui/macros/macro-path-prelude-fail-3.rs
@@ -1,3 +1,3 @@
 fn main() {
-    inline!(); //~ ERROR cannot find macro `inline!` in this scope
+    inline!(); //~ ERROR cannot find macro `inline` in this scope
 }
diff --git a/src/test/ui/macros/macro-path-prelude-fail-3.stderr b/src/test/ui/macros/macro-path-prelude-fail-3.stderr
index 96b8a24cff293..ec00760de6c6f 100644
--- a/src/test/ui/macros/macro-path-prelude-fail-3.stderr
+++ b/src/test/ui/macros/macro-path-prelude-fail-3.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `inline!` in this scope
+error: cannot find macro `inline` in this scope
   --> $DIR/macro-path-prelude-fail-3.rs:2:5
    |
 LL |     inline!();
diff --git a/src/test/ui/macros/macro-use-wrong-name.stderr b/src/test/ui/macros/macro-use-wrong-name.stderr
index 28f727d6a5808..8b4e90a5798f1 100644
--- a/src/test/ui/macros/macro-use-wrong-name.stderr
+++ b/src/test/ui/macros/macro-use-wrong-name.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `macro_two!` in this scope
+error: cannot find macro `macro_two` in this scope
   --> $DIR/macro-use-wrong-name.rs:7:5
    |
 LL |     macro_two!();
diff --git a/src/test/ui/macros/macro_undefined.stderr b/src/test/ui/macros/macro_undefined.stderr
index 9239b2a51e62b..01c8ebea62a2c 100644
--- a/src/test/ui/macros/macro_undefined.stderr
+++ b/src/test/ui/macros/macro_undefined.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `k!` in this scope
+error: cannot find macro `k` in this scope
   --> $DIR/macro_undefined.rs:11:5
    |
 LL |     k!();
diff --git a/src/test/ui/missing/missing-macro-use.rs b/src/test/ui/missing/missing-macro-use.rs
index dff4c94fcf413..d494c4471a31c 100644
--- a/src/test/ui/missing/missing-macro-use.rs
+++ b/src/test/ui/missing/missing-macro-use.rs
@@ -4,5 +4,5 @@ extern crate two_macros;
 
 pub fn main() {
     macro_two!();
-    //~^ ERROR cannot find macro `macro_two!` in this scope
+    //~^ ERROR cannot find macro `macro_two` in this scope
 }
diff --git a/src/test/ui/missing/missing-macro-use.stderr b/src/test/ui/missing/missing-macro-use.stderr
index 01a7beb3b0502..711e249d2bca1 100644
--- a/src/test/ui/missing/missing-macro-use.stderr
+++ b/src/test/ui/missing/missing-macro-use.stderr
@@ -1,4 +1,4 @@
-error: cannot find macro `macro_two!` in this scope
+error: cannot find macro `macro_two` in this scope
   --> $DIR/missing-macro-use.rs:6:5
    |
 LL |     macro_two!();
diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs
index bc46a07dd3f4b..b17c0565932fd 100644
--- a/src/test/ui/proc-macro/macro-namespace-reserved-2.rs
+++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.rs
@@ -25,12 +25,12 @@ fn check_bang1() {
     my_macro!(); //~ ERROR can't use a procedural macro from the same crate that defines it
 }
 fn check_bang2() {
-    my_macro_attr!(); //~ ERROR cannot find macro `my_macro_attr!` in this scope
+    my_macro_attr!(); //~ ERROR cannot find macro `my_macro_attr` in this scope
     crate::my_macro_attr!(); //~ ERROR can't use a procedural macro from the same crate that defines
                              //~| ERROR expected macro, found attribute macro `crate::my_macro_attr`
 }
 fn check_bang3() {
-    MyTrait!(); //~ ERROR cannot find macro `MyTrait!` in this scope
+    MyTrait!(); //~ ERROR cannot find macro `MyTrait` in this scope
     crate::MyTrait!(); //~ ERROR can't use a procedural macro from the same crate that defines it
                        //~| ERROR expected macro, found derive macro `crate::MyTrait`
 }
diff --git a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
index 9616e80fa64c7..c011a70cd0c84 100644
--- a/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
+++ b/src/test/ui/proc-macro/macro-namespace-reserved-2.stderr
@@ -88,13 +88,13 @@ error: expected derive macro, found macro `crate::my_macro`
 LL | #[derive(crate::my_macro)]
    |          ^^^^^^^^^^^^^^^ not a derive macro
 
-error: cannot find macro `my_macro_attr!` in this scope
+error: cannot find macro `my_macro_attr` in this scope
   --> $DIR/macro-namespace-reserved-2.rs:28:5
    |
 LL |     my_macro_attr!();
    |     ^^^^^^^^^^^^^
 
-error: cannot find macro `MyTrait!` in this scope
+error: cannot find macro `MyTrait` in this scope
   --> $DIR/macro-namespace-reserved-2.rs:33:5
    |
 LL |     MyTrait!();
diff --git a/src/test/ui/proc-macro/resolve-error.stderr b/src/test/ui/proc-macro/resolve-error.stderr
index 6c242cf45d64c..3dca5cee63caa 100644
--- a/src/test/ui/proc-macro/resolve-error.stderr
+++ b/src/test/ui/proc-macro/resolve-error.stderr
@@ -1,22 +1,22 @@
-error: cannot find macro `bang_proc_macrp!` in this scope
+error: cannot find macro `bang_proc_macrp` in this scope
   --> $DIR/resolve-error.rs:56:5
    |
 LL |     bang_proc_macrp!();
    |     ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `bang_proc_macro`
 
-error: cannot find macro `Dlona!` in this scope
+error: cannot find macro `Dlona` in this scope
   --> $DIR/resolve-error.rs:53:5
    |
 LL |     Dlona!();
    |     ^^^^^
 
-error: cannot find macro `attr_proc_macra!` in this scope
+error: cannot find macro `attr_proc_macra` in this scope
   --> $DIR/resolve-error.rs:50:5
    |
 LL |     attr_proc_macra!();
    |     ^^^^^^^^^^^^^^^ help: a macro with a similar name exists: `attr_proc_mac`
 
-error: cannot find macro `FooWithLongNama!` in this scope
+error: cannot find macro `FooWithLongNama` in this scope
   --> $DIR/resolve-error.rs:47:5
    |
 LL |     FooWithLongNama!();
diff --git a/src/test/ui/resolve/visibility-indeterminate.rs b/src/test/ui/resolve/visibility-indeterminate.rs
index 198ea752881f1..0e1142db37d2d 100644
--- a/src/test/ui/resolve/visibility-indeterminate.rs
+++ b/src/test/ui/resolve/visibility-indeterminate.rs
@@ -1,6 +1,6 @@
 // edition:2018
 
-foo!(); //~ ERROR cannot find macro `foo!` in this scope
+foo!(); //~ ERROR cannot find macro `foo` in this scope
 
 pub(in ::bar) struct Baz {} //~ ERROR cannot determine resolution for the visibility
 
diff --git a/src/test/ui/resolve/visibility-indeterminate.stderr b/src/test/ui/resolve/visibility-indeterminate.stderr
index 17927a5967dcb..b9678291ee40b 100644
--- a/src/test/ui/resolve/visibility-indeterminate.stderr
+++ b/src/test/ui/resolve/visibility-indeterminate.stderr
@@ -4,7 +4,7 @@ error[E0578]: cannot determine resolution for the visibility
 LL | pub(in ::bar) struct Baz {}
    |        ^^^^^
 
-error: cannot find macro `foo!` in this scope
+error: cannot find macro `foo` in this scope
   --> $DIR/visibility-indeterminate.rs:3:1
    |
 LL | foo!();
diff --git a/src/test/ui/self/self_type_keyword.rs b/src/test/ui/self/self_type_keyword.rs
index 844f13c2f896a..dfb7d6583d9dd 100644
--- a/src/test/ui/self/self_type_keyword.rs
+++ b/src/test/ui/self/self_type_keyword.rs
@@ -19,7 +19,7 @@ pub fn main() {
         ref mut Self => (),
         //~^ ERROR expected identifier, found keyword `Self`
         Self!() => (),
-        //~^ ERROR cannot find macro `Self!` in this scope
+        //~^ ERROR cannot find macro `Self` in this scope
         Foo { Self } => (),
         //~^ ERROR expected identifier, found keyword `Self`
     }
diff --git a/src/test/ui/self/self_type_keyword.stderr b/src/test/ui/self/self_type_keyword.stderr
index bb631194bf3df..11b3b012c5f5e 100644
--- a/src/test/ui/self/self_type_keyword.stderr
+++ b/src/test/ui/self/self_type_keyword.stderr
@@ -54,7 +54,7 @@ error: lifetimes cannot use keyword names
 LL | struct Bar<'Self>;
    |            ^^^^^
 
-error: cannot find macro `Self!` in this scope
+error: cannot find macro `Self` in this scope
   --> $DIR/self_type_keyword.rs:21:9
    |
 LL |         Self!() => (),
diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs
index 72929c5e80590..d5698be8d4c57 100644
--- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs
+++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.rs
@@ -11,7 +11,7 @@ fn check() {}
 #[rustfmt::skip] // OK
 fn main() {
     rustfmt; //~ ERROR expected value, found tool module `rustfmt`
-    rustfmt!(); //~ ERROR cannot find macro `rustfmt!` in this scope
+    rustfmt!(); //~ ERROR cannot find macro `rustfmt` in this scope
 
     rustfmt::skip; //~ ERROR expected value, found tool attribute `rustfmt::skip`
 }
diff --git a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr
index 393ad0949cc4b..6bef793e0e71b 100644
--- a/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr
+++ b/src/test/ui/tool-attributes/tool-attributes-misplaced-1.stderr
@@ -10,7 +10,7 @@ error: cannot find attribute `rustfmt` in this scope
 LL | #[rustfmt]
    |   ^^^^^^^
 
-error: cannot find macro `rustfmt!` in this scope
+error: cannot find macro `rustfmt` in this scope
   --> $DIR/tool-attributes-misplaced-1.rs:14:5
    |
 LL |     rustfmt!();

From 613769193397374485485fed2d9ba3ea2eee5077 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Aug 2019 19:54:54 +0200
Subject: [PATCH 760/943] const interning: move mutability computation into
 intern_shallow, and always intern constants as immutable

---
 src/librustc_mir/interpret/intern.rs          | 125 +++++++++---------
 .../mutable_references_ice.stderr             |   2 +-
 2 files changed, 60 insertions(+), 67 deletions(-)

diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 4cbbc0ffe17cc..e05b31477e175 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -3,7 +3,7 @@
 //! After a const evaluation has computed a value, before we destroy the const evaluator's session
 //! memory, we need to extract all memory allocations to the global memory pool so they stay around.
 
-use rustc::ty::{Ty, TyCtxt, ParamEnv, self};
+use rustc::ty::{Ty, ParamEnv, self};
 use rustc::mir::interpret::{InterpResult, ErrorHandled};
 use rustc::hir;
 use rustc::hir::def_id::DefId;
@@ -11,10 +11,9 @@ use super::validity::RefTracking;
 use rustc_data_structures::fx::FxHashSet;
 
 use syntax::ast::Mutability;
-use syntax_pos::Span;
 
 use super::{
-    ValueVisitor, MemoryKind, Pointer, AllocId, MPlaceTy, Scalar,
+    ValueVisitor, MemoryKind, AllocId, MPlaceTy, Scalar,
 };
 use crate::const_eval::{CompileTimeInterpreter, CompileTimeEvalContext};
 
@@ -27,12 +26,10 @@ struct InternVisitor<'rt, 'mir, 'tcx> {
     /// for sanity assertions that will ICE when `const_qualif` screws up.
     mode: InternMode,
     /// This field stores the mutability of the value *currently* being checked.
-    /// It is set to mutable when an `UnsafeCell` is encountered
-    /// When recursing across a reference, we don't recurse but store the
-    /// value to be checked in `ref_tracking` together with the mutability at which we are checking
-    /// the value.
-    /// When encountering an immutable reference, we treat everything as immutable that is behind
-    /// it.
+    /// When encountering a mutable reference, we determine the pointee mutability
+    /// taking into account the mutability of the context: `& &mut i32` is entirely immutable,
+    /// despite the nested mutable reference!
+    /// The field gets updated when an `UnsafeCell` is encountered.
     mutability: Mutability,
     /// A list of all encountered relocations. After type-based interning, we traverse this list to
     /// also intern allocations that are only referenced by a raw pointer or inside a union.
@@ -45,9 +42,10 @@ enum InternMode {
     /// `static`. In a `static mut` we start out as mutable and thus can also contain further `&mut`
     /// that will actually be treated as mutable.
     Static,
-    /// UnsafeCell is OK in the value of a constant, but not behind references in a constant
+    /// UnsafeCell is OK in the value of a constant: `const FOO = Cell::new(0)` creates
+    /// a new cell every time it is used.
     ConstBase,
-    /// `UnsafeCell` ICEs
+    /// `UnsafeCell` ICEs.
     Const,
 }
 
@@ -56,26 +54,31 @@ enum InternMode {
 struct IsStaticOrFn;
 
 impl<'rt, 'mir, 'tcx> InternVisitor<'rt, 'mir, 'tcx> {
-    /// Intern an allocation without looking at its children
+    /// Intern an allocation without looking at its children.
+    /// `mutablity` is the mutability of the place to be interned; even if that says
+    /// `immutable` things might become mutable if `ty` is not frozen.
     fn intern_shallow(
         &mut self,
-        ptr: Pointer,
+        alloc_id: AllocId,
         mutability: Mutability,
+        ty: Option<Ty<'tcx>>,
     ) -> InterpResult<'tcx, Option<IsStaticOrFn>> {
         trace!(
             "InternVisitor::intern {:?} with {:?}",
-            ptr, mutability,
+            alloc_id, mutability,
         );
         // remove allocation
         let tcx = self.ecx.tcx;
         let memory = self.ecx.memory_mut();
-        let (kind, mut alloc) = match memory.alloc_map.remove(&ptr.alloc_id) {
+        let (kind, mut alloc) = match memory.alloc_map.remove(&alloc_id) {
             Some(entry) => entry,
             None => {
-                // if the pointer is dangling (neither in local nor global memory), we leave it
+                // Pointer not found in local memory map. It is either a pointer to the global
+                // map, or dangling.
+                // If the pointer is dangling (neither in local nor global memory), we leave it
                 // to validation to error. The `delay_span_bug` ensures that we don't forget such
                 // a check in validation.
-                if tcx.alloc_map.lock().get(ptr.alloc_id).is_none() {
+                if tcx.alloc_map.lock().get(alloc_id).is_none() {
                     tcx.sess.delay_span_bug(self.ecx.tcx.span, "tried to intern dangling pointer");
                 }
                 // treat dangling pointers like other statics
@@ -88,14 +91,35 @@ impl<'rt, 'mir, 'tcx> InternVisitor<'rt, 'mir, 'tcx> {
         match kind {
             MemoryKind::Stack | MemoryKind::Vtable => {},
         }
-        // Ensure llvm knows to only put this into immutable memory if the value is immutable either
-        // by being behind a reference or by being part of a static or const without interior
-        // mutability
-        alloc.mutability = mutability;
+        // Set allocation mutability as appropriate. This is used by LLVM to put things into
+        // read-only memory, and also by Miri when evluating other constants/statics that
+        // access this one.
+        if self.mode == InternMode::Static {
+            let frozen = ty.map_or(true, |ty| ty.is_freeze(
+                self.ecx.tcx.tcx,
+                self.param_env,
+                self.ecx.tcx.span,
+            ));
+            // For statics, allocation mutability is the combination of the place mutability and
+            // the type mutability.
+            // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
+            if mutability == Mutability::Immutable && frozen {
+                alloc.mutability = Mutability::Immutable;
+            } else {
+                // Just making sure we are not "upgrading" an immutable allocation to mutable.
+                assert_eq!(alloc.mutability, Mutability::Mutable);
+            }
+        } else {
+            // We *could* be non-frozen at `ConstBase`, for constants like `Cell::new(0)`.
+            // But we still intern that as immutable as the memory cannot be changed once the
+            // initial value was computed.
+            // Constants are never mutable.
+            alloc.mutability = Mutability::Immutable;
+        };
         // link the alloc id to the actual allocation
         let alloc = tcx.intern_const_alloc(alloc);
         self.leftover_relocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc));
-        tcx.alloc_map.lock().set_alloc_id_memory(ptr.alloc_id, alloc);
+        tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
         Ok(None)
     }
 }
@@ -119,14 +143,16 @@ for
     ) -> InterpResult<'tcx> {
         if let Some(def) = mplace.layout.ty.ty_adt_def() {
             if Some(def.did) == self.ecx.tcx.lang_items().unsafe_cell_type() {
-                // We are crossing over an `UnsafeCell`, we can mutate again
+                // We are crossing over an `UnsafeCell`, we can mutate again. This means that
+                // References we encounter inside here are interned as pointing to mutable
+                // allocations.
                 let old = std::mem::replace(&mut self.mutability, Mutability::Mutable);
                 assert_ne!(
                     self.mode, InternMode::Const,
                     "UnsafeCells are not allowed behind references in constants. This should have \
                     been prevented statically by const qualification. If this were allowed one \
-                    would be able to change a constant at one use site and other use sites may \
-                    arbitrarily decide to change, too.",
+                    would be able to change a constant at one use site and other use sites could \
+                    observe that mutation.",
                 );
                 let walked = self.walk_aggregate(mplace, fields);
                 self.mutability = old;
@@ -150,7 +176,7 @@ for
                     if let Ok(vtable) = meta.unwrap().to_ptr() {
                         // explitly choose `Immutable` here, since vtables are immutable, even
                         // if the reference of the fat pointer is mutable
-                        self.intern_shallow(vtable, Mutability::Immutable)?;
+                        self.intern_shallow(vtable.alloc_id, Mutability::Immutable, None)?;
                     }
                 }
             }
@@ -195,21 +221,13 @@ for
                     (Mutability::Mutable, hir::Mutability::MutMutable) => Mutability::Mutable,
                     _ => Mutability::Immutable,
                 };
-                // Compute the mutability of the allocation
-                let intern_mutability = intern_mutability(
-                    self.ecx.tcx.tcx,
-                    self.param_env,
-                    mplace.layout.ty,
-                    self.ecx.tcx.span,
-                    mutability,
-                );
                 // Recursing behind references changes the intern mode for constants in order to
                 // cause assertions to trigger if we encounter any `UnsafeCell`s.
                 let mode = match self.mode {
                     InternMode::ConstBase => InternMode::Const,
                     other => other,
                 };
-                match self.intern_shallow(ptr, intern_mutability)? {
+                match self.intern_shallow(ptr.alloc_id, mutability, Some(mplace.layout.ty))? {
                     // No need to recurse, these are interned already and statics may have
                     // cycles, so we don't want to recurse there
                     Some(IsStaticOrFn) => {},
@@ -224,23 +242,6 @@ for
     }
 }
 
-/// Figure out the mutability of the allocation.
-/// Mutable if it has interior mutability *anywhere* in the type.
-fn intern_mutability<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    param_env: ParamEnv<'tcx>,
-    ty: Ty<'tcx>,
-    span: Span,
-    mutability: Mutability,
-) -> Mutability {
-    let has_interior_mutability = !ty.is_freeze(tcx, param_env, span);
-    if has_interior_mutability {
-        Mutability::Mutable
-    } else {
-        mutability
-    }
-}
-
 pub fn intern_const_alloc_recursive(
     ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
     def_id: DefId,
@@ -251,7 +252,7 @@ pub fn intern_const_alloc_recursive(
 ) -> InterpResult<'tcx> {
     let tcx = ecx.tcx;
     // this `mutability` is the mutability of the place, ignoring the type
-    let (mutability, base_intern_mode) = match tcx.static_mutability(def_id) {
+    let (base_mutability, base_intern_mode) = match tcx.static_mutability(def_id) {
         Some(hir::Mutability::MutImmutable) => (Mutability::Immutable, InternMode::Static),
         None => (Mutability::Immutable, InternMode::ConstBase),
         // `static mut` doesn't care about interior mutability, it's mutable anyway
@@ -259,17 +260,9 @@ pub fn intern_const_alloc_recursive(
     };
 
     // type based interning
-    let mut ref_tracking = RefTracking::new((ret, mutability, base_intern_mode));
+    let mut ref_tracking = RefTracking::new((ret, base_mutability, base_intern_mode));
     let leftover_relocations = &mut FxHashSet::default();
 
-    // This mutability is the combination of the place mutability and the type mutability. If either
-    // is mutable, `alloc_mutability` is mutable. This exists because the entire allocation needs
-    // to be mutable if it contains an `UnsafeCell` anywhere. The other `mutability` exists so that
-    // the visitor does not treat everything outside the `UnsafeCell` as mutable.
-    let alloc_mutability = intern_mutability(
-        tcx.tcx, param_env, ret.layout.ty, tcx.span, mutability,
-    );
-
     // start with the outermost allocation
     InternVisitor {
         ref_tracking: &mut ref_tracking,
@@ -277,8 +270,8 @@ pub fn intern_const_alloc_recursive(
         mode: base_intern_mode,
         leftover_relocations,
         param_env,
-        mutability,
-    }.intern_shallow(ret.ptr.to_ptr()?, alloc_mutability)?;
+        mutability: base_mutability,
+    }.intern_shallow(ret.ptr.to_ptr()?.alloc_id, base_mutability, Some(ret.layout.ty))?;
 
     while let Some(((mplace, mutability, mode), _)) = ref_tracking.todo.pop() {
         let interned = InternVisitor {
@@ -312,8 +305,8 @@ pub fn intern_const_alloc_recursive(
     let mut todo: Vec<_> = leftover_relocations.iter().cloned().collect();
     while let Some(alloc_id) = todo.pop() {
         if let Some((_, alloc)) = ecx.memory_mut().alloc_map.remove(&alloc_id) {
-            // We can't call the `intern` method here, as its logic is tailored to safe references.
-            // So we hand-roll the interning logic here again
+            // We can't call the `intern_shallow` method here, as its logic is tailored to safe
+            // references. So we hand-roll the interning logic here again.
             let alloc = tcx.intern_const_alloc(alloc);
             tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
             for &(_, ((), reloc)) in alloc.relocations().iter() {
diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr
index 82569e260143c..28cf3537d605a 100644
--- a/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr
+++ b/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr
@@ -6,7 +6,7 @@ LL |         *MUH.x.get() = 99;
 
 thread 'rustc' panicked at 'assertion failed: `(left != right)`
   left: `Const`,
- right: `Const`: UnsafeCells are not allowed behind references in constants. This should have been prevented statically by const qualification. If this were allowed one would be able to change a constant at one use site and other use sites may arbitrarily decide to change, too.', src/librustc_mir/interpret/intern.rs:LL:CC
+ right: `Const`: UnsafeCells are not allowed behind references in constants. This should have been prevented statically by const qualification. If this were allowed one would be able to change a constant at one use site and other use sites could observe that mutation.', src/librustc_mir/interpret/intern.rs:LL:CC
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
 
 error: internal compiler error: unexpected panic

From 7b8693eff85d39d7b836fa45cdcf30507d7f8731 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Aug 2019 20:59:34 +0200
Subject: [PATCH 761/943] all memory behind a constant must be immutable

---
 src/librustc_mir/interpret/intern.rs          |  7 ++++-
 .../ui/consts/miri_unleashed/mutable_const.rs | 20 ++++++++++++++
 .../miri_unleashed/mutable_const.stderr       | 27 +++++++++++++++++++
 3 files changed, 53 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/consts/miri_unleashed/mutable_const.rs
 create mode 100644 src/test/ui/consts/miri_unleashed/mutable_const.stderr

diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index e05b31477e175..6333fce2c47f2 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -304,9 +304,14 @@ pub fn intern_const_alloc_recursive(
 
     let mut todo: Vec<_> = leftover_relocations.iter().cloned().collect();
     while let Some(alloc_id) = todo.pop() {
-        if let Some((_, alloc)) = ecx.memory_mut().alloc_map.remove(&alloc_id) {
+        if let Some((_, mut alloc)) = ecx.memory_mut().alloc_map.remove(&alloc_id) {
             // We can't call the `intern_shallow` method here, as its logic is tailored to safe
             // references. So we hand-roll the interning logic here again.
+            if base_intern_mode != InternMode::Static {
+                // If it's not a static, it *must* be immutable.
+                // We cannot have mutable memory inside a constant.
+                alloc.mutability = Mutability::Immutable;
+            }
             let alloc = tcx.intern_const_alloc(alloc);
             tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
             for &(_, ((), reloc)) in alloc.relocations().iter() {
diff --git a/src/test/ui/consts/miri_unleashed/mutable_const.rs b/src/test/ui/consts/miri_unleashed/mutable_const.rs
new file mode 100644
index 0000000000000..b476e04529a52
--- /dev/null
+++ b/src/test/ui/consts/miri_unleashed/mutable_const.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Zunleash-the-miri-inside-of-you
+
+#![feature(const_raw_ptr_deref)]
+#![deny(const_err)]
+
+use std::cell::UnsafeCell;
+
+// make sure we do not just intern this as mutable
+const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
+
+const MUTATING_BEHIND_RAW: () = {
+    // Test that `MUTABLE_BEHIND_RAW` is actually immutable, by doing this at const time.
+    unsafe {
+        *MUTABLE_BEHIND_RAW = 99 //~ WARN skipping const checks
+        //~^ ERROR any use of this value will cause an error
+        //~^^ tried to modify constant memory
+    }
+};
+
+fn main() {}
diff --git a/src/test/ui/consts/miri_unleashed/mutable_const.stderr b/src/test/ui/consts/miri_unleashed/mutable_const.stderr
new file mode 100644
index 0000000000000..507d4823a111d
--- /dev/null
+++ b/src/test/ui/consts/miri_unleashed/mutable_const.stderr
@@ -0,0 +1,27 @@
+warning: skipping const checks
+  --> $DIR/mutable_const.rs:14:9
+   |
+LL |         *MUTABLE_BEHIND_RAW = 99
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: any use of this value will cause an error
+  --> $DIR/mutable_const.rs:14:9
+   |
+LL | / const MUTATING_BEHIND_RAW: () = {
+LL | |     // Test that `MUTABLE_BEHIND_RAW` is actually immutable, by doing this at const time.
+LL | |     unsafe {
+LL | |         *MUTABLE_BEHIND_RAW = 99
+   | |         ^^^^^^^^^^^^^^^^^^^^^^^^ tried to modify constant memory
+...  |
+LL | |     }
+LL | | };
+   | |__-
+   |
+note: lint level defined here
+  --> $DIR/mutable_const.rs:4:9
+   |
+LL | #![deny(const_err)]
+   |         ^^^^^^^^^
+
+error: aborting due to previous error
+

From 75c82b4dd8152562ff2056f2172b20aa9c46def2 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Aug 2019 21:13:05 +0200
Subject: [PATCH 762/943] drop redundant ParamEnv, and avoid constructing
 InternVisitor without visiting

---
 src/librustc_mir/const_eval.rs       |   6 +-
 src/librustc_mir/interpret/intern.rs | 170 +++++++++++++++------------
 2 files changed, 95 insertions(+), 81 deletions(-)

diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 57ddaa4eff038..3f53f842f314f 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -134,9 +134,8 @@ fn eval_body_using_ecx<'mir, 'tcx>(
     ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
     cid: GlobalId<'tcx>,
     body: &'mir mir::Body<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
 ) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
-    debug!("eval_body_using_ecx: {:?}, {:?}", cid, param_env);
+    debug!("eval_body_using_ecx: {:?}, {:?}", cid, ecx.param_env);
     let tcx = ecx.tcx.tcx;
     let layout = ecx.layout_of(body.return_ty().subst(tcx, cid.instance.substs))?;
     assert!(!layout.is_unsized());
@@ -162,7 +161,6 @@ fn eval_body_using_ecx<'mir, 'tcx>(
         ecx,
         cid.instance.def_id(),
         ret,
-        param_env,
     )?;
 
     debug!("eval_body_using_ecx done: {:?}", *ret);
@@ -658,7 +656,7 @@ pub fn const_eval_raw_provider<'tcx>(
 
     let res = ecx.load_mir(cid.instance.def, cid.promoted);
     res.and_then(
-        |body| eval_body_using_ecx(&mut ecx, cid, body, key.param_env)
+        |body| eval_body_using_ecx(&mut ecx, cid, body)
     ).and_then(|place| {
         Ok(RawConst {
             alloc_id: place.ptr.assert_ptr().alloc_id,
diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 6333fce2c47f2..b657a33db516e 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -3,7 +3,7 @@
 //! After a const evaluation has computed a value, before we destroy the const evaluator's session
 //! memory, we need to extract all memory allocations to the global memory pool so they stay around.
 
-use rustc::ty::{Ty, ParamEnv, self};
+use rustc::ty::{Ty, self};
 use rustc::mir::interpret::{InterpResult, ErrorHandled};
 use rustc::hir;
 use rustc::hir::def_id::DefId;
@@ -18,10 +18,10 @@ use super::{
 use crate::const_eval::{CompileTimeInterpreter, CompileTimeEvalContext};
 
 struct InternVisitor<'rt, 'mir, 'tcx> {
-    /// previously encountered safe references
-    ref_tracking: &'rt mut RefTracking<(MPlaceTy<'tcx>, Mutability, InternMode)>,
+    /// The ectx from which we intern.
     ecx: &'rt mut CompileTimeEvalContext<'mir, 'tcx>,
-    param_env: ParamEnv<'tcx>,
+    /// Previously encountered safe references.
+    ref_tracking: &'rt mut RefTracking<(MPlaceTy<'tcx>, Mutability, InternMode)>,
     /// The root node of the value that we're looking at. This field is never mutated and only used
     /// for sanity assertions that will ICE when `const_qualif` screws up.
     mode: InternMode,
@@ -53,74 +53,93 @@ enum InternMode {
 /// into the memory of other constants or statics
 struct IsStaticOrFn;
 
+/// Intern an allocation without looking at its children.
+/// `mode` is the mode of the environment where we found this pointer.
+/// `mutablity` is the mutability of the place to be interned; even if that says
+/// `immutable` things might become mutable if `ty` is not frozen.
+fn intern_shallow<'rt, 'mir, 'tcx>(
+    ecx: &'rt mut CompileTimeEvalContext<'mir, 'tcx>,
+    leftover_relocations: &'rt mut FxHashSet<AllocId>,
+    mode: InternMode,
+    alloc_id: AllocId,
+    mutability: Mutability,
+    ty: Option<Ty<'tcx>>,
+) -> InterpResult<'tcx, Option<IsStaticOrFn>> {
+    trace!(
+        "InternVisitor::intern {:?} with {:?}",
+        alloc_id, mutability,
+    );
+    // remove allocation
+    let tcx = ecx.tcx;
+    let memory = ecx.memory_mut();
+    let (kind, mut alloc) = match memory.alloc_map.remove(&alloc_id) {
+        Some(entry) => entry,
+        None => {
+            // Pointer not found in local memory map. It is either a pointer to the global
+            // map, or dangling.
+            // If the pointer is dangling (neither in local nor global memory), we leave it
+            // to validation to error. The `delay_span_bug` ensures that we don't forget such
+            // a check in validation.
+            if tcx.alloc_map.lock().get(alloc_id).is_none() {
+                tcx.sess.delay_span_bug(ecx.tcx.span, "tried to intern dangling pointer");
+            }
+            // treat dangling pointers like other statics
+            // just to stop trying to recurse into them
+            return Ok(Some(IsStaticOrFn));
+        },
+    };
+    // This match is just a canary for future changes to `MemoryKind`, which most likely need
+    // changes in this function.
+    match kind {
+        MemoryKind::Stack | MemoryKind::Vtable => {},
+    }
+    // Set allocation mutability as appropriate. This is used by LLVM to put things into
+    // read-only memory, and also by Miri when evluating other constants/statics that
+    // access this one.
+    if mode == InternMode::Static {
+        let frozen = ty.map_or(true, |ty| ty.is_freeze(
+            ecx.tcx.tcx,
+            ecx.param_env,
+            ecx.tcx.span,
+        ));
+        // For statics, allocation mutability is the combination of the place mutability and
+        // the type mutability.
+        // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
+        if mutability == Mutability::Immutable && frozen {
+            alloc.mutability = Mutability::Immutable;
+        } else {
+            // Just making sure we are not "upgrading" an immutable allocation to mutable.
+            assert_eq!(alloc.mutability, Mutability::Mutable);
+        }
+    } else {
+        // We *could* be non-frozen at `ConstBase`, for constants like `Cell::new(0)`.
+        // But we still intern that as immutable as the memory cannot be changed once the
+        // initial value was computed.
+        // Constants are never mutable.
+        alloc.mutability = Mutability::Immutable;
+    };
+    // link the alloc id to the actual allocation
+    let alloc = tcx.intern_const_alloc(alloc);
+    leftover_relocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc));
+    tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
+    Ok(None)
+}
+
 impl<'rt, 'mir, 'tcx> InternVisitor<'rt, 'mir, 'tcx> {
-    /// Intern an allocation without looking at its children.
-    /// `mutablity` is the mutability of the place to be interned; even if that says
-    /// `immutable` things might become mutable if `ty` is not frozen.
     fn intern_shallow(
         &mut self,
         alloc_id: AllocId,
         mutability: Mutability,
         ty: Option<Ty<'tcx>>,
     ) -> InterpResult<'tcx, Option<IsStaticOrFn>> {
-        trace!(
-            "InternVisitor::intern {:?} with {:?}",
-            alloc_id, mutability,
-        );
-        // remove allocation
-        let tcx = self.ecx.tcx;
-        let memory = self.ecx.memory_mut();
-        let (kind, mut alloc) = match memory.alloc_map.remove(&alloc_id) {
-            Some(entry) => entry,
-            None => {
-                // Pointer not found in local memory map. It is either a pointer to the global
-                // map, or dangling.
-                // If the pointer is dangling (neither in local nor global memory), we leave it
-                // to validation to error. The `delay_span_bug` ensures that we don't forget such
-                // a check in validation.
-                if tcx.alloc_map.lock().get(alloc_id).is_none() {
-                    tcx.sess.delay_span_bug(self.ecx.tcx.span, "tried to intern dangling pointer");
-                }
-                // treat dangling pointers like other statics
-                // just to stop trying to recurse into them
-                return Ok(Some(IsStaticOrFn));
-            },
-        };
-        // This match is just a canary for future changes to `MemoryKind`, which most likely need
-        // changes in this function.
-        match kind {
-            MemoryKind::Stack | MemoryKind::Vtable => {},
-        }
-        // Set allocation mutability as appropriate. This is used by LLVM to put things into
-        // read-only memory, and also by Miri when evluating other constants/statics that
-        // access this one.
-        if self.mode == InternMode::Static {
-            let frozen = ty.map_or(true, |ty| ty.is_freeze(
-                self.ecx.tcx.tcx,
-                self.param_env,
-                self.ecx.tcx.span,
-            ));
-            // For statics, allocation mutability is the combination of the place mutability and
-            // the type mutability.
-            // The entire allocation needs to be mutable if it contains an `UnsafeCell` anywhere.
-            if mutability == Mutability::Immutable && frozen {
-                alloc.mutability = Mutability::Immutable;
-            } else {
-                // Just making sure we are not "upgrading" an immutable allocation to mutable.
-                assert_eq!(alloc.mutability, Mutability::Mutable);
-            }
-        } else {
-            // We *could* be non-frozen at `ConstBase`, for constants like `Cell::new(0)`.
-            // But we still intern that as immutable as the memory cannot be changed once the
-            // initial value was computed.
-            // Constants are never mutable.
-            alloc.mutability = Mutability::Immutable;
-        };
-        // link the alloc id to the actual allocation
-        let alloc = tcx.intern_const_alloc(alloc);
-        self.leftover_relocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc));
-        tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
-        Ok(None)
+        intern_shallow(
+            self.ecx,
+            self.leftover_relocations,
+            self.mode,
+            alloc_id,
+            mutability,
+            ty,
+        )
     }
 }
 
@@ -171,7 +190,8 @@ for
             // Handle trait object vtables
             if let Ok(meta) = value.to_meta() {
                 if let ty::Dynamic(..) =
-                    self.ecx.tcx.struct_tail_erasing_lifetimes(referenced_ty, self.param_env).sty
+                    self.ecx.tcx.struct_tail_erasing_lifetimes(
+                        referenced_ty, self.ecx.param_env).sty
                 {
                     if let Ok(vtable) = meta.unwrap().to_ptr() {
                         // explitly choose `Immutable` here, since vtables are immutable, even
@@ -203,7 +223,7 @@ for
                     (InternMode::Const, hir::Mutability::MutMutable) => {
                         match referenced_ty.sty {
                             ty::Array(_, n)
-                                if n.eval_usize(self.ecx.tcx.tcx, self.param_env) == 0 => {}
+                                if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {}
                             ty::Slice(_)
                                 if value.to_meta().unwrap().unwrap().to_usize(self.ecx)? == 0 => {}
                             _ => bug!("const qualif failed to prevent mutable references"),
@@ -246,9 +266,6 @@ pub fn intern_const_alloc_recursive(
     ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
     def_id: DefId,
     ret: MPlaceTy<'tcx>,
-    // FIXME(oli-obk): can we scrap the param env? I think we can, the final value of a const eval
-    // must always be monomorphic, right?
-    param_env: ty::ParamEnv<'tcx>,
 ) -> InterpResult<'tcx> {
     let tcx = ecx.tcx;
     // this `mutability` is the mutability of the place, ignoring the type
@@ -264,14 +281,14 @@ pub fn intern_const_alloc_recursive(
     let leftover_relocations = &mut FxHashSet::default();
 
     // start with the outermost allocation
-    InternVisitor {
-        ref_tracking: &mut ref_tracking,
+    intern_shallow(
         ecx,
-        mode: base_intern_mode,
         leftover_relocations,
-        param_env,
-        mutability: base_mutability,
-    }.intern_shallow(ret.ptr.to_ptr()?.alloc_id, base_mutability, Some(ret.layout.ty))?;
+        base_intern_mode,
+        ret.ptr.to_ptr()?.alloc_id,
+        base_mutability,
+        Some(ret.layout.ty)
+    )?;
 
     while let Some(((mplace, mutability, mode), _)) = ref_tracking.todo.pop() {
         let interned = InternVisitor {
@@ -279,7 +296,6 @@ pub fn intern_const_alloc_recursive(
             ecx,
             mode,
             leftover_relocations,
-            param_env,
             mutability,
         }.visit_value(mplace);
         if let Err(error) = interned {

From b1d4d2bfeaf45c9f3132b863867888ec89d1d40e Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Aug 2019 21:15:55 +0200
Subject: [PATCH 763/943] relocations -> allocations

---
 src/librustc_mir/interpret/intern.rs | 31 ++++++++++++++++------------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index b657a33db516e..85bc88c86c277 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -22,6 +22,9 @@ struct InternVisitor<'rt, 'mir, 'tcx> {
     ecx: &'rt mut CompileTimeEvalContext<'mir, 'tcx>,
     /// Previously encountered safe references.
     ref_tracking: &'rt mut RefTracking<(MPlaceTy<'tcx>, Mutability, InternMode)>,
+    /// A list of all encountered allocations. After type-based interning, we traverse this list to
+    /// also intern allocations that are only referenced by a raw pointer or inside a union.
+    leftover_allocations: &'rt mut FxHashSet<AllocId>,
     /// The root node of the value that we're looking at. This field is never mutated and only used
     /// for sanity assertions that will ICE when `const_qualif` screws up.
     mode: InternMode,
@@ -31,9 +34,6 @@ struct InternVisitor<'rt, 'mir, 'tcx> {
     /// despite the nested mutable reference!
     /// The field gets updated when an `UnsafeCell` is encountered.
     mutability: Mutability,
-    /// A list of all encountered relocations. After type-based interning, we traverse this list to
-    /// also intern allocations that are only referenced by a raw pointer or inside a union.
-    leftover_relocations: &'rt mut FxHashSet<AllocId>,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Hash, Eq)]
@@ -59,7 +59,7 @@ struct IsStaticOrFn;
 /// `immutable` things might become mutable if `ty` is not frozen.
 fn intern_shallow<'rt, 'mir, 'tcx>(
     ecx: &'rt mut CompileTimeEvalContext<'mir, 'tcx>,
-    leftover_relocations: &'rt mut FxHashSet<AllocId>,
+    leftover_allocations: &'rt mut FxHashSet<AllocId>,
     mode: InternMode,
     alloc_id: AllocId,
     mutability: Mutability,
@@ -120,7 +120,7 @@ fn intern_shallow<'rt, 'mir, 'tcx>(
     };
     // link the alloc id to the actual allocation
     let alloc = tcx.intern_const_alloc(alloc);
-    leftover_relocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc));
+    leftover_allocations.extend(alloc.relocations().iter().map(|&(_, ((), reloc))| reloc));
     tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
     Ok(None)
 }
@@ -134,7 +134,7 @@ impl<'rt, 'mir, 'tcx> InternVisitor<'rt, 'mir, 'tcx> {
     ) -> InterpResult<'tcx, Option<IsStaticOrFn>> {
         intern_shallow(
             self.ecx,
-            self.leftover_relocations,
+            self.leftover_allocations,
             self.mode,
             alloc_id,
             mutability,
@@ -276,14 +276,18 @@ pub fn intern_const_alloc_recursive(
         Some(hir::Mutability::MutMutable) => (Mutability::Mutable, InternMode::Static),
     };
 
-    // type based interning
+    // Type based interning.
+    // `ref_tracking` tracks typed references we have seen and still need to crawl for
+    // more typed information inside them.
+    // `leftover_allocations` collects *all* allocations we see, because some might not
+    // be available in a typed way. They get interned at the end.
     let mut ref_tracking = RefTracking::new((ret, base_mutability, base_intern_mode));
-    let leftover_relocations = &mut FxHashSet::default();
+    let leftover_allocations = &mut FxHashSet::default();
 
     // start with the outermost allocation
     intern_shallow(
         ecx,
-        leftover_relocations,
+        leftover_allocations,
         base_intern_mode,
         ret.ptr.to_ptr()?.alloc_id,
         base_mutability,
@@ -295,7 +299,7 @@ pub fn intern_const_alloc_recursive(
             ref_tracking: &mut ref_tracking,
             ecx,
             mode,
-            leftover_relocations,
+            leftover_allocations,
             mutability,
         }.visit_value(mplace);
         if let Err(error) = interned {
@@ -318,11 +322,12 @@ pub fn intern_const_alloc_recursive(
     // Intern the rest of the allocations as mutable. These might be inside unions, padding, raw
     // pointers, ... So we can't intern them according to their type rules
 
-    let mut todo: Vec<_> = leftover_relocations.iter().cloned().collect();
+    let mut todo: Vec<_> = leftover_allocations.iter().cloned().collect();
     while let Some(alloc_id) = todo.pop() {
         if let Some((_, mut alloc)) = ecx.memory_mut().alloc_map.remove(&alloc_id) {
             // We can't call the `intern_shallow` method here, as its logic is tailored to safe
-            // references. So we hand-roll the interning logic here again.
+            // references and a `leftover_allocations` set (where we only have a todo-list here).
+            // So we hand-roll the interning logic here again.
             if base_intern_mode != InternMode::Static {
                 // If it's not a static, it *must* be immutable.
                 // We cannot have mutable memory inside a constant.
@@ -331,7 +336,7 @@ pub fn intern_const_alloc_recursive(
             let alloc = tcx.intern_const_alloc(alloc);
             tcx.alloc_map.lock().set_alloc_id_memory(alloc_id, alloc);
             for &(_, ((), reloc)) in alloc.relocations().iter() {
-                if leftover_relocations.insert(reloc) {
+                if leftover_allocations.insert(reloc) {
                     todo.push(reloc);
                 }
             }

From 14e3506738e16ffdd1d913c371c9691e36e85b13 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 27 Aug 2019 21:24:30 +0200
Subject: [PATCH 764/943] note a FIXME

---
 src/librustc_mir/interpret/intern.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 85bc88c86c277..cf4f3fda090f3 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -331,6 +331,8 @@ pub fn intern_const_alloc_recursive(
             if base_intern_mode != InternMode::Static {
                 // If it's not a static, it *must* be immutable.
                 // We cannot have mutable memory inside a constant.
+                // FIXME: ideally we would assert that they already are immutable, to double-
+                // check our static checks.
                 alloc.mutability = Mutability::Immutable;
             }
             let alloc = tcx.intern_const_alloc(alloc);

From 342481185255acef5e44af8023bab372314afe51 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Wed, 28 Aug 2019 08:31:51 +0200
Subject: [PATCH 765/943] assert that nobody asks for mutable constants

---
 src/librustc_mir/interpret/intern.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index cf4f3fda090f3..606f506434579 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -116,6 +116,10 @@ fn intern_shallow<'rt, 'mir, 'tcx>(
         // But we still intern that as immutable as the memory cannot be changed once the
         // initial value was computed.
         // Constants are never mutable.
+        assert_eq!(
+            mutability, Mutability::Immutable,
+            "Something went very wrong: mutability requested for a constant"
+        );
         alloc.mutability = Mutability::Immutable;
     };
     // link the alloc id to the actual allocation

From 224e2e5e9e1d03db1a80455d08bb1d6d8686ec3a Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Wed, 28 Aug 2019 09:44:48 +0200
Subject: [PATCH 766/943] explain ty == None

---
 src/librustc_mir/interpret/intern.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 606f506434579..0031dbc4d0d40 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -57,6 +57,8 @@ struct IsStaticOrFn;
 /// `mode` is the mode of the environment where we found this pointer.
 /// `mutablity` is the mutability of the place to be interned; even if that says
 /// `immutable` things might become mutable if `ty` is not frozen.
+/// `ty` can be `None` if there is no potential interior mutability
+/// to account for (e.g. for vtables).
 fn intern_shallow<'rt, 'mir, 'tcx>(
     ecx: &'rt mut CompileTimeEvalContext<'mir, 'tcx>,
     leftover_allocations: &'rt mut FxHashSet<AllocId>,
@@ -97,6 +99,7 @@ fn intern_shallow<'rt, 'mir, 'tcx>(
     // read-only memory, and also by Miri when evluating other constants/statics that
     // access this one.
     if mode == InternMode::Static {
+        // When `ty` is `None`, we assume no interior mutability.
         let frozen = ty.map_or(true, |ty| ty.is_freeze(
             ecx.tcx.tcx,
             ecx.param_env,

From 5462ecb4b131a513b2d821d52b9af491781bd898 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Wed, 28 Aug 2019 09:54:30 +0200
Subject: [PATCH 767/943] update intern classification comment

---
 src/librustc_mir/interpret/intern.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs
index 0031dbc4d0d40..95647ce642c5b 100644
--- a/src/librustc_mir/interpret/intern.rs
+++ b/src/librustc_mir/interpret/intern.rs
@@ -278,9 +278,10 @@ pub fn intern_const_alloc_recursive(
     // this `mutability` is the mutability of the place, ignoring the type
     let (base_mutability, base_intern_mode) = match tcx.static_mutability(def_id) {
         Some(hir::Mutability::MutImmutable) => (Mutability::Immutable, InternMode::Static),
-        None => (Mutability::Immutable, InternMode::ConstBase),
         // `static mut` doesn't care about interior mutability, it's mutable anyway
         Some(hir::Mutability::MutMutable) => (Mutability::Mutable, InternMode::Static),
+        // consts, promoteds. FIXME: what about array lengths, array initializers?
+        None => (Mutability::Immutable, InternMode::ConstBase),
     };
 
     // Type based interning.

From 959c710e8599f3c5d5c8ec1eddd4f536ffda654f Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 14 Sep 2019 19:26:49 -0400
Subject: [PATCH 768/943] Permit impls referencing errors to overlap

---
 src/librustc/ty/mod.rs                           |  7 +++++++
 .../ui/coherence/conflicting-impl-with-err.rs    | 16 ++++++++++++++++
 .../coherence/conflicting-impl-with-err.stderr   | 15 +++++++++++++++
 3 files changed, 38 insertions(+)
 create mode 100644 src/test/ui/coherence/conflicting-impl-with-err.rs
 create mode 100644 src/test/ui/coherence/conflicting-impl-with-err.stderr

diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 41e4295caecce..17eb4a8957fd5 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2894,6 +2894,13 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn impls_are_allowed_to_overlap(self, def_id1: DefId, def_id2: DefId)
                                         -> Option<ImplOverlapKind>
     {
+        // If either trait impl references an error, they're allowed to overlap,
+        // as one of them essentially doesn't exist.
+        if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error()) ||
+            self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error()) {
+            return Some(ImplOverlapKind::Permitted);
+        }
+
         let is_legit = if self.features().overlapping_marker_traits {
             let trait1_is_empty = self.impl_trait_ref(def_id1)
                 .map_or(false, |trait_ref| {
diff --git a/src/test/ui/coherence/conflicting-impl-with-err.rs b/src/test/ui/coherence/conflicting-impl-with-err.rs
new file mode 100644
index 0000000000000..3e0234b874d7b
--- /dev/null
+++ b/src/test/ui/coherence/conflicting-impl-with-err.rs
@@ -0,0 +1,16 @@
+struct ErrorKind;
+struct Error(ErrorKind);
+
+impl From<nope::Thing> for Error { //~ ERROR failed to resolve
+    fn from(_: nope::Thing) -> Self { //~ ERROR failed to resolve
+        unimplemented!()
+    }
+}
+
+impl From<ErrorKind> for Error {
+    fn from(_: ErrorKind) -> Self {
+        unimplemented!()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/coherence/conflicting-impl-with-err.stderr b/src/test/ui/coherence/conflicting-impl-with-err.stderr
new file mode 100644
index 0000000000000..a8a5730accdd8
--- /dev/null
+++ b/src/test/ui/coherence/conflicting-impl-with-err.stderr
@@ -0,0 +1,15 @@
+error[E0433]: failed to resolve: use of undeclared type or module `nope`
+  --> $DIR/conflicting-impl-with-err.rs:4:11
+   |
+LL | impl From<nope::Thing> for Error {
+   |           ^^^^ use of undeclared type or module `nope`
+
+error[E0433]: failed to resolve: use of undeclared type or module `nope`
+  --> $DIR/conflicting-impl-with-err.rs:5:16
+   |
+LL |     fn from(_: nope::Thing) -> Self {
+   |                ^^^^ use of undeclared type or module `nope`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0433`.

From f90f7ac46a5d2eb2aeeb25500827c15e623bb5e0 Mon Sep 17 00:00:00 2001
From: Igor Matuszewski <Xanewok@gmail.com>
Date: Sun, 15 Sep 2019 16:00:01 +0200
Subject: [PATCH 769/943] Update RLS

---
 src/tools/rls | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/rls b/src/tools/rls
index 412fb00b37afb..d9aa23a43ad29 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit 412fb00b37afb6b7f7fa96a35f2315c7e640b916
+Subproject commit d9aa23a43ad29e3a10551a1425ef5d5baef28d70

From 5355a16150a89503b67edbb3da545f8d653a4126 Mon Sep 17 00:00:00 2001
From: Guanqun Lu <guanqun.lu@gmail.com>
Date: Fri, 13 Sep 2019 17:36:35 +0800
Subject: [PATCH 770/943] use println!()

---
 src/librustc_codegen_llvm/lib.rs              |  6 ++--
 src/libstd/process.rs                         |  2 +-
 .../debuginfo/function-arg-initialization.rs  |  4 +--
 src/test/ui/drop/dropck_legal_cycles.rs       | 30 +++++++++----------
 src/test/ui/for/for-c-in-str.rs               |  2 +-
 src/tools/compiletest/src/main.rs             |  4 +--
 src/tools/compiletest/src/runtest.rs          |  4 +--
 7 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 9f2c303145dc8..34e39af3c39fc 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -226,21 +226,21 @@ impl CodegenBackend for LlvmCodegenBackend {
                 for &(name, _) in back::write::RELOC_MODEL_ARGS.iter() {
                     println!("    {}", name);
                 }
-                println!("");
+                println!();
             }
             PrintRequest::CodeModels => {
                 println!("Available code models:");
                 for &(name, _) in back::write::CODE_GEN_MODEL_ARGS.iter(){
                     println!("    {}", name);
                 }
-                println!("");
+                println!();
             }
             PrintRequest::TlsModels => {
                 println!("Available TLS models:");
                 for &(name, _) in back::write::TLS_MODEL_ARGS.iter(){
                     println!("    {}", name);
                 }
-                println!("");
+                println!();
             }
             req => llvm_util::print(req, sess),
         }
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index c50025ab7d1de..b8d57cfafea0a 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -422,7 +422,7 @@ impl fmt::Debug for ChildStderr {
 /// // Execute `ls` in the current directory of the program.
 /// list_dir.status().expect("process failed to execute");
 ///
-/// println!("");
+/// println!();
 ///
 /// // Change `ls` to execute in the root directory.
 /// list_dir.current_dir("/");
diff --git a/src/test/debuginfo/function-arg-initialization.rs b/src/test/debuginfo/function-arg-initialization.rs
index fef62534b304d..8c86d2cf435b6 100644
--- a/src/test/debuginfo/function-arg-initialization.rs
+++ b/src/test/debuginfo/function-arg-initialization.rs
@@ -242,12 +242,12 @@ fn non_immediate_args(a: BigStruct, b: BigStruct) {
 
 fn binding(a: i64, b: u64, c: f64) {
     let x = 0; // #break
-    println!("")
+    println!()
 }
 
 fn assignment(mut a: u64, b: u64, c: f64) {
     a = b; // #break
-    println!("")
+    println!()
 }
 
 fn function_call(x: u64, y: u64, z: f64) {
diff --git a/src/test/ui/drop/dropck_legal_cycles.rs b/src/test/ui/drop/dropck_legal_cycles.rs
index a4f4c2666ac9a..fb13fd764bfaf 100644
--- a/src/test/ui/drop/dropck_legal_cycles.rs
+++ b/src/test/ui/drop/dropck_legal_cycles.rs
@@ -143,7 +143,7 @@ pub fn main() {
     v[0].descend_into_self(&mut c);
     assert!(!c.saw_prev_marked); // <-- different from below, b/c acyclic above
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 1: { v[0] -> v[1], v[1] -> v[0] };
     // does not exercise `v` itself
@@ -158,7 +158,7 @@ pub fn main() {
     v[0].descend_into_self(&mut c);
     assert!(c.saw_prev_marked);
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 2: { v[0] -> v, v[1] -> v }
     let v: V = Named::new("v");
@@ -171,7 +171,7 @@ pub fn main() {
     v.descend_into_self(&mut c);
     assert!(c.saw_prev_marked);
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 3: { hk0 -> hv0, hv0 -> hk0, hk1 -> hv1, hv1 -> hk1 };
     // does not exercise `h` itself
@@ -193,7 +193,7 @@ pub fn main() {
         assert!(c.saw_prev_marked);
     }
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 4: { h -> (hmk0,hmv0,hmk1,hmv1), {hmk0,hmv0,hmk1,hmv1} -> h }
 
@@ -216,7 +216,7 @@ pub fn main() {
         // break;
     }
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 5: { vd[0] -> vd[1], vd[1] -> vd[0] };
     // does not exercise vd itself
@@ -232,7 +232,7 @@ pub fn main() {
     vd[0].descend_into_self(&mut c);
     assert!(c.saw_prev_marked);
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 6: { vd -> (vd0, vd1), {vd0, vd1} -> vd }
     let mut vd: VecDeque<VD> = VecDeque::new();
@@ -247,7 +247,7 @@ pub fn main() {
     vd[0].descend_into_self(&mut c);
     assert!(c.saw_prev_marked);
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 7: { vm -> (vm0, vm1), {vm0, vm1} -> vm }
     let mut vm: HashMap<usize, VM> = HashMap::new();
@@ -262,7 +262,7 @@ pub fn main() {
     vm[&0].descend_into_self(&mut c);
     assert!(c.saw_prev_marked);
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 8: { ll -> (ll0, ll1), {ll0, ll1} -> ll }
     let mut ll: LinkedList<LL> = LinkedList::new();
@@ -282,7 +282,7 @@ pub fn main() {
         // break;
     }
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 9: { bh -> (bh0, bh1), {bh0, bh1} -> bh }
     let mut bh: BinaryHeap<BH> = BinaryHeap::new();
@@ -302,7 +302,7 @@ pub fn main() {
         // break;
     }
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 10: { btm -> (btk0, btv1), {bt0, bt1} -> btm }
     let mut btm: BTreeMap<BTM, BTM> = BTreeMap::new();
@@ -323,7 +323,7 @@ pub fn main() {
         // break;
     }
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 10: { bts -> (bts0, bts1), {bts0, bts1} -> btm }
     let mut bts: BTreeSet<BTS> = BTreeSet::new();
@@ -343,7 +343,7 @@ pub fn main() {
         // break;
     }
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 11: { rc0 -> (rc1, rc2), rc1 -> (), rc2 -> rc0 }
     let (rc0, rc1, rc2): (RCRC, RCRC, RCRC);
@@ -361,7 +361,7 @@ pub fn main() {
     rc0.descend_into_self(&mut c);
     assert!(c.saw_prev_marked);
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // We want to take the previous Rc case and generalize it to Arc.
     //
@@ -395,7 +395,7 @@ pub fn main() {
     arc0.descend_into_self(&mut c);
     assert!(c.saw_prev_marked);
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 13: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, rwlocks
     let (arc0, arc1, arc2): (ARCRW, ARCRW, ARCRW);
@@ -413,7 +413,7 @@ pub fn main() {
     arc0.descend_into_self(&mut c);
     assert!(c.saw_prev_marked);
 
-    if PRINT { println!(""); }
+    if PRINT { println!(); }
 
     // Cycle 14: { arc0 -> (arc1, arc2), arc1 -> (), arc2 -> arc0 }, mutexs
     let (arc0, arc1, arc2): (ARCM, ARCM, ARCM);
diff --git a/src/test/ui/for/for-c-in-str.rs b/src/test/ui/for/for-c-in-str.rs
index 43b1a04c22d04..0fbc796d7c0d3 100644
--- a/src/test/ui/for/for-c-in-str.rs
+++ b/src/test/ui/for/for-c-in-str.rs
@@ -6,6 +6,6 @@ fn main() {
     //~| NOTE `&str` is not an iterator
     //~| HELP the trait `std::iter::Iterator` is not implemented for `&str`
     //~| NOTE required by `std::iter::IntoIterator::into_iter`
-        println!("");
+        println!();
     }
 }
diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs
index 467b7771c152e..7c51de5df2267 100644
--- a/src/tools/compiletest/src/main.rs
+++ b/src/tools/compiletest/src/main.rs
@@ -253,7 +253,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
     if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
         let message = format!("Usage: {} [OPTIONS] [TESTNAME...]", argv0);
         println!("{}", opts.usage(&message));
-        println!("");
+        println!();
         panic!()
     }
 
@@ -265,7 +265,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
     if matches.opt_present("h") || matches.opt_present("help") {
         let message = format!("Usage: {} [OPTIONS]  [TESTNAME...]", argv0);
         println!("{}", opts.usage(&message));
-        println!("");
+        println!();
         panic!()
     }
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index aff554678a3f4..baed27dd15152 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2593,7 +2593,7 @@ impl<'test> TestCx<'test> {
                     "  actual:   {}",
                     codegen_units_to_str(&actual_item.codegen_units)
                 );
-                println!("");
+                println!();
             }
         }
 
@@ -3526,7 +3526,7 @@ impl<'test> TestCx<'test> {
                             }
                         }
                     }
-                    println!("");
+                    println!();
                 }
             }
         }

From a678e3191197f145451c97c6cc884e15cae38186 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 14 Sep 2019 16:17:57 -0400
Subject: [PATCH 771/943] Hide diagnostics emitted during --cfg parsing

The early error is more than sufficient for fixing the problem.
---
 src/librustc/session/config.rs                      | 13 ++++++++++++-
 .../ui/conditional-compilation/cfg-arg-invalid-6.rs |  3 +++
 .../cfg-arg-invalid-6.stderr                        |  2 ++
 3 files changed, 17 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/conditional-compilation/cfg-arg-invalid-6.rs
 create mode 100644 src/test/ui/conditional-compilation/cfg-arg-invalid-6.stderr

diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index c74b2fee41d6c..723855c7c29cf 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -7,6 +7,7 @@ use crate::session::{early_error, early_warn, Session};
 use crate::session::search_paths::SearchPath;
 
 use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::sync::Lrc;
 
 use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
 use rustc_target::spec::{Target, TargetTriple};
@@ -19,6 +20,7 @@ use syntax::parse::{ParseSess, new_parser_from_source_str};
 use syntax::parse::token;
 use syntax::symbol::{sym, Symbol};
 use syntax::feature_gate::UnstableFeatures;
+use syntax::source_map::SourceMap;
 
 use errors::emitter::HumanReadableErrorType;
 use errors::{ColorConfig, FatalError, Handler};
@@ -1850,11 +1852,20 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
     opts
 }
 
+struct NullEmitter;
+
+impl errors::emitter::Emitter for NullEmitter {
+    fn emit_diagnostic(&mut self, _: &errors::DiagnosticBuilder<'_>) {}
+}
+
 // Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
 pub fn parse_cfgspecs(cfgspecs: Vec<String>) -> FxHashSet<(String, Option<String>)> {
     syntax::with_default_globals(move || {
         let cfg = cfgspecs.into_iter().map(|s| {
-            let sess = ParseSess::new(FilePathMapping::empty());
+
+            let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+            let handler = Handler::with_emitter(false, None, Box::new(NullEmitter));
+            let sess = ParseSess::with_span_handler(handler, cm);
             let filename = FileName::cfg_spec_source_code(&s);
             let mut parser = new_parser_from_source_str(&sess, filename, s.to_string());
 
diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-6.rs b/src/test/ui/conditional-compilation/cfg-arg-invalid-6.rs
new file mode 100644
index 0000000000000..9fa726f93e3ea
--- /dev/null
+++ b/src/test/ui/conditional-compilation/cfg-arg-invalid-6.rs
@@ -0,0 +1,3 @@
+// compile-flags: --cfg a{
+// error-pattern: invalid `--cfg` argument: `a{` (expected `key` or `key="value"`)
+fn main() {}
diff --git a/src/test/ui/conditional-compilation/cfg-arg-invalid-6.stderr b/src/test/ui/conditional-compilation/cfg-arg-invalid-6.stderr
new file mode 100644
index 0000000000000..7d2087b4b71f7
--- /dev/null
+++ b/src/test/ui/conditional-compilation/cfg-arg-invalid-6.stderr
@@ -0,0 +1,2 @@
+error: invalid `--cfg` argument: `a{` (expected `key` or `key="value"`)
+

From 04b1111ae8dd97f3cf558654015b8101d270c634 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 11:49:15 +1000
Subject: [PATCH 772/943] Name index variables consistently.

Those with type `usize` are now called `i`, those with type `NodeIndex`
are called `index`.
---
 .../obligation_forest/mod.rs                  | 97 +++++++++----------
 1 file changed, 47 insertions(+), 50 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 6c52e626ababd..7ef1953e2d812 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -295,14 +295,15 @@ impl<O: ForestObligation> ObligationForest<O> {
                 debug!("register_obligation_at({:?}, {:?}) - duplicate of {:?}!",
                        obligation, parent, o.get());
                 let node = &mut self.nodes[o.get().get()];
-                if let Some(parent) = parent {
+                if let Some(parent_index) = parent {
                     // If the node is already in `waiting_cache`, it's already
                     // been marked with a parent. (It's possible that parent
                     // has been cleared by `apply_rewrites`, though.) So just
                     // dump `parent` into `node.dependents`... unless it's
                     // already in `node.dependents` or `node.parent`.
-                    if !node.dependents.contains(&parent) && Some(parent) != node.parent {
-                        node.dependents.push(parent);
+                    if !node.dependents.contains(&parent_index) &&
+                       Some(parent_index) != node.parent {
+                        node.dependents.push(parent_index);
                     }
                 }
                 if let NodeState::Error = node.state.get() {
@@ -316,9 +317,8 @@ impl<O: ForestObligation> ObligationForest<O> {
                        obligation, parent, self.nodes.len());
 
                 let obligation_tree_id = match parent {
-                    Some(p) => {
-                        let parent_node = &self.nodes[p.get()];
-                        parent_node.obligation_tree_id
+                    Some(parent_index) => {
+                        self.nodes[parent_index.get()].obligation_tree_id
                     }
                     None => self.obligation_tree_id_generator.next().unwrap()
                 };
@@ -346,9 +346,9 @@ impl<O: ForestObligation> ObligationForest<O> {
     /// This cannot be done during a snapshot.
     pub fn to_errors<E: Clone>(&mut self, error: E) -> Vec<Error<O, E>> {
         let mut errors = vec![];
-        for index in 0..self.nodes.len() {
-            if let NodeState::Pending = self.nodes[index].state.get() {
-                let backtrace = self.error_at(index);
+        for i in 0..self.nodes.len() {
+            if let NodeState::Pending = self.nodes[i].state.get() {
+                let backtrace = self.error_at(i);
                 errors.push(Error {
                     error: error.clone(),
                     backtrace,
@@ -393,16 +393,16 @@ impl<O: ForestObligation> ObligationForest<O> {
         let mut errors = vec![];
         let mut stalled = true;
 
-        for index in 0..self.nodes.len() {
-            debug!("process_obligations: node {} == {:?}", index, self.nodes[index]);
+        for i in 0..self.nodes.len() {
+            debug!("process_obligations: node {} == {:?}", i, self.nodes[i]);
 
-            let result = match self.nodes[index] {
+            let result = match self.nodes[i] {
                 Node { ref state, ref mut obligation, .. } if state.get() == NodeState::Pending =>
                     processor.process_obligation(obligation),
                 _ => continue
             };
 
-            debug!("process_obligations: node {} got result {:?}", index, result);
+            debug!("process_obligations: node {} got result {:?}", i, result);
 
             match result {
                 ProcessResult::Unchanged => {
@@ -411,23 +411,23 @@ impl<O: ForestObligation> ObligationForest<O> {
                 ProcessResult::Changed(children) => {
                     // We are not (yet) stalled.
                     stalled = false;
-                    self.nodes[index].state.set(NodeState::Success);
+                    self.nodes[i].state.set(NodeState::Success);
 
                     for child in children {
                         let st = self.register_obligation_at(
                             child,
-                            Some(NodeIndex::new(index))
+                            Some(NodeIndex::new(i))
                         );
                         if let Err(()) = st {
                             // error already reported - propagate it
                             // to our node.
-                            self.error_at(index);
+                            self.error_at(i);
                         }
                     }
                 }
                 ProcessResult::Error(err) => {
                     stalled = false;
-                    let backtrace = self.error_at(index);
+                    let backtrace = self.error_at(i);
                     errors.push(Error {
                         error: err,
                         backtrace,
@@ -473,15 +473,15 @@ impl<O: ForestObligation> ObligationForest<O> {
 
         debug!("process_cycles()");
 
-        for index in 0..self.nodes.len() {
+        for i in 0..self.nodes.len() {
             // For rustc-benchmarks/inflate-0.1.0 this state test is extremely
             // hot and the state is almost always `Pending` or `Waiting`. It's
             // a win to handle the no-op cases immediately to avoid the cost of
             // the function call.
-            let state = self.nodes[index].state.get();
+            let state = self.nodes[i].state.get();
             match state {
                 NodeState::Waiting | NodeState::Pending | NodeState::Done | NodeState::Error => {},
-                _ => self.find_cycles_from_node(&mut stack, processor, index),
+                _ => self.find_cycles_from_node(&mut stack, processor, i),
             }
         }
 
@@ -491,24 +491,22 @@ impl<O: ForestObligation> ObligationForest<O> {
         self.scratch = Some(stack);
     }
 
-    fn find_cycles_from_node<P>(&self, stack: &mut Vec<usize>,
-                                processor: &mut P, index: usize)
+    fn find_cycles_from_node<P>(&self, stack: &mut Vec<usize>, processor: &mut P, i: usize)
         where P: ObligationProcessor<Obligation=O>
     {
-        let node = &self.nodes[index];
+        let node = &self.nodes[i];
         let state = node.state.get();
         match state {
             NodeState::OnDfsStack => {
-                let index =
-                    stack.iter().rposition(|n| *n == index).unwrap();
-                processor.process_backedge(stack[index..].iter().map(GetObligation(&self.nodes)),
+                let i = stack.iter().rposition(|n| *n == i).unwrap();
+                processor.process_backedge(stack[i..].iter().map(GetObligation(&self.nodes)),
                                            PhantomData);
             }
             NodeState::Success => {
                 node.state.set(NodeState::OnDfsStack);
-                stack.push(index);
-                for dependent in node.parent.iter().chain(node.dependents.iter()) {
-                    self.find_cycles_from_node(stack, processor, dependent.get());
+                stack.push(i);
+                for index in node.parent.iter().chain(node.dependents.iter()) {
+                    self.find_cycles_from_node(stack, processor, index.get());
                 }
                 stack.pop();
                 node.state.set(NodeState::Done);
@@ -525,33 +523,32 @@ impl<O: ForestObligation> ObligationForest<O> {
 
     /// Returns a vector of obligations for `p` and all of its
     /// ancestors, putting them into the error state in the process.
-    fn error_at(&mut self, p: usize) -> Vec<O> {
+    fn error_at(&mut self, mut i: usize) -> Vec<O> {
         let mut error_stack = self.scratch.take().unwrap();
         let mut trace = vec![];
 
-        let mut n = p;
         loop {
-            self.nodes[n].state.set(NodeState::Error);
-            trace.push(self.nodes[n].obligation.clone());
-            error_stack.extend(self.nodes[n].dependents.iter().map(|x| x.get()));
+            let node = &self.nodes[i];
+            node.state.set(NodeState::Error);
+            trace.push(node.obligation.clone());
+            error_stack.extend(node.dependents.iter().map(|index| index.get()));
 
-            // loop to the parent
-            match self.nodes[n].parent {
-                Some(q) => n = q.get(),
+            // Loop to the parent.
+            match node.parent {
+                Some(parent_index) => i = parent_index.get(),
                 None => break
             }
         }
 
         while let Some(i) = error_stack.pop() {
-            match self.nodes[i].state.get() {
+            let node = &self.nodes[i];
+            match node.state.get() {
                 NodeState::Error => continue,
                 _ => self.nodes[i].state.set(NodeState::Error),
             }
 
-            let node = &self.nodes[i];
-
             error_stack.extend(
-                node.parent.iter().chain(node.dependents.iter()).map(|x| x.get())
+                node.parent.iter().chain(node.dependents.iter()).map(|index| index.get())
             );
         }
 
@@ -689,22 +686,22 @@ impl<O: ForestObligation> ObligationForest<O> {
 
         for node in &mut self.nodes {
             if let Some(index) = node.parent {
-                let new_index = node_rewrites[index.get()];
-                if new_index >= nodes_len {
+                let new_i = node_rewrites[index.get()];
+                if new_i >= nodes_len {
                     // parent dead due to error
                     node.parent = None;
                 } else {
-                    node.parent = Some(NodeIndex::new(new_index));
+                    node.parent = Some(NodeIndex::new(new_i));
                 }
             }
 
             let mut i = 0;
             while i < node.dependents.len() {
-                let new_index = node_rewrites[node.dependents[i].get()];
-                if new_index >= nodes_len {
+                let new_i = node_rewrites[node.dependents[i].get()];
+                if new_i >= nodes_len {
                     node.dependents.swap_remove(i);
                 } else {
-                    node.dependents[i] = NodeIndex::new(new_index);
+                    node.dependents[i] = NodeIndex::new(new_i);
                     i += 1;
                 }
             }
@@ -712,11 +709,11 @@ impl<O: ForestObligation> ObligationForest<O> {
 
         let mut kill_list = vec![];
         for (predicate, index) in &mut self.waiting_cache {
-            let new_index = node_rewrites[index.get()];
-            if new_index >= nodes_len {
+            let new_i = node_rewrites[index.get()];
+            if new_i >= nodes_len {
                 kill_list.push(predicate.clone());
             } else {
-                *index = NodeIndex::new(new_index);
+                *index = NodeIndex::new(new_i);
             }
         }
 

From 43c0d2ce8eae322e0b1ffe945e356e30c808dbb3 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 11:53:12 +1000
Subject: [PATCH 773/943] Redefine `NodeIndex` as a `newtype_index!`.

This commit removes the custom index implementation of `NodeIndex`,
which probably predates `newtype_index!`.

As well as eliminating code, it improves the debugging experience,
because the custom implementation had the property of being incremented
by 1 (so it could use `NonZeroU32`), which was incredibly confusing if
you didn't expect it.

For some reason, I also had to remove an `unsafe` block marker from
`from_u32_unchecked()` that the compiler said was now unnecessary.
---
 src/librustc_data_structures/indexed_vec.rs   |  2 +-
 .../obligation_forest/graphviz.rs             |  6 +--
 .../obligation_forest/mod.rs                  | 49 ++++++++++++-------
 .../obligation_forest/node_index.rs           | 20 --------
 4 files changed, 35 insertions(+), 42 deletions(-)
 delete mode 100644 src/librustc_data_structures/obligation_forest/node_index.rs

diff --git a/src/librustc_data_structures/indexed_vec.rs b/src/librustc_data_structures/indexed_vec.rs
index 6f40d059be27f..6e80b48a68560 100644
--- a/src/librustc_data_structures/indexed_vec.rs
+++ b/src/librustc_data_structures/indexed_vec.rs
@@ -149,7 +149,7 @@ macro_rules! newtype_index {
 
             #[inline]
             $v const unsafe fn from_u32_unchecked(value: u32) -> Self {
-                unsafe { $type { private: value } }
+                $type { private: value }
             }
 
             /// Extracts the value of this index as an integer.
diff --git a/src/librustc_data_structures/obligation_forest/graphviz.rs b/src/librustc_data_structures/obligation_forest/graphviz.rs
index a0363e165e049..b2120b182fa7b 100644
--- a/src/librustc_data_structures/obligation_forest/graphviz.rs
+++ b/src/librustc_data_structures/obligation_forest/graphviz.rs
@@ -74,9 +74,9 @@ impl<'a, O: ForestObligation + 'a> dot::GraphWalk<'a> for &'a ObligationForest<O
             .flat_map(|i| {
                 let node = &self.nodes[i];
 
-                node.parent.iter().map(|p| p.get())
-                    .chain(node.dependents.iter().map(|p| p.get()))
-                    .map(move |p| (p, i))
+                node.parent.iter()
+                    .chain(node.dependents.iter())
+                    .map(move |p| (p.index(), i))
             })
             .collect()
     }
diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 7ef1953e2d812..cfc3b8194a65c 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -81,6 +81,8 @@
 //! nodes, which aren't needed anymore.
 
 use crate::fx::{FxHashMap, FxHashSet};
+use crate::indexed_vec::Idx;
+use crate::newtype_index;
 
 use std::cell::Cell;
 use std::collections::hash_map::Entry;
@@ -88,14 +90,15 @@ use std::fmt::Debug;
 use std::hash;
 use std::marker::PhantomData;
 
-mod node_index;
-use self::node_index::NodeIndex;
-
 mod graphviz;
 
 #[cfg(test)]
 mod tests;
 
+newtype_index! {
+    pub struct NodeIndex { .. }
+}
+
 pub trait ForestObligation : Clone + Debug {
     type Predicate : Clone + hash::Hash + Eq + Debug;
 
@@ -151,6 +154,10 @@ pub struct ObligationForest<O: ForestObligation> {
     /// At all times we maintain the invariant that every node appears
     /// at a higher index than its parent. This is needed by the
     /// backtrace iterator (which uses `split_at`).
+    ///
+    /// Ideally, this would be an `IndexVec<NodeIndex, Node<O>>`. But that is
+    /// slower, because this vector is accessed so often that the
+    /// `u32`-to-`usize` conversions required for accesses are significant.
     nodes: Vec<Node<O>>,
 
     /// A cache of predicates that have been successfully completed.
@@ -178,13 +185,19 @@ struct Node<O> {
     obligation: O,
     state: Cell<NodeState>,
 
-    /// The parent of a node - the original obligation of
-    /// which it is a subobligation. Except for error reporting,
-    /// it is just like any member of `dependents`.
+    /// The parent of a node - the original obligation of which it is a
+    /// subobligation. Except for error reporting, it is just like any member
+    /// of `dependents`.
+    ///
+    /// Unlike `ObligationForest::nodes`, this uses `NodeIndex` rather than
+    /// `usize` for the index, because keeping the size down is more important
+    /// than the cost of converting to a `usize` for indexing.
     parent: Option<NodeIndex>,
 
-    /// Obligations that depend on this obligation for their
-    /// completion. They must all be in a non-pending state.
+    /// Obligations that depend on this obligation for their completion. They
+    /// must all be in a non-pending state.
+    ///
+    /// This uses `NodeIndex` for the same reason as `parent`.
     dependents: Vec<NodeIndex>,
 
     /// Identifier of the obligation tree to which this node belongs.
@@ -294,7 +307,7 @@ impl<O: ForestObligation> ObligationForest<O> {
             Entry::Occupied(o) => {
                 debug!("register_obligation_at({:?}, {:?}) - duplicate of {:?}!",
                        obligation, parent, o.get());
-                let node = &mut self.nodes[o.get().get()];
+                let node = &mut self.nodes[o.get().index()];
                 if let Some(parent_index) = parent {
                     // If the node is already in `waiting_cache`, it's already
                     // been marked with a parent. (It's possible that parent
@@ -318,7 +331,7 @@ impl<O: ForestObligation> ObligationForest<O> {
 
                 let obligation_tree_id = match parent {
                     Some(parent_index) => {
-                        self.nodes[parent_index.get()].obligation_tree_id
+                        self.nodes[parent_index.index()].obligation_tree_id
                     }
                     None => self.obligation_tree_id_generator.next().unwrap()
                 };
@@ -506,7 +519,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                 node.state.set(NodeState::OnDfsStack);
                 stack.push(i);
                 for index in node.parent.iter().chain(node.dependents.iter()) {
-                    self.find_cycles_from_node(stack, processor, index.get());
+                    self.find_cycles_from_node(stack, processor, index.index());
                 }
                 stack.pop();
                 node.state.set(NodeState::Done);
@@ -531,11 +544,11 @@ impl<O: ForestObligation> ObligationForest<O> {
             let node = &self.nodes[i];
             node.state.set(NodeState::Error);
             trace.push(node.obligation.clone());
-            error_stack.extend(node.dependents.iter().map(|index| index.get()));
+            error_stack.extend(node.dependents.iter().map(|index| index.index()));
 
             // Loop to the parent.
             match node.parent {
-                Some(parent_index) => i = parent_index.get(),
+                Some(parent_index) => i = parent_index.index(),
                 None => break
             }
         }
@@ -548,7 +561,7 @@ impl<O: ForestObligation> ObligationForest<O> {
             }
 
             error_stack.extend(
-                node.parent.iter().chain(node.dependents.iter()).map(|index| index.get())
+                node.parent.iter().chain(node.dependents.iter()).map(|index| index.index())
             );
         }
 
@@ -560,7 +573,7 @@ impl<O: ForestObligation> ObligationForest<O> {
     #[inline(always)]
     fn inlined_mark_neighbors_as_waiting_from(&self, node: &Node<O>) {
         for dependent in node.parent.iter().chain(node.dependents.iter()) {
-            self.mark_as_waiting_from(&self.nodes[dependent.get()]);
+            self.mark_as_waiting_from(&self.nodes[dependent.index()]);
         }
     }
 
@@ -686,7 +699,7 @@ impl<O: ForestObligation> ObligationForest<O> {
 
         for node in &mut self.nodes {
             if let Some(index) = node.parent {
-                let new_i = node_rewrites[index.get()];
+                let new_i = node_rewrites[index.index()];
                 if new_i >= nodes_len {
                     // parent dead due to error
                     node.parent = None;
@@ -697,7 +710,7 @@ impl<O: ForestObligation> ObligationForest<O> {
 
             let mut i = 0;
             while i < node.dependents.len() {
-                let new_i = node_rewrites[node.dependents[i].get()];
+                let new_i = node_rewrites[node.dependents[i].index()];
                 if new_i >= nodes_len {
                     node.dependents.swap_remove(i);
                 } else {
@@ -709,7 +722,7 @@ impl<O: ForestObligation> ObligationForest<O> {
 
         let mut kill_list = vec![];
         for (predicate, index) in &mut self.waiting_cache {
-            let new_i = node_rewrites[index.get()];
+            let new_i = node_rewrites[index.index()];
             if new_i >= nodes_len {
                 kill_list.push(predicate.clone());
             } else {
diff --git a/src/librustc_data_structures/obligation_forest/node_index.rs b/src/librustc_data_structures/obligation_forest/node_index.rs
deleted file mode 100644
index 69ea473e05461..0000000000000
--- a/src/librustc_data_structures/obligation_forest/node_index.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-use std::num::NonZeroU32;
-use std::u32;
-
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub struct NodeIndex {
-    index: NonZeroU32,
-}
-
-impl NodeIndex {
-    #[inline]
-    pub fn new(value: usize) -> NodeIndex {
-        assert!(value < (u32::MAX as usize));
-        NodeIndex { index: NonZeroU32::new((value as u32) + 1).unwrap() }
-    }
-
-    #[inline]
-    pub fn get(self) -> usize {
-        (self.index.get() - 1) as usize
-    }
-}

From 1936e44c13753cdd060c3a33c4a1cc27443d52fc Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 11:56:17 +1000
Subject: [PATCH 774/943] Factor out repeated `self.nodes[i]` expressions.

---
 .../obligation_forest/mod.rs                  | 29 +++++++++----------
 1 file changed, 14 insertions(+), 15 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index cfc3b8194a65c..595323da02fd1 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -386,7 +386,6 @@ impl<O: ForestObligation> ObligationForest<O> {
 
     fn insert_into_error_cache(&mut self, node_index: usize) {
         let node = &self.nodes[node_index];
-
         self.error_cache
             .entry(node.obligation_tree_id)
             .or_default()
@@ -407,11 +406,12 @@ impl<O: ForestObligation> ObligationForest<O> {
         let mut stalled = true;
 
         for i in 0..self.nodes.len() {
-            debug!("process_obligations: node {} == {:?}", i, self.nodes[i]);
+            let node = &mut self.nodes[i];
+
+            debug!("process_obligations: node {} == {:?}", i, node);
 
-            let result = match self.nodes[i] {
-                Node { ref state, ref mut obligation, .. } if state.get() == NodeState::Pending =>
-                    processor.process_obligation(obligation),
+            let result = match node.state.get() {
+                NodeState::Pending => processor.process_obligation(&mut node.obligation),
                 _ => continue
             };
 
@@ -424,7 +424,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                 ProcessResult::Changed(children) => {
                     // We are not (yet) stalled.
                     stalled = false;
-                    self.nodes[i].state.set(NodeState::Success);
+                    node.state.set(NodeState::Success);
 
                     for child in children {
                         let st = self.register_obligation_at(
@@ -491,8 +491,7 @@ impl<O: ForestObligation> ObligationForest<O> {
             // hot and the state is almost always `Pending` or `Waiting`. It's
             // a win to handle the no-op cases immediately to avoid the cost of
             // the function call.
-            let state = self.nodes[i].state.get();
-            match state {
+            match self.nodes[i].state.get() {
                 NodeState::Waiting | NodeState::Pending | NodeState::Done | NodeState::Error => {},
                 _ => self.find_cycles_from_node(&mut stack, processor, i),
             }
@@ -508,8 +507,7 @@ impl<O: ForestObligation> ObligationForest<O> {
         where P: ObligationProcessor<Obligation=O>
     {
         let node = &self.nodes[i];
-        let state = node.state.get();
-        match state {
+        match node.state.get() {
             NodeState::OnDfsStack => {
                 let i = stack.iter().rposition(|n| *n == i).unwrap();
                 processor.process_backedge(stack[i..].iter().map(GetObligation(&self.nodes)),
@@ -557,7 +555,7 @@ impl<O: ForestObligation> ObligationForest<O> {
             let node = &self.nodes[i];
             match node.state.get() {
                 NodeState::Error => continue,
-                _ => self.nodes[i].state.set(NodeState::Error),
+                _ => node.state.set(NodeState::Error),
             }
 
             error_stack.extend(
@@ -630,7 +628,8 @@ impl<O: ForestObligation> ObligationForest<O> {
         //     self.nodes[i - dead_nodes..i] are all dead
         //     self.nodes[i..] are unchanged
         for i in 0..self.nodes.len() {
-            match self.nodes[i].state.get() {
+            let node = &self.nodes[i];
+            match node.state.get() {
                 NodeState::Pending | NodeState::Waiting => {
                     if dead_nodes > 0 {
                         self.nodes.swap(i, i - dead_nodes);
@@ -640,11 +639,11 @@ impl<O: ForestObligation> ObligationForest<O> {
                 NodeState::Done => {
                     // Avoid cloning the key (predicate) in case it exists in the waiting cache
                     if let Some((predicate, _)) = self.waiting_cache
-                        .remove_entry(self.nodes[i].obligation.as_predicate())
+                        .remove_entry(node.obligation.as_predicate())
                     {
                         self.done_cache.insert(predicate);
                     } else {
-                        self.done_cache.insert(self.nodes[i].obligation.as_predicate().clone());
+                        self.done_cache.insert(node.obligation.as_predicate().clone());
                     }
                     node_rewrites[i] = nodes_len;
                     dead_nodes += 1;
@@ -653,7 +652,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                     // We *intentionally* remove the node from the cache at this point. Otherwise
                     // tests must come up with a different type on every type error they
                     // check against.
-                    self.waiting_cache.remove(self.nodes[i].obligation.as_predicate());
+                    self.waiting_cache.remove(node.obligation.as_predicate());
                     node_rewrites[i] = nodes_len;
                     dead_nodes += 1;
                     self.insert_into_error_cache(i);

From 3fda9578e08680b00db87c031940c907e54d1cc3 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 12:38:24 +1000
Subject: [PATCH 775/943] Remove out-of-date comments.

These refer to code that no longer exists.
---
 .../obligation_forest/mod.rs                     | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 595323da02fd1..731d82b7cfd72 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -61,14 +61,6 @@
 //!   results. This is used by the `FulfillmentContext` to decide when it
 //!   has reached a steady state.
 //!
-//! #### Snapshots
-//!
-//! The `ObligationForest` supports a limited form of snapshots; see
-//! `start_snapshot`, `commit_snapshot`, and `rollback_snapshot`. In
-//! particular, you can use a snapshot to roll back new root
-//! obligations. However, it is an error to attempt to
-//! `process_obligations` during a snapshot.
-//!
 //! ### Implementation details
 //!
 //! For the most part, comments specific to the implementation are in the
@@ -151,10 +143,6 @@ pub struct ObligationForest<O: ForestObligation> {
     /// At the end of processing, those nodes will be removed by a
     /// call to `compress`.
     ///
-    /// At all times we maintain the invariant that every node appears
-    /// at a higher index than its parent. This is needed by the
-    /// backtrace iterator (which uses `split_at`).
-    ///
     /// Ideally, this would be an `IndexVec<NodeIndex, Node<O>>`. But that is
     /// slower, because this vector is accessed so often that the
     /// `u32`-to-`usize` conversions required for accesses are significant.
@@ -288,8 +276,6 @@ impl<O: ForestObligation> ObligationForest<O> {
     }
 
     /// Registers an obligation.
-    ///
-    /// This CAN be done in a snapshot
     pub fn register_obligation(&mut self, obligation: O) {
         // Ignore errors here - there is no guarantee of success.
         let _ = self.register_obligation_at(obligation, None);
@@ -355,8 +341,6 @@ impl<O: ForestObligation> ObligationForest<O> {
     }
 
     /// Converts all remaining obligations to the given error.
-    ///
-    /// This cannot be done during a snapshot.
     pub fn to_errors<E: Clone>(&mut self, error: E) -> Vec<Error<O, E>> {
         let mut errors = vec![];
         for i in 0..self.nodes.len() {

From ac061dc5c8497c03e14c82b7fe349ca863924fae Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 12:39:21 +1000
Subject: [PATCH 776/943] Fix some out-of-date names of things in comments.

---
 .../obligation_forest/mod.rs                       | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 731d82b7cfd72..3bf65b5739afb 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -9,7 +9,7 @@
 //! `ObligationForest` supports two main public operations (there are a
 //! few others not discussed here):
 //!
-//! 1. Add a new root obligations (`push_tree`).
+//! 1. Add a new root obligations (`register_obligation`).
 //! 2. Process the pending obligations (`process_obligations`).
 //!
 //! When a new obligation `N` is added, it becomes the root of an
@@ -20,13 +20,13 @@
 //! with every pending obligation (so that will include `N`, the first
 //! time). The callback also receives a (mutable) reference to the
 //! per-tree state `T`. The callback should process the obligation `O`
-//! that it is given and return one of three results:
+//! that it is given and return a `ProcessResult`:
 //!
-//! - `Ok(None)` -> ambiguous result. Obligation was neither a success
+//! - `Unchanged` -> ambiguous result. Obligation was neither a success
 //!   nor a failure. It is assumed that further attempts to process the
 //!   obligation will yield the same result unless something in the
 //!   surrounding environment changes.
-//! - `Ok(Some(C))` - the obligation was *shallowly successful*. The
+//! - `Changed(C)` - the obligation was *shallowly successful*. The
 //!   vector `C` is a list of subobligations. The meaning of this is that
 //!   `O` was successful on the assumption that all the obligations in `C`
 //!   are also successful. Therefore, `O` is only considered a "true"
@@ -34,7 +34,7 @@
 //!   state and the obligations in `C` become the new pending
 //!   obligations. They will be processed the next time you call
 //!   `process_obligations`.
-//! - `Err(E)` -> obligation failed with error `E`. We will collect this
+//! - `Error(E)` -> obligation failed with error `E`. We will collect this
 //!   error and return it from `process_obligations`, along with the
 //!   "backtrace" of obligations (that is, the list of obligations up to
 //!   and including the root of the failed obligation). No further
@@ -47,14 +47,14 @@
 //! - `completed`: a list of obligations where processing was fully
 //!   completed without error (meaning that all transitive subobligations
 //!   have also been completed). So, for example, if the callback from
-//!   `process_obligations` returns `Ok(Some(C))` for some obligation `O`,
+//!   `process_obligations` returns `Changed(C)` for some obligation `O`,
 //!   then `O` will be considered completed right away if `C` is the
 //!   empty vector. Otherwise it will only be considered completed once
 //!   all the obligations in `C` have been found completed.
 //! - `errors`: a list of errors that occurred and associated backtraces
 //!   at the time of error, which can be used to give context to the user.
 //! - `stalled`: if true, then none of the existing obligations were
-//!   *shallowly successful* (that is, no callback returned `Ok(Some(_))`).
+//!   *shallowly successful* (that is, no callback returned `Changed(_)`).
 //!   This implies that all obligations were either errors or returned an
 //!   ambiguous result, which means that any further calls to
 //!   `process_obligations` would simply yield back further ambiguous

From 6391ef4d6e627c87124d512892fe4e0eface96ae Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 12:40:31 +1000
Subject: [PATCH 777/943] Fix incorrect comment about contents of a `Node`.

---
 src/librustc_data_structures/obligation_forest/mod.rs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 3bf65b5739afb..7904808eb38e3 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -66,11 +66,11 @@
 //! For the most part, comments specific to the implementation are in the
 //! code. This file only contains a very high-level overview. Basically,
 //! the forest is stored in a vector. Each element of the vector is a node
-//! in some tree. Each node in the vector has the index of an (optional)
-//! parent and (for convenience) its root (which may be itself). It also
-//! has a current state, described by `NodeState`. After each
-//! processing step, we compress the vector to remove completed and error
-//! nodes, which aren't needed anymore.
+//! in some tree. Each node in the vector has the index of its dependents,
+//! including the first dependent which is known as the parent. It also
+//! has a current state, described by `NodeState`. After each processing
+//! step, we compress the vector to remove completed and error nodes, which
+//! aren't needed anymore.
 
 use crate::fx::{FxHashMap, FxHashSet};
 use crate::indexed_vec::Idx;

From e2492b716370dab5216f0123b3ed1cac78f8304e Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 12:41:36 +1000
Subject: [PATCH 778/943] Add comments about `waiting_cache`.

---
 .../obligation_forest/mod.rs                     | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 7904808eb38e3..9dbae95dc8f60 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -151,7 +151,9 @@ pub struct ObligationForest<O: ForestObligation> {
     /// A cache of predicates that have been successfully completed.
     done_cache: FxHashSet<O::Predicate>,
 
-    /// An cache of the nodes in `nodes`, indexed by predicate.
+    /// A cache of the nodes in `nodes`, indexed by predicate. Unfortunately,
+    /// its contents are not guaranteed to match those of `nodes`. See the
+    /// comments in `process_obligation` for details.
     waiting_cache: FxHashMap<O::Predicate, NodeIndex>,
 
     scratch: Option<Vec<usize>>,
@@ -394,6 +396,11 @@ impl<O: ForestObligation> ObligationForest<O> {
 
             debug!("process_obligations: node {} == {:?}", i, node);
 
+            // `processor.process_obligation` can modify the predicate within
+            // `node.obligation`, and that predicate is the key used for
+            // `self.waiting_cache`. This means that `self.waiting_cache` can
+            // get out of sync with `nodes`. It's not very common, but it does
+            // happen, and code in `compress` has to allow for it.
             let result = match node.state.get() {
                 NodeState::Pending => processor.process_obligation(&mut node.obligation),
                 _ => continue
@@ -621,7 +628,10 @@ impl<O: ForestObligation> ObligationForest<O> {
                     }
                 }
                 NodeState::Done => {
-                    // Avoid cloning the key (predicate) in case it exists in the waiting cache
+                    // This lookup can fail because the contents of
+                    // `self.waiting_cache` is not guaranteed to match those of
+                    // `self.nodes`. See the comment in `process_obligation`
+                    // for more details.
                     if let Some((predicate, _)) = self.waiting_cache
                         .remove_entry(node.obligation.as_predicate())
                     {
@@ -703,6 +713,8 @@ impl<O: ForestObligation> ObligationForest<O> {
             }
         }
 
+        // This updating of `self.waiting_cache` is necessary because the
+        // removal of nodes within `compress` can fail. See above.
         let mut kill_list = vec![];
         for (predicate, index) in &mut self.waiting_cache {
             let new_i = node_rewrites[index.index()];

From 6e48053d5d0d1c81d9a7e6548cead05c4bbac63d Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 12:43:16 +1000
Subject: [PATCH 779/943] Use iterators in `error_at` and `process_cycle`.

This makes the code a little faster, presumably because bounds checks
aren't needed on `nodes` accesses. It requires making `scratch` a
`RefCell`, which is not unreasonable.
---
 .../obligation_forest/mod.rs                  | 34 ++++++++++---------
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 9dbae95dc8f60..0fa1f707d7be3 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -76,7 +76,7 @@ use crate::fx::{FxHashMap, FxHashSet};
 use crate::indexed_vec::Idx;
 use crate::newtype_index;
 
-use std::cell::Cell;
+use std::cell::{Cell, RefCell};
 use std::collections::hash_map::Entry;
 use std::fmt::Debug;
 use std::hash;
@@ -156,7 +156,9 @@ pub struct ObligationForest<O: ForestObligation> {
     /// comments in `process_obligation` for details.
     waiting_cache: FxHashMap<O::Predicate, NodeIndex>,
 
-    scratch: Option<Vec<usize>>,
+    /// A scratch vector reused in various operations, to avoid allocating new
+    /// vectors.
+    scratch: RefCell<Vec<usize>>,
 
     obligation_tree_id_generator: ObligationTreeIdGenerator,
 
@@ -265,7 +267,7 @@ impl<O: ForestObligation> ObligationForest<O> {
             nodes: vec![],
             done_cache: Default::default(),
             waiting_cache: Default::default(),
-            scratch: Some(vec![]),
+            scratch: RefCell::new(vec![]),
             obligation_tree_id_generator: (0..).map(ObligationTreeId),
             error_cache: Default::default(),
         }
@@ -345,8 +347,8 @@ impl<O: ForestObligation> ObligationForest<O> {
     /// Converts all remaining obligations to the given error.
     pub fn to_errors<E: Clone>(&mut self, error: E) -> Vec<Error<O, E>> {
         let mut errors = vec![];
-        for i in 0..self.nodes.len() {
-            if let NodeState::Pending = self.nodes[i].state.get() {
+        for (i, node) in self.nodes.iter().enumerate() {
+            if let NodeState::Pending = node.state.get() {
                 let backtrace = self.error_at(i);
                 errors.push(Error {
                     error: error.clone(),
@@ -469,20 +471,20 @@ impl<O: ForestObligation> ObligationForest<O> {
     /// report all cycles between them. This should be called
     /// after `mark_as_waiting` marks all nodes with pending
     /// subobligations as NodeState::Waiting.
-    fn process_cycles<P>(&mut self, processor: &mut P)
+    fn process_cycles<P>(&self, processor: &mut P)
         where P: ObligationProcessor<Obligation=O>
     {
-        let mut stack = self.scratch.take().unwrap();
+        let mut stack = self.scratch.replace(vec![]);
         debug_assert!(stack.is_empty());
 
         debug!("process_cycles()");
 
-        for i in 0..self.nodes.len() {
+        for (i, node) in self.nodes.iter().enumerate() {
             // For rustc-benchmarks/inflate-0.1.0 this state test is extremely
             // hot and the state is almost always `Pending` or `Waiting`. It's
             // a win to handle the no-op cases immediately to avoid the cost of
             // the function call.
-            match self.nodes[i].state.get() {
+            match node.state.get() {
                 NodeState::Waiting | NodeState::Pending | NodeState::Done | NodeState::Error => {},
                 _ => self.find_cycles_from_node(&mut stack, processor, i),
             }
@@ -491,7 +493,7 @@ impl<O: ForestObligation> ObligationForest<O> {
         debug!("process_cycles: complete");
 
         debug_assert!(stack.is_empty());
-        self.scratch = Some(stack);
+        self.scratch.replace(stack);
     }
 
     fn find_cycles_from_node<P>(&self, stack: &mut Vec<usize>, processor: &mut P, i: usize)
@@ -525,8 +527,8 @@ impl<O: ForestObligation> ObligationForest<O> {
 
     /// Returns a vector of obligations for `p` and all of its
     /// ancestors, putting them into the error state in the process.
-    fn error_at(&mut self, mut i: usize) -> Vec<O> {
-        let mut error_stack = self.scratch.take().unwrap();
+    fn error_at(&self, mut i: usize) -> Vec<O> {
+        let mut error_stack = self.scratch.replace(vec![]);
         let mut trace = vec![];
 
         loop {
@@ -554,7 +556,7 @@ impl<O: ForestObligation> ObligationForest<O> {
             );
         }
 
-        self.scratch = Some(error_stack);
+        self.scratch.replace(error_stack);
         trace
     }
 
@@ -608,7 +610,7 @@ impl<O: ForestObligation> ObligationForest<O> {
     #[inline(never)]
     fn compress(&mut self, do_completed: DoCompleted) -> Option<Vec<O>> {
         let nodes_len = self.nodes.len();
-        let mut node_rewrites: Vec<_> = self.scratch.take().unwrap();
+        let mut node_rewrites: Vec<_> = self.scratch.replace(vec![]);
         node_rewrites.extend(0..nodes_len);
         let mut dead_nodes = 0;
 
@@ -658,7 +660,7 @@ impl<O: ForestObligation> ObligationForest<O> {
         // No compression needed.
         if dead_nodes == 0 {
             node_rewrites.truncate(0);
-            self.scratch = Some(node_rewrites);
+            self.scratch.replace(node_rewrites);
             return if do_completed == DoCompleted::Yes { Some(vec![]) } else { None };
         }
 
@@ -682,7 +684,7 @@ impl<O: ForestObligation> ObligationForest<O> {
         self.apply_rewrites(&node_rewrites);
 
         node_rewrites.truncate(0);
-        self.scratch = Some(node_rewrites);
+        self.scratch.replace(node_rewrites);
 
         successful
     }

From f22bb2e72267890782897c208bbc9114d023dfc7 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 12:43:48 +1000
Subject: [PATCH 780/943] Use `retain` for `waiting_cache` in
 `apply_rewrites()`.

It's more concise, more idiomatic, and measurably faster.
---
 src/librustc_data_structures/obligation_forest/mod.rs | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 0fa1f707d7be3..5b95bb136e962 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -717,17 +717,15 @@ impl<O: ForestObligation> ObligationForest<O> {
 
         // This updating of `self.waiting_cache` is necessary because the
         // removal of nodes within `compress` can fail. See above.
-        let mut kill_list = vec![];
-        for (predicate, index) in &mut self.waiting_cache {
+        self.waiting_cache.retain(|_predicate, index| {
             let new_i = node_rewrites[index.index()];
             if new_i >= nodes_len {
-                kill_list.push(predicate.clone());
+                false
             } else {
                 *index = NodeIndex::new(new_i);
+                true
             }
-        }
-
-        for predicate in kill_list { self.waiting_cache.remove(&predicate); }
+        });
     }
 }
 

From 201afa6455969c1c38e8b46d30cb9be9392207bc Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 12:47:04 +1000
Subject: [PATCH 781/943] Minor comment tweaks.

---
 .../obligation_forest/mod.rs                     | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 5b95bb136e962..cb28a7285a75c 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -285,7 +285,7 @@ impl<O: ForestObligation> ObligationForest<O> {
         let _ = self.register_obligation_at(obligation, None);
     }
 
-    // returns Err(()) if we already know this obligation failed.
+    // Returns Err(()) if we already know this obligation failed.
     fn register_obligation_at(&mut self, obligation: O, parent: Option<NodeIndex>)
                               -> Result<(), ()>
     {
@@ -425,7 +425,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                             Some(NodeIndex::new(i))
                         );
                         if let Err(()) = st {
-                            // error already reported - propagate it
+                            // Error already reported - propagate it
                             // to our node.
                             self.error_at(i);
                         }
@@ -454,8 +454,6 @@ impl<O: ForestObligation> ObligationForest<O> {
 
         self.mark_as_waiting();
         self.process_cycles(processor);
-
-        // Now we have to compress the result
         let completed = self.compress(do_completed);
 
         debug!("process_obligations: complete");
@@ -516,11 +514,11 @@ impl<O: ForestObligation> ObligationForest<O> {
                 node.state.set(NodeState::Done);
             },
             NodeState::Waiting | NodeState::Pending => {
-                // this node is still reachable from some pending node. We
+                // This node is still reachable from some pending node. We
                 // will get to it when they are all processed.
             }
             NodeState::Done | NodeState::Error => {
-                // already processed that node
+                // Already processed that node.
             }
         };
     }
@@ -664,8 +662,7 @@ impl<O: ForestObligation> ObligationForest<O> {
             return if do_completed == DoCompleted::Yes { Some(vec![]) } else { None };
         }
 
-        // Pop off all the nodes we killed and extract the success
-        // stories.
+        // Pop off all the nodes we killed and extract the success stories.
         let successful = if do_completed == DoCompleted::Yes {
             Some((0..dead_nodes)
                 .map(|_| self.nodes.pop().unwrap())
@@ -696,7 +693,6 @@ impl<O: ForestObligation> ObligationForest<O> {
             if let Some(index) = node.parent {
                 let new_i = node_rewrites[index.index()];
                 if new_i >= nodes_len {
-                    // parent dead due to error
                     node.parent = None;
                 } else {
                     node.parent = Some(NodeIndex::new(new_i));
@@ -745,7 +741,7 @@ impl<O> Node<O> {
     }
 }
 
-// I need a Clone closure
+// I need a Clone closure.
 #[derive(Clone)]
 struct GetObligation<'a, O>(&'a [Node<O>]);
 

From 4ecd94e1215882efde5f003c0042bd72a5f8acb2 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 12:47:46 +1000
Subject: [PATCH 782/943] Move `impl Node` just after `struct Node`.

---
 .../obligation_forest/mod.rs                  | 32 +++++++++----------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index cb28a7285a75c..189506bf8ab76 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -196,6 +196,22 @@ struct Node<O> {
     obligation_tree_id: ObligationTreeId,
 }
 
+impl<O> Node<O> {
+    fn new(
+        parent: Option<NodeIndex>,
+        obligation: O,
+        obligation_tree_id: ObligationTreeId
+    ) -> Node<O> {
+        Node {
+            obligation,
+            state: Cell::new(NodeState::Pending),
+            parent,
+            dependents: vec![],
+            obligation_tree_id,
+        }
+    }
+}
+
 /// The state of one node in some tree within the forest. This
 /// represents the current state of processing for the obligation (of
 /// type `O`) associated with this node.
@@ -725,22 +741,6 @@ impl<O: ForestObligation> ObligationForest<O> {
     }
 }
 
-impl<O> Node<O> {
-    fn new(
-        parent: Option<NodeIndex>,
-        obligation: O,
-        obligation_tree_id: ObligationTreeId
-    ) -> Node<O> {
-        Node {
-            obligation,
-            state: Cell::new(NodeState::Pending),
-            parent,
-            dependents: vec![],
-            obligation_tree_id,
-        }
-    }
-}
-
 // I need a Clone closure.
 #[derive(Clone)]
 struct GetObligation<'a, O>(&'a [Node<O>]);

From bb229865fa6f1178dcb2c87279336f9bf36d7282 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 13:27:38 +1000
Subject: [PATCH 783/943] Don't print the "total" `-Ztime-passes` output if
 `--prints=...` is also given.

Fixes #64339.
---
 src/librustc_driver/lib.rs | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index a912ea3c35821..dc2592d164098 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -132,8 +132,11 @@ pub struct TimePassesCallbacks {
 
 impl Callbacks for TimePassesCallbacks {
     fn config(&mut self, config: &mut interface::Config) {
+        // If a --prints=... option has been given, we don't print the "total"
+        // time because it will mess up the --prints output. See #64339.
         self.time_passes =
-            config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time;
+            config.opts.prints.is_empty() &&
+            (config.opts.debugging_opts.time_passes || config.opts.debugging_opts.time);
     }
 }
 

From 4333b869729bd00b8703721e206249b237a25e72 Mon Sep 17 00:00:00 2001
From: pcpthm <pcpthm@gmail.com>
Date: Mon, 16 Sep 2019 04:37:52 +0000
Subject: [PATCH 784/943] Improve BTreeSet::Intersection::size_hint The
 commented invariant that an iterator is smaller than other iterator was
 violated after next is called and two iterators are consumed at different
 rates.

---
 src/liballoc/collections/btree/set.rs | 44 +++++++++++++--------------
 src/liballoc/tests/btree/set.rs       | 11 +++++++
 2 files changed, 33 insertions(+), 22 deletions(-)

diff --git a/src/liballoc/collections/btree/set.rs b/src/liballoc/collections/btree/set.rs
index d3af910a82c27..0cb91ba4c81da 100644
--- a/src/liballoc/collections/btree/set.rs
+++ b/src/liballoc/collections/btree/set.rs
@@ -3,7 +3,7 @@
 
 use core::borrow::Borrow;
 use core::cmp::Ordering::{self, Less, Greater, Equal};
-use core::cmp::max;
+use core::cmp::{max, min};
 use core::fmt::{self, Debug};
 use core::iter::{Peekable, FromIterator, FusedIterator};
 use core::ops::{BitOr, BitAnd, BitXor, Sub, RangeBounds};
@@ -187,8 +187,8 @@ pub struct Intersection<'a, T: 'a> {
 }
 enum IntersectionInner<'a, T: 'a> {
     Stitch {
-        small_iter: Iter<'a, T>, // for size_hint, should be the smaller of the sets
-        other_iter: Iter<'a, T>,
+        a: Iter<'a, T>,
+        b: Iter<'a, T>,
     },
     Search {
         small_iter: Iter<'a, T>,
@@ -201,12 +201,12 @@ impl<T: fmt::Debug> fmt::Debug for Intersection<'_, T> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match &self.inner {
             IntersectionInner::Stitch {
-                small_iter,
-                other_iter,
+                a,
+                b,
             } => f
                 .debug_tuple("Intersection")
-                .field(&small_iter)
-                .field(&other_iter)
+                .field(&a)
+                .field(&b)
                 .finish(),
             IntersectionInner::Search {
                 small_iter,
@@ -397,8 +397,8 @@ impl<T: Ord> BTreeSet<T> {
             // Iterate both sets jointly, spotting matches along the way.
             Intersection {
                 inner: IntersectionInner::Stitch {
-                    small_iter: small.iter(),
-                    other_iter: other.iter(),
+                    a: small.iter(),
+                    b: other.iter(),
                 },
             }
         } else {
@@ -1221,11 +1221,11 @@ impl<T> Clone for Intersection<'_, T> {
         Intersection {
             inner: match &self.inner {
                 IntersectionInner::Stitch {
-                    small_iter,
-                    other_iter,
+                    a,
+                    b,
                 } => IntersectionInner::Stitch {
-                    small_iter: small_iter.clone(),
-                    other_iter: other_iter.clone(),
+                    a: a.clone(),
+                    b: b.clone(),
                 },
                 IntersectionInner::Search {
                     small_iter,
@@ -1245,16 +1245,16 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
     fn next(&mut self) -> Option<&'a T> {
         match &mut self.inner {
             IntersectionInner::Stitch {
-                small_iter,
-                other_iter,
+                a,
+                b,
             } => {
-                let mut small_next = small_iter.next()?;
-                let mut other_next = other_iter.next()?;
+                let mut a_next = a.next()?;
+                let mut b_next = b.next()?;
                 loop {
-                    match Ord::cmp(small_next, other_next) {
-                        Less => small_next = small_iter.next()?,
-                        Greater => other_next = other_iter.next()?,
-                        Equal => return Some(small_next),
+                    match Ord::cmp(a_next, b_next) {
+                        Less => a_next = a.next()?,
+                        Greater => b_next = b.next()?,
+                        Equal => return Some(a_next),
                     }
                 }
             }
@@ -1272,7 +1272,7 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
 
     fn size_hint(&self) -> (usize, Option<usize>) {
         let min_len = match &self.inner {
-            IntersectionInner::Stitch { small_iter, .. } => small_iter.len(),
+            IntersectionInner::Stitch { a, b } => min(a.len(), b.len()),
             IntersectionInner::Search { small_iter, .. } => small_iter.len(),
         };
         (0, Some(min_len))
diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs
index 62ccb53fcea18..35db18c39c83a 100644
--- a/src/liballoc/tests/btree/set.rs
+++ b/src/liballoc/tests/btree/set.rs
@@ -90,6 +90,17 @@ fn test_intersection() {
                        &[1, 3, 11, 77, 103]);
 }
 
+#[test]
+fn test_intersection_size_hint() {
+    let x: BTreeSet<i32> = [3, 4].iter().copied().collect();
+    let y: BTreeSet<i32> = [1, 2, 3].iter().copied().collect();
+    let mut iter = x.intersection(&y);
+    assert_eq!(iter.size_hint(), (0, Some(2)));
+    assert_eq!(iter.next(), Some(&3));
+    assert_eq!(iter.size_hint(), (0, Some(0)));
+    assert_eq!(iter.next(), None);
+}
+
 #[test]
 fn test_difference() {
     fn check_difference(a: &[i32], b: &[i32], expected: &[i32]) {

From 163892cf50a0f5ffaf4367475e7d4a412b008794 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Mon, 16 Sep 2019 15:00:28 +1000
Subject: [PATCH 785/943] Use `Symbol` in two more functions.

---
 src/libsyntax/ext/tt/macro_rules.rs | 44 ++++++++++++++---------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 46ffa52f7f572..b27e9c543377a 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -877,9 +877,9 @@ fn check_matcher_core(
         // Now `last` holds the complete set of NT tokens that could
         // end the sequence before SUFFIX. Check that every one works with `suffix`.
         'each_last: for token in &last.tokens {
-            if let TokenTree::MetaVarDecl(_, ref name, ref frag_spec) = *token {
+            if let TokenTree::MetaVarDecl(_, name, frag_spec) = *token {
                 for next_token in &suffix_first.tokens {
-                    match is_in_follow(next_token, &frag_spec.as_str()) {
+                    match is_in_follow(next_token, frag_spec.name) {
                         IsInFollow::Invalid(msg, help) => {
                             sess.span_diagnostic
                                 .struct_span_err(next_token.span(), &msg)
@@ -948,7 +948,7 @@ fn check_matcher_core(
 
 fn token_can_be_followed_by_any(tok: &quoted::TokenTree) -> bool {
     if let quoted::TokenTree::MetaVarDecl(_, _, frag_spec) = *tok {
-        frag_can_be_followed_by_any(&frag_spec.as_str())
+        frag_can_be_followed_by_any(frag_spec.name)
     } else {
         // (Non NT's can always be followed by anthing in matchers.)
         true
@@ -963,15 +963,15 @@ fn token_can_be_followed_by_any(tok: &quoted::TokenTree) -> bool {
 /// specifier which consumes at most one token tree can be followed by
 /// a fragment specifier (indeed, these fragments can be followed by
 /// ANYTHING without fear of future compatibility hazards).
-fn frag_can_be_followed_by_any(frag: &str) -> bool {
+fn frag_can_be_followed_by_any(frag: Symbol) -> bool {
     match frag {
-        "item"     | // always terminated by `}` or `;`
-        "block"    | // exactly one token tree
-        "ident"    | // exactly one token tree
-        "literal"  | // exactly one token tree
-        "meta"     | // exactly one token tree
-        "lifetime" | // exactly one token tree
-        "tt" =>   // exactly one token tree
+        sym::item     | // always terminated by `}` or `;`
+        sym::block    | // exactly one token tree
+        sym::ident    | // exactly one token tree
+        sym::literal  | // exactly one token tree
+        sym::meta     | // exactly one token tree
+        sym::lifetime | // exactly one token tree
+        sym::tt =>   // exactly one token tree
             true,
 
         _ =>
@@ -993,7 +993,7 @@ enum IsInFollow {
 /// break macros that were relying on that binary operator as a
 /// separator.
 // when changing this do not forget to update doc/book/macros.md!
-fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> IsInFollow {
+fn is_in_follow(tok: &quoted::TokenTree, frag: Symbol) -> IsInFollow {
     use quoted::TokenTree;
 
     if let TokenTree::Token(Token { kind: token::CloseDelim(_), .. }) = *tok {
@@ -1002,17 +1002,17 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> IsInFollow {
         IsInFollow::Yes
     } else {
         match frag {
-            "item" => {
+            sym::item => {
                 // since items *must* be followed by either a `;` or a `}`, we can
                 // accept anything after them
                 IsInFollow::Yes
             }
-            "block" => {
+            sym::block => {
                 // anything can follow block, the braces provide an easy boundary to
                 // maintain
                 IsInFollow::Yes
             }
-            "stmt" | "expr" => {
+            sym::stmt | sym::expr => {
                 const TOKENS: &[&str] = &["`=>`", "`,`", "`;`"];
                 match tok {
                     TokenTree::Token(token) => match token.kind {
@@ -1022,7 +1022,7 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> IsInFollow {
                     _ => IsInFollow::No(TOKENS),
                 }
             }
-            "pat" => {
+            sym::pat => {
                 const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"];
                 match tok {
                     TokenTree::Token(token) => match token.kind {
@@ -1033,7 +1033,7 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> IsInFollow {
                     _ => IsInFollow::No(TOKENS),
                 }
             }
-            "path" | "ty" => {
+            sym::path | sym::ty => {
                 const TOKENS: &[&str] = &[
                     "`{`", "`[`", "`=>`", "`,`", "`>`", "`=`", "`:`", "`;`", "`|`", "`as`",
                     "`where`",
@@ -1061,20 +1061,20 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> IsInFollow {
                     _ => IsInFollow::No(TOKENS),
                 }
             }
-            "ident" | "lifetime" => {
+            sym::ident | sym::lifetime => {
                 // being a single token, idents and lifetimes are harmless
                 IsInFollow::Yes
             }
-            "literal" => {
+            sym::literal => {
                 // literals may be of a single token, or two tokens (negative numbers)
                 IsInFollow::Yes
             }
-            "meta" | "tt" => {
+            sym::meta | sym::tt => {
                 // being either a single token or a delimited sequence, tt is
                 // harmless
                 IsInFollow::Yes
             }
-            "vis" => {
+            sym::vis => {
                 // Explicitly disallow `priv`, on the off chance it comes back.
                 const TOKENS: &[&str] = &["`,`", "an ident", "a type"];
                 match tok {
@@ -1099,7 +1099,7 @@ fn is_in_follow(tok: &quoted::TokenTree, frag: &str) -> IsInFollow {
                     _ => IsInFollow::No(TOKENS),
                 }
             }
-            "" => IsInFollow::Yes, // kw::Invalid
+            kw::Invalid => IsInFollow::Yes,
             _ => IsInFollow::Invalid(
                 format!("invalid fragment specifier `{}`", frag),
                 VALID_FRAGMENT_NAMES_MSG,

From 8c0f6011057b5b2f7bd4d74ce63caf8d6630c39e Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 17 Aug 2019 12:57:44 +0200
Subject: [PATCH 786/943] fix Miri discriminant load/store when overflows are
 involved

---
 src/librustc_mir/interpret/operand.rs | 40 +++++++++++++++++++++----
 src/librustc_mir/interpret/place.rs   | 42 ++++++++++++++++++++-------
 2 files changed, 65 insertions(+), 17 deletions(-)

diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 9ad1542905b68..3b07202f898ba 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -609,15 +609,20 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ) -> InterpResult<'tcx, (u128, VariantIdx)> {
         trace!("read_discriminant_value {:#?}", rval.layout);
 
-        let (discr_kind, discr_index) = match rval.layout.variants {
+        let (discr_layout, discr_kind, discr_index) = match rval.layout.variants {
             layout::Variants::Single { index } => {
                 let discr_val = rval.layout.ty.discriminant_for_variant(*self.tcx, index).map_or(
                     index.as_u32() as u128,
                     |discr| discr.val);
                 return Ok((discr_val, index));
             }
-            layout::Variants::Multiple { ref discr_kind, discr_index, .. } =>
-                (discr_kind, discr_index),
+            layout::Variants::Multiple {
+                discr: ref discr_layout,
+                ref discr_kind,
+                discr_index,
+                ..
+            } =>
+                (discr_layout, discr_kind, discr_index),
         };
 
         // read raw discriminant value
@@ -634,7 +639,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     .map_err(|_| err_unsup!(InvalidDiscriminant(raw_discr.erase_tag())))?;
                 let real_discr = if discr_val.layout.ty.is_signed() {
                     // going from layout tag type to typeck discriminant type
-                    // requires first sign extending with the layout discriminant
+                    // requires first sign extending with the discriminant layout
                     let sexted = sign_extend(bits_discr, discr_val.layout.size) as i128;
                     // and then zeroing with the typeck discriminant type
                     let discr_ty = rval.layout.ty
@@ -682,8 +687,31 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         (dataful_variant.as_u32() as u128, dataful_variant)
                     },
                     Ok(raw_discr) => {
-                        let adjusted_discr = raw_discr.wrapping_sub(niche_start)
-                            .wrapping_add(variants_start);
+                        // FIXME: WTF, some discriminants don't have integer type.
+                        use layout::Primitive;
+                        let discr_layout = self.layout_of(match discr_layout.value {
+                            Primitive::Int(int, signed) => int.to_ty(*self.tcx, signed),
+                            Primitive::Pointer => self.tcx.types.usize,
+                            Primitive::Float(..) => bug!("there are no float discriminants"),
+                        })?;
+                        let discr_val = ImmTy::from_uint(raw_discr, discr_layout);
+                        // We need to use machine arithmetic.
+                        let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
+                        let variants_start_val = ImmTy::from_uint(variants_start, discr_layout);
+                        let adjusted_discr = self.binary_op(
+                            mir::BinOp::Sub,
+                            discr_val,
+                            niche_start_val,
+                        )?;
+                        let adjusted_discr = self.binary_op(
+                            mir::BinOp::Add,
+                            adjusted_discr,
+                            variants_start_val,
+                        )?;
+                        let adjusted_discr = adjusted_discr
+                            .to_scalar()?
+                            .assert_bits(discr_val.layout.size);
+                        // Check if this is in the range that indicates an actual discriminant.
                         if variants_start <= adjusted_discr && adjusted_discr <= variants_end {
                             let index = adjusted_discr as usize;
                             assert_eq!(index as u128, adjusted_discr);
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 1a28548618206..0a23c1222b4bf 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -8,7 +8,9 @@ use std::hash::Hash;
 use rustc::mir;
 use rustc::mir::interpret::truncate;
 use rustc::ty::{self, Ty};
-use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx};
+use rustc::ty::layout::{
+    self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, IntegerExt
+};
 use rustc::ty::TypeFoldable;
 
 use super::{
@@ -1027,7 +1029,7 @@ where
             }
             layout::Variants::Multiple {
                 discr_kind: layout::DiscriminantKind::Tag,
-                ref discr,
+                discr: ref discr_layout,
                 discr_index,
                 ..
             } => {
@@ -1038,7 +1040,7 @@ where
                 // raw discriminants for enums are isize or bigger during
                 // their computation, but the in-memory tag is the smallest possible
                 // representation
-                let size = discr.value.size(self);
+                let size = discr_layout.value.size(self);
                 let discr_val = truncate(discr_val, size);
 
                 let discr_dest = self.place_field(dest, discr_index as u64)?;
@@ -1050,6 +1052,7 @@ where
                     ref niche_variants,
                     niche_start,
                 },
+                discr: ref discr_layout,
                 discr_index,
                 ..
             } => {
@@ -1057,15 +1060,32 @@ where
                     variant_index.as_usize() < dest.layout.ty.ty_adt_def().unwrap().variants.len(),
                 );
                 if variant_index != dataful_variant {
-                    let niche_dest =
-                        self.place_field(dest, discr_index as u64)?;
-                    let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
-                    let niche_value = (niche_value as u128)
-                        .wrapping_add(niche_start);
-                    self.write_scalar(
-                        Scalar::from_uint(niche_value, niche_dest.layout.size),
-                        niche_dest
+                    // FIXME: WTF, some discriminants don't have integer type.
+                    use layout::Primitive;
+                    let discr_layout = self.layout_of(match discr_layout.value {
+                        Primitive::Int(int, signed) => int.to_ty(*self.tcx, signed),
+                        Primitive::Pointer => self.tcx.types.usize,
+                        Primitive::Float(..) => bug!("there are no float discriminants"),
+                    })?;
+
+                    // We need to use machine arithmetic.
+                    let variants_start = niche_variants.start().as_u32();
+                    let variants_start_val = ImmTy::from_uint(variants_start, discr_layout);
+                    let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
+                    let variant_index_val = ImmTy::from_uint(variant_index.as_u32(), discr_layout);
+                    let niche_val = self.binary_op(
+                        mir::BinOp::Sub,
+                        variant_index_val,
+                        variants_start_val,
+                    )?;
+                    let niche_val = self.binary_op(
+                        mir::BinOp::Add,
+                        niche_val,
+                        niche_start_val,
                     )?;
+                    // Write result.
+                    let niche_dest = self.place_field(dest, discr_index as u64)?;
+                    self.write_immediate(*niche_val, niche_dest)?;
                 }
             }
         }

From b73f1a51dcd1011129dc5c5c55a7577134410dbc Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 16 Sep 2019 13:08:21 +0200
Subject: [PATCH 787/943] better and more consistent variable names

---
 src/librustc_mir/interpret/operand.rs | 16 ++++++++--------
 src/librustc_mir/interpret/place.rs   |  8 ++++----
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 3b07202f898ba..2a0bad2fa746c 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -698,28 +698,28 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         // We need to use machine arithmetic.
                         let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
                         let variants_start_val = ImmTy::from_uint(variants_start, discr_layout);
-                        let adjusted_discr = self.binary_op(
+                        let variant_index_relative_val = self.binary_op(
                             mir::BinOp::Sub,
                             discr_val,
                             niche_start_val,
                         )?;
-                        let adjusted_discr = self.binary_op(
+                        let variant_index_val = self.binary_op(
                             mir::BinOp::Add,
-                            adjusted_discr,
+                            variant_index_relative_val,
                             variants_start_val,
                         )?;
-                        let adjusted_discr = adjusted_discr
+                        let variant_index = variant_index_val
                             .to_scalar()?
                             .assert_bits(discr_val.layout.size);
                         // Check if this is in the range that indicates an actual discriminant.
-                        if variants_start <= adjusted_discr && adjusted_discr <= variants_end {
-                            let index = adjusted_discr as usize;
-                            assert_eq!(index as u128, adjusted_discr);
+                        if variants_start <= variant_index && variant_index <= variants_end {
+                            let index = variant_index as usize;
+                            assert_eq!(index as u128, variant_index);
                             assert!(index < rval.layout.ty
                                 .ty_adt_def()
                                 .expect("tagged layout for non adt")
                                 .variants.len());
-                            (adjusted_discr, VariantIdx::from_usize(index))
+                            (variant_index, VariantIdx::from_usize(index))
                         } else {
                             (dataful_variant.as_u32() as u128, dataful_variant)
                         }
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 0a23c1222b4bf..636b070a3d8f3 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -1073,19 +1073,19 @@ where
                     let variants_start_val = ImmTy::from_uint(variants_start, discr_layout);
                     let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
                     let variant_index_val = ImmTy::from_uint(variant_index.as_u32(), discr_layout);
-                    let niche_val = self.binary_op(
+                    let variant_index_relative_val = self.binary_op(
                         mir::BinOp::Sub,
                         variant_index_val,
                         variants_start_val,
                     )?;
-                    let niche_val = self.binary_op(
+                    let discr_val = self.binary_op(
                         mir::BinOp::Add,
-                        niche_val,
+                        variant_index_relative_val,
                         niche_start_val,
                     )?;
                     // Write result.
                     let niche_dest = self.place_field(dest, discr_index as u64)?;
-                    self.write_immediate(*niche_val, niche_dest)?;
+                    self.write_immediate(*discr_val, niche_dest)?;
                 }
             }
         }

From 75fe84f4fc764e0684e7fdafbe6139cc92082a44 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 16 Sep 2019 13:15:23 +0200
Subject: [PATCH 788/943] factor getting the discriminant layout to a new
 method

---
 src/librustc/ty/layout.rs             | 11 +++++++++++
 src/librustc_mir/interpret/operand.rs | 10 ++--------
 src/librustc_mir/interpret/place.rs   | 11 ++---------
 3 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 5ec4754c4535b..e52feea1624c1 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -127,6 +127,7 @@ impl IntegerExt for Integer {
 
 pub trait PrimitiveExt {
     fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
+    fn to_int_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx>;
 }
 
 impl PrimitiveExt for Primitive {
@@ -138,6 +139,16 @@ impl PrimitiveExt for Primitive {
             Pointer => tcx.mk_mut_ptr(tcx.mk_unit()),
         }
     }
+
+    /// Return an *integer* type matching this primitive.
+    /// Useful in particular when dealing with enum discriminants.
+    fn to_int_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+        match *self {
+            Int(i, signed) => i.to_ty(tcx, signed),
+            Pointer => tcx.types.usize,
+            Float(..) => bug!("floats do not have an int type"),
+        }
+    }
 }
 
 /// The first half of a fat pointer.
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 2a0bad2fa746c..94fbd4ac7d7f3 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -5,7 +5,7 @@ use std::convert::TryInto;
 
 use rustc::{mir, ty};
 use rustc::ty::layout::{
-    self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx,
+    self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, PrimitiveExt, VariantIdx,
 };
 
 use rustc::mir::interpret::{
@@ -687,13 +687,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         (dataful_variant.as_u32() as u128, dataful_variant)
                     },
                     Ok(raw_discr) => {
-                        // FIXME: WTF, some discriminants don't have integer type.
-                        use layout::Primitive;
-                        let discr_layout = self.layout_of(match discr_layout.value {
-                            Primitive::Int(int, signed) => int.to_ty(*self.tcx, signed),
-                            Primitive::Pointer => self.tcx.types.usize,
-                            Primitive::Float(..) => bug!("there are no float discriminants"),
-                        })?;
+                        let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
                         let discr_val = ImmTy::from_uint(raw_discr, discr_layout);
                         // We need to use machine arithmetic.
                         let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 636b070a3d8f3..9a3d70144a586 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -9,7 +9,7 @@ use rustc::mir;
 use rustc::mir::interpret::truncate;
 use rustc::ty::{self, Ty};
 use rustc::ty::layout::{
-    self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, IntegerExt
+    self, Size, Align, LayoutOf, TyLayout, HasDataLayout, VariantIdx, PrimitiveExt
 };
 use rustc::ty::TypeFoldable;
 
@@ -1060,14 +1060,7 @@ where
                     variant_index.as_usize() < dest.layout.ty.ty_adt_def().unwrap().variants.len(),
                 );
                 if variant_index != dataful_variant {
-                    // FIXME: WTF, some discriminants don't have integer type.
-                    use layout::Primitive;
-                    let discr_layout = self.layout_of(match discr_layout.value {
-                        Primitive::Int(int, signed) => int.to_ty(*self.tcx, signed),
-                        Primitive::Pointer => self.tcx.types.usize,
-                        Primitive::Float(..) => bug!("there are no float discriminants"),
-                    })?;
-
+                    let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
                     // We need to use machine arithmetic.
                     let variants_start = niche_variants.start().as_u32();
                     let variants_start_val = ImmTy::from_uint(variants_start, discr_layout);

From 62e86b42b5ed342d30c539e22810c26d312995e2 Mon Sep 17 00:00:00 2001
From: Ivan Tham <pickfire@riseup.net>
Date: Mon, 16 Sep 2019 20:02:36 +0800
Subject: [PATCH 789/943] Fix inconsistent link formatting

---
 src/libstd/io/mod.rs | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 0386dbd490d03..be364a10593da 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -2326,10 +2326,10 @@ impl<R: Read> Iterator for Bytes<R> {
 /// An iterator over the contents of an instance of `BufRead` split on a
 /// particular byte.
 ///
-/// This struct is generally created by calling [`split`][split] on a
-/// `BufRead`. Please see the documentation of `split()` for more details.
+/// This struct is generally created by calling [`split`] on a `BufRead`.
+/// Please see the documentation of [`split`] for more details.
 ///
-/// [split]: trait.BufRead.html#method.split
+/// [`split`]: trait.BufRead.html#method.split
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Split<B> {
@@ -2358,10 +2358,10 @@ impl<B: BufRead> Iterator for Split<B> {
 
 /// An iterator over the lines of an instance of `BufRead`.
 ///
-/// This struct is generally created by calling [`lines`][lines] on a
-/// `BufRead`. Please see the documentation of `lines()` for more details.
+/// This struct is generally created by calling [`lines`] on a `BufRead`.
+/// Please see the documentation of [`lines`] for more details.
 ///
-/// [lines]: trait.BufRead.html#method.lines
+/// [`lines`]: trait.BufRead.html#method.lines
 #[stable(feature = "rust1", since = "1.0.0")]
 #[derive(Debug)]
 pub struct Lines<B> {

From 61a28d5c881d81cca9156527851911bb5aa5b818 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 16 Sep 2019 15:04:33 +0200
Subject: [PATCH 790/943] do the variant idx computations on the host
 (non-overflowing)

---
 src/librustc_mir/interpret/operand.rs | 14 ++++++--------
 src/librustc_mir/interpret/place.rs   | 16 +++++++---------
 2 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 94fbd4ac7d7f3..9e7ae32f1eacf 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -687,24 +687,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         (dataful_variant.as_u32() as u128, dataful_variant)
                     },
                     Ok(raw_discr) => {
+                        // We need to use machine arithmetic to get the relative variant idx.
                         let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
                         let discr_val = ImmTy::from_uint(raw_discr, discr_layout);
-                        // We need to use machine arithmetic.
                         let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
-                        let variants_start_val = ImmTy::from_uint(variants_start, discr_layout);
                         let variant_index_relative_val = self.binary_op(
                             mir::BinOp::Sub,
                             discr_val,
                             niche_start_val,
                         )?;
-                        let variant_index_val = self.binary_op(
-                            mir::BinOp::Add,
-                            variant_index_relative_val,
-                            variants_start_val,
-                        )?;
-                        let variant_index = variant_index_val
+                        let variant_index_relative = variant_index_relative_val
                             .to_scalar()?
                             .assert_bits(discr_val.layout.size);
+                        // Then computing the absolute variant idx should not overflow any more.
+                        let variant_index = variants_start
+                            .checked_add(variant_index_relative)
+                            .expect("oveflow computing absolute variant idx");
                         // Check if this is in the range that indicates an actual discriminant.
                         if variants_start <= variant_index && variant_index <= variants_end {
                             let index = variant_index as usize;
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 9a3d70144a586..5f4903d61e3b2 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -1060,17 +1060,15 @@ where
                     variant_index.as_usize() < dest.layout.ty.ty_adt_def().unwrap().variants.len(),
                 );
                 if variant_index != dataful_variant {
-                    let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
-                    // We need to use machine arithmetic.
                     let variants_start = niche_variants.start().as_u32();
-                    let variants_start_val = ImmTy::from_uint(variants_start, discr_layout);
+                    let variant_index_relative = variant_index.as_u32()
+                        .checked_sub(variants_start)
+                        .expect("overflow computing relative variant idx");
+                    // We need to use machine arithmetic when taking into account `niche_start`.
+                    let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
                     let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
-                    let variant_index_val = ImmTy::from_uint(variant_index.as_u32(), discr_layout);
-                    let variant_index_relative_val = self.binary_op(
-                        mir::BinOp::Sub,
-                        variant_index_val,
-                        variants_start_val,
-                    )?;
+                    let variant_index_relative_val =
+                        ImmTy::from_uint(variant_index_relative, discr_layout);
                     let discr_val = self.binary_op(
                         mir::BinOp::Add,
                         variant_index_relative_val,

From b21622cd6cc6c88cc6760e76ba1442aee1e2b9a8 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 16 Sep 2019 16:25:39 +0200
Subject: [PATCH 791/943] add test

---
 .../miri_unleashed/enum_discriminants.rs      | 110 ++++++++++++++++++
 .../miri_unleashed/enum_discriminants.stderr  |  72 ++++++++++++
 2 files changed, 182 insertions(+)
 create mode 100644 src/test/ui/consts/miri_unleashed/enum_discriminants.rs
 create mode 100644 src/test/ui/consts/miri_unleashed/enum_discriminants.stderr

diff --git a/src/test/ui/consts/miri_unleashed/enum_discriminants.rs b/src/test/ui/consts/miri_unleashed/enum_discriminants.rs
new file mode 100644
index 0000000000000..9f34fc73953a4
--- /dev/null
+++ b/src/test/ui/consts/miri_unleashed/enum_discriminants.rs
@@ -0,0 +1,110 @@
+// compile-flags: -Zunleash-the-miri-inside-of-you
+// run-pass
+
+//! Make sure that we read and write enum discriminants correctly for corner cases caused
+//! by layout optimizations.
+
+const OVERFLOW: usize = {
+    // Tests for https://github.com/rust-lang/rust/issues/62138.
+    #[repr(u8)]
+    #[allow(dead_code)]
+    enum WithWraparoundInvalidValues {
+        X = 1,
+        Y = 254,
+    }
+
+    #[allow(dead_code)]
+    enum Foo {
+        A,
+        B,
+        C(WithWraparoundInvalidValues),
+    }
+
+    let x = Foo::B;
+    match x {
+        Foo::B => 0,
+        _ => panic!(),
+    }
+};
+
+const MORE_OVERFLOW: usize = {
+    pub enum Infallible {}
+
+    // The check that the `bool` field of `V1` is encoding a "niche variant"
+    // (i.e. not `V1`, so `V3` or `V4`) used to be mathematically incorrect,
+    // causing valid `V1` values to be interpreted as other variants.
+    #[allow(dead_code)]
+    pub enum E1 {
+        V1 { f: bool },
+        V2 { f: Infallible },
+        V3,
+        V4,
+    }
+
+    // Computing the discriminant used to be done using the niche type (here `u8`,
+    // from the `bool` field of `V1`), overflowing for variants with large enough
+    // indices (`V3` and `V4`), causing them to be interpreted as other variants.
+    #[allow(dead_code)]
+    pub enum E2<X> {
+        V1 { f: bool },
+
+        /*_00*/ _01(X), _02(X), _03(X), _04(X), _05(X), _06(X), _07(X),
+        _08(X), _09(X), _0A(X), _0B(X), _0C(X), _0D(X), _0E(X), _0F(X),
+        _10(X), _11(X), _12(X), _13(X), _14(X), _15(X), _16(X), _17(X),
+        _18(X), _19(X), _1A(X), _1B(X), _1C(X), _1D(X), _1E(X), _1F(X),
+        _20(X), _21(X), _22(X), _23(X), _24(X), _25(X), _26(X), _27(X),
+        _28(X), _29(X), _2A(X), _2B(X), _2C(X), _2D(X), _2E(X), _2F(X),
+        _30(X), _31(X), _32(X), _33(X), _34(X), _35(X), _36(X), _37(X),
+        _38(X), _39(X), _3A(X), _3B(X), _3C(X), _3D(X), _3E(X), _3F(X),
+        _40(X), _41(X), _42(X), _43(X), _44(X), _45(X), _46(X), _47(X),
+        _48(X), _49(X), _4A(X), _4B(X), _4C(X), _4D(X), _4E(X), _4F(X),
+        _50(X), _51(X), _52(X), _53(X), _54(X), _55(X), _56(X), _57(X),
+        _58(X), _59(X), _5A(X), _5B(X), _5C(X), _5D(X), _5E(X), _5F(X),
+        _60(X), _61(X), _62(X), _63(X), _64(X), _65(X), _66(X), _67(X),
+        _68(X), _69(X), _6A(X), _6B(X), _6C(X), _6D(X), _6E(X), _6F(X),
+        _70(X), _71(X), _72(X), _73(X), _74(X), _75(X), _76(X), _77(X),
+        _78(X), _79(X), _7A(X), _7B(X), _7C(X), _7D(X), _7E(X), _7F(X),
+        _80(X), _81(X), _82(X), _83(X), _84(X), _85(X), _86(X), _87(X),
+        _88(X), _89(X), _8A(X), _8B(X), _8C(X), _8D(X), _8E(X), _8F(X),
+        _90(X), _91(X), _92(X), _93(X), _94(X), _95(X), _96(X), _97(X),
+        _98(X), _99(X), _9A(X), _9B(X), _9C(X), _9D(X), _9E(X), _9F(X),
+        _A0(X), _A1(X), _A2(X), _A3(X), _A4(X), _A5(X), _A6(X), _A7(X),
+        _A8(X), _A9(X), _AA(X), _AB(X), _AC(X), _AD(X), _AE(X), _AF(X),
+        _B0(X), _B1(X), _B2(X), _B3(X), _B4(X), _B5(X), _B6(X), _B7(X),
+        _B8(X), _B9(X), _BA(X), _BB(X), _BC(X), _BD(X), _BE(X), _BF(X),
+        _C0(X), _C1(X), _C2(X), _C3(X), _C4(X), _C5(X), _C6(X), _C7(X),
+        _C8(X), _C9(X), _CA(X), _CB(X), _CC(X), _CD(X), _CE(X), _CF(X),
+        _D0(X), _D1(X), _D2(X), _D3(X), _D4(X), _D5(X), _D6(X), _D7(X),
+        _D8(X), _D9(X), _DA(X), _DB(X), _DC(X), _DD(X), _DE(X), _DF(X),
+        _E0(X), _E1(X), _E2(X), _E3(X), _E4(X), _E5(X), _E6(X), _E7(X),
+        _E8(X), _E9(X), _EA(X), _EB(X), _EC(X), _ED(X), _EE(X), _EF(X),
+        _F0(X), _F1(X), _F2(X), _F3(X), _F4(X), _F5(X), _F6(X), _F7(X),
+        _F8(X), _F9(X), _FA(X), _FB(X), _FC(X), _FD(X), _FE(X), _FF(X),
+
+        V3,
+        V4,
+    }
+
+    if let E1::V2 { .. } = (E1::V1 { f: true }) {
+        unreachable!()
+    }
+    if let E1::V1 { .. } = (E1::V1 { f: true }) {
+    } else {
+        unreachable!()
+    }
+
+    if let E2::V1 { .. } = E2::V3::<Infallible> {
+        unreachable!()
+    }
+    if let E2::V3 { .. } = E2::V3::<Infallible> {
+    } else {
+        unreachable!()
+    }
+
+    0
+};
+
+fn main() {
+    assert_eq!(OVERFLOW, 0);
+    assert_eq!(MORE_OVERFLOW, 0);
+}
diff --git a/src/test/ui/consts/miri_unleashed/enum_discriminants.stderr b/src/test/ui/consts/miri_unleashed/enum_discriminants.stderr
new file mode 100644
index 0000000000000..8ca81ad22b72b
--- /dev/null
+++ b/src/test/ui/consts/miri_unleashed/enum_discriminants.stderr
@@ -0,0 +1,72 @@
+warning: skipping const checks
+  --> $DIR/enum_discriminants.rs:23:13
+   |
+LL |     let x = Foo::B;
+   |             ^^^^^^
+
+warning: skipping const checks
+  --> $DIR/enum_discriminants.rs:25:9
+   |
+LL |         Foo::B => 0,
+   |         ^^^^^^
+
+warning: skipping const checks
+  --> $DIR/enum_discriminants.rs:88:28
+   |
+LL |     if let E1::V2 { .. } = (E1::V1 { f: true }) {
+   |                            ^^^^^^^^^^^^^^^^^^^^
+
+warning: skipping const checks
+  --> $DIR/enum_discriminants.rs:88:12
+   |
+LL |     if let E1::V2 { .. } = (E1::V1 { f: true }) {
+   |            ^^^^^^^^^^^^^
+
+warning: skipping const checks
+  --> $DIR/enum_discriminants.rs:108:5
+   |
+LL |     assert_eq!(OVERFLOW, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/enum_discriminants.rs:108:5
+   |
+LL |     assert_eq!(OVERFLOW, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/enum_discriminants.rs:108:5
+   |
+LL |     assert_eq!(OVERFLOW, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/enum_discriminants.rs:109:5
+   |
+LL |     assert_eq!(MORE_OVERFLOW, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/enum_discriminants.rs:109:5
+   |
+LL |     assert_eq!(MORE_OVERFLOW, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/enum_discriminants.rs:109:5
+   |
+LL |     assert_eq!(MORE_OVERFLOW, 0);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+

From d3d7b58c3743b6146b5fb818508d9eda958e8cd9 Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro@pietroalbini.org>
Date: Tue, 3 Sep 2019 11:33:29 +0200
Subject: [PATCH 792/943] ci: ensure all tool maintainers are assignable on
 issues

GitHub only allows people explicitly listed as collaborators on the
repository or who commented on the issue/PR to be assignees, failing to
create the issue if non-assignable people are assigned.

This adds an extra check on CI to make sure all the people listed as
tool maintainers can be assigned to toolstate issues. The check won't be
executed on PR builds due to the lack of a valid token.
---
 src/ci/azure-pipelines/steps/run.yml |  7 ++++
 src/tools/publish_toolstate.py       | 60 ++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml
index ac6b344a45e66..da0a899ac85eb 100644
--- a/src/ci/azure-pipelines/steps/run.yml
+++ b/src/ci/azure-pipelines/steps/run.yml
@@ -147,8 +147,15 @@ steps:
     git clone --depth=1 https://github.com/rust-lang-nursery/rust-toolstate.git
     cd rust-toolstate
     python2.7 "$BUILD_SOURCESDIRECTORY/src/tools/publish_toolstate.py" "$(git rev-parse HEAD)" "$(git log --format=%s -n1 HEAD)" "" ""
+    # Only check maintainers if this build is supposed to publish toolstate.
+    # Builds that are not supposed to publish don't have the access token.
+    if [ -n "${TOOLSTATE_PUBLISH+is_set}" ]; then
+      TOOLSTATE_VALIDATE_MAINTAINERS_REPO=rust-lang/rust python2.7 "${BUILD_SOURCESDIRECTORY}/src/tools/publish_toolstate.py"
+    fi
     cd ..
     rm -rf rust-toolstate
+  env:
+    TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN)
   condition: and(succeeded(), not(variables.SKIP_JOB), eq(variables['IMAGE'], 'mingw-check'))
   displayName: Verify the publish_toolstate script works
 
diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 2e2505b7f0246..bc00fbc90bf96 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -7,6 +7,8 @@
 ## It is set as callback for `src/ci/docker/x86_64-gnu-tools/repo.sh` by the CI scripts
 ## when a new commit lands on `master` (i.e., after it passed all checks on `auto`).
 
+from __future__ import print_function
+
 import sys
 import re
 import os
@@ -20,6 +22,8 @@
     import urllib.request as urllib2
 
 # List of people to ping when the status of a tool or a book changed.
+# These should be collaborators of the rust-lang/rust repository (with at least
+# read privileges on it). CI will fail otherwise.
 MAINTAINERS = {
     'miri': '@oli-obk @RalfJung @eddyb',
     'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk @phansch @flip1995 @yaahc',
@@ -52,6 +56,53 @@
 }
 
 
+def validate_maintainers(repo, github_token):
+    '''Ensure all maintainers are assignable on a GitHub repo'''
+    next_link_re = re.compile(r'<([^>]+)>; rel="next"')
+
+    # Load the list of assignable people in the GitHub repo
+    assignable = []
+    url = 'https://api.github.com/repos/%s/collaborators?per_page=100' % repo
+    while url is not None:
+        response = urllib2.urlopen(urllib2.Request(url, headers={
+            'Authorization': 'token ' + github_token,
+            # Properly load nested teams.
+            'Accept': 'application/vnd.github.hellcat-preview+json',
+        }))
+        for user in json.loads(response.read()):
+            assignable.append(user['login'])
+        # Load the next page if available
+        if 'Link' in response.headers:
+            matches = next_link_re.match(response.headers['Link'])
+            if matches is not None:
+                url = matches.group(1)
+            else:
+                url = None
+
+    errors = False
+    for tool, maintainers in MAINTAINERS.items():
+        for maintainer in maintainers.split(' '):
+            if maintainer.startswith('@'):
+                maintainer = maintainer[1:]
+            if maintainer not in assignable:
+                errors = True
+                print(
+                    "error: %s maintainer @%s is not assignable in the %s repo"
+                    % (tool, maintainer, repo),
+                )
+
+    if errors:
+        print()
+        print("  To be assignable, a person needs to be explicitly listed as a")
+        print("  collaborator in the repository settings. The simple way to")
+        print("  fix this is to ask someone with 'admin' privileges on the repo")
+        print("  to add the person or whole team as a collaborator with 'read'")
+        print("  privileges. Those privileges don't grant any extra permissions")
+        print("  so it's safe to apply them.")
+        print()
+        print("The build will fail due to this.")
+        exit(1)
+
 def read_current_status(current_commit, path):
     '''Reads build status of `current_commit` from content of `history/*.tsv`
     '''
@@ -200,6 +251,15 @@ def update_latest(
 
 
 if __name__ == '__main__':
+    if 'TOOLSTATE_VALIDATE_MAINTAINERS_REPO' in os.environ:
+        repo = os.environ['TOOLSTATE_VALIDATE_MAINTAINERS_REPO']
+        if 'TOOLSTATE_REPO_ACCESS_TOKEN' in os.environ:
+            github_token = os.environ['TOOLSTATE_REPO_ACCESS_TOKEN']
+            validate_maintainers(repo, github_token)
+        else:
+            print('skipping toolstate maintainers validation since no GitHub token is present')
+        exit(0)
+
     cur_commit = sys.argv[1]
     cur_datetime = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
     cur_commit_msg = sys.argv[2]

From eb97b1bfdede51981dbed39bb3fe483311f8f65d Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro@pietroalbini.org>
Date: Tue, 3 Sep 2019 12:04:22 +0200
Subject: [PATCH 793/943] ci: rename Gankro to Gankra in toolstate

---
 src/tools/publish_toolstate.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index bc00fbc90bf96..cd7a182da2706 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -30,7 +30,7 @@
     'rls': '@Xanewok',
     'rustfmt': '@topecongiro',
     'book': '@carols10cents @steveklabnik',
-    'nomicon': '@frewsxcv @Gankro',
+    'nomicon': '@frewsxcv @Gankra',
     'reference': '@steveklabnik @Havvy @matthewjasper @ehuss',
     'rust-by-example': '@steveklabnik @marioidival @projektir',
     'embedded-book': (

From f968c1a4f51b1e57f1f613055332b3bf63f5864e Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro@pietroalbini.org>
Date: Wed, 4 Sep 2019 10:08:54 +0200
Subject: [PATCH 794/943] ci: address publish_toolstate review comments

---
 src/tools/publish_toolstate.py | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index cd7a182da2706..5211d1141c7e0 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -69,15 +69,14 @@ def validate_maintainers(repo, github_token):
             # Properly load nested teams.
             'Accept': 'application/vnd.github.hellcat-preview+json',
         }))
-        for user in json.loads(response.read()):
-            assignable.append(user['login'])
+        assignable.extend(user['login'] for user in json.load(response))
         # Load the next page if available
-        if 'Link' in response.headers:
-            matches = next_link_re.match(response.headers['Link'])
+        url = None
+        link_header = response.headers.get('Link')
+        if link_header:
+            matches = next_link_re.match(link_header)
             if matches is not None:
                 url = matches.group(1)
-            else:
-                url = None
 
     errors = False
     for tool, maintainers in MAINTAINERS.items():
@@ -251,13 +250,14 @@ def update_latest(
 
 
 if __name__ == '__main__':
-    if 'TOOLSTATE_VALIDATE_MAINTAINERS_REPO' in os.environ:
-        repo = os.environ['TOOLSTATE_VALIDATE_MAINTAINERS_REPO']
-        if 'TOOLSTATE_REPO_ACCESS_TOKEN' in os.environ:
-            github_token = os.environ['TOOLSTATE_REPO_ACCESS_TOKEN']
+    repo = os.environ.get('TOOLSTATE_VALIDATE_MAINTAINERS_REPO')
+    if repo:
+        github_token = os.environ.get('TOOLSTATE_REPO_ACCESS_TOKEN')
+        if github_token:
             validate_maintainers(repo, github_token)
         else:
             print('skipping toolstate maintainers validation since no GitHub token is present')
+        # When validating maintainers don't run the full script.
         exit(0)
 
     cur_commit = sys.argv[1]

From f2576c821d2e15b23dcea8af9b3ed08cf4a5795f Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro@pietroalbini.org>
Date: Wed, 4 Sep 2019 10:21:23 +0200
Subject: [PATCH 795/943] ci: convert maintainer list in publish_toolstate to a
 set

---
 src/tools/publish_toolstate.py | 45 +++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 22 deletions(-)

diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 5211d1141c7e0..217f8a7f6f4c7 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -25,20 +25,23 @@
 # These should be collaborators of the rust-lang/rust repository (with at least
 # read privileges on it). CI will fail otherwise.
 MAINTAINERS = {
-    'miri': '@oli-obk @RalfJung @eddyb',
-    'clippy-driver': '@Manishearth @llogiq @mcarton @oli-obk @phansch @flip1995 @yaahc',
-    'rls': '@Xanewok',
-    'rustfmt': '@topecongiro',
-    'book': '@carols10cents @steveklabnik',
-    'nomicon': '@frewsxcv @Gankra',
-    'reference': '@steveklabnik @Havvy @matthewjasper @ehuss',
-    'rust-by-example': '@steveklabnik @marioidival @projektir',
-    'embedded-book': (
-        '@adamgreig @andre-richter @jamesmunns @korken89 '
-        '@ryankurte @thejpster @therealprof'
-    ),
-    'edition-guide': '@ehuss @Centril @steveklabnik',
-    'rustc-guide': '@mark-i-m @spastorino @amanjeev'
+    'miri': {'oli-obk', 'RalfJung', 'eddyb'},
+    'clippy-driver': {
+        'Manishearth', 'llogiq', 'mcarton', 'oli-obk', 'phansch', 'flip1995',
+        'yaahc',
+    },
+    'rls': {'Xanewok'},
+    'rustfmt': {'topecongiro'},
+    'book': {'carols10cents', 'steveklabnik'},
+    'nomicon': {'frewsxcv', 'Gankra'},
+    'reference': {'steveklabnik', 'Havvy', 'matthewjasper', 'ehuss'},
+    'rust-by-example': {'steveklabnik', 'marioidival', 'projektir'},
+    'embedded-book': {
+        'adamgreig', 'andre-richter', 'jamesmunns', 'korken89',
+        'ryankurte', 'thejpster', 'therealprof',
+    },
+    'edition-guide': {'ehuss', 'Centril', 'steveklabnik'},
+    'rustc-guide': {'mark-i-m', 'spastorino', 'amanjeev'},
 }
 
 REPOS = {
@@ -80,9 +83,7 @@ def validate_maintainers(repo, github_token):
 
     errors = False
     for tool, maintainers in MAINTAINERS.items():
-        for maintainer in maintainers.split(' '):
-            if maintainer.startswith('@'):
-                maintainer = maintainer[1:]
+        for maintainer in maintainers:
             if maintainer not in assignable:
                 errors = True
                 print(
@@ -123,13 +124,12 @@ def maybe_delink(message):
 def issue(
     tool,
     status,
-    maintainers,
+    assignees,
     relevant_pr_number,
     relevant_pr_user,
     pr_reviewer,
 ):
     # Open an issue about the toolstate failure.
-    assignees = [x.strip() for x in maintainers.split('@') if x != '']
     if status == 'test-fail':
         status_description = 'has failing tests'
     else:
@@ -150,7 +150,7 @@ def issue(
             REPOS.get(tool), relevant_pr_user, pr_reviewer
         )),
         'title': '`{}` no longer builds after {}'.format(tool, relevant_pr_number),
-        'assignees': assignees,
+        'assignees': list(assignees),
         'labels': ['T-compiler', 'I-nominated'],
     })
     print("Creating issue:\n{}".format(request))
@@ -200,18 +200,19 @@ def update_latest(
                 old = status[os]
                 new = s.get(tool, old)
                 status[os] = new
+                maintainers = ' '.join('@'+name for name in MAINTAINERS[tool])
                 if new > old: # comparing the strings, but they are ordered appropriately!
                     # things got fixed or at least the status quo improved
                     changed = True
                     message += '🎉 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
-                        .format(tool, os, old, new, MAINTAINERS.get(tool))
+                        .format(tool, os, old, new, maintainers)
                 elif new < old:
                     # tests or builds are failing and were not failing before
                     changed = True
                     title = '💔 {} on {}: {} → {}' \
                         .format(tool, os, old, new)
                     message += '{} (cc {}, @rust-lang/infra).\n' \
-                        .format(title, MAINTAINERS.get(tool))
+                        .format(title, maintainers)
                     # Most tools only create issues for build failures.
                     # Other failures can be spurious.
                     if new == 'build-fail' or (tool == 'miri' and new == 'test-fail'):

From ce451b9b269207feb565f566cdbd34d7ec369b4b Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro@pietroalbini.org>
Date: Mon, 9 Sep 2019 16:03:57 +0200
Subject: [PATCH 796/943] ci: remove projektir from toolstate notifications

They don't contribute to rust-by-example anymore.
---
 src/tools/publish_toolstate.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 217f8a7f6f4c7..4060b90d952bd 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -35,7 +35,7 @@
     'book': {'carols10cents', 'steveklabnik'},
     'nomicon': {'frewsxcv', 'Gankra'},
     'reference': {'steveklabnik', 'Havvy', 'matthewjasper', 'ehuss'},
-    'rust-by-example': {'steveklabnik', 'marioidival', 'projektir'},
+    'rust-by-example': {'steveklabnik', 'marioidival'},
     'embedded-book': {
         'adamgreig', 'andre-richter', 'jamesmunns', 'korken89',
         'ryankurte', 'thejpster', 'therealprof',

From 49854c4f71eb8470c2a4483cbad3f03eb99e67cb Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 16 Sep 2019 16:37:44 +0200
Subject: [PATCH 797/943] avoid #[cfg] in favor of cfg!

---
 src/libstd/panicking.rs            | 18 +++++++-----------
 src/libstd/sys_common/backtrace.rs |  2 --
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index e7755af7f07da..28fb40244043e 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -17,8 +17,7 @@ use crate::ptr;
 use crate::raw;
 use crate::sys::stdio::panic_output;
 use crate::sys_common::rwlock::RWLock;
-use crate::sys_common::thread_info;
-use crate::sys_common::util;
+use crate::sys_common::{thread_info, util, backtrace};
 use crate::thread;
 
 #[cfg(not(test))]
@@ -157,20 +156,18 @@ pub fn take_hook() -> Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send> {
 }
 
 fn default_hook(info: &PanicInfo<'_>) {
-    #[cfg(feature = "backtrace")]
-    use crate::sys_common::{backtrace as backtrace_mod};
-
     // If this is a double panic, make sure that we print a backtrace
     // for this panic. Otherwise only print it if logging is enabled.
-    #[cfg(feature = "backtrace")]
-    let log_backtrace = {
+    let log_backtrace = if cfg!(feature = "backtrace") {
         let panics = update_panic_count(0);
 
         if panics >= 2 {
             Some(backtrace_rs::PrintFmt::Full)
         } else {
-            backtrace_mod::log_enabled()
+            backtrace::log_enabled()
         }
+    } else {
+        None
     };
 
     // The current implementation always returns `Some`.
@@ -190,14 +187,13 @@ fn default_hook(info: &PanicInfo<'_>) {
         let _ = writeln!(err, "thread '{}' panicked at '{}', {}",
                          name, msg, location);
 
-        #[cfg(feature = "backtrace")]
-        {
+        if cfg!(feature = "backtrace") {
             use crate::sync::atomic::{AtomicBool, Ordering};
 
             static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
 
             if let Some(format) = log_backtrace {
-                let _ = backtrace_mod::print(err, format);
+                let _ = backtrace::print(err, format);
             } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) {
                 let _ = writeln!(err, "note: run with `RUST_BACKTRACE=1` \
                                        environment variable to display a backtrace.");
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index f49adc01659ff..01711d415d86c 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -33,7 +33,6 @@ pub fn lock() -> impl Drop {
 }
 
 /// Prints the current backtrace.
-#[cfg(feature = "backtrace")]
 pub fn print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
     // There are issues currently linking libbacktrace into tests, and in
     // general during libstd's own unit tests we're not testing this path. In
@@ -129,7 +128,6 @@ where
 
 // For now logging is turned off by default, and this function checks to see
 // whether the magical environment variable is present to see if it's turned on.
-#[cfg(feature = "backtrace")]
 pub fn log_enabled() -> Option<PrintFmt> {
     use crate::sync::atomic::{self, Ordering};
 

From 18b24b718d2f3d5788a1a0406ae5d0b652f176fd Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Mon, 16 Sep 2019 15:43:46 +0100
Subject: [PATCH 798/943] Make some adjustments to the documentation for
 `std::convert::identity`

Fixes some extra blank lines and makes some minor tweaks to the wording.
---
 src/libcore/convert.rs | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index 402a7b2c95a46..06f2b7bab12eb 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -42,11 +42,11 @@
 
 use crate::fmt;
 
-/// An identity function.
+/// The identity function.
 ///
 /// Two things are important to note about this function:
 ///
-/// - It is not always equivalent to a closure like `|x| x` since the
+/// - It is not always equivalent to a closure like `|x| x`, since the
 ///   closure may coerce `x` into a different type.
 ///
 /// - It moves the input `x` passed to the function.
@@ -56,31 +56,32 @@ use crate::fmt;
 ///
 /// # Examples
 ///
-/// Using `identity` to do nothing among other interesting functions:
+/// Using `identity` to do nothing in a sequence of other, interesting,
+/// functions:
 ///
 /// ```rust
 /// use std::convert::identity;
 ///
 /// fn manipulation(x: u32) -> u32 {
-///     // Let's assume that this function does something interesting.
+///     // Let's pretend that adding one is an interesting function.
 ///     x + 1
 /// }
 ///
 /// let _arr = &[identity, manipulation];
 /// ```
 ///
-/// Using `identity` to get a function that changes nothing in a conditional:
+/// Using `identity` as a "do nothing" base case in a conditional:
 ///
 /// ```rust
 /// use std::convert::identity;
 ///
 /// # let condition = true;
-///
+/// #
 /// # fn manipulation(x: u32) -> u32 { x + 1 }
-///
+/// #
 /// let do_stuff = if condition { manipulation } else { identity };
 ///
-/// // do more interesting stuff..
+/// // Do more interesting stuff...
 ///
 /// let _results = do_stuff(42);
 /// ```

From d5fe5831ecc82d2705110810261b79ae4040c403 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 29 Aug 2019 11:32:38 +0200
Subject: [PATCH 799/943] Const-stabilize `Vec::new`.

---
 src/liballoc/lib.rs                           |  2 +-
 src/liballoc/raw_vec.rs                       | 27 ++++++++++++++++++-
 src/liballoc/vec.rs                           |  4 +--
 src/test/ui/collections-const-new.rs          |  4 +--
 ...ure-gate-unleash_the_miri_inside_of_you.rs |  3 ++-
 ...gate-unleash_the_miri_inside_of_you.stderr | 10 +------
 6 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 370e5cf4b303f..9e6ed92ffb567 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -117,7 +117,7 @@
 #![feature(allocator_internals)]
 #![feature(on_unimplemented)]
 #![feature(rustc_const_unstable)]
-#![feature(const_vec_new)]
+#![cfg_attr(bootstrap, feature(const_vec_new))]
 #![feature(slice_partition_dedup)]
 #![feature(maybe_uninit_extra, maybe_uninit_slice)]
 #![feature(alloc_layout_extra)]
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index cf025eee4358b..ee75fc288fee5 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -113,13 +113,38 @@ impl<T, A: Alloc> RawVec<T, A> {
 }
 
 impl<T> RawVec<T, Global> {
+    /// HACK(Centril): This exists because `#[unstable]` `const fn`s needn't conform
+    /// to `min_const_fn` and so they cannot be called in `min_const_fn`s either.
+    ///
+    /// If you change `RawVec<T>::new` or dependencies, please take care to not
+    /// introduce anything that would truly violate `min_const_fn`.
+    ///
+    /// NOTE: We could avoid this hack and check conformance with some
+    /// `#[rustc_force_min_const_fn]` attribute which requires conformance
+    /// with `min_const_fn` but does not necessarily allow calling it in
+    /// `stable(...) const fn` / user code not enabling `foo` when
+    /// `#[rustc_const_unstable(feature = "foo", ..)]` is present.
+    pub const NEW: Self = Self::new();
+
     /// Creates the biggest possible `RawVec` (on the system heap)
     /// without allocating. If `T` has positive size, then this makes a
     /// `RawVec` with capacity `0`. If `T` is zero-sized, then it makes a
     /// `RawVec` with capacity `usize::MAX`. Useful for implementing
     /// delayed allocation.
     pub const fn new() -> Self {
-        Self::new_in(Global)
+        // FIXME(Centril): Reintegrate this with `fn new_in` when we can.
+
+        // `!0` is `usize::MAX`. This branch should be stripped at compile time.
+        // FIXME(mark-i-m): use this line when `if`s are allowed in `const`:
+        //let cap = if mem::size_of::<T>() == 0 { !0 } else { 0 };
+
+        // `Unique::empty()` doubles as "unallocated" and "zero-sized allocation".
+        RawVec {
+            ptr: Unique::empty(),
+            // FIXME(mark-i-m): use `cap` when ifs are allowed in const
+            cap: [0, !0][(mem::size_of::<T>() == 0) as usize],
+            a: Global,
+        }
     }
 
     /// Creates a `RawVec` (on the system heap) with exactly the
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index c513658c842e5..405969a550b88 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -314,10 +314,10 @@ impl<T> Vec<T> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_vec_new")]
+    #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_vec_new"))]
     pub const fn new() -> Vec<T> {
         Vec {
-            buf: RawVec::new(),
+            buf: RawVec::NEW,
             len: 0,
         }
     }
diff --git a/src/test/ui/collections-const-new.rs b/src/test/ui/collections-const-new.rs
index e01b0dfa14d6e..15c5c65ff81f3 100644
--- a/src/test/ui/collections-const-new.rs
+++ b/src/test/ui/collections-const-new.rs
@@ -1,15 +1,13 @@
 // run-pass
 
-#![allow(dead_code)]
 // Test several functions can be used for constants
 // 1. Vec::new()
 // 2. String::new()
 
-#![feature(const_vec_new)]
 #![feature(const_string_new)]
 
 const MY_VEC: Vec<usize> = Vec::new();
 
 const MY_STRING: String = String::new();
 
-pub fn main() {}
+fn main() {}
diff --git a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs
index 5fb92535502a5..8b17f6885ad3e 100644
--- a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs
+++ b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.rs
@@ -14,8 +14,9 @@ trait Bar<T, U: Foo<T>> {
 impl Foo<u32> for () {
     const X: u32 = 42;
 }
+
 impl Foo<Vec<u32>> for String {
-    const X: Vec<u32> = Vec::new(); //~ ERROR not yet stable as a const fn
+    const X: Vec<u32> = Vec::new();
 }
 
 impl Bar<u32, ()> for () {}
diff --git a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr
index c56ebf60df481..5bc7b70638c80 100644
--- a/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr
+++ b/src/test/ui/consts/miri_unleashed/feature-gate-unleash_the_miri_inside_of_you.stderr
@@ -4,13 +4,5 @@ error[E0493]: destructors cannot be evaluated at compile-time
 LL |     const F: u32 = (U::X, 42).1;
    |                    ^^^^^^^^^^ constants cannot evaluate destructors
 
-error: `std::vec::Vec::<T>::new` is not yet stable as a const fn
-  --> $DIR/feature-gate-unleash_the_miri_inside_of_you.rs:18:25
-   |
-LL |     const X: Vec<u32> = Vec::new();
-   |                         ^^^^^^^^^^
-   |
-   = help: add `#![feature(const_vec_new)]` to the crate attributes to enable
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 

From 9b3e11f635c0354040ce515ac0ed4fade6fe928f Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Thu, 29 Aug 2019 12:36:07 +0200
Subject: [PATCH 800/943] Const-stabilize `String::new`.

---
 src/liballoc/string.rs               | 2 +-
 src/test/ui/collections-const-new.rs | 4 +---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/liballoc/string.rs b/src/liballoc/string.rs
index b65f191836e9d..1166e7b5df295 100644
--- a/src/liballoc/string.rs
+++ b/src/liballoc/string.rs
@@ -369,7 +369,7 @@ impl String {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_string_new")]
+    #[cfg_attr(bootstrap, rustc_const_unstable(feature = "const_string_new"))]
     pub const fn new() -> String {
         String { vec: Vec::new() }
     }
diff --git a/src/test/ui/collections-const-new.rs b/src/test/ui/collections-const-new.rs
index 15c5c65ff81f3..a93f9a136db23 100644
--- a/src/test/ui/collections-const-new.rs
+++ b/src/test/ui/collections-const-new.rs
@@ -1,11 +1,9 @@
-// run-pass
+// check-pass
 
 // Test several functions can be used for constants
 // 1. Vec::new()
 // 2. String::new()
 
-#![feature(const_string_new)]
-
 const MY_VEC: Vec<usize> = Vec::new();
 
 const MY_STRING: String = String::new();

From 2fd4e584a8a994e3fc8e19113db58e62561fb7e9 Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Tue, 10 Sep 2019 18:59:14 +0200
Subject: [PATCH 801/943] `AdtDef` is an algebraic data type, not abstract data
 type.

---
 src/librustc/ty/mod.rs | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 17eb4a8957fd5..5ca819e12f232 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1938,9 +1938,15 @@ pub struct FieldDef {
     pub vis: Visibility,
 }
 
-/// The definition of an abstract data type -- a struct or enum.
+/// The definition of a user-defined type, e.g., a `struct`, `enum`, or `union`.
 ///
 /// These are all interned (by `intern_adt_def`) into the `adt_defs` table.
+///
+/// The initialism *"Adt"* stands for an [*algebraic data type (ADT)*][adt].
+/// This is slightly wrong because `union`s are not ADTs.
+/// Moreover, Rust only allows recursive data types through indirection.
+///
+/// [adt]: https://en.wikipedia.org/wiki/Algebraic_data_type
 pub struct AdtDef {
     /// `DefId` of the struct, enum or union item.
     pub did: DefId,

From 194d357e03dcee73bfdb32a45175c97f4c3ce422 Mon Sep 17 00:00:00 2001
From: Charles Gleason <charles_gleason@alumni.brown.edu>
Date: Tue, 3 Sep 2019 18:42:58 -0400
Subject: [PATCH 802/943] Document `From` trait for `LhsExpr`

---
 src/libsyntax/parse/parser/expr.rs | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 5b9f0f1df6718..c38b134154d62 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -66,6 +66,10 @@ pub(super) enum LhsExpr {
 }
 
 impl From<Option<ThinVec<Attribute>>> for LhsExpr {
+    /// Converts `Some(attrs)` into `LhsExpr::AttributesParsed(attrs)`
+    /// and `None` into `LhsExpr::NotYetParsed`.
+    ///
+    /// This conversion does not allocate.
     fn from(o: Option<ThinVec<Attribute>>) -> Self {
         if let Some(attrs) = o {
             LhsExpr::AttributesParsed(attrs)
@@ -76,6 +80,9 @@ impl From<Option<ThinVec<Attribute>>> for LhsExpr {
 }
 
 impl From<P<Expr>> for LhsExpr {
+    /// Converts the `expr: P<Expr>` into `LhsExpr::AlreadyParsed(expr)`.
+    ///
+    /// This conversion does not allocate.
     fn from(expr: P<Expr>) -> Self {
         LhsExpr::AlreadyParsed(expr)
     }

From 4b175339b88f033561f2ffee55bf33d47741bd20 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 15 Sep 2019 13:53:04 +0200
Subject: [PATCH 803/943] update miri

---
 Cargo.lock     | 6 +++---
 src/tools/miri | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index dc3c2ae2a58c5..5fcea25b89a1d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -232,9 +232,9 @@ dependencies = [
 
 [[package]]
 name = "byteorder"
-version = "1.2.7"
+version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
+checksum = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
 
 [[package]]
 name = "bytes"
@@ -2065,7 +2065,7 @@ dependencies = [
  "hex",
  "log",
  "num-traits",
- "rand 0.6.1",
+ "rand 0.7.0",
  "rustc-workspace-hack",
  "rustc_version",
  "shell-escape",
diff --git a/src/tools/miri b/src/tools/miri
index dd94c7c5a32be..508fdb860b2b7 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit dd94c7c5a32be2ee0adeeaf9d46f26f14925797c
+Subproject commit 508fdb860b2b7c9f0f31b51b83c8808d76f72291

From f90a81c23873b751b4d414d57a339e198b105ceb Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sun, 15 Sep 2019 13:54:04 +0200
Subject: [PATCH 804/943] with byteorder 1.3, the i128 feature is a NOP

---
 Cargo.lock                                | 1 -
 src/librustc/Cargo.toml                   | 2 +-
 src/librustc_mir/Cargo.toml               | 2 +-
 src/tools/rustc-workspace-hack/Cargo.toml | 1 -
 4 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 5fcea25b89a1d..0772dc60c8109 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3253,7 +3253,6 @@ dependencies = [
 name = "rustc-workspace-hack"
 version = "1.0.0"
 dependencies = [
- "byteorder",
  "crossbeam-utils 0.6.5",
  "serde",
  "serde_json",
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index d569573a5e94c..0834faf132424 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -31,7 +31,7 @@ syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
 backtrace = "0.3.3"
 parking_lot = "0.9"
-byteorder = { version = "1.1", features = ["i128"]}
+byteorder = { version = "1.3" }
 chalk-engine = { version = "0.9.0", default-features=false }
 rustc_fs_util = { path = "../librustc_fs_util" }
 smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index e02736078b571..0691390bead4b 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -24,6 +24,6 @@ rustc_lexer = { path = "../librustc_lexer" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
-byteorder = { version = "1.1", features = ["i128"] }
+byteorder = { version = "1.3" }
 rustc_apfloat = { path = "../librustc_apfloat" }
 smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index d068e1cf307b8..930279c0ca27b 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -62,7 +62,6 @@ crossbeam-utils = { version = "0.6.5", features = ["nightly"] }
 serde = { version = "1.0.82", features = ['derive'] }
 serde_json = { version = "1.0.31", features = ["raw_value"] }
 smallvec = { version = "0.6", features = ['union', 'may_dangle'] }
-byteorder = { version = "1.2.7", features = ["i128"] }
 
 
 [target.'cfg(not(windows))'.dependencies]

From b7ebbc291a6304488eac6b13d5656d6981728551 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 16 Sep 2019 10:06:11 +0200
Subject: [PATCH 805/943] update miri for latest breakage

---
 src/tools/miri | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/miri b/src/tools/miri
index 508fdb860b2b7..d88138723780d 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 508fdb860b2b7c9f0f31b51b83c8808d76f72291
+Subproject commit d88138723780d11ca2c09560111223dc20b9d5f3

From 821d293283f939272efecf8dd8c401c818c4428d Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Mon, 16 Sep 2019 11:43:23 -0700
Subject: [PATCH 806/943] azure: Disable more LLVM/debug assertions in

This commit disables LLVM/debug assertions in our 5 slowest builders:

* i686-gnu
* i686-gnu-nopt
* i686-msvc-1
* i686-msvc-2
* x86_64-msvc-cargo

This is reducing the amount of test coverage for LLVM/debug assertions,
but we're just unfortunately running out of time on CI too many times.
Some test builds have shown that i686-gnu drops nearly an hour of CI
time by disabling these two assertions. Perhaps when we eventually get
4-core machines we can reenable these, but for now turn them off and
hook them up to the tracking issue at #59637 which will ideally be
repurposes to tracking all of these.
---
 src/ci/azure-pipelines/auto.yml        | 9 +++++++++
 src/ci/docker/i686-gnu-nopt/Dockerfile | 3 +++
 src/ci/docker/i686-gnu/Dockerfile      | 3 +++
 3 files changed, 15 insertions(+)

diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml
index 77c9cda58b8e6..1656066eb29c9 100644
--- a/src/ci/azure-pipelines/auto.yml
+++ b/src/ci/azure-pipelines/auto.yml
@@ -236,10 +236,16 @@ jobs:
         MSYS_BITS: 32
         RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
         SCRIPT: make ci-subset-1
+        # FIXME(#59637)
+        NO_DEBUG_ASSERTIONS: 1
+        NO_LLVM_ASSERTIONS: 1
       i686-msvc-2:
         MSYS_BITS: 32
         RUST_CONFIGURE_ARGS: --build=i686-pc-windows-msvc
         SCRIPT: make ci-subset-2
+        # FIXME(#59637)
+        NO_DEBUG_ASSERTIONS: 1
+        NO_LLVM_ASSERTIONS: 1
       # MSVC aux tests
       x86_64-msvc-aux:
         MSYS_BITS: 64
@@ -250,6 +256,9 @@ jobs:
         SCRIPT: python x.py test src/tools/cargotest src/tools/cargo
         RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc
         VCVARS_BAT: vcvars64.bat
+        # FIXME(#59637)
+        NO_DEBUG_ASSERTIONS: 1
+        NO_LLVM_ASSERTIONS: 1
       # MSVC tools tests
       x86_64-msvc-tools:
         MSYS_BITS: 64
diff --git a/src/ci/docker/i686-gnu-nopt/Dockerfile b/src/ci/docker/i686-gnu-nopt/Dockerfile
index 2041ba50bc9a0..517b59c38dcb0 100644
--- a/src/ci/docker/i686-gnu-nopt/Dockerfile
+++ b/src/ci/docker/i686-gnu-nopt/Dockerfile
@@ -19,3 +19,6 @@ RUN sh /scripts/sccache.sh
 
 ENV RUST_CONFIGURE_ARGS --build=i686-unknown-linux-gnu --disable-optimize-tests
 ENV SCRIPT python2.7 ../x.py test
+
+# FIXME(#59637) takes too long on CI right now
+ENV NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1
diff --git a/src/ci/docker/i686-gnu/Dockerfile b/src/ci/docker/i686-gnu/Dockerfile
index 17441ddb4546b..03db3ba0995d6 100644
--- a/src/ci/docker/i686-gnu/Dockerfile
+++ b/src/ci/docker/i686-gnu/Dockerfile
@@ -25,3 +25,6 @@ ENV SCRIPT python2.7 ../x.py test \
   --exclude src/test/rustdoc-js \
   --exclude src/tools/error_index_generator \
   --exclude src/tools/linkchecker
+
+# FIXME(#59637) takes too long on CI right now
+ENV NO_LLVM_ASSERTIONS=1 NO_DEBUG_ASSERTIONS=1

From d1f763f60d47c6777934039f86529e189c1b92a9 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Mon, 16 Sep 2019 15:53:08 -0300
Subject: [PATCH 807/943] Use while let slice_pattern instead of carrying an
 index around

---
 src/librustc_mir/borrow_check/conflict_errors.rs    | 10 ++++++----
 src/librustc_mir/borrow_check/mod.rs                |  8 ++++----
 src/librustc_mir/borrow_check/nll/type_check/mod.rs |  7 +++++--
 src/librustc_mir/build/matches/mod.rs               |  5 +++--
 src/librustc_mir/transform/check_unsafety.rs        |  5 +++--
 src/librustc_mir/util/alignment.rs                  |  5 +++--
 6 files changed, 24 insertions(+), 16 deletions(-)

diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index 4b4516d6bf290..81359c6a46e99 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -614,8 +614,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     projection,
                 } = first_borrowed_place;
 
-                for (i, elem) in projection.iter().enumerate().rev() {
-                    let proj_base = &projection[..i];
+                let mut cursor = &**projection;
+                while let [proj_base @ .., elem] = cursor {
+                    cursor = proj_base;
 
                     match elem {
                         ProjectionElem::Field(field, _) if union_ty(base, proj_base).is_some() => {
@@ -637,8 +638,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     projection,
                 } = second_borrowed_place;
 
-                for (i, elem) in projection.iter().enumerate().rev() {
-                    let proj_base = &projection[..i];
+                let mut cursor = &**projection;
+                while let [proj_base @ .., elem] = cursor {
+                    cursor = proj_base;
 
                     if let ProjectionElem::Field(field, _) = elem {
                         if let Some(union_ty) = union_ty(base, proj_base) {
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 5ef70461296c7..1d3576244c4af 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -1758,7 +1758,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         debug!("check_if_assigned_path_is_moved place: {:?}", place);
 
         // None case => assigning to `x` does not require `x` be initialized.
-        for (i, elem) in place.projection.iter().enumerate().rev() {
+        let mut cursor = &*place.projection;
+        while let [proj_base @ .., elem] = cursor {
+            cursor = proj_base;
+
             match elem {
                 ProjectionElem::Index(_/*operand*/) |
                 ProjectionElem::ConstantIndex { .. } |
@@ -1771,8 +1774,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
                 // assigning to (*P) requires P to be initialized
                 ProjectionElem::Deref => {
-                    let proj_base = &place.projection[..i];
-
                     self.check_if_full_path_is_moved(
                         location, InitializationRequiringAction::Use,
                         (PlaceRef {
@@ -1790,7 +1791,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 }
 
                 ProjectionElem::Field(..) => {
-                    let proj_base = &place.projection[..i];
                     // if type of `P` has a dtor, then
                     // assigning to `P.f` requires `P` itself
                     // be already initialized
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 1d17bae559c59..62bff3421a078 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -2417,9 +2417,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             "add_reborrow_constraint({:?}, {:?}, {:?})",
             location, borrow_region, borrowed_place
         );
-        for (i, elem) in borrowed_place.projection.iter().enumerate().rev() {
+
+        let mut cursor = &*borrowed_place.projection;
+        while let [proj_base @ .., elem] = cursor {
+            cursor = proj_base;
+
             debug!("add_reborrow_constraint - iteration {:?}", elem);
-            let proj_base = &borrowed_place.projection[..i];
 
             match elem {
                 ProjectionElem::Deref => {
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index aa261f8eb6fb2..2b0237c7c08b9 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -1296,8 +1296,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // Insert a Shallow borrow of the prefixes of any fake borrows.
         for place in fake_borrows
         {
-            for (i, elem) in place.projection.iter().enumerate().rev() {
-                let proj_base = &place.projection[..i];
+            let mut cursor = &*place.projection;
+            while let [proj_base @ .., elem] = cursor {
+                cursor = proj_base;
 
                 if let ProjectionElem::Deref = elem {
                     // Insert a shallow borrow after a deref. For other
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index f8af9b9fcbee0..39aa5c717acc1 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -407,8 +407,9 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
         place: &Place<'tcx>,
         is_mut_use: bool,
     ) {
-        for (i, elem) in place.projection.iter().enumerate().rev() {
-            let proj_base = &place.projection[..i];
+        let mut cursor = &*place.projection;
+        while let [proj_base @ .., elem] = cursor {
+            cursor = proj_base;
 
             match elem {
                 ProjectionElem::Field(..) => {
diff --git a/src/librustc_mir/util/alignment.rs b/src/librustc_mir/util/alignment.rs
index b4c97f9191732..a75c1af04f047 100644
--- a/src/librustc_mir/util/alignment.rs
+++ b/src/librustc_mir/util/alignment.rs
@@ -38,8 +38,9 @@ fn is_within_packed<'tcx, L>(tcx: TyCtxt<'tcx>, local_decls: &L, place: &Place<'
 where
     L: HasLocalDecls<'tcx>,
 {
-    for (i, elem) in place.projection.iter().enumerate().rev() {
-        let proj_base = &place.projection[..i];
+    let mut cursor = &*place.projection;
+    while let [proj_base @ .., elem] = cursor {
+        cursor = proj_base;
 
         match elem {
             // encountered a Deref, which is ABI-aligned

From ab1a3f09fd3e1dbce850b9e1b691dc8338584e65 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Mon, 16 Sep 2019 13:06:07 -0400
Subject: [PATCH 808/943] add test for drop order of temporary in tail return
 expression

---
 ...order-for-temporary-in-tail-return-expr.rs | 94 +++++++++++++++++++
 1 file changed, 94 insertions(+)
 create mode 100644 src/test/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs

diff --git a/src/test/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs b/src/test/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs
new file mode 100644
index 0000000000000..e250506cdf0af
--- /dev/null
+++ b/src/test/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs
@@ -0,0 +1,94 @@
+// aux-build:arc_wake.rs
+// edition:2018
+// run-pass
+
+#![allow(unused_variables)]
+
+// Test that the drop order for parameters in a fn and async fn matches up. Also test that
+// parameters (used or unused) are not dropped until the async fn completes execution.
+// See also #54716.
+
+extern crate arc_wake;
+
+use arc_wake::ArcWake;
+use std::cell::RefCell;
+use std::future::Future;
+use std::sync::Arc;
+use std::rc::Rc;
+use std::task::Context;
+
+struct EmptyWaker;
+
+impl ArcWake for EmptyWaker {
+    fn wake(self: Arc<Self>) {}
+}
+
+#[derive(Debug, Eq, PartialEq)]
+enum DropOrder {
+    Function,
+    Val(&'static str),
+}
+
+type DropOrderListPtr = Rc<RefCell<Vec<DropOrder>>>;
+
+struct D(&'static str, DropOrderListPtr);
+
+impl Drop for D {
+    fn drop(&mut self) {
+        self.1.borrow_mut().push(DropOrder::Val(self.0));
+    }
+}
+
+/// Check drop order of temporary "temp" as compared to x, y, and z.
+///
+/// Expected order:
+/// - z
+/// - temp
+/// - y
+/// - x
+async fn foo_async(x: D, _y: D) {
+    let l = x.1.clone();
+    let z = D("z", l.clone());
+    l.borrow_mut().push(DropOrder::Function);
+    helper_async(&D("temp", l)).await
+}
+
+async fn helper_async(v: &D) { }
+
+fn foo_sync(x: D, _y: D) {
+    let l = x.1.clone();
+    let z = D("z", l.clone());
+    l.borrow_mut().push(DropOrder::Function);
+    helper_sync(&D("temp", l))
+}
+
+fn helper_sync(v: &D) { }
+
+fn assert_drop_order_after_poll<Fut: Future<Output = ()>>(
+    f: impl FnOnce(DropOrderListPtr) -> Fut,
+    g: impl FnOnce(DropOrderListPtr),
+) {
+    let empty = Arc::new(EmptyWaker);
+    let waker = ArcWake::into_waker(empty);
+    let mut cx = Context::from_waker(&waker);
+
+    let actual_order = Rc::new(RefCell::new(Vec::new()));
+    let mut fut = Box::pin(f(actual_order.clone()));
+    let r = fut.as_mut().poll(&mut cx);
+
+    assert!(match r {
+        std::task::Poll::Ready(()) => true,
+        _ => false,
+    });
+
+    let expected_order = Rc::new(RefCell::new(Vec::new()));
+    g(expected_order.clone());
+
+    assert_eq!(*actual_order.borrow(), *expected_order.borrow());
+}
+
+fn main() {
+    // Free functions (see doc comment on function for what it tests).
+    assert_drop_order_after_poll(|l| foo_async(D("x", l.clone()), D("_y", l.clone())),
+                                 |l| foo_sync(D("x", l.clone()), D("_y", l.clone())));
+}

From 388cd5d88eb6cbb9a2440d0a05fa0ea7d0b24dd3 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 16 Sep 2019 11:29:10 +0200
Subject: [PATCH 809/943] avoid duplicate issues for Miri build failures

---
 src/tools/publish_toolstate.py | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py
index 4060b90d952bd..7cf3cc7663b47 100755
--- a/src/tools/publish_toolstate.py
+++ b/src/tools/publish_toolstate.py
@@ -201,7 +201,9 @@ def update_latest(
                 new = s.get(tool, old)
                 status[os] = new
                 maintainers = ' '.join('@'+name for name in MAINTAINERS[tool])
-                if new > old: # comparing the strings, but they are ordered appropriately!
+                # comparing the strings, but they are ordered appropriately:
+                # "test-pass" > "test-fail" > "build-fail"
+                if new > old:
                     # things got fixed or at least the status quo improved
                     changed = True
                     message += '🎉 {} on {}: {} → {} (cc {}, @rust-lang/infra).\n' \
@@ -213,10 +215,17 @@ def update_latest(
                         .format(tool, os, old, new)
                     message += '{} (cc {}, @rust-lang/infra).\n' \
                         .format(title, maintainers)
-                    # Most tools only create issues for build failures.
-                    # Other failures can be spurious.
-                    if new == 'build-fail' or (tool == 'miri' and new == 'test-fail'):
-                        create_issue_for_status = new
+                    # See if we need to create an issue.
+                    if tool == 'miri':
+                        # Create issue if tests used to pass before. Don't open a *second*
+                        # issue when we regress from "test-fail" to "build-fail".
+                        if old == 'test-pass':
+                            create_issue_for_status = new
+                    else:
+                        # Create issue if things no longer build.
+                        # (No issue for mere test failures to avoid spurious issues.)
+                        if new == 'build-fail':
+                            create_issue_for_status = new
 
             if create_issue_for_status is not None:
                 try:

From 9ae1a664f7b947dadb9e97eea7703831d9cd5d31 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Mon, 16 Sep 2019 15:25:39 -0400
Subject: [PATCH 810/943] add regression test for issue-64391

---
 src/test/ui/async-await/issue-64391.rs | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 src/test/ui/async-await/issue-64391.rs

diff --git a/src/test/ui/async-await/issue-64391.rs b/src/test/ui/async-await/issue-64391.rs
new file mode 100644
index 0000000000000..c6faad3aad064
--- /dev/null
+++ b/src/test/ui/async-await/issue-64391.rs
@@ -0,0 +1,14 @@
+// Regression test for Issue #64391. The goal here is that this
+// function compiles. In the past, due to incorrect drop order for
+// temporaries in the tail expression, we failed to compile this
+// example. The drop order itself is directly tested in
+// `drop-order/drop-order-for-temporary-in-tail-return-expr.rs`.
+//
+// check-pass
+// edition:2018
+
+async fn add(x: u32, y: u32) -> u32 {
+    async { x + y }.await
+}
+
+fn main() { }

From 00d159095adbb14c7dfaa6a77177be1b58600dc9 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Mon, 16 Sep 2019 16:15:20 -0400
Subject: [PATCH 811/943] adjust desugaring for async fn to correct drop order

Old desugaring, given a user function body { $stmts; $expr }

```
{
    let $param_pattern0 = $raw_param0;
    ...
    let $param_patternN = $raw_paramN;
    $stmts;
    $expr
}
```

New desugaring:

```
{
    let $param_pattern0 = $raw_param0;
    ...
    let $param_patternN = $raw_paramN;
    drop-temps {
        $stmts;
        $expr
    }
}
```

The drop-temps is an internal bit of HIR that drops temporaries from
the resulting expression, but it should be equivalent to `return {
$stmts; $expr }`.
---
 src/librustc/hir/lowering.rs      | 12 ++--------
 src/librustc/hir/lowering/expr.rs |  2 +-
 src/librustc/hir/lowering/item.rs | 40 +++++++++++++++++++++++++++++--
 3 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 58789a10609b7..492029eed0570 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -2682,12 +2682,8 @@ impl<'a> LoweringContext<'a> {
         bounds.iter().map(|bound| self.lower_param_bound(bound, itctx.reborrow())).collect()
     }
 
-    fn lower_block_with_stmts(
-        &mut self,
-        b: &Block,
-        targeted_by_break: bool,
-        mut stmts: Vec<hir::Stmt>,
-    ) -> P<hir::Block> {
+    fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
+        let mut stmts = vec![];
         let mut expr = None;
 
         for (index, stmt) in b.stmts.iter().enumerate() {
@@ -2712,10 +2708,6 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
-        self.lower_block_with_stmts(b, targeted_by_break, vec![])
-    }
-
     fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
         let node = match p.node {
             PatKind::Wild => hir::PatKind::Wild,
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index a46cdabbb518f..87462e94f430d 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -1310,7 +1310,7 @@ impl LoweringContext<'_> {
     /// `{ let _t = $expr; _t }` but should provide better compile-time performance.
     ///
     /// The drop order can be important in e.g. `if expr { .. }`.
-    fn expr_drop_temps(
+    pub(super) fn expr_drop_temps(
         &mut self,
         span: Span,
         expr: P<hir::Expr>,
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 5f82e42abb308..1e621f7fdaea6 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -1219,8 +1219,44 @@ impl LoweringContext<'_> {
             let async_expr = this.make_async_expr(
                 CaptureBy::Value, closure_id, None, body.span,
                 |this| {
-                    let body = this.lower_block_with_stmts(body, false, statements);
-                    this.expr_block(body, ThinVec::new())
+                    // Create a block from the user's function body:
+                    let user_body = this.lower_block(body, false);
+                    let user_body = this.expr_block(user_body, ThinVec::new());
+
+                    // Transform into `drop-temps { <user-body> }`, an expression:
+                    let desugared_span = this.mark_span_with_reason(
+                        DesugaringKind::Async,
+                        user_body.span,
+                        None,
+                    );
+                    let user_body = this.expr_drop_temps(
+                        desugared_span,
+                        P(user_body),
+                        ThinVec::new(),
+                    );
+
+                    // Create a block like
+                    //
+                    // ```
+                    // {
+                    //   let $param_pattern = $raw_param;
+                    //   ...
+                    //   drop-temps { <user-body> }
+                    // }
+                    // ```
+                    //
+                    // This construction is carefully calibrated to
+                    // get the drop-order correct.  In particular, the
+                    // drop-temps ensures that any temporaries in the
+                    // tail expression of `<user-body>` are dropped
+                    // *before* the parameters are dropped (see
+                    // rust-lang/rust#64512).
+                    let body = this.block_all(
+                        desugared_span,
+                        statements.into(),
+                        Some(P(user_body)),
+                    );
+                    this.expr_block(P(body), ThinVec::new())
                 });
             (HirVec::from(parameters), this.expr(body.span, async_expr, ThinVec::new()))
         })

From 0a985f2c86add139d880882c968e68747b366be6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 1 Sep 2019 21:51:16 -0700
Subject: [PATCH 812/943] Tweak unsatisfied HRTB errors

---
 .../nice_region_error/placeholder_error.rs    | 53 ++++++++++--------
 .../ui/generator/auto-trait-regions.stderr    | 18 ++++---
 src/test/ui/hrtb/due-to-where-clause.rs       | 16 ++++++
 src/test/ui/hrtb/due-to-where-clause.stderr   | 17 ++++++
 .../ui/hrtb/hrtb-cache-issue-54302.stderr     |  9 ++--
 src/test/ui/hrtb/issue-30786.migrate.stderr   | 14 +++--
 src/test/ui/hrtb/issue-30786.nll.stderr       |  4 +-
 src/test/ui/hrtb/issue-30786.rs               |  3 +-
 src/test/ui/issues/issue-54302-cases.stderr   | 54 +++++++++++++------
 src/test/ui/issues/issue-54302.stderr         |  9 ++--
 src/test/ui/issues/issue-55731.stderr         | 13 +++--
 11 files changed, 148 insertions(+), 62 deletions(-)
 create mode 100644 src/test/ui/hrtb/due-to-where-clause.rs
 create mode 100644 src/test/ui/hrtb/due-to-where-clause.stderr

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 b4fb018920647..19bd38b45b30a 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
@@ -192,23 +192,28 @@ impl NiceRegionError<'me, 'tcx> {
             vid, sub_placeholder, sup_placeholder, trait_def_id, expected_substs, actual_substs
         );
 
-        let mut err = self.tcx().sess.struct_span_err(
-            cause.span(self.tcx()),
-            &format!(
-                "implementation of `{}` is not general enough",
-                self.tcx().def_path_str(trait_def_id),
-            ),
+        let span = cause.span(self.tcx());
+        let msg = format!(
+            "implementation of `{}` is not general enough",
+            self.tcx().def_path_str(trait_def_id),
+        );
+        let mut err = self.tcx().sess.struct_span_err(span, &msg);
+        err.span_label(
+            self.tcx().def_span(trait_def_id),
+            format!("trait `{}` defined here", self.tcx().def_path_str(trait_def_id)),
         );
 
-        match cause.code {
-            ObligationCauseCode::ItemObligation(def_id) => {
-                err.note(&format!(
-                    "Due to a where-clause on `{}`,",
-                    self.tcx().def_path_str(def_id),
-                ));
-            }
-            _ => (),
-        }
+        let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) = cause.code {
+            err.span_label(span, "doesn't satisfy where-clause");
+            err.span_label(
+                self.tcx().def_span(def_id),
+                &format!("due to a where-clause on `{}`...", self.tcx().def_path_str(def_id)),
+            );
+            true
+        } else {
+            err.span_label(span, &msg);
+            false
+        };
 
         let expected_trait_ref = self.infcx.resolve_vars_if_possible(&ty::TraitRef {
             def_id: trait_def_id,
@@ -295,6 +300,7 @@ impl NiceRegionError<'me, 'tcx> {
             expected_has_vid,
             actual_has_vid,
             any_self_ty_has_vid,
+            leading_ellipsis,
         );
 
         err
@@ -318,6 +324,7 @@ impl NiceRegionError<'me, 'tcx> {
         expected_has_vid: Option<usize>,
         actual_has_vid: Option<usize>,
         any_self_ty_has_vid: bool,
+        leading_ellipsis: bool,
     ) {
         // HACK(eddyb) maybe move this in a more central location.
         #[derive(Copy, Clone)]
@@ -392,13 +399,15 @@ impl NiceRegionError<'me, 'tcx> {
 
             let mut note = if passive_voice {
                 format!(
-                    "`{}` would have to be implemented for the type `{}`",
+                    "{}`{}` would have to be implemented for the type `{}`",
+                    if leading_ellipsis { "..." } else { "" },
                     expected_trait_ref,
                     expected_trait_ref.map(|tr| tr.self_ty()),
                 )
             } else {
                 format!(
-                    "`{}` must implement `{}`",
+                    "{}`{}` must implement `{}`",
+                    if leading_ellipsis { "..." } else { "" },
                     expected_trait_ref.map(|tr| tr.self_ty()),
                     expected_trait_ref,
                 )
@@ -407,20 +416,20 @@ impl NiceRegionError<'me, 'tcx> {
             match (has_sub, has_sup) {
                 (Some(n1), Some(n2)) => {
                     let _ = write!(note,
-                        ", for any two lifetimes `'{}` and `'{}`",
+                        ", for any two lifetimes `'{}` and `'{}`...",
                         std::cmp::min(n1, n2),
                         std::cmp::max(n1, n2),
                     );
                 }
                 (Some(n), _) | (_, Some(n)) => {
                     let _ = write!(note,
-                        ", for any lifetime `'{}`",
+                        ", for any lifetime `'{}`...",
                         n,
                     );
                 }
                 (None, None) => if let Some(n) = expected_has_vid {
                     let _ = write!(note,
-                        ", for some specific lifetime `'{}`",
+                        ", for some specific lifetime `'{}`...",
                         n,
                     );
                 },
@@ -439,13 +448,13 @@ impl NiceRegionError<'me, 'tcx> {
 
             let mut note = if passive_voice {
                 format!(
-                    "but `{}` is actually implemented for the type `{}`",
+                    "...but `{}` is actually implemented for the type `{}`",
                     actual_trait_ref,
                     actual_trait_ref.map(|tr| tr.self_ty()),
                 )
             } else {
                 format!(
-                    "but `{}` actually implements `{}`",
+                    "...but `{}` actually implements `{}`",
                     actual_trait_ref.map(|tr| tr.self_ty()),
                     actual_trait_ref,
                 )
diff --git a/src/test/ui/generator/auto-trait-regions.stderr b/src/test/ui/generator/auto-trait-regions.stderr
index 92f92e2a32a36..dab4d348ceb60 100644
--- a/src/test/ui/generator/auto-trait-regions.stderr
+++ b/src/test/ui/generator/auto-trait-regions.stderr
@@ -1,20 +1,26 @@
 error: implementation of `Foo` is not general enough
   --> $DIR/auto-trait-regions.rs:30:5
    |
+LL | auto trait Foo {}
+   | ----------------- trait `Foo` defined here
+...
 LL |     assert_foo(gen);
-   |     ^^^^^^^^^^
+   |     ^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0`
-   = note: but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1`
+   = note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0`...
+   = note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1`
 
 error: implementation of `Foo` is not general enough
   --> $DIR/auto-trait-regions.rs:48:5
    |
+LL | auto trait Foo {}
+   | ----------------- trait `Foo` defined here
+...
 LL |     assert_foo(gen);
-   |     ^^^^^^^^^^
+   |     ^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`
-   = note: but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2`
+   = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/hrtb/due-to-where-clause.rs b/src/test/ui/hrtb/due-to-where-clause.rs
new file mode 100644
index 0000000000000..04e2ddd4a6090
--- /dev/null
+++ b/src/test/ui/hrtb/due-to-where-clause.rs
@@ -0,0 +1,16 @@
+// ignore-compare-mode-nll
+// ^ This code works in nll mode.
+
+fn main() {
+    test::<FooS>(&mut 42); //~ ERROR implementation of `Foo` is not general enough
+}
+
+trait Foo<'a> {}
+
+struct FooS<'a> {
+    data: &'a mut u32,
+}
+
+impl<'a, 'b: 'a> Foo<'b> for FooS<'a> {}
+
+fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {}
diff --git a/src/test/ui/hrtb/due-to-where-clause.stderr b/src/test/ui/hrtb/due-to-where-clause.stderr
new file mode 100644
index 0000000000000..e698584bb716f
--- /dev/null
+++ b/src/test/ui/hrtb/due-to-where-clause.stderr
@@ -0,0 +1,17 @@
+error: implementation of `Foo` is not general enough
+  --> $DIR/due-to-where-clause.rs:5:5
+   |
+LL |     test::<FooS>(&mut 42);
+   |     ^^^^^^^^^^^^ doesn't satisfy where-clause
+...
+LL | trait Foo<'a> {}
+   | ---------------- trait `Foo` defined here
+...
+LL | fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {}
+   | ------------------------------------------------------------- due to a where-clause on `test`...
+   |
+   = note: ...`FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`...
+   = note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr
index 77a5491cb63a7..003f32659351f 100644
--- a/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr
+++ b/src/test/ui/hrtb/hrtb-cache-issue-54302.stderr
@@ -1,11 +1,14 @@
 error: implementation of `Deserialize` is not general enough
   --> $DIR/hrtb-cache-issue-54302.rs:19:5
    |
+LL | trait Deserialize<'de> {}
+   | ------------------------- trait `Deserialize` defined here
+...
 LL |     assert_deserialize_owned::<&'static str>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
    |
-   = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`
-   = note: but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
+   = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
+   = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/issue-30786.migrate.stderr b/src/test/ui/hrtb/issue-30786.migrate.stderr
index e7deca7644b0e..c0e3fd3cf4679 100644
--- a/src/test/ui/hrtb/issue-30786.migrate.stderr
+++ b/src/test/ui/hrtb/issue-30786.migrate.stderr
@@ -1,11 +1,17 @@
 error: implementation of `Stream` is not general enough
   --> $DIR/issue-30786.rs:108:22
    |
-LL |     let map = source.map(|x: &_| x);
-   |                      ^^^
+LL | / pub trait Stream {
+LL | |     type Item;
+LL | |     fn next(self) -> Option<Self::Item>;
+LL | | }
+   | |_- trait `Stream` defined here
+...
+LL |       let map = source.map(|x: &_| x);
+   |                        ^^^ implementation of `Stream` is not general enough
    |
-   = note: `Stream` would have to be implemented for the type `&'0 mut Map<Repeat, [closure@$DIR/issue-30786.rs:108:26: 108:35]>`, for any lifetime `'0`
-   = note: but `Stream` is actually implemented for the type `&'1 mut Map<Repeat, [closure@$DIR/issue-30786.rs:108:26: 108:35]>`, for some specific lifetime `'1`
+   = note: `Stream` would have to be implemented for the type `&'0 mut Map<Repeat, [closure@$DIR/issue-30786.rs:108:26: 108:35]>`, for any lifetime `'0`...
+   = note: ...but `Stream` is actually implemented for the type `&'1 mut Map<Repeat, [closure@$DIR/issue-30786.rs:108:26: 108:35]>`, for some specific lifetime `'1`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/issue-30786.nll.stderr b/src/test/ui/hrtb/issue-30786.nll.stderr
index 8614d86d93ac3..1cfd93e59d935 100644
--- a/src/test/ui/hrtb/issue-30786.nll.stderr
+++ b/src/test/ui/hrtb/issue-30786.nll.stderr
@@ -1,11 +1,11 @@
 error: higher-ranked subtype error
-  --> $DIR/issue-30786.rs:112:18
+  --> $DIR/issue-30786.rs:113:18
    |
 LL |     let filter = map.filter(|x: &_| true);
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: higher-ranked subtype error
-  --> $DIR/issue-30786.rs:114:17
+  --> $DIR/issue-30786.rs:115:17
    |
 LL |     let count = filter.count(); // Assert that we still have a valid stream.
    |                 ^^^^^^^^^^^^^^
diff --git a/src/test/ui/hrtb/issue-30786.rs b/src/test/ui/hrtb/issue-30786.rs
index b9920a1950498..c42297ca68346 100644
--- a/src/test/ui/hrtb/issue-30786.rs
+++ b/src/test/ui/hrtb/issue-30786.rs
@@ -16,7 +16,7 @@
 
 //[nll]compile-flags: -Z borrowck=mir
 
-pub trait Stream {
+pub trait Stream { //[migrate]~ NOTE trait `Stream` defined here
     type Item;
     fn next(self) -> Option<Self::Item>;
 }
@@ -109,6 +109,7 @@ fn main() {
     //[migrate]~^ ERROR implementation of `Stream` is not general enough
     //[migrate]~| NOTE  `Stream` would have to be implemented for the type `&'0 mut Map
     //[migrate]~| NOTE  but `Stream` is actually implemented for the type `&'1
+    //[migrate]~| NOTE  implementation of `Stream` is not general enough
     let filter = map.filter(|x: &_| true);
     //[nll]~^ ERROR higher-ranked subtype error
     let count = filter.count(); // Assert that we still have a valid stream.
diff --git a/src/test/ui/issues/issue-54302-cases.stderr b/src/test/ui/issues/issue-54302-cases.stderr
index 98637611b79fe..3ed2779164301 100644
--- a/src/test/ui/issues/issue-54302-cases.stderr
+++ b/src/test/ui/issues/issue-54302-cases.stderr
@@ -1,38 +1,58 @@
 error: implementation of `Foo` is not general enough
   --> $DIR/issue-54302-cases.rs:63:5
    |
-LL |     <u32 as RefFoo<u32>>::ref_foo(a)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`
-   = note: but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
+LL | / trait Foo<'x, T> {
+LL | |     fn foo(self) -> &'x T;
+LL | | }
+   | |_- trait `Foo` defined here
+...
+LL |       <u32 as RefFoo<u32>>::ref_foo(a)
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
+   = note: ...but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
 
 error: implementation of `Foo` is not general enough
   --> $DIR/issue-54302-cases.rs:69:5
    |
-LL |     <i32 as RefFoo<i32>>::ref_foo(a)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / trait Foo<'x, T> {
+LL | |     fn foo(self) -> &'x T;
+LL | | }
+   | |_- trait `Foo` defined here
+...
+LL |       <i32 as RefFoo<i32>>::ref_foo(a)
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0`
-   = note: but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for some specific lifetime `'1`
+   = note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0`...
+   = note: ...but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for some specific lifetime `'1`
 
 error: implementation of `Foo` is not general enough
   --> $DIR/issue-54302-cases.rs:75:5
    |
-LL |     <u64 as RefFoo<u64>>::ref_foo(a)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / trait Foo<'x, T> {
+LL | |     fn foo(self) -> &'x T;
+LL | | }
+   | |_- trait `Foo` defined here
+...
+LL |       <u64 as RefFoo<u64>>::ref_foo(a)
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0`
-   = note: but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for some specific lifetime `'1`
+   = note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0`...
+   = note: ...but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for some specific lifetime `'1`
 
 error: implementation of `Foo` is not general enough
   --> $DIR/issue-54302-cases.rs:81:5
    |
-LL |     <i64 as RefFoo<i64>>::ref_foo(a)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / trait Foo<'x, T> {
+LL | |     fn foo(self) -> &'x T;
+LL | | }
+   | |_- trait `Foo` defined here
+...
+LL |       <i64 as RefFoo<i64>>::ref_foo(a)
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-   = note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0`
-   = note: but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for some specific lifetime `'1`
+   = note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0`...
+   = note: ...but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for some specific lifetime `'1`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/issues/issue-54302.stderr b/src/test/ui/issues/issue-54302.stderr
index c6d0805f3ab2a..1b3f57ba188a3 100644
--- a/src/test/ui/issues/issue-54302.stderr
+++ b/src/test/ui/issues/issue-54302.stderr
@@ -1,11 +1,14 @@
 error: implementation of `Deserialize` is not general enough
   --> $DIR/issue-54302.rs:13:5
    |
+LL | trait Deserialize<'de> {}
+   | ------------------------- trait `Deserialize` defined here
+...
 LL |     assert_deserialize_owned::<&'static str>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
    |
-   = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`
-   = note: but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
+   = note: `&'static str` must implement `Deserialize<'0>`, for any lifetime `'0`...
+   = note: ...but `&str` actually implements `Deserialize<'1>`, for some specific lifetime `'1`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-55731.stderr b/src/test/ui/issues/issue-55731.stderr
index f25e18e5d90cb..f44c842187cc2 100644
--- a/src/test/ui/issues/issue-55731.stderr
+++ b/src/test/ui/issues/issue-55731.stderr
@@ -1,11 +1,16 @@
 error: implementation of `DistributedIteratorMulti` is not general enough
   --> $DIR/issue-55731.rs:48:5
    |
-LL |     multi(Map {
-   |     ^^^^^
+LL | / trait DistributedIteratorMulti<Source> {
+LL | |     type Item;
+LL | | }
+   | |_- trait `DistributedIteratorMulti` defined here
+...
+LL |       multi(Map {
+   |       ^^^^^ implementation of `DistributedIteratorMulti` is not general enough
    |
-   = note: `DistributedIteratorMulti<&'0 ()>` would have to be implemented for the type `Cloned<&()>`, for any lifetime `'0`
-   = note: but `DistributedIteratorMulti<&'1 ()>` is actually implemented for the type `Cloned<&'1 ()>`, for some specific lifetime `'1`
+   = note: `DistributedIteratorMulti<&'0 ()>` would have to be implemented for the type `Cloned<&()>`, for any lifetime `'0`...
+   = note: ...but `DistributedIteratorMulti<&'1 ()>` is actually implemented for the type `Cloned<&'1 ()>`, for some specific lifetime `'1`
 
 error: aborting due to previous error
 

From 3a046ffa71ae9a991479a435a451b528ee4f71f0 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Tue, 17 Sep 2019 08:39:34 +0900
Subject: [PATCH 813/943] Elide lifetimes in `Pin<&(mut) Self>`

---
 src/libcore/option.rs | 4 ++--
 src/libcore/pin.rs    | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 79bd04b724390..5569d99f8d81d 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -295,7 +295,7 @@ impl<T> Option<T> {
     /// [`Pin`]: ../pin/struct.Pin.html
     #[inline]
     #[stable(feature = "pin", since = "1.33.0")]
-    pub fn as_pin_ref<'a>(self: Pin<&'a Option<T>>) -> Option<Pin<&'a T>> {
+    pub fn as_pin_ref(self: Pin<&Self>) -> Option<Pin<&T>> {
         unsafe {
             Pin::get_ref(self).as_ref().map(|x| Pin::new_unchecked(x))
         }
@@ -306,7 +306,7 @@ impl<T> Option<T> {
     /// [`Pin`]: ../pin/struct.Pin.html
     #[inline]
     #[stable(feature = "pin", since = "1.33.0")]
-    pub fn as_pin_mut<'a>(self: Pin<&'a mut Option<T>>) -> Option<Pin<&'a mut T>> {
+    pub fn as_pin_mut(self: Pin<&mut Self>) -> Option<Pin<&mut T>> {
         unsafe {
             Pin::get_unchecked_mut(self).as_mut().map(|x| Pin::new_unchecked(x))
         }
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index 1080fd32a8862..bddd477c6d85c 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -233,7 +233,7 @@
 //! # type Field = i32;
 //! # struct Struct { field: Field }
 //! impl Struct {
-//!     fn pin_get_field<'a>(self: Pin<&'a mut Self>) -> &'a mut Field {
+//!     fn pin_get_field(self: Pin<&mut Self>) -> &mut Field {
 //!         // This is okay because `field` is never considered pinned.
 //!         unsafe { &mut self.get_unchecked_mut().field }
 //!     }
@@ -257,7 +257,7 @@
 //! # type Field = i32;
 //! # struct Struct { field: Field }
 //! impl Struct {
-//!     fn pin_get_field<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut Field> {
+//!     fn pin_get_field(self: Pin<&mut Self>) -> Pin<&mut Field> {
 //!         // This is okay because `field` is pinned when `self` is.
 //!         unsafe { self.map_unchecked_mut(|s| &mut s.field) }
 //!     }

From 076e0ce259104bcbf9b018add4ac1b720f747e98 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Tue, 17 Sep 2019 08:54:30 +0900
Subject: [PATCH 814/943] Use shorthand syntax in the self parameter of methods
 of Pin

---
 src/libcore/pin.rs | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index 1080fd32a8862..8ce32fd111e9d 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -549,7 +549,7 @@ impl<P: Deref> Pin<P> {
     /// ruled out by the contract of `Pin::new_unchecked`.
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn as_ref(self: &Pin<P>) -> Pin<&P::Target> {
+    pub fn as_ref(&self) -> Pin<&P::Target> {
         unsafe { Pin::new_unchecked(&*self.pointer) }
     }
 
@@ -586,7 +586,7 @@ impl<P: DerefMut> Pin<P> {
     /// ruled out by the contract of `Pin::new_unchecked`.
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn as_mut(self: &mut Pin<P>) -> Pin<&mut P::Target> {
+    pub fn as_mut(&mut self) -> Pin<&mut P::Target> {
         unsafe { Pin::new_unchecked(&mut *self.pointer) }
     }
 
@@ -596,7 +596,7 @@ impl<P: DerefMut> Pin<P> {
     /// run before being overwritten, so no pinning guarantee is violated.
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn set(self: &mut Pin<P>, value: P::Target)
+    pub fn set(&mut self, value: P::Target)
     where
         P::Target: Sized,
     {
@@ -621,7 +621,7 @@ impl<'a, T: ?Sized> Pin<&'a T> {
     ///
     /// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning
     #[stable(feature = "pin", since = "1.33.0")]
-    pub unsafe fn map_unchecked<U, F>(self: Pin<&'a T>, func: F) -> Pin<&'a U> where
+    pub unsafe fn map_unchecked<U, F>(self, func: F) -> Pin<&'a U> where
         F: FnOnce(&T) -> &U,
     {
         let pointer = &*self.pointer;
@@ -648,7 +648,7 @@ impl<'a, T: ?Sized> Pin<&'a T> {
     /// ["pinning projections"]: ../../std/pin/index.html#projections-and-structural-pinning
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn get_ref(self: Pin<&'a T>) -> &'a T {
+    pub fn get_ref(self) -> &'a T {
         self.pointer
     }
 }
@@ -657,7 +657,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// Converts this `Pin<&mut T>` into a `Pin<&T>` with the same lifetime.
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn into_ref(self: Pin<&'a mut T>) -> Pin<&'a T> {
+    pub fn into_ref(self) -> Pin<&'a T> {
         Pin { pointer: self.pointer }
     }
 
@@ -672,7 +672,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// with the same lifetime as the original `Pin`.
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub fn get_mut(self: Pin<&'a mut T>) -> &'a mut T
+    pub fn get_mut(self) -> &'a mut T
         where T: Unpin,
     {
         self.pointer
@@ -690,7 +690,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     /// instead.
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
-    pub unsafe fn get_unchecked_mut(self: Pin<&'a mut T>) -> &'a mut T {
+    pub unsafe fn get_unchecked_mut(self) -> &'a mut T {
         self.pointer
     }
 
@@ -710,7 +710,7 @@ impl<'a, T: ?Sized> Pin<&'a mut T> {
     ///
     /// [`pin` module]: ../../std/pin/index.html#projections-and-structural-pinning
     #[stable(feature = "pin", since = "1.33.0")]
-    pub unsafe fn map_unchecked_mut<U, F>(self: Pin<&'a mut T>, func: F) -> Pin<&'a mut U> where
+    pub unsafe fn map_unchecked_mut<U, F>(self, func: F) -> Pin<&'a mut U> where
         F: FnOnce(&mut T) -> &mut U,
     {
         let pointer = Pin::get_unchecked_mut(self);

From 606a31f46a066ba0d85c1915145703ae7b9d802b Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Thu, 29 Aug 2019 20:47:45 -0700
Subject: [PATCH 815/943] Add a getter for the current state to
 `DataflowResultsCursor`

---
 src/librustc_mir/dataflow/mod.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 7fe2a890a5371..c9da51233d47d 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -453,6 +453,10 @@ where
     {
         self.flow_state.each_gen_bit(f)
     }
+
+    pub fn get(&self) -> &BitSet<BD::Idx> {
+        self.flow_state.as_dense()
+    }
 }
 
 pub fn state_for_location<'tcx, T: BitDenotation<'tcx>>(loc: Location,

From 48c2a1ee3a77467f072ee00d451d43b60b13d946 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Mon, 16 Sep 2019 17:52:15 -0700
Subject: [PATCH 816/943] Replace all uses of `dataflow::state_for_location`

Use the new dataflow cursor.
---
 src/librustc_mir/transform/generator.rs | 37 ++++++++++---------------
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 0ce2db93c421d..caf588af851dd 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -67,7 +67,7 @@ use crate::transform::{MirPass, MirSource};
 use crate::transform::simplify;
 use crate::transform::no_landing_pads::no_landing_pads;
 use crate::dataflow::{DataflowResults, DataflowResultsConsumer, FlowAtLocation};
-use crate::dataflow::{do_dataflow, DebugFormatted, state_for_location};
+use crate::dataflow::{do_dataflow, DebugFormatted, DataflowResultsCursor};
 use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals, RequiresStorage};
 use crate::util::dump_mir;
 use crate::util::liveness;
@@ -436,9 +436,10 @@ fn locals_live_across_suspend_points(
     // Calculate when MIR locals have live storage. This gives us an upper bound of their
     // lifetimes.
     let storage_live_analysis = MaybeStorageLive::new(body);
-    let storage_live =
+    let storage_live_results =
         do_dataflow(tcx, body, def_id, &[], &dead_unwinds, storage_live_analysis,
                     |bd, p| DebugFormatted::new(&bd.body().local_decls[p]));
+    let mut storage_live_cursor = DataflowResultsCursor::new(&storage_live_results, body);
 
     // Find the MIR locals which do not use StorageLive/StorageDead statements.
     // The storage of these locals are always live.
@@ -448,17 +449,18 @@ fn locals_live_across_suspend_points(
     // Calculate the MIR locals which have been previously
     // borrowed (even if they are still active).
     let borrowed_locals_analysis = HaveBeenBorrowedLocals::new(body);
-    let borrowed_locals_result =
+    let borrowed_locals_results =
         do_dataflow(tcx, body, def_id, &[], &dead_unwinds, borrowed_locals_analysis,
                     |bd, p| DebugFormatted::new(&bd.body().local_decls[p]));
+    let mut borrowed_locals_cursor = DataflowResultsCursor::new(&borrowed_locals_results, body);
 
     // Calculate the MIR locals that we actually need to keep storage around
     // for.
-    let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_result);
-    let requires_storage =
+    let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_results);
+    let requires_storage_results =
         do_dataflow(tcx, body, def_id, &[], &dead_unwinds, requires_storage_analysis,
                     |bd, p| DebugFormatted::new(&bd.body().local_decls[p]));
-    let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_result);
+    let mut requires_storage_cursor = DataflowResultsCursor::new(&requires_storage_results, body);
 
     // Calculate the liveness of MIR locals ignoring borrows.
     let mut live_locals = liveness::LiveVarSet::new_empty(body.local_decls.len());
@@ -484,10 +486,6 @@ fn locals_live_across_suspend_points(
             };
 
             if !movable {
-                let borrowed_locals = state_for_location(loc,
-                                                         &borrowed_locals_analysis,
-                                                         &borrowed_locals_result,
-                                                         body);
                 // The `liveness` variable contains the liveness of MIR locals ignoring borrows.
                 // This is correct for movable generators since borrows cannot live across
                 // suspension points. However for immovable generators we need to account for
@@ -498,22 +496,19 @@ fn locals_live_across_suspend_points(
                 // If a borrow is converted to a raw reference, we must also assume that it lives
                 // forever. Note that the final liveness is still bounded by the storage liveness
                 // of the local, which happens using the `intersect` operation below.
-                liveness.outs[block].union(&borrowed_locals);
+                borrowed_locals_cursor.seek(loc);
+                liveness.outs[block].union(borrowed_locals_cursor.get());
             }
 
-            let storage_liveness = state_for_location(loc,
-                                                      &storage_live_analysis,
-                                                      &storage_live,
-                                                      body);
+            storage_live_cursor.seek(loc);
+            let storage_liveness = storage_live_cursor.get();
 
             // Store the storage liveness for later use so we can restore the state
             // after a suspension point
             storage_liveness_map.insert(block, storage_liveness.clone());
 
-            let mut storage_required = state_for_location(loc,
-                                                          &requires_storage_analysis,
-                                                          &requires_storage,
-                                                          body);
+            requires_storage_cursor.seek(loc);
+            let mut storage_required = requires_storage_cursor.get().clone();
 
             // Mark locals without storage statements as always requiring storage
             storage_required.union(&ignored.0);
@@ -549,8 +544,7 @@ fn locals_live_across_suspend_points(
         body,
         &live_locals,
         &ignored,
-        requires_storage,
-        requires_storage_analysis);
+        requires_storage_results);
 
     LivenessInfo {
         live_locals,
@@ -588,7 +582,6 @@ fn compute_storage_conflicts(
     stored_locals: &liveness::LiveVarSet,
     ignored: &StorageIgnored,
     requires_storage: DataflowResults<'tcx, RequiresStorage<'mir, 'tcx>>,
-    _requires_storage_analysis: RequiresStorage<'mir, 'tcx>,
 ) -> BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal> {
     assert_eq!(body.local_decls.len(), ignored.0.domain_size());
     assert_eq!(body.local_decls.len(), stored_locals.domain_size());

From 73c7a6813d1eae1e5c37c00fecd897cb7d45908c Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Mon, 16 Sep 2019 17:53:02 -0700
Subject: [PATCH 817/943] Remove `dataflow::state_for_location`

---
 src/librustc_mir/dataflow/mod.rs | 28 ----------------------------
 1 file changed, 28 deletions(-)

diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index c9da51233d47d..a4dc3989c5bd1 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -459,34 +459,6 @@ where
     }
 }
 
-pub fn state_for_location<'tcx, T: BitDenotation<'tcx>>(loc: Location,
-                                                        analysis: &T,
-                                                        result: &DataflowResults<'tcx, T>,
-                                                        body: &Body<'tcx>)
-    -> BitSet<T::Idx> {
-    let mut trans = GenKill::from_elem(HybridBitSet::new_empty(analysis.bits_per_block()));
-
-    for stmt in 0..loc.statement_index {
-        let mut stmt_loc = loc;
-        stmt_loc.statement_index = stmt;
-        analysis.before_statement_effect(&mut trans, stmt_loc);
-        analysis.statement_effect(&mut trans, stmt_loc);
-    }
-
-    // Apply the pre-statement effect of the statement we're evaluating.
-    if loc.statement_index == body[loc.block].statements.len() {
-        analysis.before_terminator_effect(&mut trans, loc);
-    } else {
-        analysis.before_statement_effect(&mut trans, loc);
-    }
-
-    // Apply the transfer function for all preceding statements to the fixpoint
-    // at the start of the block.
-    let mut state = result.sets().entry_set_for(loc.block.index()).to_owned();
-    trans.apply(&mut state);
-    state
-}
-
 pub struct DataflowAnalysis<'a, 'tcx, O>
 where
     O: BitDenotation<'tcx>,

From 02c1b892c1dfa6d0f00254f9c058ce7595921d61 Mon Sep 17 00:00:00 2001
From: Afnan Enayet <afnan@afnan.io>
Date: Fri, 13 Sep 2019 06:48:47 -0700
Subject: [PATCH 818/943] Fix failure note `to_str` implementation

* Serialize the level to something a little more useful for a failure note
  struct
* Update tests accordingly
---
 src/librustc_errors/emitter.rs              | 15 +++++++++------
 src/librustc_errors/lib.rs                  |  2 +-
 src/test/ui/json-short.stderr               |  2 +-
 src/test/ui/lint/use_suggestion_json.stderr |  2 +-
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 0ce69eecc6b1e..5214806c6ea98 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -1144,15 +1144,18 @@ impl EmitterWriter {
                 buffer.prepend(0, " ", Style::NoStyle);
             }
             draw_note_separator(&mut buffer, 0, max_line_num_len + 1);
-            let level_str = level.to_string();
-            if !level_str.is_empty() {
-                buffer.append(0, &level_str, Style::MainHeaderMsg);
-                buffer.append(0, ": ", Style::NoStyle);
+            if *level != Level::FailureNote {
+                let level_str = level.to_string();
+                if !level_str.is_empty() {
+                    buffer.append(0, &level_str, Style::MainHeaderMsg);
+                    buffer.append(0, ": ", Style::NoStyle);
+                }
             }
             self.msg_to_buffer(&mut buffer, msg, max_line_num_len, "note", None);
         } else {
             let level_str = level.to_string();
-            if !level_str.is_empty() {
+            // The failure note level itself does not provide any useful diagnostic information
+            if *level != Level::FailureNote && !level_str.is_empty() {
                 buffer.append(0, &level_str, Style::Level(level.clone()));
             }
             // only render error codes, not lint codes
@@ -1161,7 +1164,7 @@ impl EmitterWriter {
                 buffer.append(0, &code, Style::Level(level.clone()));
                 buffer.append(0, "]", Style::Level(level.clone()));
             }
-            if !level_str.is_empty() {
+            if *level != Level::FailureNote && !level_str.is_empty() {
                 buffer.append(0, ": ", header_style);
             }
             for &(ref text, _) in msg.iter() {
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index c1fba416d6433..8b543be6e6497 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -833,7 +833,7 @@ impl Level {
             Warning => "warning",
             Note => "note",
             Help => "help",
-            FailureNote => "",
+            FailureNote => "failure-note",
             Cancelled => panic!("Shouldn't call on cancelled error"),
         }
     }
diff --git a/src/test/ui/json-short.stderr b/src/test/ui/json-short.stderr
index dffbdb7e4802d..549de0d27102e 100644
--- a/src/test/ui/json-short.stderr
+++ b/src/test/ui/json-short.stderr
@@ -15,5 +15,5 @@ started: https://doc.rust-lang.org/book/
 "}
 {"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error
 "}
-{"message":"For more information about this error, try `rustc --explain E0601`.","code":null,"level":"","spans":[],"children":[],"rendered":"For more information about this error, try `rustc --explain E0601`.
+{"message":"For more information about this error, try `rustc --explain E0601`.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"For more information about this error, try `rustc --explain E0601`.
 "}
diff --git a/src/test/ui/lint/use_suggestion_json.stderr b/src/test/ui/lint/use_suggestion_json.stderr
index c7c53abcf4406..678c88849b561 100644
--- a/src/test/ui/lint/use_suggestion_json.stderr
+++ b/src/test/ui/lint/use_suggestion_json.stderr
@@ -412,7 +412,7 @@ mod foo {
 {
   "message": "For more information about this error, try `rustc --explain E0412`.",
   "code": null,
-  "level": "",
+  "level": "failure-note",
   "spans": [],
   "children": [],
   "rendered": "\u001b[0m\u001b[1mFor more information about this error, try `rustc --explain E0412`.\u001b[0m

From 476e75ded71ad6f573daabe2ca7a1be9fe3ce3cb Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 17 Sep 2019 12:08:24 +1000
Subject: [PATCH 819/943] Move a `Node`'s parent into the descendents list.

`Node` has an optional parent and a list of other descendents. Most of
the time the parent is treated the same as the other descendents --
error-handling is the exception -- and chaining them together for
iteration has a non-trivial cost.

This commit changes the representation. There is now a single list of
descendants, and a boolean flag that indicates if there is a parent (in
which case it is first descendent). This representation encodes the same
information, in a way that is less idiomatic but cheaper to iterate over
for the common case where the parent doesn't need special treatment.

As a result, some benchmark workloads are up to 2% faster.
---
 .../obligation_forest/graphviz.rs             |  4 +-
 .../obligation_forest/mod.rs                  | 75 +++++++++----------
 2 files changed, 36 insertions(+), 43 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/graphviz.rs b/src/librustc_data_structures/obligation_forest/graphviz.rs
index b2120b182fa7b..fe0a3cb0500c5 100644
--- a/src/librustc_data_structures/obligation_forest/graphviz.rs
+++ b/src/librustc_data_structures/obligation_forest/graphviz.rs
@@ -74,9 +74,7 @@ impl<'a, O: ForestObligation + 'a> dot::GraphWalk<'a> for &'a ObligationForest<O
             .flat_map(|i| {
                 let node = &self.nodes[i];
 
-                node.parent.iter()
-                    .chain(node.dependents.iter())
-                    .map(move |p| (p.index(), i))
+                node.dependents.iter().map(move |p| (p.index(), i))
             })
             .collect()
     }
diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 189506bf8ab76..0ae4a04eb50f5 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -177,21 +177,17 @@ struct Node<O> {
     obligation: O,
     state: Cell<NodeState>,
 
-    /// The parent of a node - the original obligation of which it is a
-    /// subobligation. Except for error reporting, it is just like any member
-    /// of `dependents`.
-    ///
-    /// Unlike `ObligationForest::nodes`, this uses `NodeIndex` rather than
-    /// `usize` for the index, because keeping the size down is more important
-    /// than the cost of converting to a `usize` for indexing.
-    parent: Option<NodeIndex>,
-
     /// Obligations that depend on this obligation for their completion. They
     /// must all be in a non-pending state.
-    ///
-    /// This uses `NodeIndex` for the same reason as `parent`.
     dependents: Vec<NodeIndex>,
 
+    /// If true, dependents[0] points to a "parent" node, which requires
+    /// special treatment upon error but is otherwise treated the same.
+    /// (It would be more idiomatic to store the parent node in a separate
+    /// `Option<NodeIndex>` field, but that slows down the common case of
+    /// iterating over the parent and other descendants together.)
+    has_parent: bool,
+
     /// Identifier of the obligation tree to which this node belongs.
     obligation_tree_id: ObligationTreeId,
 }
@@ -205,8 +201,13 @@ impl<O> Node<O> {
         Node {
             obligation,
             state: Cell::new(NodeState::Pending),
-            parent,
-            dependents: vec![],
+            dependents:
+                if let Some(parent_index) = parent {
+                    vec![parent_index]
+                } else {
+                    vec![]
+                },
+            has_parent: parent.is_some(),
             obligation_tree_id,
         }
     }
@@ -315,13 +316,11 @@ impl<O: ForestObligation> ObligationForest<O> {
                        obligation, parent, o.get());
                 let node = &mut self.nodes[o.get().index()];
                 if let Some(parent_index) = parent {
-                    // If the node is already in `waiting_cache`, it's already
-                    // been marked with a parent. (It's possible that parent
-                    // has been cleared by `apply_rewrites`, though.) So just
-                    // dump `parent` into `node.dependents`... unless it's
-                    // already in `node.dependents` or `node.parent`.
-                    if !node.dependents.contains(&parent_index) &&
-                       Some(parent_index) != node.parent {
+                    // If the node is already in `waiting_cache`, it has
+                    // already had its chance to be marked with a parent. So if
+                    // it's not already present, just dump `parent` into the
+                    // dependents as a non-parent.
+                    if !node.dependents.contains(&parent_index) {
                         node.dependents.push(parent_index);
                     }
                 }
@@ -523,7 +522,7 @@ impl<O: ForestObligation> ObligationForest<O> {
             NodeState::Success => {
                 node.state.set(NodeState::OnDfsStack);
                 stack.push(i);
-                for index in node.parent.iter().chain(node.dependents.iter()) {
+                for index in node.dependents.iter() {
                     self.find_cycles_from_node(stack, processor, index.index());
                 }
                 stack.pop();
@@ -549,12 +548,15 @@ impl<O: ForestObligation> ObligationForest<O> {
             let node = &self.nodes[i];
             node.state.set(NodeState::Error);
             trace.push(node.obligation.clone());
-            error_stack.extend(node.dependents.iter().map(|index| index.index()));
-
-            // Loop to the parent.
-            match node.parent {
-                Some(parent_index) => i = parent_index.index(),
-                None => break
+            if node.has_parent {
+                // The first dependent is the parent, which is treated
+                // specially.
+                error_stack.extend(node.dependents.iter().skip(1).map(|index| index.index()));
+                i = node.dependents[0].index();
+            } else {
+                // No parent; treat all dependents non-specially.
+                error_stack.extend(node.dependents.iter().map(|index| index.index()));
+                break;
             }
         }
 
@@ -565,9 +567,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                 _ => node.state.set(NodeState::Error),
             }
 
-            error_stack.extend(
-                node.parent.iter().chain(node.dependents.iter()).map(|index| index.index())
-            );
+            error_stack.extend(node.dependents.iter().map(|index| index.index()));
         }
 
         self.scratch.replace(error_stack);
@@ -577,7 +577,7 @@ impl<O: ForestObligation> ObligationForest<O> {
     // This always-inlined function is for the hot call site.
     #[inline(always)]
     fn inlined_mark_neighbors_as_waiting_from(&self, node: &Node<O>) {
-        for dependent in node.parent.iter().chain(node.dependents.iter()) {
+        for dependent in node.dependents.iter() {
             self.mark_as_waiting_from(&self.nodes[dependent.index()]);
         }
     }
@@ -706,20 +706,15 @@ impl<O: ForestObligation> ObligationForest<O> {
         let nodes_len = node_rewrites.len();
 
         for node in &mut self.nodes {
-            if let Some(index) = node.parent {
-                let new_i = node_rewrites[index.index()];
-                if new_i >= nodes_len {
-                    node.parent = None;
-                } else {
-                    node.parent = Some(NodeIndex::new(new_i));
-                }
-            }
-
             let mut i = 0;
             while i < node.dependents.len() {
                 let new_i = node_rewrites[node.dependents[i].index()];
                 if new_i >= nodes_len {
                     node.dependents.swap_remove(i);
+                    if i == 0 && node.has_parent {
+                        // We just removed the parent.
+                        node.has_parent = false;
+                    }
                 } else {
                     node.dependents[i] = NodeIndex::new(new_i);
                     i += 1;

From cf3a562c981252f2f4e4c89d7cae353ea00529e3 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 17 Sep 2019 14:19:44 +1000
Subject: [PATCH 820/943] Remove `NodeIndex`.

The size of the indices doesn't matter much here, and having a
`newtype_index!` index type without also using `IndexVec` requires lots
of conversions. So this commit removes `NodeIndex` in favour of uniform
use of `usize` as the index type. As well as making the code slightly
more concise, it also slightly speeds things up.
---
 .../obligation_forest/graphviz.rs             |  2 +-
 .../obligation_forest/mod.rs                  | 61 ++++++++-----------
 2 files changed, 27 insertions(+), 36 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/graphviz.rs b/src/librustc_data_structures/obligation_forest/graphviz.rs
index fe0a3cb0500c5..ddf89d99621ca 100644
--- a/src/librustc_data_structures/obligation_forest/graphviz.rs
+++ b/src/librustc_data_structures/obligation_forest/graphviz.rs
@@ -74,7 +74,7 @@ impl<'a, O: ForestObligation + 'a> dot::GraphWalk<'a> for &'a ObligationForest<O
             .flat_map(|i| {
                 let node = &self.nodes[i];
 
-                node.dependents.iter().map(move |p| (p.index(), i))
+                node.dependents.iter().map(move |&d| (d, i))
             })
             .collect()
     }
diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index 0ae4a04eb50f5..afec7a24b1785 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -73,8 +73,6 @@
 //! aren't needed anymore.
 
 use crate::fx::{FxHashMap, FxHashSet};
-use crate::indexed_vec::Idx;
-use crate::newtype_index;
 
 use std::cell::{Cell, RefCell};
 use std::collections::hash_map::Entry;
@@ -87,10 +85,6 @@ mod graphviz;
 #[cfg(test)]
 mod tests;
 
-newtype_index! {
-    pub struct NodeIndex { .. }
-}
-
 pub trait ForestObligation : Clone + Debug {
     type Predicate : Clone + hash::Hash + Eq + Debug;
 
@@ -143,9 +137,10 @@ pub struct ObligationForest<O: ForestObligation> {
     /// At the end of processing, those nodes will be removed by a
     /// call to `compress`.
     ///
-    /// Ideally, this would be an `IndexVec<NodeIndex, Node<O>>`. But that is
-    /// slower, because this vector is accessed so often that the
-    /// `u32`-to-`usize` conversions required for accesses are significant.
+    /// `usize` indices are used here and throughout this module, rather than
+    /// `newtype_index!` indices, because this code is hot enough that the
+    /// `u32`-to-`usize` conversions that would be required are significant,
+    /// and space considerations are not important.
     nodes: Vec<Node<O>>,
 
     /// A cache of predicates that have been successfully completed.
@@ -154,7 +149,7 @@ pub struct ObligationForest<O: ForestObligation> {
     /// A cache of the nodes in `nodes`, indexed by predicate. Unfortunately,
     /// its contents are not guaranteed to match those of `nodes`. See the
     /// comments in `process_obligation` for details.
-    waiting_cache: FxHashMap<O::Predicate, NodeIndex>,
+    waiting_cache: FxHashMap<O::Predicate, usize>,
 
     /// A scratch vector reused in various operations, to avoid allocating new
     /// vectors.
@@ -179,12 +174,12 @@ struct Node<O> {
 
     /// Obligations that depend on this obligation for their completion. They
     /// must all be in a non-pending state.
-    dependents: Vec<NodeIndex>,
+    dependents: Vec<usize>,
 
     /// If true, dependents[0] points to a "parent" node, which requires
     /// special treatment upon error but is otherwise treated the same.
     /// (It would be more idiomatic to store the parent node in a separate
-    /// `Option<NodeIndex>` field, but that slows down the common case of
+    /// `Option<usize>` field, but that slows down the common case of
     /// iterating over the parent and other descendants together.)
     has_parent: bool,
 
@@ -194,7 +189,7 @@ struct Node<O> {
 
 impl<O> Node<O> {
     fn new(
-        parent: Option<NodeIndex>,
+        parent: Option<usize>,
         obligation: O,
         obligation_tree_id: ObligationTreeId
     ) -> Node<O> {
@@ -303,9 +298,7 @@ impl<O: ForestObligation> ObligationForest<O> {
     }
 
     // Returns Err(()) if we already know this obligation failed.
-    fn register_obligation_at(&mut self, obligation: O, parent: Option<NodeIndex>)
-                              -> Result<(), ()>
-    {
+    fn register_obligation_at(&mut self, obligation: O, parent: Option<usize>) -> Result<(), ()> {
         if self.done_cache.contains(obligation.as_predicate()) {
             return Ok(());
         }
@@ -314,7 +307,7 @@ impl<O: ForestObligation> ObligationForest<O> {
             Entry::Occupied(o) => {
                 debug!("register_obligation_at({:?}, {:?}) - duplicate of {:?}!",
                        obligation, parent, o.get());
-                let node = &mut self.nodes[o.get().index()];
+                let node = &mut self.nodes[*o.get()];
                 if let Some(parent_index) = parent {
                     // If the node is already in `waiting_cache`, it has
                     // already had its chance to be marked with a parent. So if
@@ -335,10 +328,8 @@ impl<O: ForestObligation> ObligationForest<O> {
                        obligation, parent, self.nodes.len());
 
                 let obligation_tree_id = match parent {
-                    Some(parent_index) => {
-                        self.nodes[parent_index.index()].obligation_tree_id
-                    }
-                    None => self.obligation_tree_id_generator.next().unwrap()
+                    Some(parent_index) => self.nodes[parent_index].obligation_tree_id,
+                    None => self.obligation_tree_id_generator.next().unwrap(),
                 };
 
                 let already_failed =
@@ -351,7 +342,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                 if already_failed {
                     Err(())
                 } else {
-                    v.insert(NodeIndex::new(self.nodes.len()));
+                    v.insert(self.nodes.len());
                     self.nodes.push(Node::new(parent, obligation, obligation_tree_id));
                     Ok(())
                 }
@@ -437,7 +428,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                     for child in children {
                         let st = self.register_obligation_at(
                             child,
-                            Some(NodeIndex::new(i))
+                            Some(i)
                         );
                         if let Err(()) = st {
                             // Error already reported - propagate it
@@ -522,8 +513,8 @@ impl<O: ForestObligation> ObligationForest<O> {
             NodeState::Success => {
                 node.state.set(NodeState::OnDfsStack);
                 stack.push(i);
-                for index in node.dependents.iter() {
-                    self.find_cycles_from_node(stack, processor, index.index());
+                for &index in node.dependents.iter() {
+                    self.find_cycles_from_node(stack, processor, index);
                 }
                 stack.pop();
                 node.state.set(NodeState::Done);
@@ -551,11 +542,11 @@ impl<O: ForestObligation> ObligationForest<O> {
             if node.has_parent {
                 // The first dependent is the parent, which is treated
                 // specially.
-                error_stack.extend(node.dependents.iter().skip(1).map(|index| index.index()));
-                i = node.dependents[0].index();
+                error_stack.extend(node.dependents.iter().skip(1));
+                i = node.dependents[0];
             } else {
                 // No parent; treat all dependents non-specially.
-                error_stack.extend(node.dependents.iter().map(|index| index.index()));
+                error_stack.extend(node.dependents.iter());
                 break;
             }
         }
@@ -567,7 +558,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                 _ => node.state.set(NodeState::Error),
             }
 
-            error_stack.extend(node.dependents.iter().map(|index| index.index()));
+            error_stack.extend(node.dependents.iter());
         }
 
         self.scratch.replace(error_stack);
@@ -577,8 +568,8 @@ impl<O: ForestObligation> ObligationForest<O> {
     // This always-inlined function is for the hot call site.
     #[inline(always)]
     fn inlined_mark_neighbors_as_waiting_from(&self, node: &Node<O>) {
-        for dependent in node.dependents.iter() {
-            self.mark_as_waiting_from(&self.nodes[dependent.index()]);
+        for &dependent in node.dependents.iter() {
+            self.mark_as_waiting_from(&self.nodes[dependent]);
         }
     }
 
@@ -708,7 +699,7 @@ impl<O: ForestObligation> ObligationForest<O> {
         for node in &mut self.nodes {
             let mut i = 0;
             while i < node.dependents.len() {
-                let new_i = node_rewrites[node.dependents[i].index()];
+                let new_i = node_rewrites[node.dependents[i]];
                 if new_i >= nodes_len {
                     node.dependents.swap_remove(i);
                     if i == 0 && node.has_parent {
@@ -716,7 +707,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                         node.has_parent = false;
                     }
                 } else {
-                    node.dependents[i] = NodeIndex::new(new_i);
+                    node.dependents[i] = new_i;
                     i += 1;
                 }
             }
@@ -725,11 +716,11 @@ impl<O: ForestObligation> ObligationForest<O> {
         // This updating of `self.waiting_cache` is necessary because the
         // removal of nodes within `compress` can fail. See above.
         self.waiting_cache.retain(|_predicate, index| {
-            let new_i = node_rewrites[index.index()];
+            let new_i = node_rewrites[*index];
             if new_i >= nodes_len {
                 false
             } else {
-                *index = NodeIndex::new(new_i);
+                *index = new_i;
                 true
             }
         });

From 7f6e160875f375bb71d1ae761cb5cab8f0b02e19 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 17 Sep 2019 14:23:32 +1000
Subject: [PATCH 821/943] Rename some index variables.

Now that all indices have type `usize`, it makes sense to be more
consistent about their naming. This commit removes all uses of `i` in
favour of `index`.
---
 .../obligation_forest/mod.rs                  | 88 +++++++++----------
 1 file changed, 44 insertions(+), 44 deletions(-)

diff --git a/src/librustc_data_structures/obligation_forest/mod.rs b/src/librustc_data_structures/obligation_forest/mod.rs
index afec7a24b1785..98ae1a5832447 100644
--- a/src/librustc_data_structures/obligation_forest/mod.rs
+++ b/src/librustc_data_structures/obligation_forest/mod.rs
@@ -353,9 +353,9 @@ impl<O: ForestObligation> ObligationForest<O> {
     /// Converts all remaining obligations to the given error.
     pub fn to_errors<E: Clone>(&mut self, error: E) -> Vec<Error<O, E>> {
         let mut errors = vec![];
-        for (i, node) in self.nodes.iter().enumerate() {
+        for (index, node) in self.nodes.iter().enumerate() {
             if let NodeState::Pending = node.state.get() {
-                let backtrace = self.error_at(i);
+                let backtrace = self.error_at(index);
                 errors.push(Error {
                     error: error.clone(),
                     backtrace,
@@ -399,10 +399,10 @@ impl<O: ForestObligation> ObligationForest<O> {
         let mut errors = vec![];
         let mut stalled = true;
 
-        for i in 0..self.nodes.len() {
-            let node = &mut self.nodes[i];
+        for index in 0..self.nodes.len() {
+            let node = &mut self.nodes[index];
 
-            debug!("process_obligations: node {} == {:?}", i, node);
+            debug!("process_obligations: node {} == {:?}", index, node);
 
             // `processor.process_obligation` can modify the predicate within
             // `node.obligation`, and that predicate is the key used for
@@ -414,7 +414,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                 _ => continue
             };
 
-            debug!("process_obligations: node {} got result {:?}", i, result);
+            debug!("process_obligations: node {} got result {:?}", index, result);
 
             match result {
                 ProcessResult::Unchanged => {
@@ -428,18 +428,18 @@ impl<O: ForestObligation> ObligationForest<O> {
                     for child in children {
                         let st = self.register_obligation_at(
                             child,
-                            Some(i)
+                            Some(index)
                         );
                         if let Err(()) = st {
                             // Error already reported - propagate it
                             // to our node.
-                            self.error_at(i);
+                            self.error_at(index);
                         }
                     }
                 }
                 ProcessResult::Error(err) => {
                     stalled = false;
-                    let backtrace = self.error_at(i);
+                    let backtrace = self.error_at(index);
                     errors.push(Error {
                         error: err,
                         backtrace,
@@ -483,14 +483,14 @@ impl<O: ForestObligation> ObligationForest<O> {
 
         debug!("process_cycles()");
 
-        for (i, node) in self.nodes.iter().enumerate() {
+        for (index, node) in self.nodes.iter().enumerate() {
             // For rustc-benchmarks/inflate-0.1.0 this state test is extremely
             // hot and the state is almost always `Pending` or `Waiting`. It's
             // a win to handle the no-op cases immediately to avoid the cost of
             // the function call.
             match node.state.get() {
                 NodeState::Waiting | NodeState::Pending | NodeState::Done | NodeState::Error => {},
-                _ => self.find_cycles_from_node(&mut stack, processor, i),
+                _ => self.find_cycles_from_node(&mut stack, processor, index),
             }
         }
 
@@ -500,19 +500,19 @@ impl<O: ForestObligation> ObligationForest<O> {
         self.scratch.replace(stack);
     }
 
-    fn find_cycles_from_node<P>(&self, stack: &mut Vec<usize>, processor: &mut P, i: usize)
+    fn find_cycles_from_node<P>(&self, stack: &mut Vec<usize>, processor: &mut P, index: usize)
         where P: ObligationProcessor<Obligation=O>
     {
-        let node = &self.nodes[i];
+        let node = &self.nodes[index];
         match node.state.get() {
             NodeState::OnDfsStack => {
-                let i = stack.iter().rposition(|n| *n == i).unwrap();
-                processor.process_backedge(stack[i..].iter().map(GetObligation(&self.nodes)),
+                let index = stack.iter().rposition(|&n| n == index).unwrap();
+                processor.process_backedge(stack[index..].iter().map(GetObligation(&self.nodes)),
                                            PhantomData);
             }
             NodeState::Success => {
                 node.state.set(NodeState::OnDfsStack);
-                stack.push(i);
+                stack.push(index);
                 for &index in node.dependents.iter() {
                     self.find_cycles_from_node(stack, processor, index);
                 }
@@ -531,19 +531,19 @@ impl<O: ForestObligation> ObligationForest<O> {
 
     /// Returns a vector of obligations for `p` and all of its
     /// ancestors, putting them into the error state in the process.
-    fn error_at(&self, mut i: usize) -> Vec<O> {
+    fn error_at(&self, mut index: usize) -> Vec<O> {
         let mut error_stack = self.scratch.replace(vec![]);
         let mut trace = vec![];
 
         loop {
-            let node = &self.nodes[i];
+            let node = &self.nodes[index];
             node.state.set(NodeState::Error);
             trace.push(node.obligation.clone());
             if node.has_parent {
                 // The first dependent is the parent, which is treated
                 // specially.
                 error_stack.extend(node.dependents.iter().skip(1));
-                i = node.dependents[0];
+                index = node.dependents[0];
             } else {
                 // No parent; treat all dependents non-specially.
                 error_stack.extend(node.dependents.iter());
@@ -551,8 +551,8 @@ impl<O: ForestObligation> ObligationForest<O> {
             }
         }
 
-        while let Some(i) = error_stack.pop() {
-            let node = &self.nodes[i];
+        while let Some(index) = error_stack.pop() {
+            let node = &self.nodes[index];
             match node.state.get() {
                 NodeState::Error => continue,
                 _ => node.state.set(NodeState::Error),
@@ -568,8 +568,8 @@ impl<O: ForestObligation> ObligationForest<O> {
     // This always-inlined function is for the hot call site.
     #[inline(always)]
     fn inlined_mark_neighbors_as_waiting_from(&self, node: &Node<O>) {
-        for &dependent in node.dependents.iter() {
-            self.mark_as_waiting_from(&self.nodes[dependent]);
+        for &index in node.dependents.iter() {
+            self.mark_as_waiting_from(&self.nodes[index]);
         }
     }
 
@@ -622,16 +622,16 @@ impl<O: ForestObligation> ObligationForest<O> {
         // Now move all popped nodes to the end. Try to keep the order.
         //
         // LOOP INVARIANT:
-        //     self.nodes[0..i - dead_nodes] are the first remaining nodes
-        //     self.nodes[i - dead_nodes..i] are all dead
-        //     self.nodes[i..] are unchanged
-        for i in 0..self.nodes.len() {
-            let node = &self.nodes[i];
+        //     self.nodes[0..index - dead_nodes] are the first remaining nodes
+        //     self.nodes[index - dead_nodes..index] are all dead
+        //     self.nodes[index..] are unchanged
+        for index in 0..self.nodes.len() {
+            let node = &self.nodes[index];
             match node.state.get() {
                 NodeState::Pending | NodeState::Waiting => {
                     if dead_nodes > 0 {
-                        self.nodes.swap(i, i - dead_nodes);
-                        node_rewrites[i] -= dead_nodes;
+                        self.nodes.swap(index, index - dead_nodes);
+                        node_rewrites[index] -= dead_nodes;
                     }
                 }
                 NodeState::Done => {
@@ -646,7 +646,7 @@ impl<O: ForestObligation> ObligationForest<O> {
                     } else {
                         self.done_cache.insert(node.obligation.as_predicate().clone());
                     }
-                    node_rewrites[i] = nodes_len;
+                    node_rewrites[index] = nodes_len;
                     dead_nodes += 1;
                 }
                 NodeState::Error => {
@@ -654,9 +654,9 @@ impl<O: ForestObligation> ObligationForest<O> {
                     // tests must come up with a different type on every type error they
                     // check against.
                     self.waiting_cache.remove(node.obligation.as_predicate());
-                    node_rewrites[i] = nodes_len;
+                    node_rewrites[index] = nodes_len;
                     dead_nodes += 1;
-                    self.insert_into_error_cache(i);
+                    self.insert_into_error_cache(index);
                 }
                 NodeState::OnDfsStack | NodeState::Success => unreachable!()
             }
@@ -697,18 +697,18 @@ impl<O: ForestObligation> ObligationForest<O> {
         let nodes_len = node_rewrites.len();
 
         for node in &mut self.nodes {
-            let mut i = 0;
-            while i < node.dependents.len() {
-                let new_i = node_rewrites[node.dependents[i]];
-                if new_i >= nodes_len {
-                    node.dependents.swap_remove(i);
-                    if i == 0 && node.has_parent {
+            let mut index = 0;
+            while index < node.dependents.len() {
+                let new_index = node_rewrites[node.dependents[index]];
+                if new_index >= nodes_len {
+                    node.dependents.swap_remove(index);
+                    if index == 0 && node.has_parent {
                         // We just removed the parent.
                         node.has_parent = false;
                     }
                 } else {
-                    node.dependents[i] = new_i;
-                    i += 1;
+                    node.dependents[index] = new_index;
+                    index += 1;
                 }
             }
         }
@@ -716,11 +716,11 @@ impl<O: ForestObligation> ObligationForest<O> {
         // This updating of `self.waiting_cache` is necessary because the
         // removal of nodes within `compress` can fail. See above.
         self.waiting_cache.retain(|_predicate, index| {
-            let new_i = node_rewrites[*index];
-            if new_i >= nodes_len {
+            let new_index = node_rewrites[*index];
+            if new_index >= nodes_len {
                 false
             } else {
-                *index = new_i;
+                *index = new_index;
                 true
             }
         });

From daafeb35b731a599fc8b6c4cf37b81f838dae319 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 17 Sep 2019 08:58:51 +0200
Subject: [PATCH 822/943] document Miri error categories

---
 src/librustc/mir/interpret/error.rs | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 09c822f7508a0..2975944c7fba7 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -313,6 +313,9 @@ impl<O: fmt::Debug> fmt::Debug for PanicInfo<O> {
     }
 }
 
+/// Error information for when the program we executed turned out not to actually be a valid
+/// program. This cannot happen in stand-alone Miri, but it can happen during CTFE/ConstProp
+/// where we work on generic code or execution does not have all information available.
 #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum InvalidProgramInfo<'tcx> {
     /// Resolution can fail if we are in a too generic context.
@@ -342,6 +345,7 @@ impl fmt::Debug for InvalidProgramInfo<'tcx> {
     }
 }
 
+/// Error information for when the program caused Undefined Behavior.
 #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum UndefinedBehaviorInfo {
     /// Free-form case. Only for errors that are never caught!
@@ -364,12 +368,19 @@ impl fmt::Debug for UndefinedBehaviorInfo {
     }
 }
 
+/// Error information for when the program did something that might (or might not) be correct
+/// to do according to the Rust spec, but due to limitations in the interpreter, the
+/// operation could not be carried out. These limitations can differ between CTFE and the
+/// Miri engine, e.g., CTFE does not support casting pointers to "real" integers.
+///
+/// Currently, we also use this as fall-back error kind for errors that have not been
+/// categorized yet.
 #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum UnsupportedOpInfo<'tcx> {
     /// Free-form case. Only for errors that are never caught!
     Unsupported(String),
 
-    // -- Everything below is not classified yet --
+    // -- Everything below is not categorized yet --
     FunctionAbiMismatch(Abi, Abi),
     FunctionArgMismatch(Ty<'tcx>, Ty<'tcx>),
     FunctionRetMismatch(Ty<'tcx>, Ty<'tcx>),
@@ -536,6 +547,8 @@ impl fmt::Debug for UnsupportedOpInfo<'tcx> {
     }
 }
 
+/// Error information for when the program exhausted the resources granted to it
+/// by the interpreter.
 #[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub enum ResourceExhaustionInfo {
     /// The stack grew too big.

From e8d858ef3c52dcbdc7091e5cd19ecca0c36a0428 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Mon, 16 Sep 2019 11:34:27 +0200
Subject: [PATCH 823/943] rename Allocation::retag -> with_tags_and_extra

---
 src/librustc/mir/interpret/allocation.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index 755cda792ba79..15e6cb6bcabae 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -130,9 +130,9 @@ impl<Tag> Allocation<Tag> {
     }
 }
 
-impl Allocation<()> {
+impl Allocation<(), ()> {
     /// Add Tag and Extra fields
-    pub fn retag<T, E>(
+    pub fn with_tags_and_extra<T, E>(
         self,
         mut tagger: impl FnMut(AllocId) -> T,
         extra: E,

From a7a6dedfe661a6d9d181afeb0fbaa894fcb7362b Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro@pietroalbini.org>
Date: Tue, 17 Sep 2019 09:58:55 +0200
Subject: [PATCH 824/943] Revert "Rollup merge of #64451 -
 RalfJung:miri-manifest, r=pietroalbini"

This reverts commit 7975973e2b806a7ee8e54b40f9e774528a777e31, reversing
changes made to f0320e54c7c2c923e2e05996ac1d74f781115bbc.
---
 Cargo.lock                           |  2 --
 src/bootstrap/dist.rs                | 14 +++-----
 src/tools/build-manifest/Cargo.toml  |  2 --
 src/tools/build-manifest/src/main.rs | 54 +++-------------------------
 4 files changed, 9 insertions(+), 63 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index b717460e5d427..326f3b10b4196 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -201,9 +201,7 @@ dependencies = [
 name = "build-manifest"
 version = "0.1.0"
 dependencies = [
- "reqwest",
  "serde",
- "serde_json",
  "toml",
 ]
 
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 076bcd878df71..500d5766a899e 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -2000,8 +2000,6 @@ impl Step for HashSign {
     }
 
     fn run(self, builder: &Builder<'_>) {
-        // This gets called by `promote-release`
-        // (https://github.com/rust-lang/rust-central-station/tree/master/promote-release).
         let mut cmd = builder.tool_cmd(Tool::BuildManifest);
         if builder.config.dry_run {
             return;
@@ -2012,14 +2010,10 @@ impl Step for HashSign {
         let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| {
             panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
         });
-        let pass = if env::var("BUILD_MANIFEST_DISABLE_SIGNING").is_err() {
-            let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
-                panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
-            });
-            t!(fs::read_to_string(&file))
-        } else {
-            String::new()
-        };
+        let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
+            panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
+        });
+        let pass = t!(fs::read_to_string(&file));
 
         let today = output(Command::new("date").arg("+%Y-%m-%d"));
 
diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml
index 63ae445f99b60..c364479d8db13 100644
--- a/src/tools/build-manifest/Cargo.toml
+++ b/src/tools/build-manifest/Cargo.toml
@@ -7,5 +7,3 @@ edition = "2018"
 [dependencies]
 toml = "0.5"
 serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-reqwest = "0.9"
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index c2d642bb136be..9ffa9391c820b 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -1,19 +1,12 @@
-//! Build a dist manifest, hash and sign everything.
-//! This gets called by `promote-release`
-//! (https://github.com/rust-lang/rust-central-station/tree/master/promote-release)
-//! via `x.py dist hash-and-sign`; the cmdline arguments are set up
-//! by rustbuild (in `src/bootstrap/dist.rs`).
-
 use toml;
 use serde::Serialize;
 
 use std::collections::BTreeMap;
 use std::env;
 use std::fs;
-use std::io::{self, Read, Write, BufRead, BufReader};
+use std::io::{self, Read, Write};
 use std::path::{PathBuf, Path};
 use std::process::{Command, Stdio};
-use std::collections::HashMap;
 
 static HOSTS: &[&str] = &[
     "aarch64-unknown-linux-gnu",
@@ -153,9 +146,6 @@ static MINGW: &[&str] = &[
     "x86_64-pc-windows-gnu",
 ];
 
-static TOOLSTATE: &str =
-    "https://raw.githubusercontent.com/rust-lang-nursery/rust-toolstate/master/history/linux.tsv";
-
 #[derive(Serialize)]
 #[serde(rename_all = "kebab-case")]
 struct Manifest {
@@ -280,7 +270,6 @@ fn main() {
     // Do not ask for a passphrase while manually testing
     let mut passphrase = String::new();
     if should_sign {
-        // `x.py` passes the passphrase via stdin.
         t!(io::stdin().read_to_string(&mut passphrase));
     }
 
@@ -364,7 +353,6 @@ impl Builder {
         self.lldb_git_commit_hash = self.git_commit_hash("lldb", "x86_64-unknown-linux-gnu");
         self.miri_git_commit_hash = self.git_commit_hash("miri", "x86_64-unknown-linux-gnu");
 
-        self.check_toolstate();
         self.digest_and_sign();
         let manifest = self.build_manifest();
         self.write_channel_files(&self.rust_release, &manifest);
@@ -374,37 +362,6 @@ impl Builder {
         }
     }
 
-    /// If a tool does not pass its tests, don't ship it.
-    /// Right now, we do this only for Miri.
-    fn check_toolstate(&mut self) {
-        // Get the toolstate for this rust revision.
-        let rev = self.rust_git_commit_hash.as_ref().expect("failed to determine rust git hash");
-        let toolstates = reqwest::get(TOOLSTATE).expect("failed to get toolstates");
-        let toolstates = BufReader::new(toolstates);
-        let toolstate = toolstates.lines()
-            .find_map(|line| {
-                let line = line.expect("failed to read toolstate lines");
-                let mut pieces = line.splitn(2, '\t');
-                let commit = pieces.next().expect("malformed toolstate line");
-                if commit != rev {
-                    // Not the right commit.
-                    return None;
-                }
-                // Return the 2nd piece, the JSON.
-                Some(pieces.next().expect("malformed toolstate line").to_owned())
-            })
-            .expect("failed to find toolstate for rust commit");
-        let toolstate: HashMap<String, String> =
-            serde_json::from_str(&toolstate).expect("toolstate is malformed JSON");
-        // Mark some tools as missing based on toolstate.
-        if toolstate.get("miri").map(|s| &*s as &str) != Some("test-pass") {
-            println!("Miri tests are not passing, removing component");
-            self.miri_version = None;
-            self.miri_git_commit_hash = None;
-        }
-    }
-
-    /// Hash all files, compute their signatures, and collect the hashes in `self.digests`.
     fn digest_and_sign(&mut self) {
         for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
             let filename = file.file_name().unwrap().to_str().unwrap();
@@ -575,20 +532,19 @@ impl Builder {
             .as_ref()
             .cloned()
             .map(|version| (version, true))
-            .unwrap_or_default(); // `is_present` defaults to `false` here.
+            .unwrap_or_default();
 
-        // Miri is nightly-only; never ship it for other trains.
+        // miri needs to build std with xargo, which doesn't allow stable/beta:
+        // <https://github.com/japaric/xargo/pull/204#issuecomment-374888868>
         if pkgname == "miri-preview" && self.rust_release != "nightly" {
-            is_present = false; // Pretend the component is entirely missing.
+            is_present = false; // ignore it
         }
 
         let targets = targets.iter().map(|name| {
             if is_present {
-                // The component generally exists, but it might still be missing for this target.
                 let filename = self.filename(pkgname, name);
                 let digest = match self.digests.remove(&filename) {
                     Some(digest) => digest,
-                    // This component does not exist for this target -- skip it.
                     None => return (name.to_string(), Target::unavailable()),
                 };
                 let xz_filename = filename.replace(".tar.gz", ".tar.xz");

From 123f129f795a5f55a0094263f72d56249656145e Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Tue, 17 Sep 2019 04:50:40 -0400
Subject: [PATCH 825/943] apply nits from centril

Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
---
 ...rop-order-for-temporary-in-tail-return-expr.rs | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/test/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs b/src/test/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs
index e250506cdf0af..e40acff6dc117 100644
--- a/src/test/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs
+++ b/src/test/ui/async-await/drop-order/drop-order-for-temporary-in-tail-return-expr.rs
@@ -4,9 +4,10 @@
 
 #![allow(unused_variables)]
 
-// Test that the drop order for parameters in a fn and async fn matches up. Also test that
-// parameters (used or unused) are not dropped until the async fn completes execution.
-// See also #54716.
+// Test the drop order for parameters relative to local variables and
+// temporaries created in the tail return expression of the function
+// body. In particular, check that this drop order is the same between
+// a `async fn` and an ordinary `fn`. See #64512.
 
 extern crate arc_wake;
 
@@ -39,13 +40,13 @@ impl Drop for D {
     }
 }
 
-/// Check drop order of temporary "temp" as compared to x, y, and z.
+/// Check drop order of temporary "temp" as compared to `x`, `y`, and `z`.
 ///
 /// Expected order:
-/// - z
+/// - `z`
 /// - temp
-/// - y
-/// - x
+/// - `y`
+/// - `x`
 async fn foo_async(x: D, _y: D) {
     let l = x.1.clone();
     let z = D("z", l.clone());

From 0a11e80fa83cd3ace4ca306531d84a6c8138d549 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Tue, 17 Sep 2019 04:39:21 -0400
Subject: [PATCH 826/943] introduce `lower_block_expr` convenience function,
 and use it

---
 src/librustc/hir/lowering.rs      |  7 +++++++
 src/librustc/hir/lowering/expr.rs | 11 +++--------
 src/librustc/hir/lowering/item.rs |  8 ++------
 3 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 492029eed0570..48f7fc4446505 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -2708,6 +2708,13 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
+    /// Lowers a block directly to an expression, presuming that it
+    /// has no attributes and is not targeted by a `break`.
+    fn lower_block_expr(&mut self, b: &Block) -> hir::Expr {
+        let block = self.lower_block(b, false);
+        self.expr_block(block, ThinVec::new())
+    }
+
     fn lower_pat(&mut self, p: &Pat) -> P<hir::Pat> {
         let node = match p.node {
             PatKind::Wild => hir::PatKind::Wild,
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index 87462e94f430d..ef0bef9d569a4 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -90,10 +90,7 @@ impl LoweringContext<'_> {
             ),
             ExprKind::Async(capture_clause, closure_node_id, ref block) => {
                 self.make_async_expr(capture_clause, closure_node_id, None, block.span, |this| {
-                    this.with_new_scopes(|this| {
-                        let block = this.lower_block(block, false);
-                        this.expr_block(block, ThinVec::new())
-                    })
+                    this.with_new_scopes(|this| this.lower_block_expr(block))
                 })
             }
             ExprKind::Await(ref expr) => self.lower_expr_await(e.span, expr),
@@ -284,8 +281,7 @@ impl LoweringContext<'_> {
         let else_arm = self.arm(hir_vec![else_pat], P(else_expr));
 
         // Handle then + scrutinee:
-        let then_blk = self.lower_block(then, false);
-        let then_expr = self.expr_block(then_blk, ThinVec::new());
+        let then_expr = self.lower_block_expr(then);
         let (then_pat, scrutinee, desugar) = match cond.node {
             // `<pat> => <then>`:
             ExprKind::Let(ref pat, ref scrutinee) => {
@@ -335,8 +331,7 @@ impl LoweringContext<'_> {
         };
 
         // Handle then + scrutinee:
-        let then_blk = self.lower_block(body, false);
-        let then_expr = self.expr_block(then_blk, ThinVec::new());
+        let then_expr = self.lower_block_expr(body);
         let (then_pat, scrutinee, desugar, source) = match cond.node {
             ExprKind::Let(ref pat, ref scrutinee) => {
                 // to:
diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 1e621f7fdaea6..9ac3a6bdc87af 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -1071,10 +1071,7 @@ impl LoweringContext<'_> {
     }
 
     fn lower_fn_body_block(&mut self, decl: &FnDecl, body: &Block) -> hir::BodyId {
-        self.lower_fn_body(decl, |this| {
-            let body = this.lower_block(body, false);
-            this.expr_block(body, ThinVec::new())
-        })
+        self.lower_fn_body(decl, |this| this.lower_block_expr(body))
     }
 
     pub(super) fn lower_const_body(&mut self, expr: &Expr) -> hir::BodyId {
@@ -1220,8 +1217,7 @@ impl LoweringContext<'_> {
                 CaptureBy::Value, closure_id, None, body.span,
                 |this| {
                     // Create a block from the user's function body:
-                    let user_body = this.lower_block(body, false);
-                    let user_body = this.expr_block(user_body, ThinVec::new());
+                    let user_body = this.lower_block_expr(body);
 
                     // Transform into `drop-temps { <user-body> }`, an expression:
                     let desugared_span = this.mark_span_with_reason(

From 716b2bcfb36111ea8afb49d289ddfba2b62a7b8e Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Tue, 17 Sep 2019 04:44:35 -0400
Subject: [PATCH 827/943] use drop-temps { .. } pseudo-notation

DropTemps(...) looks like a function, this looks like wacko special stuff
---
 src/librustc/hir/lowering/expr.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index ef0bef9d569a4..990728fa0e680 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -351,7 +351,7 @@ impl LoweringContext<'_> {
                 //
                 // ```
                 // 'label: loop {
-                //     match DropTemps($cond) {
+                //     match drop-temps { $cond } {
                 //         true => $body,
                 //         _ => break,
                 //     }

From 2d8b10f63c394c99f2268de3132086bc72ee5a2b Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Tue, 17 Sep 2019 04:47:54 -0400
Subject: [PATCH 828/943] adjust larger comment to include the body

---
 src/librustc/hir/lowering/item.rs | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/librustc/hir/lowering/item.rs b/src/librustc/hir/lowering/item.rs
index 9ac3a6bdc87af..61be40a6b907f 100644
--- a/src/librustc/hir/lowering/item.rs
+++ b/src/librustc/hir/lowering/item.rs
@@ -1099,8 +1099,7 @@ impl LoweringContext<'_> {
             // from:
             //
             //     async fn foo(<pattern>: <ty>, <pattern>: <ty>, <pattern>: <ty>) {
-            //       async move {
-            //       }
+            //         <body>
             //     }
             //
             // into:
@@ -1113,11 +1112,19 @@ impl LoweringContext<'_> {
             //         let <pattern> = __arg1;
             //         let __arg0 = __arg0;
             //         let <pattern> = __arg0;
+            //         drop-temps { <body> } // see comments later in fn for details
             //       }
             //     }
             //
             // If `<pattern>` is a simple ident, then it is lowered to a single
             // `let <pattern> = <pattern>;` statement as an optimization.
+            //
+            // Note that the body is embedded in `drop-temps`; an
+            // equivalent desugaring would be `return { <body>
+            // };`. The key point is that we wish to drop all the
+            // let-bound variables and temporaries created in the body
+            // (and its tail expression!) before we drop the
+            // parameters (c.f. rust-lang/rust#64512).
             for (index, parameter) in decl.inputs.iter().enumerate() {
                 let parameter = this.lower_param(parameter);
                 let span = parameter.pat.span;
@@ -1231,7 +1238,7 @@ impl LoweringContext<'_> {
                         ThinVec::new(),
                     );
 
-                    // Create a block like
+                    // As noted above, create the final block like
                     //
                     // ```
                     // {
@@ -1240,13 +1247,6 @@ impl LoweringContext<'_> {
                     //   drop-temps { <user-body> }
                     // }
                     // ```
-                    //
-                    // This construction is carefully calibrated to
-                    // get the drop-order correct.  In particular, the
-                    // drop-temps ensures that any temporaries in the
-                    // tail expression of `<user-body>` are dropped
-                    // *before* the parameters are dropped (see
-                    // rust-lang/rust#64512).
                     let body = this.block_all(
                         desugared_span,
                         statements.into(),

From f4f136e67bedc098bea5e5dce6b286611908355b Mon Sep 17 00:00:00 2001
From: Arno Haase <arno.haase@haase-consulting.com>
Date: Tue, 17 Sep 2019 12:09:07 +0200
Subject: [PATCH 829/943] newly phrased documentation for spin loop hints

---
 src/libcore/hint.rs        | 22 +++++-----------------
 src/libcore/sync/atomic.rs | 27 +++++++++++++++------------
 2 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 53c576abb7998..3ea8b31fda6d0 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -49,28 +49,16 @@ pub unsafe fn unreachable_unchecked() -> ! {
     intrinsics::unreachable()
 }
 
-/// Signals the processor that it is entering a busy-wait spin-loop.
+/// Emits a machine instruction hinting to the processor that it is running in busy-wait
+/// spin-loop ("spin lock").
 ///
-/// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving
-/// power or switching hyper-threads.
-///
-/// This function is different than [`std::thread::yield_now`] which directly yields to the
-/// system's scheduler, whereas `spin_loop` only signals the processor that it is entering a
-/// busy-wait spin-loop without yielding control to the system's scheduler.
-///
-/// Using a busy-wait spin-loop with `spin_loop` is ideally used in situations where a
-/// contended lock is held by another thread executed on a different CPU or core and where the
-/// waiting times are relatively small. Because entering busy-wait spin-loop does not trigger the
-/// system's scheduler, no overhead for switching threads occurs. However, if the thread holding the
-/// contended lock is running on the same CPU or core, the spin-loop is likely to occupy an entire
-/// CPU slice before switching to the thread that holds the lock. If the contending lock is held by
-/// a thread on the same CPU or core or if the waiting times for acquiring the lock are longer, it
-/// is often better to use [`std::thread::yield_now`].
+/// For a discussion of different locking strategies and their trade-offs, see
+/// [`core::sync::atomic::spin_loop_hint`].
 ///
 /// **Note**: On platforms that do not support receiving spin-loop hints this function does not
 /// do anything at all.
 ///
-/// [`std::thread::yield_now`]: ../../std/thread/fn.yield_now.html
+/// [`core::sync::atomic::spin_loop_hint`]: ./sync/atomic/fn.spin_loop_hint.html
 #[inline]
 #[unstable(feature = "renamed_spin_loop", issue = "55002")]
 pub fn spin_loop() {
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 38339996090b1..63ee9a42a0f72 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -124,28 +124,31 @@ use crate::fmt;
 
 use crate::hint::spin_loop;
 
-/// Signals the processor that it is entering a busy-wait spin-loop.
+/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
 ///
 /// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving
 /// power or switching hyper-threads.
 ///
-/// This function is different than [`std::thread::yield_now`] which directly yields to the
-/// system's scheduler, whereas `spin_loop_hint` only signals the processor that it is entering a
-/// busy-wait spin-loop without yielding control to the system's scheduler.
+/// This function is different from [`std::thread::yield_now`] which directly yields to the
+/// system's scheduler, whereas `spin_loop_hint` does not interact with the operating system.
 ///
-/// Using a busy-wait spin-loop with `spin_loop_hint` is ideally used in situations where a
-/// contended lock is held by another thread executed on a different CPU or core and where the
-/// waiting times are relatively small. Because entering busy-wait spin-loop does not trigger the
-/// system's scheduler, no overhead for switching threads occurs. However, if the thread holding the
-/// contended lock is running on the same CPU or core, the spin-loop is likely to occupy an entire
-/// CPU slice before switching to the thread that holds the lock. If the contending lock is held by
-/// a thread on the same CPU or core or if the waiting times for acquiring the lock are longer, it
-/// is often better to use [`std::thread::yield_now`].
+/// Spin locks can be very efficient for short lock durations because they do not involve context
+/// switches or interaction with the operating system. For long lock durations they become wasteful
+/// however because they use CPU cycles for the entire lock duration, and using a
+/// [`std::sync::Mutex`] is likely the better approach. If actively spinning for a long time is
+/// required, e.g. because code polls a non-blocking API, calling [`std::thread::yield_now`]
+/// or [`std::thread::sleep`] may be the best option.
+///
+/// **Note**: Spin locks are based on the underlying assumption that another thread will release
+/// the lock 'soon'. In order for this to work, that other thread must run on a different CPU or
+/// core (at least potentially). Spin locks do not work efficiently on single CPU / core platforms.
 ///
 /// **Note**: On platforms that do not support receiving spin-loop hints this function does not
 /// do anything at all.
 ///
 /// [`std::thread::yield_now`]: ../../../std/thread/fn.yield_now.html
+/// [`std::thread::sleep`]: ../../../std/thread/fn.sleep.html
+/// [`std::sync::Mutex`]: ../../../std/sync/Mutex.html
 #[inline]
 #[stable(feature = "spin_loop_hint", since = "1.24.0")]
 pub fn spin_loop_hint() {

From 686170e87de3493e86fee3a74e10263026fabbbb Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 17 Sep 2019 12:31:49 +0200
Subject: [PATCH 830/943] update miri

---
 src/tools/miri | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/miri b/src/tools/miri
index d88138723780d..130f9488d3b86 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit d88138723780d11ca2c09560111223dc20b9d5f3
+Subproject commit 130f9488d3b861e02c9282b686eec717e30912cf

From 522f4e1f3e69a29ab3772df877f2e2e30f986256 Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Tue, 17 Sep 2019 19:41:12 +0900
Subject: [PATCH 831/943] Add an example to Pin::as_mut

---
 src/libcore/pin.rs | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index be59e830beda3..e8d63b8c3130b 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -584,6 +584,27 @@ impl<P: DerefMut> Pin<P> {
     /// the pointee cannot move after `Pin<Pointer<T>>` got created.
     /// "Malicious" implementations of `Pointer::DerefMut` are likewise
     /// ruled out by the contract of `Pin::new_unchecked`.
+    ///
+    /// This method is useful when doing multiple calls to functions that consume the pinned type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::pin::Pin;
+    ///
+    /// # struct Type {}
+    /// impl Type {
+    ///     fn method(self: Pin<&mut Self>) {
+    ///         // do something
+    ///     }
+    ///
+    ///     fn call_method_twice(mut self: Pin<&mut Self>) {
+    ///         // `method` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`.
+    ///         self.as_mut().method();
+    ///         self.as_mut().method();
+    ///     }
+    /// }
+    /// ```
     #[stable(feature = "pin", since = "1.33.0")]
     #[inline(always)]
     pub fn as_mut(&mut self) -> Pin<&mut P::Target> {

From a22e9ee8d0801f9738533b76a492e94065767cbc Mon Sep 17 00:00:00 2001
From: Taiki Endo <te316e89@gmail.com>
Date: Tue, 17 Sep 2019 20:02:48 +0900
Subject: [PATCH 832/943] Update src/libcore/pin.rs

Co-Authored-By: Ralf Jung <post@ralfj.de>
---
 src/libcore/pin.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index e8d63b8c3130b..1dc6d54b08a5a 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -587,7 +587,7 @@ impl<P: DerefMut> Pin<P> {
     ///
     /// This method is useful when doing multiple calls to functions that consume the pinned type.
     ///
-    /// # Examples
+    /// # Example
     ///
     /// ```
     /// use std::pin::Pin;

From cdd805506e7a01d60906f8b153afb697d687609d Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 7 Sep 2019 09:57:11 -0400
Subject: [PATCH 833/943] Replace DiagnosticBuilder with Diagnostic when
 emitting error

---
 src/librustc/session/mod.rs                   | 14 +++++++---
 src/librustc_codegen_ssa/back/write.rs        |  4 +--
 src/librustc_driver/lib.rs                    |  1 +
 .../annotate_snippet_emitter_writer.rs        | 12 ++++++---
 src/librustc_errors/emitter.rs                | 20 +++++++++-----
 src/librustc_errors/lib.rs                    |  3 ++-
 src/librustdoc/core.rs                        |  2 ++
 src/librustdoc/test.rs                        |  2 +-
 src/libsyntax/json.rs                         | 26 +++++++++++++------
 src/libsyntax/parse/lexer/tests.rs            |  1 +
 src/libsyntax/tests.rs                        |  1 +
 11 files changed, 60 insertions(+), 26 deletions(-)

diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 8656ebb2e6d72..af9cb5a0941e5 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -1040,6 +1040,7 @@ fn default_emitter(
     source_map: &Lrc<source_map::SourceMap>,
     emitter_dest: Option<Box<dyn Write + Send>>,
 ) -> Box<dyn Emitter + sync::Send> {
+    let external_macro_backtrace = sopts.debugging_opts.external_macro_backtrace;
     match (sopts.error_format, emitter_dest) {
         (config::ErrorOutputType::HumanReadable(kind), dst) => {
             let (short, color_config) = kind.unzip();
@@ -1048,6 +1049,7 @@ fn default_emitter(
                 let emitter = AnnotateSnippetEmitterWriter::new(
                     Some(source_map.clone()),
                     short,
+                    external_macro_backtrace,
                 );
                 Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing))
             } else {
@@ -1058,6 +1060,7 @@ fn default_emitter(
                         short,
                         sopts.debugging_opts.teach,
                         sopts.debugging_opts.terminal_width,
+                        external_macro_backtrace,
                     ),
                     Some(dst) => EmitterWriter::new(
                         dst,
@@ -1066,6 +1069,7 @@ fn default_emitter(
                         false, // no teach messages when writing to a buffer
                         false, // no colors when writing to a buffer
                         None,  // no terminal width
+                        external_macro_backtrace,
                     ),
                 };
                 Box::new(emitter.ui_testing(sopts.debugging_opts.ui_testing))
@@ -1077,6 +1081,7 @@ fn default_emitter(
                 source_map.clone(),
                 pretty,
                 json_rendered,
+                external_macro_backtrace,
             ).ui_testing(sopts.debugging_opts.ui_testing),
         ),
         (config::ErrorOutputType::Json { pretty, json_rendered }, Some(dst)) => Box::new(
@@ -1086,6 +1091,7 @@ fn default_emitter(
                 source_map.clone(),
                 pretty,
                 json_rendered,
+                external_macro_backtrace,
             ).ui_testing(sopts.debugging_opts.ui_testing),
         ),
     }
@@ -1382,10 +1388,10 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
     let emitter: Box<dyn Emitter + sync::Send> = match output {
         config::ErrorOutputType::HumanReadable(kind) => {
             let (short, color_config) = kind.unzip();
-            Box::new(EmitterWriter::stderr(color_config, None, short, false, None))
+            Box::new(EmitterWriter::stderr(color_config, None, short, false, None, false))
         }
         config::ErrorOutputType::Json { pretty, json_rendered } =>
-            Box::new(JsonEmitter::basic(pretty, json_rendered)),
+            Box::new(JsonEmitter::basic(pretty, json_rendered, false)),
     };
     let handler = errors::Handler::with_emitter(true, None, emitter);
     handler.emit(&MultiSpan::new(), msg, errors::Level::Fatal);
@@ -1396,10 +1402,10 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
     let emitter: Box<dyn Emitter + sync::Send> = match output {
         config::ErrorOutputType::HumanReadable(kind) => {
             let (short, color_config) = kind.unzip();
-            Box::new(EmitterWriter::stderr(color_config, None, short, false, None))
+            Box::new(EmitterWriter::stderr(color_config, None, short, false, None, false))
         }
         config::ErrorOutputType::Json { pretty, json_rendered } =>
-            Box::new(JsonEmitter::basic(pretty, json_rendered)),
+            Box::new(JsonEmitter::basic(pretty, json_rendered, false)),
     };
     let handler = errors::Handler::with_emitter(true, None, emitter);
     handler.emit(&MultiSpan::new(), msg, errors::Level::Warning);
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index eec098426239c..38a0818d290bd 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -22,7 +22,7 @@ use rustc::util::common::{time_depth, set_time_depth, print_time_passes_entry};
 use rustc::util::profiling::SelfProfiler;
 use rustc_fs_util::link_or_copy;
 use rustc_data_structures::svh::Svh;
-use rustc_errors::{Handler, Level, DiagnosticBuilder, FatalError, DiagnosticId};
+use rustc_errors::{Handler, Level, FatalError, DiagnosticId};
 use rustc_errors::emitter::{Emitter};
 use rustc_target::spec::MergeFunctions;
 use syntax::attr;
@@ -1725,7 +1725,7 @@ impl SharedEmitter {
 }
 
 impl Emitter for SharedEmitter {
-    fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
+    fn emit_diagnostic(&mut self, db: &rustc_errors::Diagnostic) {
         drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
             msg: db.message(),
             code: db.code.clone(),
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 8c5d8536c32fa..3a09f459e9c1f 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -1196,6 +1196,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
         false,
         false,
         None,
+        false,
     ));
     let handler = errors::Handler::with_emitter(true, None, emitter);
 
diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs
index c626dd0434d52..0281d10fd930e 100644
--- a/src/librustc_errors/annotate_snippet_emitter_writer.rs
+++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs
@@ -7,7 +7,7 @@
 
 use syntax_pos::{SourceFile, MultiSpan, Loc};
 use crate::{
-    Level, CodeSuggestion, DiagnosticBuilder, Emitter,
+    Level, CodeSuggestion, Diagnostic, Emitter,
     SourceMapperDyn, SubDiagnostic, DiagnosticId
 };
 use crate::emitter::FileWithAnnotatedLines;
@@ -25,11 +25,13 @@ pub struct AnnotateSnippetEmitterWriter {
     short_message: bool,
     /// If true, will normalize line numbers with `LL` to prevent noise in UI test diffs.
     ui_testing: bool,
+
+    external_macro_backtrace: bool,
 }
 
 impl Emitter for AnnotateSnippetEmitterWriter {
     /// The entry point for the diagnostics generation
-    fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
+    fn emit_diagnostic(&mut self, db: &Diagnostic) {
         let mut children = db.children.clone();
         let (mut primary_span, suggestions) = self.primary_span_formatted(&db);
 
@@ -37,7 +39,7 @@ impl Emitter for AnnotateSnippetEmitterWriter {
                                           &mut primary_span,
                                           &mut children,
                                           &db.level,
-                                          db.handler().flags.external_macro_backtrace);
+                                          self.external_macro_backtrace);
 
         self.emit_messages_default(&db.level,
                                    db.message(),
@@ -163,12 +165,14 @@ impl<'a>  DiagnosticConverter<'a> {
 impl AnnotateSnippetEmitterWriter {
     pub fn new(
         source_map: Option<Lrc<SourceMapperDyn>>,
-        short_message: bool
+        short_message: bool,
+        external_macro_backtrace: bool,
     ) -> Self {
         Self {
             source_map,
             short_message,
             ui_testing: false,
+            external_macro_backtrace,
         }
     }
 
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 66608361c8d44..c5274c7e99a51 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -12,7 +12,7 @@ use Destination::*;
 use syntax_pos::{SourceFile, Span, MultiSpan};
 
 use crate::{
-    Level, CodeSuggestion, DiagnosticBuilder, SubDiagnostic,
+    Level, CodeSuggestion, Diagnostic, SubDiagnostic,
     SuggestionStyle, SourceMapperDyn, DiagnosticId,
 };
 use crate::Level::Error;
@@ -52,10 +52,12 @@ impl HumanReadableErrorType {
         source_map: Option<Lrc<SourceMapperDyn>>,
         teach: bool,
         terminal_width: Option<usize>,
+        external_macro_backtrace: bool,
     ) -> EmitterWriter {
         let (short, color_config) = self.unzip();
         let color = color_config.suggests_using_colors();
-        EmitterWriter::new(dst, source_map, short, teach, color, terminal_width)
+        EmitterWriter::new(dst, source_map, short, teach, color, terminal_width,
+            external_macro_backtrace)
     }
 }
 
@@ -180,7 +182,7 @@ const ANONYMIZED_LINE_NUM: &str = "LL";
 /// Emitter trait for emitting errors.
 pub trait Emitter {
     /// Emit a structured diagnostic.
-    fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>);
+    fn emit_diagnostic(&mut self, db: &Diagnostic);
 
     /// Emit a notification that an artifact has been output.
     /// This is currently only supported for the JSON format,
@@ -204,7 +206,7 @@ pub trait Emitter {
     ///   we return the original `primary_span` and the original suggestions.
     fn primary_span_formatted<'a>(
         &mut self,
-        db: &'a DiagnosticBuilder<'_>
+        db: &'a Diagnostic
     ) -> (MultiSpan, &'a [CodeSuggestion]) {
         let mut primary_span = db.span.clone();
         if let Some((sugg, rest)) = db.suggestions.split_first() {
@@ -377,7 +379,7 @@ pub trait Emitter {
 }
 
 impl Emitter for EmitterWriter {
-    fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
+    fn emit_diagnostic(&mut self, db: &Diagnostic) {
         let mut children = db.children.clone();
         let (mut primary_span, suggestions) = self.primary_span_formatted(&db);
 
@@ -385,7 +387,7 @@ impl Emitter for EmitterWriter {
                                           &mut primary_span,
                                           &mut children,
                                           &db.level,
-                                          db.handler().flags.external_macro_backtrace);
+                                          self.external_macro_backtrace);
 
         self.emit_messages_default(&db.level,
                                    &db.styled_message(),
@@ -449,6 +451,8 @@ pub struct EmitterWriter {
     teach: bool,
     ui_testing: bool,
     terminal_width: Option<usize>,
+
+    external_macro_backtrace: bool,
 }
 
 #[derive(Debug)]
@@ -465,6 +469,7 @@ impl EmitterWriter {
         short_message: bool,
         teach: bool,
         terminal_width: Option<usize>,
+        external_macro_backtrace: bool,
     ) -> EmitterWriter {
         let dst = Destination::from_stderr(color_config);
         EmitterWriter {
@@ -474,6 +479,7 @@ impl EmitterWriter {
             teach,
             ui_testing: false,
             terminal_width,
+            external_macro_backtrace,
         }
     }
 
@@ -484,6 +490,7 @@ impl EmitterWriter {
         teach: bool,
         colored: bool,
         terminal_width: Option<usize>,
+        external_macro_backtrace: bool,
     ) -> EmitterWriter {
         EmitterWriter {
             dst: Raw(dst, colored),
@@ -492,6 +499,7 @@ impl EmitterWriter {
             teach,
             ui_testing: false,
             terminal_width,
+            external_macro_backtrace,
         }
     }
 
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index c1fba416d6433..4ff18578bca6a 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -383,7 +383,8 @@ impl Handler {
                                       cm: Option<Lrc<SourceMapperDyn>>,
                                       flags: HandlerFlags)
                                       -> Handler {
-        let emitter = Box::new(EmitterWriter::stderr(color_config, cm, false, false, None));
+        let emitter = Box::new(EmitterWriter::stderr(
+            color_config, cm, false, false, None, flags.external_macro_backtrace));
         Handler::with_emitter_and_flags(emitter, flags)
     }
 
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 57b016a08c2fe..010e4cf6cd0d5 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -193,6 +193,7 @@ pub fn new_handler(error_format: ErrorOutputType,
                     short,
                     sessopts.debugging_opts.teach,
                     sessopts.debugging_opts.terminal_width,
+                    false,
                 ).ui_testing(ui_testing)
             )
         },
@@ -205,6 +206,7 @@ pub fn new_handler(error_format: ErrorOutputType,
                     source_map,
                     pretty,
                     json_rendered,
+                    false,
                 ).ui_testing(ui_testing)
             )
         },
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 482c69c1ab5b5..424239c998237 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -401,7 +401,7 @@ pub fn make_test(s: &str,
         // Any errors in parsing should also appear when the doctest is compiled for real, so just
         // send all the errors that libsyntax emits directly into a `Sink` instead of stderr.
         let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
-        let emitter = EmitterWriter::new(box io::sink(), None, false, false, false, None);
+        let emitter = EmitterWriter::new(box io::sink(), None, false, false, false, None, false);
         // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
         let handler = Handler::with_emitter(false, None, box emitter);
         let sess = ParseSess::with_span_handler(handler, cm);
diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs
index ada46f7bc5a74..5cdea3aabbe11 100644
--- a/src/libsyntax/json.rs
+++ b/src/libsyntax/json.rs
@@ -12,7 +12,7 @@
 use crate::source_map::{SourceMap, FilePathMapping};
 
 use errors::registry::Registry;
-use errors::{DiagnosticBuilder, SubDiagnostic, CodeSuggestion, SourceMapper};
+use errors::{SubDiagnostic, CodeSuggestion, SourceMapper};
 use errors::{DiagnosticId, Applicability};
 use errors::emitter::{Emitter, HumanReadableErrorType};
 
@@ -32,6 +32,7 @@ pub struct JsonEmitter {
     pretty: bool,
     ui_testing: bool,
     json_rendered: HumanReadableErrorType,
+    external_macro_backtrace: bool,
 }
 
 impl JsonEmitter {
@@ -40,6 +41,7 @@ impl JsonEmitter {
         source_map: Lrc<SourceMap>,
         pretty: bool,
         json_rendered: HumanReadableErrorType,
+        external_macro_backtrace: bool,
     ) -> JsonEmitter {
         JsonEmitter {
             dst: Box::new(io::stderr()),
@@ -48,13 +50,18 @@ impl JsonEmitter {
             pretty,
             ui_testing: false,
             json_rendered,
+            external_macro_backtrace,
         }
     }
 
-    pub fn basic(pretty: bool, json_rendered: HumanReadableErrorType) -> JsonEmitter {
+    pub fn basic(
+        pretty: bool,
+        json_rendered: HumanReadableErrorType,
+        external_macro_backtrace: bool,
+    ) -> JsonEmitter {
         let file_path_mapping = FilePathMapping::empty();
         JsonEmitter::stderr(None, Lrc::new(SourceMap::new(file_path_mapping)),
-                            pretty, json_rendered)
+                            pretty, json_rendered, external_macro_backtrace)
     }
 
     pub fn new(
@@ -63,6 +70,7 @@ impl JsonEmitter {
         source_map: Lrc<SourceMap>,
         pretty: bool,
         json_rendered: HumanReadableErrorType,
+        external_macro_backtrace: bool,
     ) -> JsonEmitter {
         JsonEmitter {
             dst,
@@ -71,6 +79,7 @@ impl JsonEmitter {
             pretty,
             ui_testing: false,
             json_rendered,
+            external_macro_backtrace,
         }
     }
 
@@ -80,8 +89,8 @@ impl JsonEmitter {
 }
 
 impl Emitter for JsonEmitter {
-    fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) {
-        let data = Diagnostic::from_diagnostic_builder(db, self);
+    fn emit_diagnostic(&mut self, db: &errors::Diagnostic) {
+        let data = Diagnostic::from_errors_diagnostic(db, self);
         let result = if self.pretty {
             writeln!(&mut self.dst, "{}", as_pretty_json(&data))
         } else {
@@ -189,7 +198,7 @@ struct ArtifactNotification<'a> {
 }
 
 impl Diagnostic {
-    fn from_diagnostic_builder(db: &DiagnosticBuilder<'_>,
+    fn from_errors_diagnostic(db: &errors::Diagnostic,
                                je: &JsonEmitter)
                                -> Diagnostic {
         let sugg = db.suggestions.iter().map(|sugg| {
@@ -219,8 +228,9 @@ impl Diagnostic {
         }
         let buf = BufWriter::default();
         let output = buf.clone();
-        je.json_rendered.new_emitter(Box::new(buf), Some(je.sm.clone()), false, None)
-            .ui_testing(je.ui_testing).emit_diagnostic(db);
+        je.json_rendered.new_emitter(
+            Box::new(buf), Some(je.sm.clone()), false, None, je.external_macro_backtrace
+        ).ui_testing(je.ui_testing).emit_diagnostic(db);
         let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap();
         let output = String::from_utf8(output).unwrap();
 
diff --git a/src/libsyntax/parse/lexer/tests.rs b/src/libsyntax/parse/lexer/tests.rs
index c1ec41902e2be..de301b1fc499d 100644
--- a/src/libsyntax/parse/lexer/tests.rs
+++ b/src/libsyntax/parse/lexer/tests.rs
@@ -18,6 +18,7 @@ fn mk_sess(sm: Lrc<SourceMap>) -> ParseSess {
         false,
         false,
         None,
+        false,
     );
     ParseSess::with_span_handler(Handler::with_emitter(true, None, Box::new(emitter)), sm)
 }
diff --git a/src/libsyntax/tests.rs b/src/libsyntax/tests.rs
index 540881b0a5496..f510ac9273d09 100644
--- a/src/libsyntax/tests.rs
+++ b/src/libsyntax/tests.rs
@@ -147,6 +147,7 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &
             false,
             false,
             None,
+            false,
         );
         let handler = Handler::with_emitter(true, None, Box::new(emitter));
         handler.span_err(msp, "foo");

From 0b586b436d6ea2dddc213c18bf17f2314441c32f Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 7 Sep 2019 10:03:15 -0400
Subject: [PATCH 834/943] Take Diagnostic in Handler::emit_diagnostic

---
 src/librustc/session/config.rs            |  2 +-
 src/librustc_errors/diagnostic_builder.rs | 10 +---------
 src/librustc_errors/lib.rs                | 14 ++++++++------
 3 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 723855c7c29cf..5eda3df378126 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1855,7 +1855,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
 struct NullEmitter;
 
 impl errors::emitter::Emitter for NullEmitter {
-    fn emit_diagnostic(&mut self, _: &errors::DiagnosticBuilder<'_>) {}
+    fn emit_diagnostic(&mut self, _: &errors::Diagnostic) {}
 }
 
 // Converts strings provided as `--cfg [cfgspec]` into a `crate_cfg`.
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index 7b8902f125aee..25ffb146da756 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -99,17 +99,9 @@ impl<'a> DerefMut for DiagnosticBuilder<'a> {
 }
 
 impl<'a> DiagnosticBuilder<'a> {
-    pub fn handler(&self) -> &'a Handler{
-        self.0.handler
-    }
-
     /// Emit the diagnostic.
     pub fn emit(&mut self) {
-        if self.cancelled() {
-            return;
-        }
-
-        self.0.handler.emit_db(&self);
+        self.0.handler.emit_diagnostic(&self);
         self.cancel();
     }
 
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 4ff18578bca6a..11e2265cf3618 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -589,7 +589,7 @@ impl Handler {
     }
     fn delay_as_bug(&self, diagnostic: Diagnostic) {
         if self.flags.report_delayed_bugs {
-            DiagnosticBuilder::new_diagnostic(self, diagnostic.clone()).emit();
+            self.emit_diagnostic(&diagnostic);
         }
         self.delayed_span_bugs.borrow_mut().push(diagnostic);
     }
@@ -747,8 +747,10 @@ impl Handler {
         db.cancel();
     }
 
-    fn emit_db(&self, db: &DiagnosticBuilder<'_>) {
-        let diagnostic = &**db;
+    fn emit_diagnostic(&self, diagnostic: &Diagnostic) {
+        if diagnostic.cancelled() {
+            return;
+        }
 
         TRACK_DIAGNOSTICS.with(|track_diagnostics| {
             track_diagnostics.get()(diagnostic);
@@ -768,12 +770,12 @@ impl Handler {
         // Only emit the diagnostic if we haven't already emitted an equivalent
         // one:
         if self.emitted_diagnostics.borrow_mut().insert(diagnostic_hash) {
-            self.emitter.borrow_mut().emit_diagnostic(db);
-            if db.is_error() {
+            self.emitter.borrow_mut().emit_diagnostic(diagnostic);
+            if diagnostic.is_error() {
                 self.deduplicated_err_count.fetch_add(1, SeqCst);
             }
         }
-        if db.is_error() {
+        if diagnostic.is_error() {
             self.bump_err_count();
         }
     }

From 2a3930d43ced5204f53a6e1eebd741a81c4c1e9a Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 7 Sep 2019 10:20:56 -0400
Subject: [PATCH 835/943] Privatize DiagnosticBuilder constructors

---
 src/librustc/dep_graph/graph.rs           | 4 ++--
 src/librustc/ty/query/plumbing.rs         | 7 +++----
 src/librustc_errors/diagnostic_builder.rs | 5 +++--
 src/librustc_errors/lib.rs                | 5 ++---
 src/librustc_mir/borrow_check/mod.rs      | 2 +-
 src/librustc_typeck/check/writeback.rs    | 3 +--
 src/libsyntax/ext/proc_macro_server.rs    | 4 ++--
 src/libsyntax/lib.rs                      | 4 ++--
 src/libsyntax/parse/mod.rs                | 2 +-
 9 files changed, 17 insertions(+), 19 deletions(-)

diff --git a/src/librustc/dep_graph/graph.rs b/src/librustc/dep_graph/graph.rs
index 7eea336cbbfa1..e76a70350b33e 100644
--- a/src/librustc/dep_graph/graph.rs
+++ b/src/librustc/dep_graph/graph.rs
@@ -1,4 +1,4 @@
-use errors::{Diagnostic, DiagnosticBuilder};
+use errors::Diagnostic;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
@@ -819,7 +819,7 @@ impl DepGraph {
             let handle = tcx.sess.diagnostic();
 
             for diagnostic in diagnostics {
-                DiagnosticBuilder::new_diagnostic(handle, diagnostic).emit();
+                handle.emit_diagnostic(&diagnostic);
             }
 
             // Mark the node as green now that diagnostics are emitted
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index d199a26475be7..a1828bb5ab7a7 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -330,14 +330,13 @@ impl<'tcx> TyCtxt<'tcx> {
                 let mut i = 0;
 
                 while let Some(query) = current_query {
-                    let mut db = DiagnosticBuilder::new(icx.tcx.sess.diagnostic(),
-                        Level::FailureNote,
+                    let mut diag = Diagnostic::new(Level::FailureNote,
                         &format!("#{} [{}] {}",
                                  i,
                                  query.info.query.name(),
                                  query.info.query.describe(icx.tcx)));
-                    db.set_span(icx.tcx.sess.source_map().def_span(query.info.span));
-                    icx.tcx.sess.diagnostic().force_print_db(db);
+                    diag.span = icx.tcx.sess.source_map().def_span(query.info.span).into();
+                    icx.tcx.sess.diagnostic().force_print_diagnostic(diag);
 
                     current_query = query.parent.clone();
                     i += 1;
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index 25ffb146da756..e85388bfea29c 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -346,7 +346,7 @@ impl<'a> DiagnosticBuilder<'a> {
 
     /// Convenience function for internal use, clients should use one of the
     /// struct_* methods on Handler.
-    pub fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuilder<'a> {
+    crate fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuilder<'a> {
         DiagnosticBuilder::new_with_code(handler, level, None, message)
     }
 
@@ -363,7 +363,8 @@ impl<'a> DiagnosticBuilder<'a> {
 
     /// Creates a new `DiagnosticBuilder` with an already constructed
     /// diagnostic.
-    pub fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> DiagnosticBuilder<'a> {
+    crate fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic)
+                         -> DiagnosticBuilder<'a> {
         DiagnosticBuilder(Box::new(DiagnosticBuilderInner {
             handler,
             diagnostic,
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 11e2265cf3618..51309f37e174f 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -742,12 +742,11 @@ impl Handler {
         self.taught_diagnostics.borrow_mut().insert(code.clone())
     }
 
-    pub fn force_print_db(&self, mut db: DiagnosticBuilder<'_>) {
+    pub fn force_print_diagnostic(&self, db: Diagnostic) {
         self.emitter.borrow_mut().emit_diagnostic(&db);
-        db.cancel();
     }
 
-    fn emit_diagnostic(&self, diagnostic: &Diagnostic) {
+    pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) {
         if diagnostic.cancelled() {
             return;
         }
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 1d3576244c4af..32c6dd67a4b5a 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -402,7 +402,7 @@ fn do_mir_borrowck<'a, 'tcx>(
         }
 
         for diag in mbcx.errors_buffer.drain(..) {
-            DiagnosticBuilder::new_diagnostic(mbcx.infcx.tcx.sess.diagnostic(), diag).emit();
+            mbcx.infcx.tcx.sess.diagnostic().emit_diagnostic(&diag);
         }
     }
 
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 487dc8ec2ae0c..1cc71ea5649de 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -3,7 +3,6 @@
 // substitutions.
 
 use crate::check::FnCtxt;
-use errors::DiagnosticBuilder;
 use rustc::hir;
 use rustc::hir::def_id::{DefId, DefIndex};
 use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
@@ -407,7 +406,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         if !errors_buffer.is_empty() {
             errors_buffer.sort_by_key(|diag| diag.span.primary_span());
             for diag in errors_buffer.drain(..) {
-                DiagnosticBuilder::new_diagnostic(self.tcx().sess.diagnostic(), diag).emit();
+                self.tcx().sess.diagnostic().emit_diagnostic(&diag);
             }
         }
     }
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index 544ec789d80a9..dfec9ee28809a 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -4,7 +4,7 @@ use crate::parse::{self, token, ParseSess};
 use crate::parse::lexer::comments;
 use crate::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint};
 
-use errors::{Diagnostic, DiagnosticBuilder};
+use errors::Diagnostic;
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span};
 use syntax_pos::symbol::{kw, sym, Symbol};
@@ -650,7 +650,7 @@ impl server::Diagnostic for Rustc<'_> {
         diag.sub(level.to_internal(), msg, MultiSpan::from_spans(spans), None);
     }
     fn emit(&mut self, diag: Self::Diagnostic) {
-        DiagnosticBuilder::new_diagnostic(&self.sess.span_diagnostic, diag).emit()
+        self.sess.span_diagnostic.emit_diagnostic(&diag);
     }
 }
 
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index aaf6f3e537eb6..b4ae1e87bca28 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -60,12 +60,12 @@ macro_rules! panictry {
 macro_rules! panictry_buffer {
     ($handler:expr, $e:expr) => ({
         use std::result::Result::{Ok, Err};
-        use errors::{FatalError, DiagnosticBuilder};
+        use errors::FatalError;
         match $e {
             Ok(e) => e,
             Err(errs) => {
                 for e in errs {
-                    DiagnosticBuilder::new_diagnostic($handler, e).emit();
+                    $handler.emit_diagnostic(&e);
                 }
                 FatalError.raise()
             }
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 2441a027f9940..c4f31bcd9b041 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -306,7 +306,7 @@ fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
     match try_file_to_source_file(sess, path, spanopt) {
         Ok(source_file) => source_file,
         Err(d) => {
-            DiagnosticBuilder::new_diagnostic(&sess.span_diagnostic, d).emit();
+            sess.span_diagnostic.emit_diagnostic(&d);
             FatalError.raise();
         }
     }

From 998df0d70b0c837d52a1c8100773409390df840c Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 7 Sep 2019 10:38:02 -0400
Subject: [PATCH 836/943] Remove Handler::cancel

---
 src/librustc/infer/error_reporting/mod.rs | 2 +-
 src/librustc_errors/lib.rs                | 4 ----
 src/libsyntax/parse/attr.rs               | 4 ++--
 src/libsyntax/parse/diagnostics.rs        | 8 +-------
 src/libsyntax/parse/parser/expr.rs        | 2 +-
 src/libsyntax/parse/parser/pat.rs         | 2 +-
 src/libsyntax/parse/parser/stmt.rs        | 2 +-
 7 files changed, 7 insertions(+), 17 deletions(-)

diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index ab24b3f2f059f..0b6740d7bbbc8 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1119,7 +1119,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     Some((expected, found)) => Some((expected, found)),
                     None => {
                         // Derived error. Cancel the emitter.
-                        self.tcx.sess.diagnostic().cancel(diag);
+                        diag.cancel();
                         return;
                     }
                 };
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 51309f37e174f..47ac2e5a667d5 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -520,10 +520,6 @@ impl Handler {
         DiagnosticBuilder::new(self, Level::Fatal, msg)
     }
 
-    pub fn cancel(&self, err: &mut DiagnosticBuilder<'_>) {
-        err.cancel();
-    }
-
     fn panic_if_treat_err_as_bug(&self) {
         if self.treat_err_as_bug() {
             let s = match (self.err_count(), self.flags.treat_err_as_bug.unwrap_or(0)) {
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 9aa1ec0b14fe9..9fbed66854c64 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -309,14 +309,14 @@ impl<'a> Parser<'a> {
             Ok(lit) => {
                 return Ok(ast::NestedMetaItem::Literal(lit))
             }
-            Err(ref mut err) => self.diagnostic().cancel(err)
+            Err(ref mut err) => err.cancel(),
         }
 
         match self.parse_meta_item() {
             Ok(mi) => {
                 return Ok(ast::NestedMetaItem::MetaItem(mi))
             }
-            Err(ref mut err) => self.diagnostic().cancel(err)
+            Err(ref mut err) => err.cancel(),
         }
 
         let found = self.this_token_to_string();
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index b74f2492c351f..1e7058ff71563 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -197,10 +197,6 @@ impl<'a> Parser<'a> {
         self.sess.span_diagnostic.span_bug(sp, m)
     }
 
-    crate fn cancel(&self, err: &mut DiagnosticBuilder<'_>) {
-        self.sess.span_diagnostic.cancel(err)
-    }
-
     crate fn diagnostic(&self) -> &'a errors::Handler {
         &self.sess.span_diagnostic
     }
@@ -426,15 +422,13 @@ impl<'a> Parser<'a> {
     /// Eats and discards tokens until one of `kets` is encountered. Respects token trees,
     /// passes through any errors encountered. Used for error recovery.
     crate fn eat_to_tokens(&mut self, kets: &[&TokenKind]) {
-        let handler = self.diagnostic();
-
         if let Err(ref mut err) = self.parse_seq_to_before_tokens(
             kets,
             SeqSep::none(),
             TokenExpectType::Expect,
             |p| Ok(p.parse_token_tree()),
         ) {
-            handler.cancel(err);
+            err.cancel();
         }
     }
 
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 31b28443abbc3..5764934b3cd16 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -770,7 +770,7 @@ impl<'a> Parser<'a> {
                         ex = ExprKind::Lit(literal);
                     }
                     Err(mut err) => {
-                        self.cancel(&mut err);
+                        err.cancel();
                         return Err(self.expected_expression_found());
                     }
                 }
diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs
index 08ee3a6bd86d4..3c624959eadb1 100644
--- a/src/libsyntax/parse/parser/pat.rs
+++ b/src/libsyntax/parse/parser/pat.rs
@@ -537,7 +537,7 @@ impl<'a> Parser<'a> {
         mut err: DiagnosticBuilder<'a>,
         expected: Expected,
     ) -> PResult<'a, P<Pat>> {
-        self.cancel(&mut err);
+        err.cancel();
 
         let expected = expected.unwrap_or("pattern");
         let msg = format!("expected {}, found {}", expected, self.this_token_descr());
diff --git a/src/libsyntax/parse/parser/stmt.rs b/src/libsyntax/parse/parser/stmt.rs
index 04bd61a4cfb5b..02da56f6e35a7 100644
--- a/src/libsyntax/parse/parser/stmt.rs
+++ b/src/libsyntax/parse/parser/stmt.rs
@@ -361,7 +361,7 @@ impl<'a> Parser<'a> {
                 }
                 Err(mut e) => {
                     self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
-                    self.cancel(&mut e);
+                    e.cancel();
                 }
                 _ => ()
             }

From b304e60131a081930382a6bf327aa11c6432698c Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 7 Sep 2019 11:21:17 -0400
Subject: [PATCH 837/943] Remove Handler::{emit, emit_with_code}

---
 src/librustc/session/mod.rs            |  4 +-
 src/librustc_codegen_ssa/back/write.rs | 18 +++-----
 src/librustc_driver/lib.rs             | 12 +++---
 src/librustc_errors/lib.rs             | 59 ++++++++++++--------------
 4 files changed, 40 insertions(+), 53 deletions(-)

diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index af9cb5a0941e5..afaea54006018 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -1394,7 +1394,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
             Box::new(JsonEmitter::basic(pretty, json_rendered, false)),
     };
     let handler = errors::Handler::with_emitter(true, None, emitter);
-    handler.emit(&MultiSpan::new(), msg, errors::Level::Fatal);
+    handler.struct_fatal(msg).emit();
     errors::FatalError.raise();
 }
 
@@ -1408,7 +1408,7 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
             Box::new(JsonEmitter::basic(pretty, json_rendered, false)),
     };
     let handler = errors::Handler::with_emitter(true, None, emitter);
-    handler.emit(&MultiSpan::new(), msg, errors::Level::Warning);
+    handler.struct_warn(msg).emit();
 }
 
 pub type CompileResult = Result<(), ErrorReported>;
diff --git a/src/librustc_codegen_ssa/back/write.rs b/src/librustc_codegen_ssa/back/write.rs
index 38a0818d290bd..1bba479c1fd5d 100644
--- a/src/librustc_codegen_ssa/back/write.rs
+++ b/src/librustc_codegen_ssa/back/write.rs
@@ -27,7 +27,6 @@ use rustc_errors::emitter::{Emitter};
 use rustc_target::spec::MergeFunctions;
 use syntax::attr;
 use syntax::ext::hygiene::ExpnId;
-use syntax_pos::MultiSpan;
 use syntax_pos::symbol::{Symbol, sym};
 use jobserver::{Client, Acquired};
 
@@ -1760,19 +1759,12 @@ impl SharedEmitterMain {
             match message {
                 Ok(SharedEmitterMessage::Diagnostic(diag)) => {
                     let handler = sess.diagnostic();
-                    match diag.code {
-                        Some(ref code) => {
-                            handler.emit_with_code(&MultiSpan::new(),
-                                                   &diag.msg,
-                                                   code.clone(),
-                                                   diag.lvl);
-                        }
-                        None => {
-                            handler.emit(&MultiSpan::new(),
-                                         &diag.msg,
-                                         diag.lvl);
-                        }
+                    let mut d = rustc_errors::Diagnostic::new(diag.lvl, &diag.msg);
+                    if let Some(code) = diag.code {
+                        d.code(code);
                     }
+                    handler.emit_diagnostic(&d);
+                    handler.abort_if_errors_and_should_abort();
                 }
                 Ok(SharedEmitterMessage::InlineAsmError(cookie, msg)) => {
                     sess.span_err(ExpnId::from_u32(cookie).expn_data().call_site, &msg)
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 3a09f459e9c1f..f99e65b4494a7 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -66,7 +66,7 @@ use syntax::source_map::FileLoader;
 use syntax::feature_gate::{GatedCfg, UnstableFeatures};
 use syntax::parse::{self, PResult};
 use syntax::symbol::sym;
-use syntax_pos::{DUMMY_SP, MultiSpan, FileName};
+use syntax_pos::{DUMMY_SP, FileName};
 
 pub mod pretty;
 mod args;
@@ -1203,9 +1203,9 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
     // a .span_bug or .bug call has already printed what
     // it wants to print.
     if !info.payload().is::<errors::ExplicitBug>() {
-        handler.emit(&MultiSpan::new(),
-                     "unexpected panic",
-                     errors::Level::Bug);
+        let d = errors::Diagnostic::new(errors::Level::Bug, "unexpected panic");
+        handler.emit_diagnostic(&d);
+        handler.abort_if_errors_and_should_abort();
     }
 
     let mut xs: Vec<Cow<'static, str>> = vec![
@@ -1225,9 +1225,7 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
     }
 
     for note in &xs {
-        handler.emit(&MultiSpan::new(),
-                     note,
-                     errors::Level::Note);
+        handler.note_without_error(&note);
     }
 
     // If backtraces are enabled, also print the query stack
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 47ac2e5a667d5..b74a6035032fa 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -539,7 +539,8 @@ impl Handler {
     }
 
     pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> FatalError {
-        self.emit(&sp.into(), msg, Fatal);
+        self.emit_diagnostic(Diagnostic::new(Fatal, msg).set_span(sp));
+        self.abort_if_errors_and_should_abort();
         FatalError
     }
     pub fn span_fatal_with_code<S: Into<MultiSpan>>(&self,
@@ -547,11 +548,13 @@ impl Handler {
                                                     msg: &str,
                                                     code: DiagnosticId)
                                                     -> FatalError {
-        self.emit_with_code(&sp.into(), msg, code, Fatal);
+        self.emit_diagnostic(Diagnostic::new_with_code(Fatal, Some(code), msg).set_span(sp));
+        self.abort_if_errors_and_should_abort();
         FatalError
     }
     pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
-        self.emit(&sp.into(), msg, Error);
+        self.emit_diagnostic(Diagnostic::new(Error, msg).set_span(sp));
+        self.abort_if_errors_and_should_abort();
     }
     pub fn mut_span_err<S: Into<MultiSpan>>(&self,
                                             sp: S,
@@ -562,16 +565,20 @@ impl Handler {
         result
     }
     pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
-        self.emit_with_code(&sp.into(), msg, code, Error);
+        self.emit_diagnostic(Diagnostic::new_with_code(Error, Some(code), msg).set_span(sp));
+        self.abort_if_errors_and_should_abort();
     }
     pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
-        self.emit(&sp.into(), msg, Warning);
+        self.emit_diagnostic(Diagnostic::new(Warning, msg).set_span(sp));
+        self.abort_if_errors_and_should_abort();
     }
     pub fn span_warn_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
-        self.emit_with_code(&sp.into(), msg, code, Warning);
+        self.emit_diagnostic(Diagnostic::new_with_code(Warning, Some(code), msg).set_span(sp));
+        self.abort_if_errors_and_should_abort();
     }
     pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
-        self.emit(&sp.into(), msg, Bug);
+        self.emit_diagnostic(Diagnostic::new(Bug, msg).set_span(sp));
+        self.abort_if_errors_and_should_abort();
         panic!(ExplicitBug);
     }
     pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
@@ -590,10 +597,12 @@ impl Handler {
         self.delayed_span_bugs.borrow_mut().push(diagnostic);
     }
     pub fn span_bug_no_panic<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
-        self.emit(&sp.into(), msg, Bug);
+        self.emit_diagnostic(Diagnostic::new(Bug, msg).set_span(sp));
+        self.abort_if_errors_and_should_abort();
     }
     pub fn span_note_without_error<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
-        self.emit(&sp.into(), msg, Note);
+        self.emit_diagnostic(Diagnostic::new(Note, msg).set_span(sp));
+        self.abort_if_errors_and_should_abort();
     }
     pub fn span_note_diag(&self,
                           sp: Span,
@@ -701,31 +710,15 @@ impl Handler {
         }
     }
 
-    pub fn abort_if_errors(&self) {
-        if self.has_errors() {
+    pub fn abort_if_errors_and_should_abort(&self) {
+        if self.has_errors() && !self.continue_after_error.load(SeqCst) {
             FatalError.raise();
         }
     }
-    pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) {
-        if lvl == Warning && !self.flags.can_emit_warnings {
-            return;
-        }
-        let mut db = DiagnosticBuilder::new(self, lvl, msg);
-        db.set_span(msp.clone());
-        db.emit();
-        if !self.continue_after_error.load(SeqCst) {
-            self.abort_if_errors();
-        }
-    }
-    pub fn emit_with_code(&self, msp: &MultiSpan, msg: &str, code: DiagnosticId, lvl: Level) {
-        if lvl == Warning && !self.flags.can_emit_warnings {
-            return;
-        }
-        let mut db = DiagnosticBuilder::new_with_code(self, lvl, Some(code), msg);
-        db.set_span(msp.clone());
-        db.emit();
-        if !self.continue_after_error.load(SeqCst) {
-            self.abort_if_errors();
+
+    pub fn abort_if_errors(&self) {
+        if self.has_errors() {
+            FatalError.raise();
         }
     }
 
@@ -747,6 +740,10 @@ impl Handler {
             return;
         }
 
+        if diagnostic.level == Warning && !self.flags.can_emit_warnings {
+            return;
+        }
+
         TRACK_DIAGNOSTICS.with(|track_diagnostics| {
             track_diagnostics.get()(diagnostic);
         });

From 2a767eec0cae5aedb197d8fb823df67d93257fbd Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 7 Sep 2019 11:26:32 -0400
Subject: [PATCH 838/943] Remove unused methods from Handler

---
 src/librustc/session/mod.rs | 6 ------
 src/librustc_errors/lib.rs  | 6 ------
 src/libsyntax/ext/base.rs   | 3 ---
 3 files changed, 15 deletions(-)

diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index afaea54006018..a24fed8f21c5a 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -365,12 +365,6 @@ impl Session {
     pub fn span_note_without_error<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.diagnostic().span_note_without_error(sp, msg)
     }
-    pub fn span_unimpl<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
-        self.diagnostic().span_unimpl(sp, msg)
-    }
-    pub fn unimpl(&self, msg: &str) -> ! {
-        self.diagnostic().unimpl(msg)
-    }
 
     pub fn buffer_lint<S: Into<MultiSpan>>(
         &self,
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index b74a6035032fa..bd57cc41ef335 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -612,9 +612,6 @@ impl Handler {
         db.set_span(sp);
         db
     }
-    pub fn span_unimpl<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
-        self.span_bug(sp, &format!("unimplemented {}", msg));
-    }
     pub fn failure(&self, msg: &str) {
         DiagnosticBuilder::new(self, FailureNote, msg).emit()
     }
@@ -648,9 +645,6 @@ impl Handler {
         db.emit();
         panic!(ExplicitBug);
     }
-    pub fn unimpl(&self, msg: &str) -> ! {
-        self.bug(&format!("unimplemented {}", msg));
-    }
 
     fn bump_err_count(&self) {
         self.err_count.fetch_add(1, SeqCst);
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 384c0555c85bd..a6be5b101788e 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -1048,9 +1048,6 @@ impl<'a> ExtCtxt<'a> {
     pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.parse_sess.span_diagnostic.span_warn(sp, msg);
     }
-    pub fn span_unimpl<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
-        self.parse_sess.span_diagnostic.span_unimpl(sp, msg);
-    }
     pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
         self.parse_sess.span_diagnostic.span_bug(sp, msg);
     }

From 4cc5aaada2f8ffd444a7fbb10394b83ba3156525 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 7 Sep 2019 12:09:52 -0400
Subject: [PATCH 839/943] Protect error handler fields with single lock

This avoids concurrency-related bugs when locks are acquired for too
short a time and similar cases.
---
 src/librustc/session/config/tests.rs |   6 +-
 src/librustc_errors/lib.rs           | 336 ++++++++++++++++-----------
 2 files changed, 207 insertions(+), 135 deletions(-)

diff --git a/src/librustc/session/config/tests.rs b/src/librustc/session/config/tests.rs
index 3d6312548a47b..9eb68056bfd97 100644
--- a/src/librustc/session/config/tests.rs
+++ b/src/librustc/session/config/tests.rs
@@ -87,7 +87,7 @@ fn test_can_print_warnings() {
         let registry = errors::registry::Registry::new(&[]);
         let (sessopts, _) = build_session_options_and_crate_config(&matches);
         let sess = build_session(sessopts, None, registry);
-        assert!(!sess.diagnostic().flags.can_emit_warnings);
+        assert!(!sess.diagnostic().can_emit_warnings());
     });
 
     syntax::with_default_globals(|| {
@@ -97,7 +97,7 @@ fn test_can_print_warnings() {
         let registry = errors::registry::Registry::new(&[]);
         let (sessopts, _) = build_session_options_and_crate_config(&matches);
         let sess = build_session(sessopts, None, registry);
-        assert!(sess.diagnostic().flags.can_emit_warnings);
+        assert!(sess.diagnostic().can_emit_warnings());
     });
 
     syntax::with_default_globals(|| {
@@ -105,7 +105,7 @@ fn test_can_print_warnings() {
         let registry = errors::registry::Registry::new(&[]);
         let (sessopts, _) = build_session_options_and_crate_config(&matches);
         let sess = build_session(sessopts, None, registry);
-        assert!(sess.diagnostic().flags.can_emit_warnings);
+        assert!(sess.diagnostic().can_emit_warnings());
     });
 }
 
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index bd57cc41ef335..a1a63664a4be3 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -16,7 +16,7 @@ use Level::*;
 use emitter::{Emitter, EmitterWriter};
 use registry::Registry;
 
-use rustc_data_structures::sync::{self, Lrc, Lock, AtomicUsize, AtomicBool, SeqCst};
+use rustc_data_structures::sync::{self, Lrc, Lock};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::stable_hasher::StableHasher;
 
@@ -298,30 +298,34 @@ pub use diagnostic_builder::DiagnosticBuilder;
 /// Certain errors (fatal, bug, unimpl) may cause immediate exit,
 /// others log errors for later reporting.
 pub struct Handler {
-    pub flags: HandlerFlags,
+    flags: HandlerFlags,
+    inner: Lock<HandlerInner>,
+}
 
+struct HandlerInner {
+    flags: HandlerFlags,
     /// The number of errors that have been emitted, including duplicates.
     ///
     /// This is not necessarily the count that's reported to the user once
     /// compilation ends.
-    err_count: AtomicUsize,
-    deduplicated_err_count: AtomicUsize,
-    emitter: Lock<Box<dyn Emitter + sync::Send>>,
-    continue_after_error: AtomicBool,
-    delayed_span_bugs: Lock<Vec<Diagnostic>>,
+    err_count: usize,
+    deduplicated_err_count: usize,
+    emitter: Box<dyn Emitter + sync::Send>,
+    continue_after_error: bool,
+    delayed_span_bugs: Vec<Diagnostic>,
 
     /// This set contains the `DiagnosticId` of all emitted diagnostics to avoid
     /// emitting the same diagnostic with extended help (`--teach`) twice, which
     /// would be uneccessary repetition.
-    taught_diagnostics: Lock<FxHashSet<DiagnosticId>>,
+    taught_diagnostics: FxHashSet<DiagnosticId>,
 
     /// Used to suggest rustc --explain <error code>
-    emitted_diagnostic_codes: Lock<FxHashSet<DiagnosticId>>,
+    emitted_diagnostic_codes: FxHashSet<DiagnosticId>,
 
     /// This set contains a hash of every diagnostic that has been emitted by
     /// this handler. These hashes is used to avoid emitting the same error
     /// twice.
-    emitted_diagnostics: Lock<FxHashSet<u128>>,
+    emitted_diagnostics: FxHashSet<u128>,
 }
 
 fn default_track_diagnostic(_: &Diagnostic) {}
@@ -329,7 +333,7 @@ fn default_track_diagnostic(_: &Diagnostic) {}
 thread_local!(pub static TRACK_DIAGNOSTICS: Cell<fn(&Diagnostic)> =
                 Cell::new(default_track_diagnostic));
 
-#[derive(Default)]
+#[derive(Copy, Clone, Default)]
 pub struct HandlerFlags {
     /// If false, warning-level lints are suppressed.
     /// (rustc: see `--allow warnings` and `--cap-lints`)
@@ -348,13 +352,13 @@ pub struct HandlerFlags {
     pub external_macro_backtrace: bool,
 }
 
-impl Drop for Handler {
+impl Drop for HandlerInner {
     fn drop(&mut self) {
-        if !self.has_errors() {
-            let mut bugs = self.delayed_span_bugs.borrow_mut();
+        if self.err_count == 0 {
+            let bugs = std::mem::replace(&mut self.delayed_span_bugs, Vec::new());
             let has_bugs = !bugs.is_empty();
-            for bug in bugs.drain(..) {
-                DiagnosticBuilder::new_diagnostic(self, bug).emit();
+            for bug in bugs {
+                self.emit_diagnostic(&bug);
             }
             if has_bugs {
                 panic!("no errors encountered even though `delay_span_bug` issued");
@@ -405,19 +409,28 @@ impl Handler {
     {
         Handler {
             flags,
-            err_count: AtomicUsize::new(0),
-            deduplicated_err_count: AtomicUsize::new(0),
-            emitter: Lock::new(e),
-            continue_after_error: AtomicBool::new(true),
-            delayed_span_bugs: Lock::new(Vec::new()),
-            taught_diagnostics: Default::default(),
-            emitted_diagnostic_codes: Default::default(),
-            emitted_diagnostics: Default::default(),
+            inner: Lock::new(HandlerInner {
+                flags,
+                err_count: 0,
+                deduplicated_err_count: 0,
+                emitter: e,
+                continue_after_error: true,
+                delayed_span_bugs: Vec::new(),
+                taught_diagnostics: Default::default(),
+                emitted_diagnostic_codes: Default::default(),
+                emitted_diagnostics: Default::default(),
+            }),
         }
     }
 
     pub fn set_continue_after_error(&self, continue_after_error: bool) {
-        self.continue_after_error.store(continue_after_error, SeqCst);
+        self.inner.borrow_mut().continue_after_error = continue_after_error;
+    }
+
+    // This is here to not allow mutation of flags;
+    // as of this writing it's only used in tests in librustc.
+    pub fn can_emit_warnings(&self) -> bool {
+        self.flags.can_emit_warnings
     }
 
     /// Resets the diagnostic error count as well as the cached emitted diagnostics.
@@ -425,11 +438,13 @@ impl Handler {
     /// NOTE: *do not* call this function from rustc. It is only meant to be called from external
     /// tools that want to reuse a `Parser` cleaning the previously emitted diagnostics as well as
     /// the overall count of emitted error diagnostics.
+    // FIXME: this does not clear inner entirely
     pub fn reset_err_count(&self) {
+        let mut inner = self.inner.borrow_mut();
         // actually frees the underlying memory (which `clear` would not do)
-        *self.emitted_diagnostics.borrow_mut() = Default::default();
-        self.deduplicated_err_count.store(0, SeqCst);
-        self.err_count.store(0, SeqCst);
+        inner.emitted_diagnostics = Default::default();
+        inner.deduplicated_err_count = 0;
+        inner.err_count = 0;
     }
 
     pub fn struct_dummy(&self) -> DiagnosticBuilder<'_> {
@@ -520,24 +535,6 @@ impl Handler {
         DiagnosticBuilder::new(self, Level::Fatal, msg)
     }
 
-    fn panic_if_treat_err_as_bug(&self) {
-        if self.treat_err_as_bug() {
-            let s = match (self.err_count(), self.flags.treat_err_as_bug.unwrap_or(0)) {
-                (0, _) => return,
-                (1, 1) => "aborting due to `-Z treat-err-as-bug=1`".to_string(),
-                (1, _) => return,
-                (count, as_bug) => {
-                    format!(
-                        "aborting after {} errors due to `-Z treat-err-as-bug={}`",
-                        count,
-                        as_bug,
-                    )
-                }
-            };
-            panic!(s);
-        }
-    }
-
     pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> FatalError {
         self.emit_diagnostic(Diagnostic::new(Fatal, msg).set_span(sp));
         self.abort_if_errors_and_should_abort();
@@ -577,24 +574,10 @@ impl Handler {
         self.abort_if_errors_and_should_abort();
     }
     pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
-        self.emit_diagnostic(Diagnostic::new(Bug, msg).set_span(sp));
-        self.abort_if_errors_and_should_abort();
-        panic!(ExplicitBug);
+        self.inner.borrow_mut().span_bug(sp, msg)
     }
     pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
-        if self.treat_err_as_bug() {
-            // FIXME: don't abort here if report_delayed_bugs is off
-            self.span_bug(sp, msg);
-        }
-        let mut diagnostic = Diagnostic::new(Level::Bug, msg);
-        diagnostic.set_span(sp.into());
-        self.delay_as_bug(diagnostic);
-    }
-    fn delay_as_bug(&self, diagnostic: Diagnostic) {
-        if self.flags.report_delayed_bugs {
-            self.emit_diagnostic(&diagnostic);
-        }
-        self.delayed_span_bugs.borrow_mut().push(diagnostic);
+        self.inner.borrow_mut().delay_span_bug(sp, msg)
     }
     pub fn span_bug_no_panic<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.emit_diagnostic(Diagnostic::new(Bug, msg).set_span(sp));
@@ -613,46 +596,28 @@ impl Handler {
         db
     }
     pub fn failure(&self, msg: &str) {
-        DiagnosticBuilder::new(self, FailureNote, msg).emit()
+        self.inner.borrow_mut().failure(msg);
     }
     pub fn fatal(&self, msg: &str) -> FatalError {
-        if self.treat_err_as_bug() {
-            self.bug(msg);
-        }
-        DiagnosticBuilder::new(self, Fatal, msg).emit();
-        FatalError
+        self.inner.borrow_mut().fatal(msg)
     }
     pub fn err(&self, msg: &str) {
-        if self.treat_err_as_bug() {
-            self.bug(msg);
-        }
-        let mut db = DiagnosticBuilder::new(self, Error, msg);
-        db.emit();
+        self.inner.borrow_mut().err(msg);
     }
     pub fn warn(&self, msg: &str) {
         let mut db = DiagnosticBuilder::new(self, Warning, msg);
         db.emit();
     }
-    fn treat_err_as_bug(&self) -> bool {
-        self.flags.treat_err_as_bug.map(|c| self.err_count() >= c).unwrap_or(false)
-    }
     pub fn note_without_error(&self, msg: &str) {
         let mut db = DiagnosticBuilder::new(self, Note, msg);
         db.emit();
     }
     pub fn bug(&self, msg: &str) -> ! {
-        let mut db = DiagnosticBuilder::new(self, Bug, msg);
-        db.emit();
-        panic!(ExplicitBug);
-    }
-
-    fn bump_err_count(&self) {
-        self.err_count.fetch_add(1, SeqCst);
-        self.panic_if_treat_err_as_bug();
+        self.inner.borrow_mut().bug(msg)
     }
 
     pub fn err_count(&self) -> usize {
-        self.err_count.load(SeqCst)
+        self.inner.borrow().err_count
     }
 
     pub fn has_errors(&self) -> bool {
@@ -660,7 +625,99 @@ impl Handler {
     }
 
     pub fn print_error_count(&self, registry: &Registry) {
-        let s = match self.deduplicated_err_count.load(SeqCst) {
+        self.inner.borrow_mut().print_error_count(registry)
+    }
+
+    pub fn abort_if_errors(&self) {
+        self.inner.borrow().abort_if_errors()
+    }
+
+    pub fn abort_if_errors_and_should_abort(&self) {
+        self.inner.borrow().abort_if_errors_and_should_abort()
+    }
+
+    pub fn must_teach(&self, code: &DiagnosticId) -> bool {
+        self.inner.borrow_mut().must_teach(code)
+    }
+
+    pub fn force_print_diagnostic(&self, db: Diagnostic) {
+        self.inner.borrow_mut().force_print_diagnostic(db)
+    }
+
+    pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) {
+        self.inner.borrow_mut().emit_diagnostic(diagnostic)
+    }
+
+    pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
+        self.inner.borrow_mut().emit_artifact_notification(path, artifact_type)
+    }
+
+    pub fn delay_as_bug(&self, diagnostic: Diagnostic) {
+        self.inner.borrow_mut().delay_as_bug(diagnostic)
+    }
+}
+
+impl HandlerInner {
+    /// `true` if we haven't taught a diagnostic with this code already.
+    /// The caller must then teach the user about such a diagnostic.
+    ///
+    /// Used to suppress emitting the same error multiple times with extended explanation when
+    /// calling `-Zteach`.
+    fn must_teach(&mut self, code: &DiagnosticId) -> bool {
+        self.taught_diagnostics.insert(code.clone())
+    }
+
+    fn force_print_diagnostic(&mut self, db: Diagnostic) {
+        self.emitter.emit_diagnostic(&db);
+    }
+
+    fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) {
+        if diagnostic.cancelled() {
+            return;
+        }
+
+        if diagnostic.level == Warning && !self.flags.can_emit_warnings {
+            return;
+        }
+
+        TRACK_DIAGNOSTICS.with(|track_diagnostics| {
+            track_diagnostics.get()(diagnostic);
+        });
+
+        if let Some(ref code) = diagnostic.code {
+            self.emitted_diagnostic_codes.insert(code.clone());
+        }
+
+        let diagnostic_hash = {
+            use std::hash::Hash;
+            let mut hasher = StableHasher::new();
+            diagnostic.hash(&mut hasher);
+            hasher.finish()
+        };
+
+        // Only emit the diagnostic if we haven't already emitted an equivalent
+        // one:
+        if self.emitted_diagnostics.insert(diagnostic_hash) {
+            self.emitter.emit_diagnostic(diagnostic);
+            if diagnostic.is_error() {
+                self.deduplicated_err_count += 1;
+            }
+        }
+        if diagnostic.is_error() {
+            self.bump_err_count();
+        }
+    }
+
+    fn emit_artifact_notification(&mut self, path: &Path, artifact_type: &str) {
+        self.emitter.emit_artifact_notification(path, artifact_type);
+    }
+
+    fn treat_err_as_bug(&self) -> bool {
+        self.flags.treat_err_as_bug.map(|c| self.err_count >= c).unwrap_or(false)
+    }
+
+    fn print_error_count(&mut self, registry: &Registry) {
+        let s = match self.deduplicated_err_count {
             0 => return,
             1 => "aborting due to previous error".to_string(),
             count => format!("aborting due to {} previous errors", count)
@@ -671,12 +728,11 @@ impl Handler {
 
         let _ = self.fatal(&s);
 
-        let can_show_explain = self.emitter.borrow().should_show_explain();
-        let are_there_diagnostics = !self.emitted_diagnostic_codes.borrow().is_empty();
+        let can_show_explain = self.emitter.should_show_explain();
+        let are_there_diagnostics = !self.emitted_diagnostic_codes.is_empty();
         if can_show_explain && are_there_diagnostics {
             let mut error_codes = self
                 .emitted_diagnostic_codes
-                .borrow()
                 .iter()
                 .filter_map(|x| match &x {
                     DiagnosticId::Error(s) if registry.find_description(s).is_some() => {
@@ -704,70 +760,86 @@ impl Handler {
         }
     }
 
-    pub fn abort_if_errors_and_should_abort(&self) {
-        if self.has_errors() && !self.continue_after_error.load(SeqCst) {
+    fn abort_if_errors_and_should_abort(&self) {
+        if self.err_count > 0 && !self.continue_after_error {
             FatalError.raise();
         }
     }
 
-    pub fn abort_if_errors(&self) {
-        if self.has_errors() {
+    fn abort_if_errors(&self) {
+        if self.err_count > 0 {
             FatalError.raise();
         }
     }
 
-    /// `true` if we haven't taught a diagnostic with this code already.
-    /// The caller must then teach the user about such a diagnostic.
-    ///
-    /// Used to suppress emitting the same error multiple times with extended explanation when
-    /// calling `-Zteach`.
-    pub fn must_teach(&self, code: &DiagnosticId) -> bool {
-        self.taught_diagnostics.borrow_mut().insert(code.clone())
+    fn span_bug<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) -> ! {
+        self.emit_diagnostic(Diagnostic::new(Bug, msg).set_span(sp));
+        self.abort_if_errors_and_should_abort();
+        panic!(ExplicitBug);
     }
 
-    pub fn force_print_diagnostic(&self, db: Diagnostic) {
-        self.emitter.borrow_mut().emit_diagnostic(&db);
+    fn delay_span_bug<S: Into<MultiSpan>>(&mut self, sp: S, msg: &str) {
+        if self.treat_err_as_bug() {
+            // FIXME: don't abort here if report_delayed_bugs is off
+            self.span_bug(sp, msg);
+        }
+        let mut diagnostic = Diagnostic::new(Level::Bug, msg);
+        diagnostic.set_span(sp.into());
+        self.delay_as_bug(diagnostic)
     }
 
-    pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) {
-        if diagnostic.cancelled() {
-            return;
-        }
+    fn failure(&mut self, msg: &str) {
+        self.emit_diagnostic(&Diagnostic::new(FailureNote, msg));
+    }
 
-        if diagnostic.level == Warning && !self.flags.can_emit_warnings {
-            return;
+    fn fatal(&mut self, msg: &str) -> FatalError {
+        if self.treat_err_as_bug() {
+            self.bug(msg);
         }
+        self.emit_diagnostic(&Diagnostic::new(Fatal, msg));
+        FatalError
+    }
 
-        TRACK_DIAGNOSTICS.with(|track_diagnostics| {
-            track_diagnostics.get()(diagnostic);
-        });
-
-        if let Some(ref code) = diagnostic.code {
-            self.emitted_diagnostic_codes.borrow_mut().insert(code.clone());
+    fn err(&mut self, msg: &str) {
+        if self.treat_err_as_bug() {
+            self.bug(msg);
         }
+        self.emit_diagnostic(&Diagnostic::new(Error, msg));
+    }
 
-        let diagnostic_hash = {
-            use std::hash::Hash;
-            let mut hasher = StableHasher::new();
-            diagnostic.hash(&mut hasher);
-            hasher.finish()
-        };
+    fn bug(&mut self, msg: &str) -> ! {
+        self.emit_diagnostic(&Diagnostic::new(Bug, msg));
+        panic!(ExplicitBug);
+    }
 
-        // Only emit the diagnostic if we haven't already emitted an equivalent
-        // one:
-        if self.emitted_diagnostics.borrow_mut().insert(diagnostic_hash) {
-            self.emitter.borrow_mut().emit_diagnostic(diagnostic);
-            if diagnostic.is_error() {
-                self.deduplicated_err_count.fetch_add(1, SeqCst);
-            }
-        }
-        if diagnostic.is_error() {
-            self.bump_err_count();
+    fn delay_as_bug(&mut self, diagnostic: Diagnostic) {
+        if self.flags.report_delayed_bugs {
+            self.emit_diagnostic(&diagnostic);
         }
+        self.delayed_span_bugs.push(diagnostic);
     }
 
-    pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
-        self.emitter.borrow_mut().emit_artifact_notification(path, artifact_type);
+    fn bump_err_count(&mut self) {
+        self.err_count += 1;
+        self.panic_if_treat_err_as_bug();
+    }
+
+    fn panic_if_treat_err_as_bug(&self) {
+        if self.treat_err_as_bug() {
+            let s = match (self.err_count, self.flags.treat_err_as_bug.unwrap_or(0)) {
+                (0, _) => return,
+                (1, 1) => "aborting due to `-Z treat-err-as-bug=1`".to_string(),
+                (1, _) => return,
+                (count, as_bug) => {
+                    format!(
+                        "aborting after {} errors due to `-Z treat-err-as-bug={}`",
+                        count,
+                        as_bug,
+                    )
+                }
+            };
+            panic!(s);
+        }
     }
 }
 

From 0de9485038a5a068644efbfa397feec6d02e05ea Mon Sep 17 00:00:00 2001
From: Oliver Scherer <github35764891676564198441@oli-obk.de>
Date: Fri, 7 Jun 2019 19:22:42 +0200
Subject: [PATCH 840/943] Get rid of special const intrinsic query in favour of
 `const_eval`

---
 src/librustc/mir/interpret/error.rs           |  9 ++
 src/librustc/query/mod.rs                     |  9 --
 src/librustc_codegen_llvm/intrinsic.rs        | 36 +++----
 src/librustc_codegen_ssa/mir/block.rs         |  3 +-
 src/librustc_codegen_ssa/traits/intrinsic.rs  |  4 +-
 src/librustc_mir/const_eval.rs                | 18 ++++
 src/librustc_mir/interpret/eval_context.rs    | 10 +-
 src/librustc_mir/interpret/intrinsics.rs      | 99 ++++++++++++-------
 .../interpret/intrinsics/type_name.rs         | 21 +---
 src/librustc_mir/interpret/mod.rs             |  4 +-
 src/librustc_mir/lib.rs                       |  1 -
 .../issues => compile-fail}/issue-44415.rs    |  0
 src/test/ui/consts/const-size_of-cycle.stderr |  5 +
 src/test/ui/issues/issue-44415.stderr         | 28 ------
 14 files changed, 117 insertions(+), 130 deletions(-)
 rename src/test/{ui/issues => compile-fail}/issue-44415.rs (100%)
 delete mode 100644 src/test/ui/issues/issue-44415.stderr

diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index 09c822f7508a0..67b3ce0e63fb0 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -213,6 +213,15 @@ fn print_backtrace(backtrace: &mut Backtrace) {
     eprintln!("\n\nAn error occurred in miri:\n{:?}", backtrace);
 }
 
+impl From<ErrorHandled> for InterpErrorInfo<'tcx> {
+    fn from(err: ErrorHandled) -> Self {
+        match err {
+            ErrorHandled::Reported => err_inval!(ReferencedConstant),
+            ErrorHandled::TooGeneric => err_inval!(TooGeneric),
+        }.into()
+    }
+}
+
 impl<'tcx> From<InterpError<'tcx>> for InterpErrorInfo<'tcx> {
     fn from(kind: InterpError<'tcx>) -> Self {
         let backtrace = match env::var("RUSTC_CTFE_BACKTRACE") {
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 4ebc2e72490d4..c7260945295a6 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -462,15 +462,6 @@ rustc_queries! {
             no_force
             desc { "extract field of const" }
         }
-
-        /// Produces an absolute path representation of the given type. See also the documentation
-        /// on `std::any::type_name`.
-        query type_name(key: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
-            eval_always
-            no_force
-            desc { "get absolute path of type" }
-        }
-
     }
 
     TypeChecking {
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 5fbfe9138f2a4..3f3c5ac1460a3 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -15,6 +15,7 @@ use rustc_codegen_ssa::glue;
 use rustc_codegen_ssa::base::{to_immediate, wants_msvc_seh, compare_simd_types};
 use rustc::ty::{self, Ty};
 use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Primitive};
+use rustc::mir::interpret::GlobalId;
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
 use rustc::hir;
 use syntax::ast::{self, FloatTy};
@@ -81,13 +82,14 @@ fn get_simple_intrinsic(cx: &CodegenCx<'ll, '_>, name: &str) -> Option<&'ll Valu
 impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
     fn codegen_intrinsic_call(
         &mut self,
-        callee_ty: Ty<'tcx>,
+        instance: ty::Instance<'tcx>,
         fn_ty: &FnType<'tcx, Ty<'tcx>>,
         args: &[OperandRef<'tcx, &'ll Value>],
         llresult: &'ll Value,
         span: Span,
     ) {
         let tcx = self.tcx;
+        let callee_ty = instance.ty(tcx);
 
         let (def_id, substs) = match callee_ty.sty {
             ty::FnDef(def_id, substs) => (def_id, substs),
@@ -133,10 +135,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                 let llfn = self.get_intrinsic(&("llvm.debugtrap"));
                 self.call(llfn, &[], None)
             }
-            "size_of" => {
-                let tp_ty = substs.type_at(0);
-                self.const_usize(self.size_of(tp_ty).bytes())
-            }
             "va_start" => {
                 self.va_start(args[0].immediate())
             }
@@ -188,10 +186,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                     self.const_usize(self.size_of(tp_ty).bytes())
                 }
             }
-            "min_align_of" => {
-                let tp_ty = substs.type_at(0);
-                self.const_usize(self.align_of(tp_ty).bytes())
-            }
             "min_align_of_val" => {
                 let tp_ty = substs.type_at(0);
                 if let OperandValue::Pair(_, meta) = args[0].val {
@@ -201,18 +195,19 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                     self.const_usize(self.align_of(tp_ty).bytes())
                 }
             }
-            "pref_align_of" => {
-                let tp_ty = substs.type_at(0);
-                self.const_usize(self.layout_of(tp_ty).align.pref.bytes())
-            }
+            "size_of" |
+            "pref_align_of" |
+            "min_align_of" |
+            "needs_drop" |
+            "type_id" |
             "type_name" => {
-                let tp_ty = substs.type_at(0);
-                let ty_name = self.tcx.type_name(tp_ty);
+                let gid = GlobalId {
+                    instance,
+                    promoted: None,
+                };
+                let ty_name = self.tcx.const_eval(ty::ParamEnv::reveal_all().and(gid)).unwrap();
                 OperandRef::from_const(self, ty_name).immediate_or_packed_pair(self)
             }
-            "type_id" => {
-                self.const_u64(self.tcx.type_id_hash(substs.type_at(0)))
-            }
             "init" => {
                 let ty = substs.type_at(0);
                 if !self.layout_of(ty).is_zst() {
@@ -235,11 +230,6 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
             "uninit" | "forget" => {
                 return;
             }
-            "needs_drop" => {
-                let tp_ty = substs.type_at(0);
-
-                self.const_bool(self.type_needs_drop(tp_ty))
-            }
             "offset" => {
                 let ptr = args[0].immediate();
                 let offset = args[1].immediate();
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index 8829a33992ae3..1bb0ea5dae44b 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -667,8 +667,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             }).collect();
 
 
-            let callee_ty = instance.as_ref().unwrap().ty(bx.tcx());
-            bx.codegen_intrinsic_call(callee_ty, &fn_ty, &args, dest,
+            bx.codegen_intrinsic_call(*instance.as_ref().unwrap(), &fn_ty, &args, dest,
                                       terminator.source_info.span);
 
             if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
diff --git a/src/librustc_codegen_ssa/traits/intrinsic.rs b/src/librustc_codegen_ssa/traits/intrinsic.rs
index ede30a0bed756..7c79cd6021031 100644
--- a/src/librustc_codegen_ssa/traits/intrinsic.rs
+++ b/src/librustc_codegen_ssa/traits/intrinsic.rs
@@ -1,6 +1,6 @@
 use super::BackendTypes;
 use crate::mir::operand::OperandRef;
-use rustc::ty::Ty;
+use rustc::ty::{self, Ty};
 use rustc_target::abi::call::FnType;
 use syntax_pos::Span;
 
@@ -10,7 +10,7 @@ pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
     /// add them to librustc_codegen_llvm/context.rs
     fn codegen_intrinsic_call(
         &mut self,
-        callee_ty: Ty<'tcx>,
+        instance: ty::Instance<'tcx>,
         fn_ty: &FnType<'tcx, Ty<'tcx>>,
         args: &[OperandRef<'tcx, Self::Value>],
         llresult: Self::Value,
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 3f53f842f314f..435159827e6c3 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -15,6 +15,7 @@ use rustc::ty::{self, Ty, TyCtxt, subst::Subst};
 use rustc::ty::layout::{self, LayoutOf, VariantIdx};
 use rustc::traits::Reveal;
 use rustc_data_structures::fx::FxHashMap;
+use crate::interpret::eval_nullary_intrinsic;
 
 use syntax::source_map::{Span, DUMMY_SP};
 
@@ -602,6 +603,23 @@ pub fn const_eval_provider<'tcx>(
             other => return other,
         }
     }
+
+    // We call `const_eval` for zero arg intrinsics, too, in order to cache their value.
+    // Catch such calls and evaluate them instead of trying to load a constant's MIR.
+    if let ty::InstanceDef::Intrinsic(def_id) = key.value.instance.def {
+        let ty = key.value.instance.ty(tcx);
+        let substs = match ty.sty {
+            ty::FnDef(_, substs) => substs,
+            _ => bug!("intrinsic with type {:?}", ty),
+        };
+        return eval_nullary_intrinsic(tcx, key.param_env, def_id, substs)
+            .map_err(|error| {
+                let span = tcx.def_span(def_id);
+                let error = ConstEvalErr { error: error.kind, stacktrace: vec![], span };
+                error.report_as_error(tcx.at(span), "could not evaluate nullary intrinsic")
+            })
+    }
+
     tcx.const_eval_raw(key).and_then(|val| {
         validate_and_turn_into_const(tcx, val, key)
     })
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 054b65f0e1a9e..78996ed6939d8 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -14,7 +14,6 @@ use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc::ty::query::TyCtxtAt;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc::mir::interpret::{
-    ErrorHandled,
     GlobalId, Scalar, Pointer, FrameInfo, AllocId,
     InterpResult, truncate, sign_extend,
 };
@@ -672,14 +671,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // Our result will later be validated anyway, and there seems no good reason
         // to have to fail early here.  This is also more consistent with
         // `Memory::get_static_alloc` which has to use `const_eval_raw` to avoid cycles.
-        let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| {
-            match err {
-                ErrorHandled::Reported =>
-                    err_inval!(ReferencedConstant),
-                ErrorHandled::TooGeneric =>
-                    err_inval!(TooGeneric),
-            }
-        })?;
+        let val = self.tcx.const_eval_raw(param_env.and(gid))?;
         self.raw_const_to_mplace(val)
     }
 
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index 0f2305e03ff33..ec09e69ec8537 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -5,17 +5,18 @@
 use syntax::symbol::Symbol;
 use rustc::ty;
 use rustc::ty::layout::{LayoutOf, Primitive, Size};
+use rustc::ty::subst::SubstsRef;
+use rustc::hir::def_id::DefId;
+use rustc::ty::TyCtxt;
 use rustc::mir::BinOp;
-use rustc::mir::interpret::{InterpResult, Scalar};
+use rustc::mir::interpret::{InterpResult, Scalar, GlobalId, ConstValue};
 
 use super::{
-    Machine, PlaceTy, OpTy, InterpCx, Immediate,
+    Machine, PlaceTy, OpTy, InterpCx,
 };
 
 mod type_name;
 
-pub use type_name::*;
-
 fn numeric_intrinsic<'tcx, Tag>(
     name: &str,
     bits: u128,
@@ -37,6 +38,50 @@ fn numeric_intrinsic<'tcx, Tag>(
     Ok(Scalar::from_uint(bits_out, size))
 }
 
+/// The logic for all nullary intrinsics is implemented here. These intrinsics don't get evaluated
+/// inside an `InterpCx` and instead have their value computed directly from rustc internal info.
+crate fn eval_nullary_intrinsic<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    def_id: DefId,
+    substs: SubstsRef<'tcx>,
+) -> InterpResult<'tcx, &'tcx ty::Const<'tcx>> {
+    let tp_ty = substs.type_at(0);
+    let name = &*tcx.item_name(def_id).as_str();
+    Ok(match name {
+        "type_name" => {
+            let alloc = type_name::alloc_type_name(tcx, tp_ty);
+            tcx.mk_const(ty::Const {
+                val: ConstValue::Slice {
+                    data: alloc,
+                    start: 0,
+                    end: alloc.len(),
+                },
+                ty: tcx.mk_static_str(),
+            })
+        },
+        "needs_drop" => ty::Const::from_bool(tcx, tp_ty.needs_drop(tcx, param_env)),
+        "size_of" |
+        "min_align_of" |
+        "pref_align_of" => {
+            let layout = tcx.layout_of(param_env.and(tp_ty)).map_err(|e| err_inval!(Layout(e)))?;
+            let n = match name {
+                "pref_align_of" => layout.align.pref.bytes(),
+                "min_align_of" => layout.align.abi.bytes(),
+                "size_of" => layout.size.bytes(),
+                _ => bug!(),
+            };
+            ty::Const::from_usize(tcx, n)
+        },
+        "type_id" => ty::Const::from_bits(
+            tcx,
+            tcx.type_id_hash(tp_ty).into(),
+            param_env.and(tcx.types.u64),
+        ),
+        other => bug!("`{}` is not a zero arg intrinsic", other),
+    })
+}
+
 impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     /// Returns `true` if emulation happened.
     pub fn emulate_intrinsic(
@@ -49,41 +94,19 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
         let intrinsic_name = &self.tcx.item_name(instance.def_id()).as_str()[..];
         match intrinsic_name {
-            "min_align_of" => {
-                let elem_ty = substs.type_at(0);
-                let elem_align = self.layout_of(elem_ty)?.align.abi.bytes();
-                let align_val = Scalar::from_uint(elem_align, dest.layout.size);
-                self.write_scalar(align_val, dest)?;
-            }
-
-            "needs_drop" => {
-                let ty = substs.type_at(0);
-                let ty_needs_drop = ty.needs_drop(self.tcx.tcx, self.param_env);
-                let val = Scalar::from_bool(ty_needs_drop);
-                self.write_scalar(val, dest)?;
-            }
-
-            "size_of" => {
-                let ty = substs.type_at(0);
-                let size = self.layout_of(ty)?.size.bytes() as u128;
-                let size_val = Scalar::from_uint(size, dest.layout.size);
-                self.write_scalar(size_val, dest)?;
-            }
-
-            "type_id" => {
-                let ty = substs.type_at(0);
-                let type_id = self.tcx.type_id_hash(ty) as u128;
-                let id_val = Scalar::from_uint(type_id, dest.layout.size);
-                self.write_scalar(id_val, dest)?;
-            }
-
+            "min_align_of" |
+            "pref_align_of" |
+            "needs_drop" |
+            "size_of" |
+            "type_id" |
             "type_name" => {
-                let alloc = alloc_type_name(self.tcx.tcx, substs.type_at(0));
-                let name_id = self.tcx.alloc_map.lock().create_memory_alloc(alloc);
-                let id_ptr = self.memory.tag_static_base_pointer(name_id.into());
-                let alloc_len = alloc.size.bytes();
-                let name_val = Immediate::new_slice(Scalar::Ptr(id_ptr), alloc_len, self);
-                self.write_immediate(name_val, dest)?;
+                let gid = GlobalId {
+                    instance,
+                    promoted: None,
+                };
+                let val = self.tcx.const_eval(self.param_env.and(gid))?;
+                let val = self.eval_const_to_op(val, None)?;
+                self.copy_op(val, dest)?;
             }
 
             | "ctpop"
diff --git a/src/librustc_mir/interpret/intrinsics/type_name.rs b/src/librustc_mir/interpret/intrinsics/type_name.rs
index 032d16a49db4b..1e765a4ed982c 100644
--- a/src/librustc_mir/interpret/intrinsics/type_name.rs
+++ b/src/librustc_mir/interpret/intrinsics/type_name.rs
@@ -7,7 +7,7 @@ use rustc::ty::{
 use rustc::hir::map::{DefPathData, DisambiguatedDefPathData};
 use rustc::hir::def_id::CrateNum;
 use std::fmt::Write;
-use rustc::mir::interpret::{Allocation, ConstValue};
+use rustc::mir::interpret::Allocation;
 
 struct AbsolutePathPrinter<'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -213,22 +213,11 @@ impl Write for AbsolutePathPrinter<'_> {
     }
 }
 
-/// Produces an absolute path representation of the given type. See also the documentation on
-/// `std::any::type_name`
-pub fn type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
-    let alloc = alloc_type_name(tcx, ty);
-    tcx.mk_const(ty::Const {
-        val: ConstValue::Slice {
-            data: alloc,
-            start: 0,
-            end: alloc.len(),
-        },
-        ty: tcx.mk_static_str(),
-    })
-}
-
 /// Directly returns an `Allocation` containing an absolute path representation of the given type.
-pub(super) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Allocation {
+crate fn alloc_type_name<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    ty: Ty<'tcx>
+) -> &'tcx Allocation {
     let path = AbsolutePathPrinter { tcx, path: String::new() }.print_type(ty).unwrap().path;
     let alloc = Allocation::from_byte_aligned_bytes(path.into_bytes());
     tcx.intern_const_alloc(alloc)
diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs
index 45d24347e4efd..0c61be283dfd0 100644
--- a/src/librustc_mir/interpret/mod.rs
+++ b/src/librustc_mir/interpret/mod.rs
@@ -34,6 +34,6 @@ pub use self::visitor::{ValueVisitor, MutValueVisitor};
 
 pub use self::validity::RefTracking;
 
-pub(super) use self::intrinsics::type_name;
-
 pub use self::intern::intern_const_alloc_recursive;
+
+crate use self::intrinsics::eval_nullary_intrinsic;
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index f27db351b74db..034ad5b01d346 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -59,5 +59,4 @@ pub fn provide(providers: &mut Providers<'_>) {
         let (param_env, (value, field)) = param_env_and_value.into_parts();
         const_eval::const_field(tcx, param_env, None, field, value)
     };
-    providers.type_name = interpret::type_name;
 }
diff --git a/src/test/ui/issues/issue-44415.rs b/src/test/compile-fail/issue-44415.rs
similarity index 100%
rename from src/test/ui/issues/issue-44415.rs
rename to src/test/compile-fail/issue-44415.rs
diff --git a/src/test/ui/consts/const-size_of-cycle.stderr b/src/test/ui/consts/const-size_of-cycle.stderr
index fdba359e7464a..1ae39e7563a82 100644
--- a/src/test/ui/consts/const-size_of-cycle.stderr
+++ b/src/test/ui/consts/const-size_of-cycle.stderr
@@ -14,6 +14,11 @@ note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`...
    |
 LL |     intrinsics::size_of::<T>()
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires const-evaluating + checking `std::intrinsics::size_of`...
+  --> $SRC_DIR/libcore/intrinsics.rs:LL:COL
+   |
+LL |     pub fn size_of<T>() -> usize;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...which requires computing layout of `Foo`...
    = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
    = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle
diff --git a/src/test/ui/issues/issue-44415.stderr b/src/test/ui/issues/issue-44415.stderr
deleted file mode 100644
index 8008e53f65f4d..0000000000000
--- a/src/test/ui/issues/issue-44415.stderr
+++ /dev/null
@@ -1,28 +0,0 @@
-error[E0391]: cycle detected when const-evaluating + checking `Foo::bytes::{{constant}}#0`
-  --> $DIR/issue-44415.rs:6:17
-   |
-LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
-   |                 ^^^^^^
-   |
-note: ...which requires const-evaluating + checking `Foo::bytes::{{constant}}#0`...
-  --> $DIR/issue-44415.rs:6:17
-   |
-LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
-   |                 ^^^^^^
-note: ...which requires const-evaluating `Foo::bytes::{{constant}}#0`...
-  --> $DIR/issue-44415.rs:6:26
-   |
-LL |     bytes: [u8; unsafe { intrinsics::size_of::<Foo>() }],
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which requires computing layout of `Foo`...
-   = note: ...which requires normalizing `ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: All, def_id: None }, value: [u8; _] }`...
-   = note: ...which again requires const-evaluating + checking `Foo::bytes::{{constant}}#0`, completing the cycle
-note: cycle used when processing `Foo`
-  --> $DIR/issue-44415.rs:5:1
-   |
-LL | struct Foo {
-   | ^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0391`.

From a4dc33baf6496e58eed16f612031475c88545091 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 17 Sep 2019 10:39:26 +0200
Subject: [PATCH 841/943] build-manifest: add some comments

---
 src/bootstrap/dist.rs                | 14 ++++++++++----
 src/tools/build-manifest/src/main.rs | 17 +++++++++++++----
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 500d5766a899e..076bcd878df71 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -2000,6 +2000,8 @@ impl Step for HashSign {
     }
 
     fn run(self, builder: &Builder<'_>) {
+        // This gets called by `promote-release`
+        // (https://github.com/rust-lang/rust-central-station/tree/master/promote-release).
         let mut cmd = builder.tool_cmd(Tool::BuildManifest);
         if builder.config.dry_run {
             return;
@@ -2010,10 +2012,14 @@ impl Step for HashSign {
         let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| {
             panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n")
         });
-        let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
-            panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
-        });
-        let pass = t!(fs::read_to_string(&file));
+        let pass = if env::var("BUILD_MANIFEST_DISABLE_SIGNING").is_err() {
+            let file = builder.config.dist_gpg_password_file.as_ref().unwrap_or_else(|| {
+                panic!("\n\nfailed to specify `dist.gpg-password-file` in `config.toml`\n\n")
+            });
+            t!(fs::read_to_string(&file))
+        } else {
+            String::new()
+        };
 
         let today = output(Command::new("date").arg("+%Y-%m-%d"));
 
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 9ffa9391c820b..eab23f3cfffc4 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -1,3 +1,9 @@
+//! Build a dist manifest, hash and sign everything.
+//! This gets called by `promote-release`
+//! (https://github.com/rust-lang/rust-central-station/tree/master/promote-release)
+//! via `x.py dist hash-and-sign`; the cmdline arguments are set up
+//! by rustbuild (in `src/bootstrap/dist.rs`).
+
 use toml;
 use serde::Serialize;
 
@@ -270,6 +276,7 @@ fn main() {
     // Do not ask for a passphrase while manually testing
     let mut passphrase = String::new();
     if should_sign {
+        // `x.py` passes the passphrase via stdin.
         t!(io::stdin().read_to_string(&mut passphrase));
     }
 
@@ -362,6 +369,7 @@ impl Builder {
         }
     }
 
+    /// Hash all files, compute their signatures, and collect the hashes in `self.digests`.
     fn digest_and_sign(&mut self) {
         for file in t!(self.input.read_dir()).map(|e| t!(e).path()) {
             let filename = file.file_name().unwrap().to_str().unwrap();
@@ -532,19 +540,20 @@ impl Builder {
             .as_ref()
             .cloned()
             .map(|version| (version, true))
-            .unwrap_or_default();
+            .unwrap_or_default(); // `is_present` defaults to `false` here.
 
-        // miri needs to build std with xargo, which doesn't allow stable/beta:
-        // <https://github.com/japaric/xargo/pull/204#issuecomment-374888868>
+        // Miri is nightly-only; never ship it for other trains.
         if pkgname == "miri-preview" && self.rust_release != "nightly" {
-            is_present = false; // ignore it
+            is_present = false; // Pretend the component is entirely missing.
         }
 
         let targets = targets.iter().map(|name| {
             if is_present {
+                // The component generally exists, but it might still be missing for this target.
                 let filename = self.filename(pkgname, name);
                 let digest = match self.digests.remove(&filename) {
                     Some(digest) => digest,
+                    // This component does not exist for this target -- skip it.
                     None => return (name.to_string(), Target::unavailable()),
                 };
                 let xz_filename = filename.replace(".tar.gz", ".tar.xz");

From ab6e108644474ece91711e889cff7d36a0adf7f0 Mon Sep 17 00:00:00 2001
From: Andre Bogus <bogusandre@gmail.com>
Date: Fri, 13 Sep 2019 18:42:09 +0200
Subject: [PATCH 842/943] improve Vec example soundness in mem::transmute docs

---
 src/libcore/intrinsics.rs | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index d145f2212f93a..ecff40a75978d 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -845,21 +845,26 @@ extern "rust-intrinsic" {
     ///
     /// ```
     /// let store = [0, 1, 2, 3];
-    /// let mut v_orig = store.iter().collect::<Vec<&i32>>();
+    /// let v_orig = store.iter().collect::<Vec<&i32>>();
+    ///
+    /// // clone the vector as we will reuse them later
+    /// let v_clone = v_orig.clone();
     ///
     /// // Using transmute: this is Undefined Behavior, and a bad idea.
     /// // However, it is no-copy.
     /// let v_transmuted = unsafe {
-    ///     std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(
-    ///         v_orig.clone())
+    ///     std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(v_clone)
     /// };
     ///
+    /// let v_clone = v_orig.clone();
+    ///
     /// // This is the suggested, safe way.
     /// // It does copy the entire vector, though, into a new array.
-    /// let v_collected = v_orig.clone()
-    ///                         .into_iter()
-    ///                         .map(|r| Some(r))
-    ///                         .collect::<Vec<Option<&i32>>>();
+    /// let v_collected = v_clone.into_iter()
+    ///                          .map(Some)
+    ///                          .collect::<Vec<Option<&i32>>>();
+    ///
+    /// let v_clone = v_orig.clone();
     ///
     /// // The no-copy, unsafe way, still using transmute, but not UB.
     /// // This is equivalent to the original, but safer, and reuses the
@@ -869,11 +874,12 @@ extern "rust-intrinsic" {
     /// // the original inner type (`&i32`) to the converted inner type
     /// // (`Option<&i32>`), so read the nomicon pages linked above.
     /// let v_from_raw = unsafe {
-    ///     Vec::from_raw_parts(v_orig.as_mut_ptr() as *mut Option<&i32>,
-    ///                         v_orig.len(),
-    ///                         v_orig.capacity())
+    ///     // Ensure the original vector is not dropped.
+    ///     let mut v_clone = std::mem::ManuallyDrop::new(v_clone);
+    ///     Vec::from_raw_parts(v_clone.as_mut_ptr() as *mut Option<&i32>,
+    ///                         v_clone.len(),
+    ///                         v_clone.capacity())
     /// };
-    /// std::mem::forget(v_orig);
     /// ```
     ///
     /// Implementing `split_at_mut`:

From 9f4351d406fe904a99a7588ebb1411e369ba71f7 Mon Sep 17 00:00:00 2001
From: lqd <remy.rakic+github@gmail.com>
Date: Tue, 17 Sep 2019 19:28:49 +0200
Subject: [PATCH 843/943] Bless output of test
 borrowck/return-local-binding-from-desugaring.rs for Polonius

---
 ...rrowck-escaping-closure-error.polonius.stderr | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 src/test/ui/async-await/async-borrowck-escaping-closure-error.polonius.stderr

diff --git a/src/test/ui/async-await/async-borrowck-escaping-closure-error.polonius.stderr b/src/test/ui/async-await/async-borrowck-escaping-closure-error.polonius.stderr
new file mode 100644
index 0000000000000..5f20367b6aba9
--- /dev/null
+++ b/src/test/ui/async-await/async-borrowck-escaping-closure-error.polonius.stderr
@@ -0,0 +1,16 @@
+error[E0597]: `x` does not live long enough
+  --> $DIR/async-borrowck-escaping-closure-error.rs:5:24
+   |
+LL |     Box::new((async || x)())
+   |     -------------------^----
+   |     |         |        |
+   |     |         |        borrowed value does not live long enough
+   |     |         value captured here
+   |     borrow later used here
+LL |
+LL | }
+   | - `x` dropped here while still borrowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0597`.

From 222e9201511bb9a6eaca7fc2c0ee0b85d78c4fd7 Mon Sep 17 00:00:00 2001
From: lqd <remy.rakic+github@gmail.com>
Date: Tue, 17 Sep 2019 19:30:34 +0200
Subject: [PATCH 844/943] Bless output of test
 borrowck/return-local-binding-from-desugaring.rs for Polonius

---
 ...local-binding-from-desugaring.polonius.stderr | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
 create mode 100644 src/test/ui/borrowck/return-local-binding-from-desugaring.polonius.stderr

diff --git a/src/test/ui/borrowck/return-local-binding-from-desugaring.polonius.stderr b/src/test/ui/borrowck/return-local-binding-from-desugaring.polonius.stderr
new file mode 100644
index 0000000000000..c818379762c9d
--- /dev/null
+++ b/src/test/ui/borrowck/return-local-binding-from-desugaring.polonius.stderr
@@ -0,0 +1,16 @@
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/return-local-binding-from-desugaring.rs:26:18
+   |
+LL |     for ref x in xs {
+   |                  ^^ creates a temporary which is freed while still in use
+...
+LL |     }
+   |     - temporary value is freed at the end of this statement
+LL |     result
+   |     ------ borrow later used here
+   |
+   = note: consider using a `let` binding to create a longer lived value
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.

From 3ef980aeaae3ae92c1ed3bdbefe35c6175ed24fb Mon Sep 17 00:00:00 2001
From: lqd <remy.rakic+github@gmail.com>
Date: Tue, 17 Sep 2019 19:32:36 +0200
Subject: [PATCH 845/943] Update expectations of test
 ui/dropck/dropck_trait_cycle_checked.rs for Polonius

as its output was changed by https://github.com/rust-lang/rust/commit/2ff337a8e286a5b472f71b3bbdc3d4b6b840870f#diff-bd3f80b956148a5d1567aa8698b8a507
---
 .../dropck_trait_cycle_checked.polonius.stderr       | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr b/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr
index dbcb0fcebb73d..5e93a0234259c 100644
--- a/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr
+++ b/src/test/ui/dropck/dropck_trait_cycle_checked.polonius.stderr
@@ -8,7 +8,9 @@ LL | }
    | -
    | |
    | `o2` dropped here while still borrowed
-   | borrow might be used here, when `o2` is dropped and runs the destructor for type `std::boxed::Box<dyn Obj<'_>>`
+   | borrow might be used here, when `o1` is dropped and runs the destructor for type `std::boxed::Box<dyn Obj<'_>>`
+   |
+   = note: values in a scope are dropped in the opposite order they are defined
 
 error[E0597]: `o3` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:112:13
@@ -20,7 +22,9 @@ LL | }
    | -
    | |
    | `o3` dropped here while still borrowed
-   | borrow might be used here, when `o3` is dropped and runs the destructor for type `std::boxed::Box<dyn Obj<'_>>`
+   | borrow might be used here, when `o1` is dropped and runs the destructor for type `std::boxed::Box<dyn Obj<'_>>`
+   |
+   = note: values in a scope are dropped in the opposite order they are defined
 
 error[E0597]: `o2` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:113:13
@@ -38,7 +42,7 @@ error[E0597]: `o3` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:114:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                                         -------- cast requires that `o3` is borrowed for `'static`
+   |                                                                               -------- cast requires that `o3` is borrowed for `'static`
 ...
 LL |     o2.set1(&o3);
    |             ^^^ borrowed value does not live long enough
@@ -62,7 +66,7 @@ error[E0597]: `o2` does not live long enough
   --> $DIR/dropck_trait_cycle_checked.rs:116:13
    |
 LL |     let (o1, o2, o3): (Box<dyn Obj>, Box<dyn Obj>, Box<dyn Obj>) = (O::new(), O::new(), O::new());
-   |                                                                               -------- cast requires that `o2` is borrowed for `'static`
+   |                                                                                         -------- cast requires that `o2` is borrowed for `'static`
 ...
 LL |     o3.set1(&o2);
    |             ^^^ borrowed value does not live long enough

From 34d31673684a34b3858ba8dbc05fff8804a50508 Mon Sep 17 00:00:00 2001
From: lqd <remy.rakic+github@gmail.com>
Date: Tue, 17 Sep 2019 19:34:12 +0200
Subject: [PATCH 846/943] Bless json output of test ui/json-multiple.rs for
 Polonius

---
 src/test/ui/json-multiple.polonius.stderr | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 src/test/ui/json-multiple.polonius.stderr

diff --git a/src/test/ui/json-multiple.polonius.stderr b/src/test/ui/json-multiple.polonius.stderr
new file mode 100644
index 0000000000000..0e4d442f299c3
--- /dev/null
+++ b/src/test/ui/json-multiple.polonius.stderr
@@ -0,0 +1 @@
+{"artifact":"$TEST_BUILD_DIR/json-multiple.polonius/libjson_multiple.rlib","emit":"link"}

From f9c73293e231f1179c426311bd7ab11f46473e9a Mon Sep 17 00:00:00 2001
From: lqd <remy.rakic+github@gmail.com>
Date: Tue, 17 Sep 2019 19:35:16 +0200
Subject: [PATCH 847/943] Bless json output of test ui/json-options.rs for
 Polonius

---
 src/test/ui/json-options.polonius.stderr | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 src/test/ui/json-options.polonius.stderr

diff --git a/src/test/ui/json-options.polonius.stderr b/src/test/ui/json-options.polonius.stderr
new file mode 100644
index 0000000000000..e21f6f85d162d
--- /dev/null
+++ b/src/test/ui/json-options.polonius.stderr
@@ -0,0 +1 @@
+{"artifact":"$TEST_BUILD_DIR/json-options.polonius/libjson_options.rlib","emit":"link"}

From 3c2fd1a72d2e8cc80b354b4d2dd7931a7afe1b02 Mon Sep 17 00:00:00 2001
From: Matthew Jasper <mjjasper1@gmail.com>
Date: Sun, 14 Jul 2019 21:17:37 +0100
Subject: [PATCH 848/943] Print syntax contexts and marks when printing hygiene
 information

---
 src/librustc_driver/pretty.rs             |  9 +++++--
 src/libsyntax/print/pprust.rs             |  2 ++
 src/libsyntax_pos/hygiene.rs              | 32 +++++++++++++++++++++++
 src/test/ui/hygiene/unpretty-debug.stdout | 10 +++++++
 4 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index c4d3ad946f9f6..fa9504e22019e 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -326,6 +326,7 @@ impl<'hir> pprust::PpAnn for IdentifiedAnnotation<'hir> {
     }
     fn post(&self, s: &mut pprust::State<'_>, node: pprust::AnnNode<'_>) {
         match node {
+            pprust::AnnNode::Crate(_) |
             pprust::AnnNode::Ident(_) |
             pprust::AnnNode::Name(_) => {},
 
@@ -431,14 +432,18 @@ impl<'a> pprust::PpAnn for HygieneAnnotation<'a> {
         match node {
             pprust::AnnNode::Ident(&ast::Ident { name, span }) => {
                 s.s.space();
-                // FIXME #16420: this doesn't display the connections
-                // between syntax contexts
                 s.synth_comment(format!("{}{:?}", name.as_u32(), span.ctxt()))
             }
             pprust::AnnNode::Name(&name) => {
                 s.s.space();
                 s.synth_comment(name.as_u32().to_string())
             }
+            pprust::AnnNode::Crate(_) => {
+                s.s.hardbreak();
+                let verbose = self.sess.verbose();
+                s.synth_comment(syntax_pos::hygiene::debug_hygiene_data(verbose));
+                s.s.hardbreak_if_not_bol();
+            }
             _ => {}
         }
     }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index dd8c76342e35b..bf36c0d2f5658 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -35,6 +35,7 @@ pub enum AnnNode<'a> {
     SubItem(ast::NodeId),
     Expr(&'a ast::Expr),
     Pat(&'a ast::Pat),
+    Crate(&'a ast::Crate),
 }
 
 pub trait PpAnn {
@@ -140,6 +141,7 @@ pub fn print_crate<'a>(cm: &'a SourceMap,
 
     s.print_mod(&krate.module, &krate.attrs);
     s.print_remaining_comments();
+    s.ann.post(&mut s, AnnNode::Crate(krate));
     s.s.eof()
 }
 
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index f0e7344c1b986..8142d44b3f609 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -343,6 +343,38 @@ pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symb
     }))
 }
 
+pub fn debug_hygiene_data(verbose: bool) -> String {
+    HygieneData::with(|data| {
+        if verbose {
+            format!("{:#?}", data)
+        } else {
+            let mut s = String::from("");
+            s.push_str("Expansions:");
+            data.expn_data.iter().enumerate().for_each(|(id, expn_info)| {
+                let expn_info = expn_info.as_ref().expect("no expansion data for an expansion ID");
+                s.push_str(&format!(
+                    "\n{}: parent: {:?}, call_site_ctxt: {:?}, kind: {:?}",
+                    id,
+                    expn_info.parent,
+                    expn_info.call_site.ctxt(),
+                    expn_info.kind,
+                ));
+            });
+            s.push_str("\n\nSyntaxContexts:");
+            data.syntax_context_data.iter().enumerate().for_each(|(id, ctxt)| {
+                s.push_str(&format!(
+                    "\n#{}: parent: {:?}, outer_mark: ({:?}, {:?})",
+                    id,
+                    ctxt.parent,
+                    ctxt.outer_expn,
+                    ctxt.outer_transparency,
+                ));
+            });
+            s
+        }
+    })
+}
+
 impl SyntaxContext {
     #[inline]
     pub const fn root() -> Self {
diff --git a/src/test/ui/hygiene/unpretty-debug.stdout b/src/test/ui/hygiene/unpretty-debug.stdout
index beac4c17abf9c..6971873ba601e 100644
--- a/src/test/ui/hygiene/unpretty-debug.stdout
+++ b/src/test/ui/hygiene/unpretty-debug.stdout
@@ -13,3 +13,13 @@ macro_rules! foo /* 0#0 */ { ($ x : ident) => { y + $ x } }
 fn bar /* 0#0 */() { let x /* 0#0 */ = 1; y /* 0#1 */ + x /* 0#0 */ }
 
 fn y /* 0#0 */() { }
+
+/*
+Expansions:
+0: parent: ExpnId(0), call_site_ctxt: #0, kind: Root
+1: parent: ExpnId(0), call_site_ctxt: #0, kind: Macro(Bang, foo)
+
+SyntaxContexts:
+#0: parent: #0, outer_mark: (ExpnId(0), Opaque)
+#1: parent: #0, outer_mark: (ExpnId(1), SemiTransparent)
+*/

From ebd129b7ff2b67f93dedf27ce9aadd5197f0d015 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Tue, 17 Sep 2019 22:28:49 +0200
Subject: [PATCH 849/943] update Nomicon and Reference

---
 src/doc/nomicon   | 2 +-
 src/doc/reference | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/doc/nomicon b/src/doc/nomicon
index 38b9a76bc8b59..4374786f0b4bf 160000
--- a/src/doc/nomicon
+++ b/src/doc/nomicon
@@ -1 +1 @@
-Subproject commit 38b9a76bc8b59ac862663807fc51c9b757337fd6
+Subproject commit 4374786f0b4bf0606b35d5c30a9681f342e5707b
diff --git a/src/doc/reference b/src/doc/reference
index 1944efed35989..fa5dfb832ef8a 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit 1944efed35989ba57fa397c0724c4921310311fc
+Subproject commit fa5dfb832ef8a7568e17dabf612f486d641ff4ac

From 3daa8bd2e473c80e71b036786fa15729960562af Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Tue, 17 Sep 2019 19:07:35 -0400
Subject: [PATCH 850/943] Generate proc macro harness in AST order.

This ensures that we match the order used by proc macro metadata
serialization.

Fixes #64251
---
 src/librustc_metadata/decoder.rs            |   6 +-
 src/libsyntax_ext/proc_macro_harness.rs     | 109 +++++++++++---------
 src/test/rustdoc/inline_cross/proc_macro.rs |  13 ++-
 3 files changed, 79 insertions(+), 49 deletions(-)

diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 75d7261704722..34c84b1d79d4b 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -489,7 +489,11 @@ impl<'a, 'tcx> CrateMetadata {
 
     fn raw_proc_macro(&self, id: DefIndex) -> &ProcMacro {
         // DefIndex's in root.proc_macro_data have a one-to-one correspondence
-        // with items in 'raw_proc_macros'
+        // with items in 'raw_proc_macros'.
+        // NOTE: If you update the order of macros in 'proc_macro_data' for any reason,
+        // you must also update src/libsyntax_ext/proc_macro_harness.rs
+        // Failing to do so will result in incorrect data being associated
+        // with proc macros when deserialized.
         let pos = self.root.proc_macro_data.unwrap().decode(self).position(|i| i == id).unwrap();
         &self.raw_proc_macros.unwrap()[pos]
     }
diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs
index a5dcfb9840aca..f33c813d86cfe 100644
--- a/src/libsyntax_ext/proc_macro_harness.rs
+++ b/src/libsyntax_ext/proc_macro_harness.rs
@@ -20,15 +20,24 @@ struct ProcMacroDerive {
     attrs: Vec<ast::Name>,
 }
 
+enum ProcMacroDefType {
+    Attr,
+    Bang
+}
+
 struct ProcMacroDef {
     function_name: Ident,
     span: Span,
+    def_type: ProcMacroDefType
+}
+
+enum ProcMacro {
+    Derive(ProcMacroDerive),
+    Def(ProcMacroDef)
 }
 
 struct CollectProcMacros<'a> {
-    derives: Vec<ProcMacroDerive>,
-    attr_macros: Vec<ProcMacroDef>,
-    bang_macros: Vec<ProcMacroDef>,
+    macros: Vec<ProcMacro>,
     in_root: bool,
     handler: &'a errors::Handler,
     is_proc_macro_crate: bool,
@@ -46,22 +55,22 @@ pub fn inject(sess: &ParseSess,
     let ecfg = ExpansionConfig::default("proc_macro".to_string());
     let mut cx = ExtCtxt::new(sess, ecfg, resolver);
 
-    let (derives, attr_macros, bang_macros) = {
-        let mut collect = CollectProcMacros {
-            derives: Vec::new(),
-            attr_macros: Vec::new(),
-            bang_macros: Vec::new(),
-            in_root: true,
-            handler,
-            is_proc_macro_crate,
-            is_test_crate,
-        };
-        if has_proc_macro_decls || is_proc_macro_crate {
-            visit::walk_crate(&mut collect, &krate);
-        }
-        (collect.derives, collect.attr_macros, collect.bang_macros)
+    let mut collect = CollectProcMacros {
+        macros: Vec::new(),
+        in_root: true,
+        handler,
+        is_proc_macro_crate,
+        is_test_crate,
     };
 
+    if has_proc_macro_decls || is_proc_macro_crate {
+        visit::walk_crate(&mut collect, &krate);
+    }
+    // NOTE: If you change the order of macros in this vec
+    // for any reason, you must also update 'raw_proc_macro'
+    // in src/librustc_metadata/decoder.rs
+    let macros = collect.macros;
+
     if !is_proc_macro_crate {
         return krate
     }
@@ -74,7 +83,7 @@ pub fn inject(sess: &ParseSess,
         return krate;
     }
 
-    krate.module.items.push(mk_decls(&mut cx, &derives, &attr_macros, &bang_macros));
+    krate.module.items.push(mk_decls(&mut cx, &macros));
 
     krate
 }
@@ -161,12 +170,12 @@ impl<'a> CollectProcMacros<'a> {
         };
 
         if self.in_root && item.vis.node.is_pub() {
-            self.derives.push(ProcMacroDerive {
+            self.macros.push(ProcMacro::Derive(ProcMacroDerive {
                 span: item.span,
                 trait_name: trait_ident.name,
                 function_name: item.ident,
                 attrs: proc_attrs,
-            });
+            }));
         } else {
             let msg = if !self.in_root {
                 "functions tagged with `#[proc_macro_derive]` must \
@@ -180,10 +189,11 @@ impl<'a> CollectProcMacros<'a> {
 
     fn collect_attr_proc_macro(&mut self, item: &'a ast::Item) {
         if self.in_root && item.vis.node.is_pub() {
-            self.attr_macros.push(ProcMacroDef {
+            self.macros.push(ProcMacro::Def(ProcMacroDef {
                 span: item.span,
                 function_name: item.ident,
-            });
+                def_type: ProcMacroDefType::Attr
+            }));
         } else {
             let msg = if !self.in_root {
                 "functions tagged with `#[proc_macro_attribute]` must \
@@ -197,10 +207,11 @@ impl<'a> CollectProcMacros<'a> {
 
     fn collect_bang_proc_macro(&mut self, item: &'a ast::Item) {
         if self.in_root && item.vis.node.is_pub() {
-            self.bang_macros.push(ProcMacroDef {
+            self.macros.push(ProcMacro::Def(ProcMacroDef {
                 span: item.span,
                 function_name: item.ident,
-            });
+                def_type: ProcMacroDefType::Bang
+            }));
         } else {
             let msg = if !self.in_root {
                 "functions tagged with `#[proc_macro]` must \
@@ -322,9 +333,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> {
 //      }
 fn mk_decls(
     cx: &mut ExtCtxt<'_>,
-    custom_derives: &[ProcMacroDerive],
-    custom_attrs: &[ProcMacroDef],
-    custom_macros: &[ProcMacroDef],
+    macros: &[ProcMacro],
 ) -> P<ast::Item> {
     let expn_id = cx.resolver.expansion_for_ast_pass(
         DUMMY_SP,
@@ -354,26 +363,32 @@ fn mk_decls(
         let proc_macro_ty_method_path = |method| cx.expr_path(cx.path(span, vec![
             proc_macro, bridge, client, proc_macro_ty, method,
         ]));
-        custom_derives.iter().map(|cd| {
-            cx.expr_call(span, proc_macro_ty_method_path(custom_derive), vec![
-                cx.expr_str(cd.span, cd.trait_name),
-                cx.expr_vec_slice(
-                    span,
-                    cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::<Vec<_>>()
-                ),
-                local_path(cd.span, cd.function_name),
-            ])
-        }).chain(custom_attrs.iter().map(|ca| {
-            cx.expr_call(span, proc_macro_ty_method_path(attr), vec![
-                cx.expr_str(ca.span, ca.function_name.name),
-                local_path(ca.span, ca.function_name),
-            ])
-        })).chain(custom_macros.iter().map(|cm| {
-            cx.expr_call(span, proc_macro_ty_method_path(bang), vec![
-                cx.expr_str(cm.span, cm.function_name.name),
-                local_path(cm.span, cm.function_name),
-            ])
-        })).collect()
+        macros.iter().map(|m| {
+            match m {
+                ProcMacro::Derive(cd) => {
+                    cx.expr_call(span, proc_macro_ty_method_path(custom_derive), vec![
+                        cx.expr_str(cd.span, cd.trait_name),
+                        cx.expr_vec_slice(
+                            span,
+                            cd.attrs.iter().map(|&s| cx.expr_str(cd.span, s)).collect::<Vec<_>>()
+                        ),
+                        local_path(cd.span, cd.function_name),
+                    ])
+                },
+                ProcMacro::Def(ca) => {
+                    let ident = match ca.def_type {
+                        ProcMacroDefType::Attr => attr,
+                        ProcMacroDefType::Bang => bang
+                    };
+
+                    cx.expr_call(span, proc_macro_ty_method_path(ident), vec![
+                        cx.expr_str(ca.span, ca.function_name.name),
+                        local_path(ca.span, ca.function_name),
+                    ])
+
+                }
+            }
+        }).collect()
     };
 
     let decls_static = cx.item_static(
diff --git a/src/test/rustdoc/inline_cross/proc_macro.rs b/src/test/rustdoc/inline_cross/proc_macro.rs
index 6880e303df90b..3dc8de3fe579d 100644
--- a/src/test/rustdoc/inline_cross/proc_macro.rs
+++ b/src/test/rustdoc/inline_cross/proc_macro.rs
@@ -10,8 +10,19 @@ extern crate some_macros;
 // @has proc_macro/macro.some_proc_macro.html
 // @has proc_macro/attr.some_proc_attr.html
 // @has proc_macro/derive.SomeDerive.html
-pub use some_macros::{some_proc_macro, some_proc_attr, SomeDerive};
+
+// @has proc_macro/macro.some_proc_macro.html
+// @has - 'a proc-macro that swallows its input and does nothing.'
+pub use some_macros::some_proc_macro;
 
 // @has proc_macro/macro.reexported_macro.html
 // @has - 'Doc comment from the original crate'
 pub use some_macros::reexported_macro;
+
+// @has proc_macro/attr.some_proc_attr.html
+// @has - 'a proc-macro attribute that passes its item through verbatim.'
+pub use some_macros::some_proc_attr;
+
+// @has proc_macro/derive.SomeDerive.html
+// @has - 'a derive attribute that adds nothing to its input.'
+pub use some_macros::SomeDerive;

From ceb72e4ad144f4887f67e539bcd143b4d303dade Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Tue, 17 Sep 2019 16:25:29 -0700
Subject: [PATCH 851/943] Add generic dataflow impl

---
 src/librustc_mir/dataflow/generic.rs | 444 +++++++++++++++++++++++++++
 src/librustc_mir/dataflow/mod.rs     |   1 +
 src/librustc_mir/lib.rs              |   1 +
 3 files changed, 446 insertions(+)
 create mode 100644 src/librustc_mir/dataflow/generic.rs

diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs
new file mode 100644
index 0000000000000..7819fd11845e6
--- /dev/null
+++ b/src/librustc_mir/dataflow/generic.rs
@@ -0,0 +1,444 @@
+use std::cmp::Ordering;
+use std::ops;
+
+use rustc::mir::{self, traversal, BasicBlock, Location};
+use rustc_data_structures::bit_set::BitSet;
+use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use rustc_data_structures::work_queue::WorkQueue;
+
+use crate::dataflow::BottomValue;
+
+pub trait Analysis<'tcx>: BottomValue {
+    type Idx: Idx;
+
+    fn name() -> &'static str;
+
+    fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize;
+
+    fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>);
+
+    fn apply_statement_effect(
+        &self,
+        state: &mut BitSet<Self::Idx>,
+        statement: &mir::Statement<'tcx>,
+        location: Location,
+    );
+
+    fn apply_terminator_effect(
+        &self,
+        state: &mut BitSet<Self::Idx>,
+        terminator: &mir::Terminator<'tcx>,
+        location: Location,
+    );
+
+    fn apply_call_return_effect(
+        &self,
+        state: &mut BitSet<Self::Idx>,
+        block: BasicBlock,
+        func: &mir::Operand<'tcx>,
+        args: &[mir::Operand<'tcx>],
+        return_place: &mir::Place<'tcx>,
+    );
+
+    /// Applies the cumulative effect of an entire basic block to the dataflow state (except for
+    /// `call_return_effect`, which is handled in the `Engine`).
+    ///
+    /// The default implementation calls `statement_effect` for every statement in the block before
+    /// finally calling `terminator_effect`. However, some dataflow analyses are able to coalesce
+    /// transfer functions for an entire block and apply them at once. Such analyses should
+    /// override `block_effect`.
+    fn apply_whole_block_effect(
+        &self,
+        state: &mut BitSet<Self::Idx>,
+        block: BasicBlock,
+        block_data: &mir::BasicBlockData<'tcx>,
+    ) {
+        for (statement_index, stmt) in block_data.statements.iter().enumerate() {
+            let location = Location { block, statement_index };
+            self.apply_statement_effect(state, stmt, location);
+        }
+
+        let location = Location { block, statement_index: block_data.statements.len() };
+        self.apply_terminator_effect(state, block_data.terminator(), location);
+    }
+
+    /// Applies the cumulative effect of a sequence of statements (and possibly a terminator)
+    /// within a single basic block.
+    ///
+    /// When called with `0..block_data.statements.len() + 1` as the statement range, this function
+    /// is equivalent to `apply_whole_block_effect`.
+    fn apply_partial_block_effect(
+        &self,
+        state: &mut BitSet<Self::Idx>,
+        block: BasicBlock,
+        block_data: &mir::BasicBlockData<'tcx>,
+        mut range: ops::Range<usize>,
+    ) {
+        if range.is_empty() {
+            return;
+        }
+
+        // The final location might be a terminator, so iterate through all statements until the
+        // final one, then check to see whether the final one is a statement or terminator.
+        //
+        // This can't cause the range to wrap-around since we check that the range contains at
+        // least one element above.
+        range.end -= 1;
+        let final_location = Location { block, statement_index: range.end };
+
+        for statement_index in range {
+            let location = Location { block, statement_index };
+            let stmt = &block_data.statements[statement_index];
+            self.apply_statement_effect(state, stmt, location);
+        }
+
+        if final_location.statement_index == block_data.statements.len() {
+            let terminator = block_data.terminator();
+            self.apply_terminator_effect(state, terminator, final_location);
+        } else {
+            let stmt = &block_data.statements[final_location.statement_index];
+            self.apply_statement_effect(state, stmt, final_location);
+        }
+    }
+}
+
+#[derive(Clone, Copy, Debug)]
+enum CursorPosition {
+    AtBlockStart(BasicBlock),
+    After(Location),
+}
+
+impl CursorPosition {
+    fn block(&self) -> BasicBlock {
+        match *self {
+            Self::AtBlockStart(block) => block,
+            Self::After(Location { block, .. }) => block,
+        }
+    }
+}
+
+pub struct ResultsCursor<'mir, 'tcx, A>
+where
+    A: Analysis<'tcx>,
+{
+    body: &'mir mir::Body<'tcx>,
+    results: Results<'tcx, A>,
+    state: BitSet<A::Idx>,
+
+    pos: CursorPosition,
+
+    /// Whether the effects of `apply_call_return_effect` are currently stored in `state`.
+    ///
+    /// This flag ensures that multiple calls to `seek_after_assume_call_returns` with the same
+    /// target only result in one invocation of `apply_call_return_effect`.
+    is_call_return_effect_applied: bool,
+}
+
+impl<'mir, 'tcx, A> ResultsCursor<'mir, 'tcx, A>
+where
+    A: Analysis<'tcx>,
+{
+    /// Returns a new cursor for `results` that points to the start of the `START_BLOCK`.
+    pub fn new(body: &'mir mir::Body<'tcx>, results: Results<'tcx, A>) -> Self {
+        ResultsCursor {
+            body,
+            pos: CursorPosition::AtBlockStart(mir::START_BLOCK),
+            is_call_return_effect_applied: false,
+            state: results.entry_sets[mir::START_BLOCK].clone(),
+            results,
+        }
+    }
+
+    /// Resets the cursor to the start of the given `block`.
+    pub fn seek_to_block_start(&mut self, block: BasicBlock) {
+        self.state.overwrite(&self.results.entry_sets[block]);
+        self.pos = CursorPosition::AtBlockStart(block);
+        self.is_call_return_effect_applied = false;
+    }
+
+    /// Updates the cursor to hold the dataflow state immediately before `target`.
+    #[allow(unused)]
+    pub fn seek_before(&mut self, target: Location) {
+        assert!(target <= self.body.terminator_loc(target.block));
+
+        if target.statement_index == 0 {
+            self.seek_to_block_start(target.block);
+        } else {
+            self._seek_after(Location {
+                block: target.block,
+                statement_index: target.statement_index - 1,
+            });
+        }
+    }
+
+    /// Updates the cursor to hold the dataflow state at `target`.
+    ///
+    /// If `target` is a `Call` terminator, `apply_call_return_effect` will not be called. See
+    /// `seek_after_assume_call_returns` if you wish to observe the dataflow state upon a
+    /// successful return.
+    #[allow(unused)]
+    pub fn seek_after(&mut self, target: Location) {
+        assert!(target <= self.body.terminator_loc(target.block));
+
+        // This check ensures the correctness of a call to `seek_after_assume_call_returns`
+        // followed by one to `seek_after` with the same target.
+        if self.is_call_return_effect_applied {
+            self.seek_to_block_start(target.block);
+        }
+
+        self._seek_after(target);
+    }
+
+    /// Equivalent to `seek_after`, but also calls `apply_call_return_effect` if `target` is a
+    /// `Call` terminator whose callee is convergent.
+    #[allow(unused)]
+    pub fn seek_after_assume_call_returns(&mut self, target: Location) {
+        assert!(target <= self.body.terminator_loc(target.block));
+
+        self._seek_after(target);
+
+        if target != self.body.terminator_loc(target.block) {
+            return;
+        }
+
+        let term = self.body.basic_blocks()[target.block].terminator();
+        if let mir::TerminatorKind::Call {
+            destination: Some((return_place, _)),
+            func,
+            args,
+            ..
+        } = &term.kind {
+            if !self.is_call_return_effect_applied {
+                self.results.analysis.apply_call_return_effect(
+                    &mut self.state,
+                    target.block,
+                    func,
+                    args,
+                    return_place,
+                );
+            }
+        }
+    }
+
+    fn _seek_after(&mut self, target: Location) {
+        let Location { block: target_block, statement_index: target_index } = target;
+
+        if self.pos.block() != target_block {
+            self.seek_to_block_start(target_block);
+        }
+
+        // If we're in the same block but after the target statement, we need to reset to the start
+        // of the block.
+        if let CursorPosition::After(Location { statement_index: curr_index, .. }) = self.pos {
+            match curr_index.cmp(&target_index) {
+                Ordering::Equal => return,
+                Ordering::Less => {},
+                Ordering::Greater => self.seek_to_block_start(target_block),
+            }
+        }
+
+        // The cursor is now in the same block as the target location pointing at an earlier
+        // statement.
+        debug_assert_eq!(self.pos.block(), target_block);
+        if let CursorPosition::After(Location { statement_index, .. }) = self.pos {
+            debug_assert!(statement_index < target_index);
+        }
+
+        let first_unapplied_statement = match self.pos {
+            CursorPosition::AtBlockStart(_) => 0,
+            CursorPosition::After(Location { statement_index, .. }) => statement_index + 1,
+        };
+
+        let block_data = &self.body.basic_blocks()[target_block];
+        self.results.analysis.apply_partial_block_effect(
+            &mut self.state,
+            target_block,
+            block_data,
+            first_unapplied_statement..target_index + 1,
+        );
+
+        self.pos = CursorPosition::After(target);
+        self.is_call_return_effect_applied = false;
+    }
+
+    /// Gets the dataflow state at the current location.
+    pub fn get(&self) -> &BitSet<A::Idx> {
+        &self.state
+    }
+}
+
+pub struct Results<'tcx, A>
+where
+    A: Analysis<'tcx>,
+{
+    analysis: A,
+    entry_sets: IndexVec<BasicBlock, BitSet<A::Idx>>,
+}
+
+pub struct Engine<'a, 'tcx, A>
+where
+    A: Analysis<'tcx>,
+{
+    analysis: A,
+    bits_per_block: usize,
+    body: &'a mir::Body<'tcx>,
+    dead_unwinds: &'a BitSet<BasicBlock>,
+    entry_sets: IndexVec<BasicBlock, BitSet<A::Idx>>,
+}
+
+impl<A> Engine<'a, 'tcx, A>
+where
+    A: Analysis<'tcx>,
+{
+    pub fn new(
+        body: &'a mir::Body<'tcx>,
+        dead_unwinds: &'a BitSet<BasicBlock>,
+        analysis: A,
+    ) -> Self {
+        let bits_per_block = analysis.bits_per_block(body);
+
+        let bottom_value_set = if A::BOTTOM_VALUE == true {
+            BitSet::new_filled(bits_per_block)
+        } else {
+            BitSet::new_empty(bits_per_block)
+        };
+
+        let mut entry_sets = IndexVec::from_elem(bottom_value_set, body.basic_blocks());
+        analysis.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]);
+
+        Engine {
+            analysis,
+            bits_per_block,
+            body,
+            dead_unwinds,
+            entry_sets,
+        }
+    }
+
+    pub fn iterate_to_fixpoint(mut self) -> Results<'tcx, A> {
+        let mut temp_state = BitSet::new_empty(self.bits_per_block);
+
+        let mut dirty_queue: WorkQueue<BasicBlock> =
+            WorkQueue::with_none(self.body.basic_blocks().len());
+
+        for (bb, _) in traversal::reverse_postorder(self.body) {
+            dirty_queue.insert(bb);
+        }
+
+        // Add blocks that are not reachable from START_BLOCK to the work queue. These blocks will
+        // be processed after the ones added above.
+        for bb in self.body.basic_blocks().indices() {
+            dirty_queue.insert(bb);
+        }
+
+        while let Some(bb) = dirty_queue.pop() {
+            let bb_data = &self.body[bb];
+            let on_entry = &self.entry_sets[bb];
+
+            temp_state.overwrite(on_entry);
+            self.analysis.apply_whole_block_effect(&mut temp_state, bb, bb_data);
+
+            self.propagate_bits_into_graph_successors_of(
+                &mut temp_state,
+                (bb, bb_data),
+                &mut dirty_queue,
+            );
+        }
+
+        Results {
+            analysis: self.analysis,
+            entry_sets: self.entry_sets,
+        }
+    }
+
+    fn propagate_bits_into_graph_successors_of(
+        &mut self,
+        in_out: &mut BitSet<A::Idx>,
+        (bb, bb_data): (BasicBlock, &'a mir::BasicBlockData<'tcx>),
+        dirty_list: &mut WorkQueue<BasicBlock>,
+    ) {
+        match bb_data.terminator().kind {
+            mir::TerminatorKind::Return
+            | mir::TerminatorKind::Resume
+            | mir::TerminatorKind::Abort
+            | mir::TerminatorKind::GeneratorDrop
+            | mir::TerminatorKind::Unreachable => {}
+
+            mir::TerminatorKind::Goto { target }
+            | mir::TerminatorKind::Assert { target, cleanup: None, .. }
+            | mir::TerminatorKind::Yield { resume: target, drop: None, .. }
+            | mir::TerminatorKind::Drop { target, location: _, unwind: None }
+            | mir::TerminatorKind::DropAndReplace { target, value: _, location: _, unwind: None } =>
+            {
+                self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
+            }
+
+            mir::TerminatorKind::Yield { resume: target, drop: Some(drop), .. } => {
+                self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
+                self.propagate_bits_into_entry_set_for(in_out, drop, dirty_list);
+            }
+
+            mir::TerminatorKind::Assert { target, cleanup: Some(unwind), .. }
+            | mir::TerminatorKind::Drop { target, location: _, unwind: Some(unwind) }
+            | mir::TerminatorKind::DropAndReplace {
+                target,
+                value: _,
+                location: _,
+                unwind: Some(unwind),
+            } => {
+                self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
+                if !self.dead_unwinds.contains(bb) {
+                    self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
+                }
+            }
+
+            mir::TerminatorKind::SwitchInt { ref targets, .. } => {
+                for target in targets {
+                    self.propagate_bits_into_entry_set_for(in_out, *target, dirty_list);
+                }
+            }
+
+            mir::TerminatorKind::Call { cleanup, ref destination, ref func, ref args, .. } => {
+                if let Some(unwind) = cleanup {
+                    if !self.dead_unwinds.contains(bb) {
+                        self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
+                    }
+                }
+
+                if let Some((ref dest_place, dest_bb)) = *destination {
+                    // N.B.: This must be done *last*, after all other
+                    // propagation, as documented in comment above.
+                    self.analysis.apply_call_return_effect(in_out, bb, func, args, dest_place);
+                    self.propagate_bits_into_entry_set_for(in_out, dest_bb, dirty_list);
+                }
+            }
+
+            mir::TerminatorKind::FalseEdges { real_target, imaginary_target } => {
+                self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list);
+                self.propagate_bits_into_entry_set_for(in_out, imaginary_target, dirty_list);
+            }
+
+            mir::TerminatorKind::FalseUnwind { real_target, unwind } => {
+                self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list);
+                if let Some(unwind) = unwind {
+                    if !self.dead_unwinds.contains(bb) {
+                        self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
+                    }
+                }
+            }
+        }
+    }
+
+    fn propagate_bits_into_entry_set_for(
+        &mut self,
+        in_out: &BitSet<A::Idx>,
+        bb: BasicBlock,
+        dirty_queue: &mut WorkQueue<BasicBlock>,
+    ) {
+        let entry_set = &mut self.entry_sets[bb];
+        let set_changed = self.analysis.join(entry_set, &in_out);
+        if set_changed {
+            dirty_queue.insert(bb);
+        }
+    }
+}
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index 7fe2a890a5371..55baeef8860d0 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -30,6 +30,7 @@ use self::move_paths::MoveData;
 
 mod at_location;
 pub mod drop_flag_effects;
+pub mod generic;
 mod graphviz;
 mod impls;
 pub mod move_paths;
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index f27db351b74db..c4738d846be63 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -23,6 +23,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(try_blocks)]
 #![feature(mem_take)]
 #![feature(associated_type_bounds)]
+#![feature(range_is_empty)]
 
 #![recursion_limit="256"]
 

From 5496a1fbbe3facc09dfc23be80707905eb844a62 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Tue, 17 Sep 2019 17:22:05 -0700
Subject: [PATCH 852/943] Document new dataflow analysis

---
 src/librustc_mir/dataflow/generic.rs | 50 ++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs
index 7819fd11845e6..696b44ac2efc2 100644
--- a/src/librustc_mir/dataflow/generic.rs
+++ b/src/librustc_mir/dataflow/generic.rs
@@ -8,15 +8,48 @@ use rustc_data_structures::work_queue::WorkQueue;
 
 use crate::dataflow::BottomValue;
 
+/// A specific kind of dataflow analysis.
+///
+/// To run a dataflow analysis, one must set the initial state of the `START_BLOCK` via
+/// `initialize_start_block` and define a transfer function for each statement or terminator via
+/// the various `effect` methods. The entry set for all other basic blocks is initialized to
+/// `Self::BOTTOM_VALUE`. The dataflow `Engine` then iteratively updates the various entry sets for
+/// each block with the cumulative effects of the transfer functions of all preceding blocks.
+///
+/// You should use an `Engine` to actually run an analysis, and a `ResultsCursor` to inspect the
+/// results of that analysis like so:
+///
+/// ```ignore
+/// fn do_my_analysis(body: &mir::Body<'tcx>, dead_unwinds: &BitSet<BasicBlock>) {
+///     let analysis = MyAnalysis::new();
+///     let results = Engine::new(body, dead_unwinds, analysis).iterate_to_fixpoint();
+///     let mut cursor = dataflow::ResultsCursor::new(body, results);
+///
+///     for statement_index in body.block_data[START_BLOCK].statements.iter() {
+///         cursor.seek_after(Location { block: START_BLOCK, statement_index });
+///         let state = cursor.get();
+///         println!("{:?}", state);
+///     }
+/// }
+/// ```
 pub trait Analysis<'tcx>: BottomValue {
+    /// The index type used to access the dataflow state.
     type Idx: Idx;
 
+    /// A name describing the dataflow analysis being implemented.
+    ///
+    /// The name should be suitable as part of a filename, so avoid whitespace, slashes or periods
+    /// and try to keep it short.
     fn name() -> &'static str;
 
+    /// The size of each bitvector allocated for each block.
     fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize;
 
+    /// Mutates the entry set of the `START_BLOCK` to containthe initial state for dataflow
+    /// analysis.
     fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>);
 
+    /// Updates the current dataflow state with the effect of evaluating a statement.
     fn apply_statement_effect(
         &self,
         state: &mut BitSet<Self::Idx>,
@@ -24,6 +57,11 @@ pub trait Analysis<'tcx>: BottomValue {
         location: Location,
     );
 
+    /// Updates the current dataflow state with the effect of evaluating a statement.
+    ///
+    /// Note that the effect of a successful return from a `Call` terminator should **not** be
+    /// acounted for in this function. That should go in `apply_call_return_effect`. For example,
+    /// in the `InitializedPlaces` analyses, the return place is not marked as initialized here.
     fn apply_terminator_effect(
         &self,
         state: &mut BitSet<Self::Idx>,
@@ -31,6 +69,11 @@ pub trait Analysis<'tcx>: BottomValue {
         location: Location,
     );
 
+    /// Updates the current dataflow state with the effect of a successful return from a `Call`
+    /// terminator.
+    ///
+    /// This is separated from `apply_terminator_effect` to properly track state across
+    /// unwind edges for `Call`s.
     fn apply_call_return_effect(
         &self,
         state: &mut BitSet<Self::Idx>,
@@ -117,6 +160,11 @@ impl CursorPosition {
     }
 }
 
+/// Inspect the results of dataflow analysis.
+///
+/// This cursor has linear performance when visiting statements in a block in order. Visiting
+/// statements within a block in reverse order is `O(n^2)`, where `n` is the number of statements
+/// in that block.
 pub struct ResultsCursor<'mir, 'tcx, A>
 where
     A: Analysis<'tcx>,
@@ -267,6 +315,7 @@ where
     }
 }
 
+/// A completed dataflow analysis.
 pub struct Results<'tcx, A>
 where
     A: Analysis<'tcx>,
@@ -275,6 +324,7 @@ where
     entry_sets: IndexVec<BasicBlock, BitSet<A::Idx>>,
 }
 
+/// All information required to iterate a dataflow analysis to fixpoint.
 pub struct Engine<'a, 'tcx, A>
 where
     A: Analysis<'tcx>,

From 288603709ecb1fc8fb4cf342ff681e112468e593 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Tue, 17 Sep 2019 17:22:20 -0700
Subject: [PATCH 853/943] Temporarily add `#[allow(unused)]` for CI

This can be removed once dataflow-based const validation is merged.
---
 src/librustc_mir/dataflow/generic.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs
index 696b44ac2efc2..e890b2c66e61c 100644
--- a/src/librustc_mir/dataflow/generic.rs
+++ b/src/librustc_mir/dataflow/generic.rs
@@ -1,3 +1,5 @@
+#![allow(unused)]
+
 use std::cmp::Ordering;
 use std::ops;
 

From d583fefa59e87cf39714c92c90fd9449f0975ea2 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Tue, 17 Sep 2019 17:49:13 -0700
Subject: [PATCH 854/943] Add ignore reason to placate `tidy`

---
 src/librustc_mir/dataflow/generic.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs
index e890b2c66e61c..47d6bd9caba43 100644
--- a/src/librustc_mir/dataflow/generic.rs
+++ b/src/librustc_mir/dataflow/generic.rs
@@ -21,7 +21,7 @@ use crate::dataflow::BottomValue;
 /// You should use an `Engine` to actually run an analysis, and a `ResultsCursor` to inspect the
 /// results of that analysis like so:
 ///
-/// ```ignore
+/// ```ignore(cross-crate-imports)
 /// fn do_my_analysis(body: &mir::Body<'tcx>, dead_unwinds: &BitSet<BasicBlock>) {
 ///     let analysis = MyAnalysis::new();
 ///     let results = Engine::new(body, dead_unwinds, analysis).iterate_to_fixpoint();

From bec0a7672752810547a3a191d49d56a338bc1c90 Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Wed, 18 Sep 2019 08:24:24 +0000
Subject: [PATCH 855/943] doc: Format some primitives examples

---
 src/libcore/num/mod.rs | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index df1c00ccd184f..0cf2ebb487ddd 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -2092,11 +2092,14 @@ $to_xe_bytes_doc,
 
 ```
 let bytes = ", $swap_op, stringify!($SelfT), ".to_ne_bytes();
-assert_eq!(bytes, if cfg!(target_endian = \"big\") {
+assert_eq!(
+    bytes,
+    if cfg!(target_endian = \"big\") {
         ", $be_bytes, "
     } else {
         ", $le_bytes, "
-    });
+    }
+);
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -2188,10 +2191,10 @@ $from_xe_bytes_doc,
 
 ```
 let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"big\") {
-        ", $be_bytes, "
-    } else {
-        ", $le_bytes, "
-    });
+    ", $be_bytes, "
+} else {
+    ", $le_bytes, "
+});
 assert_eq!(value, ", $swap_op, ");
 ```
 
@@ -3911,11 +3914,14 @@ $to_xe_bytes_doc,
 
 ```
 let bytes = ", $swap_op, stringify!($SelfT), ".to_ne_bytes();
-assert_eq!(bytes, if cfg!(target_endian = \"big\") {
+assert_eq!(
+    bytes,
+    if cfg!(target_endian = \"big\") {
         ", $be_bytes, "
     } else {
         ", $le_bytes, "
-    });
+    }
+);
 ```"),
             #[stable(feature = "int_to_from_bytes", since = "1.32.0")]
             #[rustc_const_unstable(feature = "const_int_conversion")]
@@ -4007,10 +4013,10 @@ $from_xe_bytes_doc,
 
 ```
 let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"big\") {
-        ", $be_bytes, "
-    } else {
-        ", $le_bytes, "
-    });
+    ", $be_bytes, "
+} else {
+    ", $le_bytes, "
+});
 assert_eq!(value, ", $swap_op, ");
 ```
 

From eb48b5d983fde79ab3595f250871116ee650c5e9 Mon Sep 17 00:00:00 2001
From: Arno Haase <arno.haase@haase-consulting.com>
Date: Wed, 18 Sep 2019 12:31:34 +0200
Subject: [PATCH 856/943] broken hyperlinks in documentation

---
 src/libcore/hint.rs        | 2 +-
 src/libcore/sync/atomic.rs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs
index 3ea8b31fda6d0..ee4be6c915119 100644
--- a/src/libcore/hint.rs
+++ b/src/libcore/hint.rs
@@ -58,7 +58,7 @@ pub unsafe fn unreachable_unchecked() -> ! {
 /// **Note**: On platforms that do not support receiving spin-loop hints this function does not
 /// do anything at all.
 ///
-/// [`core::sync::atomic::spin_loop_hint`]: ./sync/atomic/fn.spin_loop_hint.html
+/// [`core::sync::atomic::spin_loop_hint`]: ../sync/atomic/fn.spin_loop_hint.html
 #[inline]
 #[unstable(feature = "renamed_spin_loop", issue = "55002")]
 pub fn spin_loop() {
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 63ee9a42a0f72..ab5af5682c180 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -148,7 +148,7 @@ use crate::hint::spin_loop;
 ///
 /// [`std::thread::yield_now`]: ../../../std/thread/fn.yield_now.html
 /// [`std::thread::sleep`]: ../../../std/thread/fn.sleep.html
-/// [`std::sync::Mutex`]: ../../../std/sync/Mutex.html
+/// [`std::sync::Mutex`]: ../../../std/sync/struct.Mutex.html
 #[inline]
 #[stable(feature = "spin_loop_hint", since = "1.24.0")]
 pub fn spin_loop_hint() {

From cbaaf05b9425996d8d14bbd5fe435ac7d3d955f1 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Wed, 18 Sep 2019 07:32:15 -0700
Subject: [PATCH 857/943] Fix `Analysis` example

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

diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs
index 47d6bd9caba43..73f17e75afe37 100644
--- a/src/librustc_mir/dataflow/generic.rs
+++ b/src/librustc_mir/dataflow/generic.rs
@@ -23,11 +23,13 @@ use crate::dataflow::BottomValue;
 ///
 /// ```ignore(cross-crate-imports)
 /// fn do_my_analysis(body: &mir::Body<'tcx>, dead_unwinds: &BitSet<BasicBlock>) {
+///     // `MyAnalysis` implements `Analysis`.
 ///     let analysis = MyAnalysis::new();
+///
 ///     let results = Engine::new(body, dead_unwinds, analysis).iterate_to_fixpoint();
-///     let mut cursor = dataflow::ResultsCursor::new(body, results);
+///     let mut cursor = ResultsCursor::new(body, results);
 ///
-///     for statement_index in body.block_data[START_BLOCK].statements.iter() {
+///     for (_, statement_index) in body.block_data[START_BLOCK].statements.iter_enumerated() {
 ///         cursor.seek_after(Location { block: START_BLOCK, statement_index });
 ///         let state = cursor.get();
 ///         println!("{:?}", state);

From a526e4faa6b69f1b6ea60e5e692b679e24bb1994 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Wed, 18 Sep 2019 07:32:42 -0700
Subject: [PATCH 858/943] Use an associated const for `name`

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

diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs
index 73f17e75afe37..6ee81de19f138 100644
--- a/src/librustc_mir/dataflow/generic.rs
+++ b/src/librustc_mir/dataflow/generic.rs
@@ -40,11 +40,11 @@ pub trait Analysis<'tcx>: BottomValue {
     /// The index type used to access the dataflow state.
     type Idx: Idx;
 
-    /// A name describing the dataflow analysis being implemented.
+    /// A name, used for debugging, that describes this dataflow analysis.
     ///
     /// The name should be suitable as part of a filename, so avoid whitespace, slashes or periods
     /// and try to keep it short.
-    fn name() -> &'static str;
+    const NAME: &'static str;
 
     /// The size of each bitvector allocated for each block.
     fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize;

From 19bf0f4c905aa17fb9f975432c1d32e210e2deb8 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Wed, 18 Sep 2019 07:32:57 -0700
Subject: [PATCH 859/943] Fix typo

---
 src/librustc_mir/dataflow/generic.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs
index 6ee81de19f138..901467d52dc51 100644
--- a/src/librustc_mir/dataflow/generic.rs
+++ b/src/librustc_mir/dataflow/generic.rs
@@ -49,7 +49,7 @@ pub trait Analysis<'tcx>: BottomValue {
     /// The size of each bitvector allocated for each block.
     fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize;
 
-    /// Mutates the entry set of the `START_BLOCK` to containthe initial state for dataflow
+    /// Mutates the entry set of the `START_BLOCK` to contain the initial state for dataflow
     /// analysis.
     fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>);
 

From 08aff1afe5edb5c31ebb2b1bcdf6025fa323a8fe Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Wed, 18 Sep 2019 07:35:44 -0700
Subject: [PATCH 860/943] Publish `rustc_mir::dataflow` and remove
 `#[allow(unused)]`

---
 src/librustc_mir/dataflow/generic.rs | 5 -----
 src/librustc_mir/lib.rs              | 2 +-
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs
index 901467d52dc51..a4b81968d727c 100644
--- a/src/librustc_mir/dataflow/generic.rs
+++ b/src/librustc_mir/dataflow/generic.rs
@@ -1,5 +1,3 @@
-#![allow(unused)]
-
 use std::cmp::Ordering;
 use std::ops;
 
@@ -209,7 +207,6 @@ where
     }
 
     /// Updates the cursor to hold the dataflow state immediately before `target`.
-    #[allow(unused)]
     pub fn seek_before(&mut self, target: Location) {
         assert!(target <= self.body.terminator_loc(target.block));
 
@@ -228,7 +225,6 @@ where
     /// If `target` is a `Call` terminator, `apply_call_return_effect` will not be called. See
     /// `seek_after_assume_call_returns` if you wish to observe the dataflow state upon a
     /// successful return.
-    #[allow(unused)]
     pub fn seek_after(&mut self, target: Location) {
         assert!(target <= self.body.terminator_loc(target.block));
 
@@ -243,7 +239,6 @@ where
 
     /// Equivalent to `seek_after`, but also calls `apply_call_return_effect` if `target` is a
     /// `Call` terminator whose callee is convergent.
-    #[allow(unused)]
     pub fn seek_after_assume_call_returns(&mut self, target: Location) {
         assert!(target <= self.body.terminator_loc(target.block));
 
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index c4738d846be63..091dfbea5a88e 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -36,7 +36,7 @@ pub mod error_codes;
 
 mod borrow_check;
 mod build;
-mod dataflow;
+pub mod dataflow;
 mod hair;
 mod lints;
 mod shim;

From 445af68c23098596d70b7f9f74b37fcb43146cf5 Mon Sep 17 00:00:00 2001
From: Maximilian Roos <m@maxroos.com>
Date: Wed, 18 Sep 2019 10:42:55 -0400
Subject: [PATCH 861/943] fix debuginfo/issue22656 with LLDB 8

---
 src/test/debuginfo/issue-22656.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/debuginfo/issue-22656.rs b/src/test/debuginfo/issue-22656.rs
index 86d31909a0b3b..e4634d96a6f31 100644
--- a/src/test/debuginfo/issue-22656.rs
+++ b/src/test/debuginfo/issue-22656.rs
@@ -15,7 +15,7 @@
 // lldbg-check:[...]$0 = vec![1, 2, 3]
 // lldbr-check:(alloc::vec::Vec<i32>) v = vec![1, 2, 3]
 // lldb-command:print zs
-// lldbg-check:[...]$1 = StructWithZeroSizedField { x: ZeroSizedStruct, y: 123, z: ZeroSizedStruct, w: 456 }
+// lldbg-check:[...]$1 = StructWithZeroSizedField { x: ZeroSizedStruct[...], y: 123, z: ZeroSizedStruct[...], w: 456 }
 // lldbr-check:(issue_22656::StructWithZeroSizedField) zs = StructWithZeroSizedField { x: ZeroSizedStruct { }, y: 123, z: ZeroSizedStruct { }, w: 456 }
 // lldbr-command:continue
 

From a7f52520d5433a2bd3e4e6727b311047ef066500 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Wed, 18 Sep 2019 08:41:38 -0700
Subject: [PATCH 862/943] Add summary of the current state and future plans

---
 src/librustc_mir/dataflow/generic.rs | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs
index a4b81968d727c..5a28df42f20a5 100644
--- a/src/librustc_mir/dataflow/generic.rs
+++ b/src/librustc_mir/dataflow/generic.rs
@@ -1,3 +1,21 @@
+//! Dataflow analysis with arbitrary transfer functions.
+//!
+//! This module is a work in progress. You should instead use `BitDenotation` in
+//! `librustc_mir/dataflow/mod.rs` and encode your transfer function as a [gen/kill set][gk]. In
+//! doing so, your analysis will run faster and you will be able to generate graphviz diagrams for
+//! debugging with no extra effort. The interface in this module is intended only for dataflow
+//! problems that cannot be expressed using gen/kill sets.
+//!
+//! FIXME(ecstaticmorse): In the long term, the plan is to preserve the existing `BitDenotation`
+//! interface, but make `Engine` and `ResultsCursor` the canonical way to perform and inspect a
+//! dataflow analysis. This requires porting the graphviz debugging logic to this module, deciding
+//! on a way to handle the `before` methods in `BitDenotation` and creating an adapter so that
+//! gen-kill problems can still be evaluated efficiently. See the discussion in [#64566][] for more
+//! information.
+//!
+//! [gk]: https://en.wikipedia.org/wiki/Data-flow_analysis#Bit_vector_problems
+//! [#64566]: https://github.com/rust-lang/rust/pull/64566
+
 use std::cmp::Ordering;
 use std::ops;
 

From 003fcda6a9da057200c61ac87d4703ca33ada5e4 Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Wed, 18 Sep 2019 08:54:06 -0700
Subject: [PATCH 863/943] Update books

---
 src/doc/book            | 2 +-
 src/doc/rust-by-example | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/doc/book b/src/doc/book
index 7ddc46460f09a..871416b85c1a7 160000
--- a/src/doc/book
+++ b/src/doc/book
@@ -1 +1 @@
-Subproject commit 7ddc46460f09a5cd9bd2a620565bdc20b3315ea9
+Subproject commit 871416b85c1a73717d65d6f4a9ea29e5aef3db0e
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index e76be6b2dc84c..67cfbf31df880 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit e76be6b2dc84c6a992e186157efe29d625e29b94
+Subproject commit 67cfbf31df880728dcf7cb35b15b028ec92caf31

From b4e94d9a3a04798201676be8f18ee483eb292104 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Wed, 18 Sep 2019 09:22:02 -0700
Subject: [PATCH 864/943] Fix bug where `is_call_return_effect_applied` was
 never set

---
 src/librustc_mir/dataflow/generic.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs
index 5a28df42f20a5..886044c069282 100644
--- a/src/librustc_mir/dataflow/generic.rs
+++ b/src/librustc_mir/dataflow/generic.rs
@@ -274,6 +274,7 @@ where
             ..
         } = &term.kind {
             if !self.is_call_return_effect_applied {
+                self.is_call_return_effect_applied = true;
                 self.results.analysis.apply_call_return_effect(
                     &mut self.state,
                     target.block,

From d95a7768a1c5497c6ccb0c2ded30f5968552513c Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Wed, 18 Sep 2019 14:13:36 -0400
Subject: [PATCH 865/943] don't record all intermediate adjustment types

That's way more than is needed, and winds up recording types
that will never appear in MIR.
---
 .../check/generator_interior.rs               | 33 +++++++++++++++----
 src/test/ui/async-await/issues/issue-64477.rs | 20 +++++++++++
 2 files changed, 47 insertions(+), 6 deletions(-)
 create mode 100644 src/test/ui/async-await/issues/issue-64477.rs

diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index 5cee3d63ffc04..a7c307fdf894f 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -181,13 +181,34 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
 
         let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id);
 
-        // Record the unadjusted type
+        // If there are adjustments, then record the final type --
+        // this is the actual value that is being produced.
+        if let Some(adjusted_ty) = self.fcx.tables.borrow().expr_ty_adjusted_opt(expr) {
+            self.record(adjusted_ty, scope, Some(expr), expr.span);
+        }
+
+        // Also record the unadjusted type (which is the only type if
+        // there are no adjustments). The reason for this is that the
+        // unadjusted value is sometimes a "temporary" that would wind
+        // up in a MIR temporary.
+        //
+        // As an example, consider an expression like `vec![].push()`.
+        // Here, the `vec![]` would wind up MIR stored into a
+        // temporary variable `t` which we can borrow to invoke
+        // `<Vec<_>>::push(&mut t)`.
+        //
+        // Note that an expression can have many adjustments, and we
+        // are just ignoring those intermediate types. This is because
+        // those intermediate values are always linearly "consumed" by
+        // the other adjustments, and hence would never be directly
+        // captured in the MIR.
+        //
+        // (Note that this partly relies on the fact that the `Deref`
+        // traits always return references, which means their content
+        // can be reborrowed without needing to spill to a temporary.
+        // If this were not the case, then we could conceivably have
+        // to create intermediate temporaries.)
         let ty = self.fcx.tables.borrow().expr_ty(expr);
         self.record(ty, scope, Some(expr), expr.span);
-
-        // Also include the adjusted types, since these can result in MIR locals
-        for adjustment in self.fcx.tables.borrow().expr_adjustments(expr) {
-            self.record(adjustment.target, scope, Some(expr), expr.span);
-        }
     }
 }
diff --git a/src/test/ui/async-await/issues/issue-64477.rs b/src/test/ui/async-await/issues/issue-64477.rs
new file mode 100644
index 0000000000000..5bd52d44a5827
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-64477.rs
@@ -0,0 +1,20 @@
+// Regression test for #64477.
+//
+// We were incorrectly claiming that the `f(x).await` future captured
+// a value of type `T`, and hence that `T: Send` would have to hold.
+//
+// check-pass
+// edition:2018
+
+use std::future::Future;
+use std::pin::Pin;
+
+fn f<T>(_: &T) -> Pin<Box<dyn Future<Output = ()> + Send>> {
+    unimplemented!()
+}
+
+pub fn g<T: Sync>(x: &'static T) -> impl Future<Output = ()> + Send {
+    async move { f(x).await }
+}
+
+fn main() { }

From 82e5c6ee6597e7d8926b4f2fea89d02d77f978d4 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 17 Sep 2019 16:48:21 +1000
Subject: [PATCH 866/943] Use explicit iteration instead of `all()` in
 `process_obligation()`.

Amazingly enough, this is a 3.5% instruction count win on `keccak`.
---
 src/librustc/traits/fulfill.rs | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 4494c034d51e2..5eaaeca82f2c0 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -256,15 +256,22 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
         &mut self,
         pending_obligation: &mut Self::Obligation,
     ) -> ProcessResult<Self::Obligation, Self::Error> {
-        // if we were stalled on some unresolved variables, first check
+        // If we were stalled on some unresolved variables, first check
         // whether any of them have been resolved; if not, don't bother
         // doing more work yet
         if !pending_obligation.stalled_on.is_empty() {
-            if pending_obligation.stalled_on.iter().all(|&ty| {
+            let mut changed = false;
+            // This `for` loop was once a call to `all()`, but this lower-level
+            // form was a perf win. See #64545 for details.
+            for &ty in &pending_obligation.stalled_on {
                 // Use the force-inlined variant of shallow_resolve() because this code is hot.
                 let resolved = ShallowResolver::new(self.selcx.infcx()).inlined_shallow_resolve(ty);
-                resolved == ty // nothing changed here
-            }) {
+                if resolved != ty {
+                    changed = true;
+                    break;
+                }
+            }
+            if !changed {
                 debug!("process_predicate: pending obligation {:?} still stalled on {:?}",
                        self.selcx.infcx()
                            .resolve_vars_if_possible(&pending_obligation.obligation),

From 3b85597d22dc9dc9226445a95e275b8130880e63 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote <nnethercote@mozilla.com>
Date: Tue, 17 Sep 2019 18:05:57 +1000
Subject: [PATCH 867/943] Add a specialized version of `shallow_resolve()`.

The super-hot call site of `inlined_shallow_resolve()` basically does
`r.inlined_shallow_resolve(ty) != ty`. This commit introduces a
version of that function specialized for that particular call pattern,
`shallow_resolve_changed()`. Incredibly, this reduces the instruction
count for `keccak` by 5%.

The commit also renames `inlined_shallow_resolve()` as
`shallow_resolve()` and removes the `inline(always)` annotation, as it's
no longer nearly so hot.
---
 src/librustc/infer/mod.rs      | 44 +++++++++++++++++++++++++++++-----
 src/librustc/traits/fulfill.rs |  4 +---
 2 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 8638f42976f04..46a364cfe99a4 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -1558,11 +1558,7 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
         ShallowResolver { infcx }
     }
 
-    // We have this force-inlined variant of `shallow_resolve` for the one
-    // callsite that is extremely hot. All other callsites use the normal
-    // variant.
-    #[inline(always)]
-    pub fn inlined_shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> {
+    pub fn shallow_resolve(&mut self, typ: Ty<'tcx>) -> Ty<'tcx> {
         match typ.sty {
             ty::Infer(ty::TyVar(v)) => {
                 // Not entirely obvious: if `typ` is a type variable,
@@ -1597,6 +1593,42 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> {
             _ => typ,
         }
     }
+
+    // `resolver.shallow_resolve_changed(ty)` is equivalent to
+    // `resolver.shallow_resolve(ty) != ty`, but more efficient. It's always
+    // inlined, despite being large, because it has a single call site that is
+    // extremely hot.
+    #[inline(always)]
+    pub fn shallow_resolve_changed(&mut self, typ: Ty<'tcx>) -> bool {
+        match typ.sty {
+            ty::Infer(ty::TyVar(v)) => {
+                use self::type_variable::TypeVariableValue;
+
+                // See the comment in `shallow_resolve()`.
+                match self.infcx.type_variables.borrow_mut().probe(v) {
+                    TypeVariableValue::Known { value: t } => self.fold_ty(t) != typ,
+                    TypeVariableValue::Unknown { .. } => false,
+                }
+            }
+
+            ty::Infer(ty::IntVar(v)) => {
+                match self.infcx.int_unification_table.borrow_mut().probe_value(v) {
+                    Some(v) => v.to_type(self.infcx.tcx) != typ,
+                    None => false,
+                }
+            }
+
+            ty::Infer(ty::FloatVar(v)) => {
+                match self.infcx.float_unification_table.borrow_mut().probe_value(v) {
+                    Some(v) => v.to_type(self.infcx.tcx) != typ,
+                    None => false,
+                }
+            }
+
+            _ => false,
+        }
+    }
+
 }
 
 impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
@@ -1605,7 +1637,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> {
     }
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        self.inlined_shallow_resolve(ty)
+        self.shallow_resolve(ty)
     }
 
     fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 5eaaeca82f2c0..805727b6ce0d7 100644
--- a/src/librustc/traits/fulfill.rs
+++ b/src/librustc/traits/fulfill.rs
@@ -264,9 +264,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
             // This `for` loop was once a call to `all()`, but this lower-level
             // form was a perf win. See #64545 for details.
             for &ty in &pending_obligation.stalled_on {
-                // Use the force-inlined variant of shallow_resolve() because this code is hot.
-                let resolved = ShallowResolver::new(self.selcx.infcx()).inlined_shallow_resolve(ty);
-                if resolved != ty {
+                if ShallowResolver::new(self.selcx.infcx()).shallow_resolve_changed(ty) {
                     changed = true;
                     break;
                 }

From f233a4c18bec906dab0b8531f326a15fadece547 Mon Sep 17 00:00:00 2001
From: James Munns <james.munns@ferrous-systems.com>
Date: Thu, 19 Sep 2019 00:16:16 +0200
Subject: [PATCH 868/943] Fix a minor grammar nit, update UI tests

---
 src/librustc/traits/select.rs                                 | 2 +-
 src/test/ui/codemap_tests/overlapping_inherent_impls.stderr   | 2 +-
 .../coherence/coherence-overlap-upstream-inherent.old.stderr  | 2 +-
 .../coherence/coherence-overlap-upstream-inherent.re.stderr   | 2 +-
 src/test/ui/coherence/coherence-overlap-upstream.old.stderr   | 2 +-
 src/test/ui/coherence/coherence-overlap-upstream.re.stderr    | 2 +-
 .../coherence/coherence-projection-conflict-orphan.old.stderr | 4 ++--
 .../coherence/coherence-projection-conflict-orphan.re.stderr  | 4 ++--
 ...oherence_copy_like_err_fundamental_struct_tuple.old.stderr | 2 +-
 ...coherence_copy_like_err_fundamental_struct_tuple.re.stderr | 2 +-
 .../ui/coherence/coherence_copy_like_err_struct.old.stderr    | 2 +-
 .../ui/coherence/coherence_copy_like_err_struct.re.stderr     | 2 +-
 .../ui/coherence/coherence_copy_like_err_tuple.old.stderr     | 2 +-
 src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr | 2 +-
 src/test/ui/issues/issue-48728.stderr                         | 2 +-
 src/test/ui/specialization/issue-52050.stderr                 | 4 ++--
 16 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 217c887d5254e..a54bc05f16961 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -134,7 +134,7 @@ impl IntercrateAmbiguityCause {
                     String::new()
                 };
                 format!(
-                    "upstream crates may add new impl of trait `{}`{} \
+                    "upstream crates may add a new impl of trait `{}`{} \
                      in future versions",
                     trait_desc, self_desc
                 )
diff --git a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr
index 70c1093e9ed48..8fe24bae7c6ca 100644
--- a/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr
+++ b/src/test/ui/codemap_tests/overlapping_inherent_impls.stderr
@@ -25,7 +25,7 @@ LL |     fn baz(&self) {}
 LL |     fn baz(&self) {}
    |     ---------------- other definition for `baz`
    |
-   = note: upstream crates may add new impl of trait `std::marker::Copy` for type `std::vec::Vec<_>` in future versions
+   = note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::vec::Vec<_>` in future versions
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/coherence/coherence-overlap-upstream-inherent.old.stderr b/src/test/ui/coherence/coherence-overlap-upstream-inherent.old.stderr
index 928b65e003918..3a3e1a4afc3bb 100644
--- a/src/test/ui/coherence/coherence-overlap-upstream-inherent.old.stderr
+++ b/src/test/ui/coherence/coherence-overlap-upstream-inherent.old.stderr
@@ -7,7 +7,7 @@ LL | impl<T> A<T> where T: Remote { fn dummy(&self) { } }
 LL | impl A<i16> { fn dummy(&self) { } }
    |               ------------------- other definition for `dummy`
    |
-   = note: upstream crates may add new impl of trait `coherence_lib::Remote` for type `i16` in future versions
+   = note: upstream crates may add a new impl of trait `coherence_lib::Remote` for type `i16` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-overlap-upstream-inherent.re.stderr b/src/test/ui/coherence/coherence-overlap-upstream-inherent.re.stderr
index 928b65e003918..3a3e1a4afc3bb 100644
--- a/src/test/ui/coherence/coherence-overlap-upstream-inherent.re.stderr
+++ b/src/test/ui/coherence/coherence-overlap-upstream-inherent.re.stderr
@@ -7,7 +7,7 @@ LL | impl<T> A<T> where T: Remote { fn dummy(&self) { } }
 LL | impl A<i16> { fn dummy(&self) { } }
    |               ------------------- other definition for `dummy`
    |
-   = note: upstream crates may add new impl of trait `coherence_lib::Remote` for type `i16` in future versions
+   = note: upstream crates may add a new impl of trait `coherence_lib::Remote` for type `i16` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-overlap-upstream.old.stderr b/src/test/ui/coherence/coherence-overlap-upstream.old.stderr
index 6c3484c2d8c4d..bd6f59f346b6d 100644
--- a/src/test/ui/coherence/coherence-overlap-upstream.old.stderr
+++ b/src/test/ui/coherence/coherence-overlap-upstream.old.stderr
@@ -6,7 +6,7 @@ LL | impl<T> Foo for T where T: Remote {}
 LL | impl Foo for i16 {}
    | ^^^^^^^^^^^^^^^^ conflicting implementation for `i16`
    |
-   = note: upstream crates may add new impl of trait `coherence_lib::Remote` for type `i16` in future versions
+   = note: upstream crates may add a new impl of trait `coherence_lib::Remote` for type `i16` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-overlap-upstream.re.stderr b/src/test/ui/coherence/coherence-overlap-upstream.re.stderr
index 6c3484c2d8c4d..bd6f59f346b6d 100644
--- a/src/test/ui/coherence/coherence-overlap-upstream.re.stderr
+++ b/src/test/ui/coherence/coherence-overlap-upstream.re.stderr
@@ -6,7 +6,7 @@ LL | impl<T> Foo for T where T: Remote {}
 LL | impl Foo for i16 {}
    | ^^^^^^^^^^^^^^^^ conflicting implementation for `i16`
    |
-   = note: upstream crates may add new impl of trait `coherence_lib::Remote` for type `i16` in future versions
+   = note: upstream crates may add a new impl of trait `coherence_lib::Remote` for type `i16` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-projection-conflict-orphan.old.stderr b/src/test/ui/coherence/coherence-projection-conflict-orphan.old.stderr
index cde9360ddf2c8..26dadec5bba7e 100644
--- a/src/test/ui/coherence/coherence-projection-conflict-orphan.old.stderr
+++ b/src/test/ui/coherence/coherence-projection-conflict-orphan.old.stderr
@@ -3,11 +3,11 @@ error[E0119]: conflicting implementations of trait `Foo<i32>` for type `i32`:
    |
 LL | impl Foo<i32> for i32 { }
    | --------------------- first implementation here
-LL | 
+LL |
 LL | impl<A:Iterator> Foo<A::Item> for A { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
    |
-   = note: upstream crates may add new impl of trait `std::iter::Iterator` for type `i32` in future versions
+   = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr b/src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr
index cde9360ddf2c8..26dadec5bba7e 100644
--- a/src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr
+++ b/src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr
@@ -3,11 +3,11 @@ error[E0119]: conflicting implementations of trait `Foo<i32>` for type `i32`:
    |
 LL | impl Foo<i32> for i32 { }
    | --------------------- first implementation here
-LL | 
+LL |
 LL | impl<A:Iterator> Foo<A::Item> for A { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
    |
-   = note: upstream crates may add new impl of trait `std::iter::Iterator` for type `i32` in future versions
+   = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `i32` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr
index 12c7a1f977c3f..4d9f55c121547 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.old.stderr
@@ -7,7 +7,7 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyFundamentalStruct<(MyType,)>`
    |
-   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions
+   = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr
index 12c7a1f977c3f..4d9f55c121547 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_fundamental_struct_tuple.re.stderr
@@ -7,7 +7,7 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 LL | impl MyTrait for lib::MyFundamentalStruct<(MyType,)> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyFundamentalStruct<(MyType,)>`
    |
-   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions
+   = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyFundamentalStruct<(MyType,)>` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr b/src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr
index 1b6c62e9bf3a8..f0bcf659bb696 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_struct.old.stderr
@@ -7,7 +7,7 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 LL | impl MyTrait for lib::MyStruct<MyType> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyStruct<MyType>`
    |
-   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions
+   = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr b/src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr
index 1b6c62e9bf3a8..f0bcf659bb696 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_struct.re.stderr
@@ -7,7 +7,7 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 LL | impl MyTrait for lib::MyStruct<MyType> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `lib::MyStruct<MyType>`
    |
-   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions
+   = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `lib::MyStruct<MyType>` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr b/src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr
index 11bd788c76153..a40153af2cf30 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_tuple.old.stderr
@@ -7,7 +7,7 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 LL | impl MyTrait for (MyType,) { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(MyType,)`
    |
-   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `(MyType,)` in future versions
+   = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `(MyType,)` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr b/src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr
index 11bd788c76153..a40153af2cf30 100644
--- a/src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr
+++ b/src/test/ui/coherence/coherence_copy_like_err_tuple.re.stderr
@@ -7,7 +7,7 @@ LL | impl<T: lib::MyCopy> MyTrait for T { }
 LL | impl MyTrait for (MyType,) { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(MyType,)`
    |
-   = note: upstream crates may add new impl of trait `lib::MyCopy` for type `(MyType,)` in future versions
+   = note: upstream crates may add a new impl of trait `lib::MyCopy` for type `(MyType,)` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-48728.stderr b/src/test/ui/issues/issue-48728.stderr
index 99a9bf9903e25..84c10d8fbc477 100644
--- a/src/test/ui/issues/issue-48728.stderr
+++ b/src/test/ui/issues/issue-48728.stderr
@@ -7,7 +7,7 @@ LL | #[derive(Clone)]
 LL | impl<T: Clone + ?Sized> Clone for Node<[T]> {
    | ------------------------------------------- first implementation here
    |
-   = note: upstream crates may add new impl of trait `std::clone::Clone` for type `[_]` in future versions
+   = note: upstream crates may add a new impl of trait `std::clone::Clone` for type `[_]` in future versions
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/specialization/issue-52050.stderr b/src/test/ui/specialization/issue-52050.stderr
index dcb34f3ad4836..2a0f127bdaf60 100644
--- a/src/test/ui/specialization/issue-52050.stderr
+++ b/src/test/ui/specialization/issue-52050.stderr
@@ -7,11 +7,11 @@ LL | |     I: Iterator,
 LL | | {
 LL | | }
    | |_- first implementation here
-LL | 
+LL |
 LL |   impl IntoPyDictPointer for ()
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
    |
-   = note: upstream crates may add new impl of trait `std::iter::Iterator` for type `()` in future versions
+   = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `()` in future versions
 
 error: aborting due to previous error
 

From 822393d690eb7c238c18c1bb0b1e7831c4776cd3 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Wed, 18 Sep 2019 18:22:13 -0400
Subject: [PATCH 869/943] Point at original span when emitting unreachable lint

Fixes #64590

When we emit an 'unreachable' lint, we now add a note pointing at the
expression that actually causes the code to be unreachable (e.g.
`return`, `break`, `panic`).

This is especially useful when macros are involved, since a diverging
expression might be hidden inside of a macro invocation.
---
 src/librustc_typeck/check/_match.rs           |  4 +--
 src/librustc_typeck/check/expr.rs             |  2 +-
 src/librustc_typeck/check/mod.rs              | 25 +++++++++++++------
 src/test/ui/dead-code-ret.stderr              |  5 ++++
 src/test/ui/if-ret.stderr                     |  5 ++++
 src/test/ui/issues/issue-2150.stderr          |  6 +++++
 src/test/ui/issues/issue-7246.stderr          |  5 ++++
 .../ui/lint/lint-attr-non-item-node.stderr    |  5 ++++
 src/test/ui/liveness/liveness-unused.stderr   |  5 ++++
 .../match-no-arms-unreachable-after.stderr    |  5 ++++
 src/test/ui/never-assign-dead-code.stderr     | 12 +++++++++
 src/test/ui/reachable/expr_add.stderr         |  5 ++++
 src/test/ui/reachable/expr_again.stderr       |  5 ++++
 src/test/ui/reachable/expr_array.stderr       | 11 ++++++++
 src/test/ui/reachable/expr_assign.stderr      | 17 +++++++++++++
 src/test/ui/reachable/expr_block.stderr       | 10 ++++++++
 src/test/ui/reachable/expr_box.stderr         |  5 ++++
 src/test/ui/reachable/expr_call.stderr        | 11 ++++++++
 src/test/ui/reachable/expr_cast.stderr        |  5 ++++
 src/test/ui/reachable/expr_if.stderr          | 10 ++++++++
 src/test/ui/reachable/expr_loop.stderr        | 15 +++++++++++
 src/test/ui/reachable/expr_match.stderr       | 10 ++++++++
 src/test/ui/reachable/expr_method.stderr      | 11 ++++++++
 src/test/ui/reachable/expr_repeat.stderr      |  5 ++++
 src/test/ui/reachable/expr_return.stderr      |  5 ++++
 src/test/ui/reachable/expr_return_in_macro.rs | 15 +++++++++++
 .../ui/reachable/expr_return_in_macro.stderr  | 22 ++++++++++++++++
 src/test/ui/reachable/expr_struct.stderr      | 23 +++++++++++++++++
 src/test/ui/reachable/expr_tup.stderr         | 11 ++++++++
 src/test/ui/reachable/expr_type.stderr        |  5 ++++
 src/test/ui/reachable/expr_unary.stderr       |  5 ++++
 src/test/ui/reachable/expr_while.stderr       | 11 ++++++++
 .../protect-precedences.stderr                |  5 ++++
 .../ui/unreachable/unreachable-code.stderr    |  5 ++++
 .../ui/unreachable/unreachable-in-call.stderr | 11 ++++++++
 .../unreachable-try-pattern.stderr            |  5 ++++
 .../unwarned-match-on-never.stderr            | 17 +++++++++++++
 37 files changed, 328 insertions(+), 11 deletions(-)
 create mode 100644 src/test/ui/reachable/expr_return_in_macro.rs
 create mode 100644 src/test/ui/reachable/expr_return_in_macro.stderr

diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 308a3d8ebc2cf..a1c937b95ba8c 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -43,7 +43,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // If there are no arms, that is a diverging match; a special case.
         if arms.is_empty() {
-            self.diverges.set(self.diverges.get() | Diverges::Always);
+            self.diverges.set(self.diverges.get() | Diverges::Always(expr.span));
             return tcx.types.never;
         }
 
@@ -69,7 +69,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // warnings).
             match all_pats_diverge {
                 Diverges::Maybe => Diverges::Maybe,
-                Diverges::Always | Diverges::WarnedAlways => Diverges::WarnedAlways,
+                Diverges::Always(..) | Diverges::WarnedAlways => Diverges::WarnedAlways,
             }
         }).collect();
 
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 56bd903040ab4..3ba453748ff32 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -170,7 +170,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Any expression that produces a value of type `!` must have diverged
         if ty.is_never() {
-            self.diverges.set(self.diverges.get() | Diverges::Always);
+            self.diverges.set(self.diverges.get() | Diverges::Always(expr.span));
         }
 
         // Record the type, which applies it effects.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 1197160fa9501..0fced37394616 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -450,7 +450,10 @@ pub enum Diverges {
 
     /// Definitely known to diverge and therefore
     /// not reach the next sibling or its parent.
-    Always,
+    /// The `Span` points to the expression
+    /// that caused us to diverge
+    /// (e.g. `return`, `break`, etc)
+    Always(Span),
 
     /// Same as `Always` but with a reachability
     /// warning already emitted.
@@ -487,7 +490,7 @@ impl ops::BitOrAssign for Diverges {
 
 impl Diverges {
     fn always(self) -> bool {
-        self >= Diverges::Always
+        self >= Diverges::Always(DUMMY_SP)
     }
 }
 
@@ -2307,17 +2310,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Produces warning on the given node, if the current point in the
     /// function is unreachable, and there hasn't been another warning.
     fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
-        if self.diverges.get() == Diverges::Always &&
+        // FIXME: Combine these two 'if' expressions into one once
+        // let chains are implemented
+        if let Diverges::Always(orig_span) = self.diverges.get() {
             // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
             // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
             // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
-            !span.is_desugaring(DesugaringKind::CondTemporary) {
-            self.diverges.set(Diverges::WarnedAlways);
+            if !span.is_desugaring(DesugaringKind::CondTemporary) {
+                self.diverges.set(Diverges::WarnedAlways);
 
-            debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
+                debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
 
-            let msg = format!("unreachable {}", kind);
-            self.tcx().lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg);
+                let msg = format!("unreachable {}", kind);
+                let mut err = self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE,
+                                                              id, span, &msg);
+                err.span_note(orig_span, "any code following this expression is unreachable");
+                err.emit();
+            }
         }
     }
 
diff --git a/src/test/ui/dead-code-ret.stderr b/src/test/ui/dead-code-ret.stderr
index 092a176f443b2..0ce31ea40ddbb 100644
--- a/src/test/ui/dead-code-ret.stderr
+++ b/src/test/ui/dead-code-ret.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/dead-code-ret.rs:6:5
+   |
+LL |     return;
+   |     ^^^^^^
    = 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
diff --git a/src/test/ui/if-ret.stderr b/src/test/ui/if-ret.stderr
index 73402e55a4fd8..2df8f22944ee8 100644
--- a/src/test/ui/if-ret.stderr
+++ b/src/test/ui/if-ret.stderr
@@ -5,4 +5,9 @@ LL | fn foo() { if (return) { } }
    |                        ^^^
    |
    = note: `#[warn(unreachable_code)]` on by default
+note: any code following this expression is unreachable
+  --> $DIR/if-ret.rs:6:15
+   |
+LL | fn foo() { if (return) { } }
+   |               ^^^^^^^^
 
diff --git a/src/test/ui/issues/issue-2150.stderr b/src/test/ui/issues/issue-2150.stderr
index 59000f3dd5338..623f098d0b337 100644
--- a/src/test/ui/issues/issue-2150.stderr
+++ b/src/test/ui/issues/issue-2150.stderr
@@ -9,6 +9,12 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/issue-2150.rs:7:5
+   |
+LL |     panic!();
+   |     ^^^^^^^^^
+   = 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
 
diff --git a/src/test/ui/issues/issue-7246.stderr b/src/test/ui/issues/issue-7246.stderr
index e049295e9136f..d1b23672dc7f4 100644
--- a/src/test/ui/issues/issue-7246.stderr
+++ b/src/test/ui/issues/issue-7246.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/issue-7246.rs:6:5
+   |
+LL |     return;
+   |     ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/lint-attr-non-item-node.stderr b/src/test/ui/lint/lint-attr-non-item-node.stderr
index 6eb72c098df5c..e6c76c24c9110 100644
--- a/src/test/ui/lint/lint-attr-non-item-node.stderr
+++ b/src/test/ui/lint/lint-attr-non-item-node.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL |     #[deny(unreachable_code)]
    |            ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/lint-attr-non-item-node.rs:6:9
+   |
+LL |         break;
+   |         ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/liveness/liveness-unused.stderr b/src/test/ui/liveness/liveness-unused.stderr
index 40a677c08f2b0..84e9b5bab99ff 100644
--- a/src/test/ui/liveness/liveness-unused.stderr
+++ b/src/test/ui/liveness/liveness-unused.stderr
@@ -10,6 +10,11 @@ note: lint level defined here
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]`
+note: any code following this expression is unreachable
+  --> $DIR/liveness-unused.rs:91:9
+   |
+LL |         continue;
+   |         ^^^^^^^^
 
 error: unused variable: `x`
   --> $DIR/liveness-unused.rs:8:7
diff --git a/src/test/ui/match/match-no-arms-unreachable-after.stderr b/src/test/ui/match/match-no-arms-unreachable-after.stderr
index 65dcc6ee46554..6c46b2473cce6 100644
--- a/src/test/ui/match/match-no-arms-unreachable-after.stderr
+++ b/src/test/ui/match/match-no-arms-unreachable-after.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/match-no-arms-unreachable-after.rs:7:5
+   |
+LL |     match v { }
+   |     ^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/never-assign-dead-code.stderr b/src/test/ui/never-assign-dead-code.stderr
index b1b5bf03fe52a..436c703e4b6b9 100644
--- a/src/test/ui/never-assign-dead-code.stderr
+++ b/src/test/ui/never-assign-dead-code.stderr
@@ -10,12 +10,24 @@ note: lint level defined here
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]`
+note: any code following this expression is unreachable
+  --> $DIR/never-assign-dead-code.rs:9:16
+   |
+LL |     let x: ! = panic!("aah");
+   |                ^^^^^^^^^^^^^
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
 warning: unreachable call
   --> $DIR/never-assign-dead-code.rs:10:5
    |
 LL |     drop(x);
    |     ^^^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/never-assign-dead-code.rs:10:10
+   |
+LL |     drop(x);
+   |          ^
 
 warning: unused variable: `x`
   --> $DIR/never-assign-dead-code.rs:9:9
diff --git a/src/test/ui/reachable/expr_add.stderr b/src/test/ui/reachable/expr_add.stderr
index 02b29021cb61a..47b4e467abecb 100644
--- a/src/test/ui/reachable/expr_add.stderr
+++ b/src/test/ui/reachable/expr_add.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_add.rs:17:19
+   |
+LL |     let x = Foo + return;
+   |                   ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_again.stderr b/src/test/ui/reachable/expr_again.stderr
index bdc3d143ea57e..8e246d940fd8d 100644
--- a/src/test/ui/reachable/expr_again.stderr
+++ b/src/test/ui/reachable/expr_again.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_again.rs:7:9
+   |
+LL |         continue;
+   |         ^^^^^^^^
    = 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
diff --git a/src/test/ui/reachable/expr_array.stderr b/src/test/ui/reachable/expr_array.stderr
index 18d7ffe74bd18..419a332e632f3 100644
--- a/src/test/ui/reachable/expr_array.stderr
+++ b/src/test/ui/reachable/expr_array.stderr
@@ -9,12 +9,23 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_array.rs:9:26
+   |
+LL |     let x: [usize; 2] = [return, 22];
+   |                          ^^^^^^
 
 error: unreachable expression
   --> $DIR/expr_array.rs:14:25
    |
 LL |     let x: [usize; 2] = [22, return];
    |                         ^^^^^^^^^^^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/expr_array.rs:14:30
+   |
+LL |     let x: [usize; 2] = [22, return];
+   |                              ^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/reachable/expr_assign.stderr b/src/test/ui/reachable/expr_assign.stderr
index def16d90a7490..7388fb4a6b9b2 100644
--- a/src/test/ui/reachable/expr_assign.stderr
+++ b/src/test/ui/reachable/expr_assign.stderr
@@ -9,18 +9,35 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_assign.rs:10:9
+   |
+LL |     x = return;
+   |         ^^^^^^
 
 error: unreachable expression
   --> $DIR/expr_assign.rs:20:14
    |
 LL |         *p = return;
    |              ^^^^^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/expr_assign.rs:20:9
+   |
+LL |         *p = return;
+   |         ^^
 
 error: unreachable expression
   --> $DIR/expr_assign.rs:26:15
    |
 LL |     *{return; &mut i} = 22;
    |               ^^^^^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/expr_assign.rs:26:7
+   |
+LL |     *{return; &mut i} = 22;
+   |       ^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/reachable/expr_block.stderr b/src/test/ui/reachable/expr_block.stderr
index a498502e6cb1a..03a6139d688bb 100644
--- a/src/test/ui/reachable/expr_block.stderr
+++ b/src/test/ui/reachable/expr_block.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_block.rs:9:9
+   |
+LL |         return;
+   |         ^^^^^^
 
 error: unreachable statement
   --> $DIR/expr_block.rs:25:9
@@ -16,6 +21,11 @@ error: unreachable statement
 LL |         println!("foo");
    |         ^^^^^^^^^^^^^^^^
    |
+note: any code following this expression is unreachable
+  --> $DIR/expr_block.rs:24:9
+   |
+LL |         return;
+   |         ^^^^^^
    = 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 2 previous errors
diff --git a/src/test/ui/reachable/expr_box.stderr b/src/test/ui/reachable/expr_box.stderr
index 63137ce3da180..d0f666d2be44b 100644
--- a/src/test/ui/reachable/expr_box.stderr
+++ b/src/test/ui/reachable/expr_box.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_box.rs:6:17
+   |
+LL |     let x = box return;
+   |                 ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_call.stderr b/src/test/ui/reachable/expr_call.stderr
index f2db17e4dfe8e..3fcea90e7cd87 100644
--- a/src/test/ui/reachable/expr_call.stderr
+++ b/src/test/ui/reachable/expr_call.stderr
@@ -9,12 +9,23 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_call.rs:13:9
+   |
+LL |     foo(return, 22);
+   |         ^^^^^^
 
 error: unreachable call
   --> $DIR/expr_call.rs:18:5
    |
 LL |     bar(return);
    |     ^^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/expr_call.rs:18:9
+   |
+LL |     bar(return);
+   |         ^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/reachable/expr_cast.stderr b/src/test/ui/reachable/expr_cast.stderr
index 3086745d28ed4..d3ce0ca079f90 100644
--- a/src/test/ui/reachable/expr_cast.stderr
+++ b/src/test/ui/reachable/expr_cast.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_cast.rs:9:14
+   |
+LL |     let x = {return} as !;
+   |              ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr
index f1690e595e5d1..03284576086a7 100644
--- a/src/test/ui/reachable/expr_if.stderr
+++ b/src/test/ui/reachable/expr_if.stderr
@@ -12,6 +12,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_if.rs:7:9
+   |
+LL |     if {return} {
+   |         ^^^^^^
 
 error: unreachable statement
   --> $DIR/expr_if.rs:27:5
@@ -19,6 +24,11 @@ error: unreachable statement
 LL |     println!("But I am.");
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
+note: any code following this expression is unreachable
+  --> $DIR/expr_if.rs:21:9
+   |
+LL |         return;
+   |         ^^^^^^
    = 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 2 previous errors
diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr
index 4d3e06c93a376..a4cf8cfcfd9e6 100644
--- a/src/test/ui/reachable/expr_loop.stderr
+++ b/src/test/ui/reachable/expr_loop.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_loop.rs:7:12
+   |
+LL |     loop { return; }
+   |            ^^^^^^
    = 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: unreachable statement
@@ -17,6 +22,11 @@ error: unreachable statement
 LL |     println!("I am dead.");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
+note: any code following this expression is unreachable
+  --> $DIR/expr_loop.rs:20:12
+   |
+LL |     loop { return; }
+   |            ^^^^^^
    = 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: unreachable statement
@@ -25,6 +35,11 @@ error: unreachable statement
 LL |     println!("I am dead.");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
+note: any code following this expression is unreachable
+  --> $DIR/expr_loop.rs:31:5
+   |
+LL |     loop { 'middle: loop { loop { break 'middle; } } }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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 3 previous errors
diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr
index 1aef06aec5ba6..b846b92dcec8b 100644
--- a/src/test/ui/reachable/expr_match.stderr
+++ b/src/test/ui/reachable/expr_match.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_match.rs:7:22
+   |
+LL |     match () { () => return }
+   |                      ^^^^^^
    = 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: unreachable statement
@@ -17,6 +22,11 @@ error: unreachable statement
 LL |     println!("I am dead");
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
+note: any code following this expression is unreachable
+  --> $DIR/expr_match.rs:18:31
+   |
+LL |     match () { () if false => return, () => return }
+   |                               ^^^^^^
    = 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 2 previous errors
diff --git a/src/test/ui/reachable/expr_method.stderr b/src/test/ui/reachable/expr_method.stderr
index 947ea0fee889c..7ad279c9f487a 100644
--- a/src/test/ui/reachable/expr_method.stderr
+++ b/src/test/ui/reachable/expr_method.stderr
@@ -9,12 +9,23 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_method.rs:16:13
+   |
+LL |     Foo.foo(return, 22);
+   |             ^^^^^^
 
 error: unreachable call
   --> $DIR/expr_method.rs:21:9
    |
 LL |     Foo.bar(return);
    |         ^^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/expr_method.rs:21:13
+   |
+LL |     Foo.bar(return);
+   |             ^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/reachable/expr_repeat.stderr b/src/test/ui/reachable/expr_repeat.stderr
index 0536cdef72128..3ff6be76daea5 100644
--- a/src/test/ui/reachable/expr_repeat.stderr
+++ b/src/test/ui/reachable/expr_repeat.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_repeat.rs:9:26
+   |
+LL |     let x: [usize; 2] = [return; 2];
+   |                          ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_return.stderr b/src/test/ui/reachable/expr_return.stderr
index 3317da58aba1c..31f7ebe7618ea 100644
--- a/src/test/ui/reachable/expr_return.stderr
+++ b/src/test/ui/reachable/expr_return.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_return.rs:10:30
+   |
+LL |     let x = {return {return {return;}}};
+   |                              ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_return_in_macro.rs b/src/test/ui/reachable/expr_return_in_macro.rs
new file mode 100644
index 0000000000000..198ede6b14106
--- /dev/null
+++ b/src/test/ui/reachable/expr_return_in_macro.rs
@@ -0,0 +1,15 @@
+// Tests that we generate nice error messages
+// when an expression is unreachble due to control
+// flow inside of a macro expansion
+#![deny(unreachable_code)]
+
+macro_rules! early_return {
+    () => {
+        return ()
+    }
+}
+
+fn main() {
+    return early_return!();
+    //~^ ERROR unreachable expression
+}
diff --git a/src/test/ui/reachable/expr_return_in_macro.stderr b/src/test/ui/reachable/expr_return_in_macro.stderr
new file mode 100644
index 0000000000000..ff3abb5551f92
--- /dev/null
+++ b/src/test/ui/reachable/expr_return_in_macro.stderr
@@ -0,0 +1,22 @@
+error: unreachable expression
+  --> $DIR/expr_return_in_macro.rs:13:5
+   |
+LL |     return early_return!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/expr_return_in_macro.rs:4:9
+   |
+LL | #![deny(unreachable_code)]
+   |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_return_in_macro.rs:8:9
+   |
+LL |         return ()
+   |         ^^^^^^^^^
+...
+LL |     return early_return!();
+   |            --------------- in this macro invocation
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/reachable/expr_struct.stderr b/src/test/ui/reachable/expr_struct.stderr
index dcccb7a4db307..d08bcc4f0d1ae 100644
--- a/src/test/ui/reachable/expr_struct.stderr
+++ b/src/test/ui/reachable/expr_struct.stderr
@@ -9,24 +9,47 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_struct.rs:14:35
+   |
+LL |     let x = Foo { a: 22, b: 33, ..return };
+   |                                   ^^^^^^
 
 error: unreachable expression
   --> $DIR/expr_struct.rs:19:33
    |
 LL |     let x = Foo { a: return, b: 33, ..return };
    |                                 ^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/expr_struct.rs:19:22
+   |
+LL |     let x = Foo { a: return, b: 33, ..return };
+   |                      ^^^^^^
 
 error: unreachable expression
   --> $DIR/expr_struct.rs:24:39
    |
 LL |     let x = Foo { a: 22, b: return, ..return };
    |                                       ^^^^^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/expr_struct.rs:24:29
+   |
+LL |     let x = Foo { a: 22, b: return, ..return };
+   |                             ^^^^^^
 
 error: unreachable expression
   --> $DIR/expr_struct.rs:29:13
    |
 LL |     let x = Foo { a: 22, b: return };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/expr_struct.rs:29:29
+   |
+LL |     let x = Foo { a: 22, b: return };
+   |                             ^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/reachable/expr_tup.stderr b/src/test/ui/reachable/expr_tup.stderr
index 1837031107d59..788499533db33 100644
--- a/src/test/ui/reachable/expr_tup.stderr
+++ b/src/test/ui/reachable/expr_tup.stderr
@@ -9,12 +9,23 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_tup.rs:9:30
+   |
+LL |     let x: (usize, usize) = (return, 2);
+   |                              ^^^^^^
 
 error: unreachable expression
   --> $DIR/expr_tup.rs:14:29
    |
 LL |     let x: (usize, usize) = (2, return);
    |                             ^^^^^^^^^^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/expr_tup.rs:14:33
+   |
+LL |     let x: (usize, usize) = (2, return);
+   |                                 ^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/reachable/expr_type.stderr b/src/test/ui/reachable/expr_type.stderr
index f867c89163415..15eb735da75d8 100644
--- a/src/test/ui/reachable/expr_type.stderr
+++ b/src/test/ui/reachable/expr_type.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_type.rs:9:14
+   |
+LL |     let x = {return}: !;
+   |              ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr
index 61982289cdc6e..7f86519616639 100644
--- a/src/test/ui/reachable/expr_unary.stderr
+++ b/src/test/ui/reachable/expr_unary.stderr
@@ -15,6 +15,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_unary.rs:8:20
+   |
+LL |     let x: ! = ! { return; };
+   |                    ^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/reachable/expr_while.stderr b/src/test/ui/reachable/expr_while.stderr
index fc528926b4c97..b6d6d11ac691e 100644
--- a/src/test/ui/reachable/expr_while.stderr
+++ b/src/test/ui/reachable/expr_while.stderr
@@ -13,6 +13,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/expr_while.rs:7:12
+   |
+LL |     while {return} {
+   |            ^^^^^^
 
 error: unreachable block in `while` expression
   --> $DIR/expr_while.rs:22:20
@@ -23,6 +28,12 @@ LL | |
 LL | |         println!("I am dead.");
 LL | |     }
    | |_____^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/expr_while.rs:22:12
+   |
+LL |     while {return} {
+   |            ^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr
index be7ef658411e1..ca98a3947146e 100644
--- a/src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr
@@ -5,4 +5,9 @@ LL |         if let _ = return true && false {};
    |                                         ^^
    |
    = note: `#[warn(unreachable_code)]` on by default
+note: any code following this expression is unreachable
+  --> $DIR/protect-precedences.rs:13:20
+   |
+LL |         if let _ = return true && false {};
+   |                    ^^^^^^^^^^^^^^^^^^^^
 
diff --git a/src/test/ui/unreachable/unreachable-code.stderr b/src/test/ui/unreachable/unreachable-code.stderr
index 803bb966be8fc..226f088c63a5e 100644
--- a/src/test/ui/unreachable/unreachable-code.stderr
+++ b/src/test/ui/unreachable/unreachable-code.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/unreachable-code.rs:5:3
+   |
+LL |   loop{}
+   |   ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unreachable/unreachable-in-call.stderr b/src/test/ui/unreachable/unreachable-in-call.stderr
index c740011c4a125..928f5634a1248 100644
--- a/src/test/ui/unreachable/unreachable-in-call.stderr
+++ b/src/test/ui/unreachable/unreachable-in-call.stderr
@@ -9,12 +9,23 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/unreachable-in-call.rs:13:10
+   |
+LL |     call(diverge(),
+   |          ^^^^^^^^^
 
 error: unreachable call
   --> $DIR/unreachable-in-call.rs:17:5
    |
 LL |     call(
    |     ^^^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/unreachable-in-call.rs:19:9
+   |
+LL |         diverge());
+   |         ^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unreachable/unreachable-try-pattern.stderr b/src/test/ui/unreachable/unreachable-try-pattern.stderr
index 758aa5a45bc17..889df790124da 100644
--- a/src/test/ui/unreachable/unreachable-try-pattern.stderr
+++ b/src/test/ui/unreachable/unreachable-try-pattern.stderr
@@ -9,6 +9,11 @@ note: lint level defined here
    |
 LL | #![warn(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/unreachable-try-pattern.rs:19:36
+   |
+LL |     let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
+   |                                    ^
 
 warning: unreachable pattern
   --> $DIR/unreachable-try-pattern.rs:19:24
diff --git a/src/test/ui/unreachable/unwarned-match-on-never.stderr b/src/test/ui/unreachable/unwarned-match-on-never.stderr
index ccb70d7431145..9ce6e3df8046e 100644
--- a/src/test/ui/unreachable/unwarned-match-on-never.stderr
+++ b/src/test/ui/unreachable/unwarned-match-on-never.stderr
@@ -9,12 +9,23 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
+note: any code following this expression is unreachable
+  --> $DIR/unwarned-match-on-never.rs:8:11
+   |
+LL |     match x {}
+   |           ^
 
 error: unreachable arm
   --> $DIR/unwarned-match-on-never.rs:15:15
    |
 LL |         () => ()
    |               ^^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/unwarned-match-on-never.rs:14:11
+   |
+LL |     match (return) {
+   |           ^^^^^^^^
 
 error: unreachable expression
   --> $DIR/unwarned-match-on-never.rs:21:5
@@ -23,6 +34,12 @@ LL | /     match () {
 LL | |         () => (),
 LL | |     }
    | |_____^
+   |
+note: any code following this expression is unreachable
+  --> $DIR/unwarned-match-on-never.rs:20:5
+   |
+LL |     return;
+   |     ^^^^^^
 
 error: aborting due to 3 previous errors
 

From 333230fd140b3b39aa655bcfcda3ee6810b0ac3c Mon Sep 17 00:00:00 2001
From: James Munns <james.munns@ferrous-systems.com>
Date: Thu, 19 Sep 2019 00:50:03 +0200
Subject: [PATCH 870/943] Restore whitespace

---
 .../coherence/coherence-projection-conflict-orphan.old.stderr   | 2 +-
 .../ui/coherence/coherence-projection-conflict-orphan.re.stderr | 2 +-
 src/test/ui/specialization/issue-52050.stderr                   | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/test/ui/coherence/coherence-projection-conflict-orphan.old.stderr b/src/test/ui/coherence/coherence-projection-conflict-orphan.old.stderr
index 26dadec5bba7e..728eae5e547da 100644
--- a/src/test/ui/coherence/coherence-projection-conflict-orphan.old.stderr
+++ b/src/test/ui/coherence/coherence-projection-conflict-orphan.old.stderr
@@ -3,7 +3,7 @@ error[E0119]: conflicting implementations of trait `Foo<i32>` for type `i32`:
    |
 LL | impl Foo<i32> for i32 { }
    | --------------------- first implementation here
-LL |
+LL | 
 LL | impl<A:Iterator> Foo<A::Item> for A { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
    |
diff --git a/src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr b/src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr
index 26dadec5bba7e..728eae5e547da 100644
--- a/src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr
+++ b/src/test/ui/coherence/coherence-projection-conflict-orphan.re.stderr
@@ -3,7 +3,7 @@ error[E0119]: conflicting implementations of trait `Foo<i32>` for type `i32`:
    |
 LL | impl Foo<i32> for i32 { }
    | --------------------- first implementation here
-LL |
+LL | 
 LL | impl<A:Iterator> Foo<A::Item> for A { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
    |
diff --git a/src/test/ui/specialization/issue-52050.stderr b/src/test/ui/specialization/issue-52050.stderr
index 2a0f127bdaf60..36f96b011983f 100644
--- a/src/test/ui/specialization/issue-52050.stderr
+++ b/src/test/ui/specialization/issue-52050.stderr
@@ -7,7 +7,7 @@ LL | |     I: Iterator,
 LL | | {
 LL | | }
    | |_- first implementation here
-LL |
+LL | 
 LL |   impl IntoPyDictPointer for ()
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
    |

From cd4b468e07ab27eef87aa8757220d6439defc699 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Wed, 18 Sep 2019 19:07:39 -0400
Subject: [PATCH 871/943] Make note better when all arms in a `match` diverge

---
 src/librustc_typeck/check/_match.rs     | 26 +++++++++++++++++--
 src/librustc_typeck/check/expr.rs       |  5 +++-
 src/librustc_typeck/check/mod.rs        | 33 +++++++++++++++++++------
 src/test/ui/reachable/expr_match.stderr | 12 ++++-----
 4 files changed, 60 insertions(+), 16 deletions(-)

diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index a1c937b95ba8c..86774466ba586 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -43,7 +43,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // If there are no arms, that is a diverging match; a special case.
         if arms.is_empty() {
-            self.diverges.set(self.diverges.get() | Diverges::Always(expr.span));
+            self.diverges.set(self.diverges.get() | Diverges::Always {
+                span: expr.span,
+                custom_note: None
+            });
             return tcx.types.never;
         }
 
@@ -69,7 +72,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // warnings).
             match all_pats_diverge {
                 Diverges::Maybe => Diverges::Maybe,
-                Diverges::Always(..) | Diverges::WarnedAlways => Diverges::WarnedAlways,
+                Diverges::Always { .. } | Diverges::WarnedAlways => Diverges::WarnedAlways,
             }
         }).collect();
 
@@ -167,6 +170,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             prior_arm_ty = Some(arm_ty);
         }
 
+        // If all of the arms in the 'match' diverge,
+        // and we're dealing with an actual 'match' block
+        // (as opposed to a 'match' desugared from something else'),
+        // we can emit a better note. Rather than pointing
+        // at a diverging expression in an arbitrary arm,
+        // we can point at the entire 'match' expression
+        match (all_arms_diverge, match_src) {
+            (Diverges::Always { .. }, hir::MatchSource::Normal) => {
+                all_arms_diverge = Diverges::Always {
+                    span: expr.span,
+                    custom_note: Some(
+                        "any code following this `match` expression is unreachable, \
+                        as all arms diverge"
+                    )
+                };
+            },
+            _ => {}
+        }
+
         // We won't diverge unless the discriminant or all arms diverge.
         self.diverges.set(discrim_diverges | all_arms_diverge);
 
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 3ba453748ff32..5733b8d1db13e 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -170,7 +170,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Any expression that produces a value of type `!` must have diverged
         if ty.is_never() {
-            self.diverges.set(self.diverges.get() | Diverges::Always(expr.span));
+            self.diverges.set(self.diverges.get() | Diverges::Always {
+                span: expr.span,
+                custom_note: None
+            });
         }
 
         // Record the type, which applies it effects.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 0fced37394616..c44648bb9df85 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -450,10 +450,20 @@ pub enum Diverges {
 
     /// Definitely known to diverge and therefore
     /// not reach the next sibling or its parent.
-    /// The `Span` points to the expression
-    /// that caused us to diverge
-    /// (e.g. `return`, `break`, etc)
-    Always(Span),
+    Always {
+        /// The `Span` points to the expression
+        /// that caused us to diverge
+        /// (e.g. `return`, `break`, etc)
+        span: Span,
+        /// In some cases (e.g. a 'match' expression
+        /// where all arms diverge), we may be
+        /// able to provide a more informative
+        /// message to the user.
+        /// If this is None, a default messsage
+        /// will be generated, which is suitable
+        /// for most cases
+        custom_note: Option<&'static str>
+    },
 
     /// Same as `Always` but with a reachability
     /// warning already emitted.
@@ -490,7 +500,13 @@ impl ops::BitOrAssign for Diverges {
 
 impl Diverges {
     fn always(self) -> bool {
-        self >= Diverges::Always(DUMMY_SP)
+        // Enum comparison ignores the
+        // contents of fields, so we just
+        // fill them in with garbage here
+        self >= Diverges::Always {
+            span: DUMMY_SP,
+            custom_note: None
+        }
     }
 }
 
@@ -2312,7 +2328,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
         // FIXME: Combine these two 'if' expressions into one once
         // let chains are implemented
-        if let Diverges::Always(orig_span) = self.diverges.get() {
+        if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
             // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
             // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
             // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
@@ -2324,7 +2340,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let msg = format!("unreachable {}", kind);
                 let mut err = self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE,
                                                               id, span, &msg);
-                err.span_note(orig_span, "any code following this expression is unreachable");
+                err.span_note(
+                    orig_span,
+                    custom_note.unwrap_or("any code following this expression is unreachable")
+                );
                 err.emit();
             }
         }
diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr
index b846b92dcec8b..f587e524d350d 100644
--- a/src/test/ui/reachable/expr_match.stderr
+++ b/src/test/ui/reachable/expr_match.stderr
@@ -9,11 +9,11 @@ note: lint level defined here
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_match.rs:7:22
+note: any code following this `match` expression is unreachable, as all arms diverge
+  --> $DIR/expr_match.rs:7:5
    |
 LL |     match () { () => return }
-   |                      ^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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: unreachable statement
@@ -22,11 +22,11 @@ error: unreachable statement
 LL |     println!("I am dead");
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
-note: any code following this expression is unreachable
-  --> $DIR/expr_match.rs:18:31
+note: any code following this `match` expression is unreachable, as all arms diverge
+  --> $DIR/expr_match.rs:18:5
    |
 LL |     match () { () if false => return, () => return }
-   |                               ^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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 2 previous errors

From 9e777eb45de2bf972bbf7f2075fa491e22d2d071 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Wed, 18 Sep 2019 19:31:38 -0400
Subject: [PATCH 872/943] Some formatting cleanup

---
 src/librustc_typeck/check/mod.rs              | 13 ++++++-------
 src/test/ui/reachable/expr_return_in_macro.rs |  2 +-
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c44648bb9df85..f6f3173e81c89 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2338,13 +2338,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
 
                 let msg = format!("unreachable {}", kind);
-                let mut err = self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE,
-                                                              id, span, &msg);
-                err.span_note(
-                    orig_span,
-                    custom_note.unwrap_or("any code following this expression is unreachable")
-                );
-                err.emit();
+                self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg)
+                    .span_note(
+                        orig_span,
+                        custom_note.unwrap_or("any code following this expression is unreachable")
+                    )
+                    .emit();
             }
         }
     }
diff --git a/src/test/ui/reachable/expr_return_in_macro.rs b/src/test/ui/reachable/expr_return_in_macro.rs
index 198ede6b14106..4e57618bf5e77 100644
--- a/src/test/ui/reachable/expr_return_in_macro.rs
+++ b/src/test/ui/reachable/expr_return_in_macro.rs
@@ -1,6 +1,6 @@
 // Tests that we generate nice error messages
 // when an expression is unreachble due to control
-// flow inside of a macro expansion
+// flow inside of a macro expansion.
 #![deny(unreachable_code)]
 
 macro_rules! early_return {

From 6edcfbe59a2067df7aadc18de990b9a86216099e Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Wed, 18 Sep 2019 19:48:37 -0400
Subject: [PATCH 873/943] Apply formatting fixes

Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
---
 src/librustc_typeck/check/_match.rs |  8 ++++----
 src/librustc_typeck/check/mod.rs    | 10 +++++-----
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 86774466ba586..034cba0f12a62 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -170,12 +170,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             prior_arm_ty = Some(arm_ty);
         }
 
-        // If all of the arms in the 'match' diverge,
-        // and we're dealing with an actual 'match' block
-        // (as opposed to a 'match' desugared from something else'),
+        // If all of the arms in the `match` diverge,
+        // and we're dealing with an actual `match` block
+        // (as opposed to a `match` desugared from something else'),
         // we can emit a better note. Rather than pointing
         // at a diverging expression in an arbitrary arm,
-        // we can point at the entire 'match' expression
+        // we can point at the entire `match` expression
         match (all_arms_diverge, match_src) {
             (Diverges::Always { .. }, hir::MatchSource::Normal) => {
                 all_arms_diverge = Diverges::Always {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index f6f3173e81c89..e424aa679088d 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -453,15 +453,15 @@ pub enum Diverges {
     Always {
         /// The `Span` points to the expression
         /// that caused us to diverge
-        /// (e.g. `return`, `break`, etc)
+        /// (e.g. `return`, `break`, etc).
         span: Span,
-        /// In some cases (e.g. a 'match' expression
+        /// In some cases (e.g. a `match` expression
         /// where all arms diverge), we may be
         /// able to provide a more informative
         /// message to the user.
-        /// If this is None, a default messsage
+        /// If this is `None`, a default messsage
         /// will be generated, which is suitable
-        /// for most cases
+        /// for most cases.
         custom_note: Option<&'static str>
     },
 
@@ -502,7 +502,7 @@ impl Diverges {
     fn always(self) -> bool {
         // Enum comparison ignores the
         // contents of fields, so we just
-        // fill them in with garbage here
+        // fill them in with garbage here.
         self >= Diverges::Always {
             span: DUMMY_SP,
             custom_note: None

From a8ce93e13a9f1e7d7933ca76f6cae9c8f6127c34 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Wed, 18 Sep 2019 20:04:01 -0400
Subject: [PATCH 874/943] Introduce Diverges::always constructor

Rename the existing Diverges.always method to Diverges.is_always
---
 src/librustc_typeck/check/_match.rs |  7 ++-----
 src/librustc_typeck/check/expr.rs   |  5 +----
 src/librustc_typeck/check/mod.rs    | 14 ++++++++++++--
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 034cba0f12a62..9481638fc14d8 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -43,10 +43,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // If there are no arms, that is a diverging match; a special case.
         if arms.is_empty() {
-            self.diverges.set(self.diverges.get() | Diverges::Always {
-                span: expr.span,
-                custom_note: None
-            });
+            self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
             return tcx.types.never;
         }
 
@@ -198,7 +195,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// When the previously checked expression (the scrutinee) diverges,
     /// warn the user about the match arms being unreachable.
     fn warn_arms_when_scrutinee_diverges(&self, arms: &'tcx [hir::Arm], source: hir::MatchSource) {
-        if self.diverges.get().always() {
+        if self.diverges.get().is_always() {
             use hir::MatchSource::*;
             let msg = match source {
                 IfDesugar { .. } | IfLetDesugar { .. } => "block in `if` expression",
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 5733b8d1db13e..049f2eb16bb00 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -170,10 +170,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Any expression that produces a value of type `!` must have diverged
         if ty.is_never() {
-            self.diverges.set(self.diverges.get() | Diverges::Always {
-                span: expr.span,
-                custom_note: None
-            });
+            self.diverges.set(self.diverges.get() | Diverges::always(expr.span));
         }
 
         // Record the type, which applies it effects.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index e424aa679088d..410eef5e092d9 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -470,6 +470,16 @@ pub enum Diverges {
     WarnedAlways
 }
 
+impl Diverges {
+    /// Creates a `Diverges::Always` with the provided span and the default note message
+    fn always(span: Span) -> Diverges {
+        Diverges::Always {
+            span,
+            custom_note: None
+        }
+    }
+}
+
 // Convenience impls for combinig `Diverges`.
 
 impl ops::BitAnd for Diverges {
@@ -499,7 +509,7 @@ impl ops::BitOrAssign for Diverges {
 }
 
 impl Diverges {
-    fn always(self) -> bool {
+    fn is_always(self) -> bool {
         // Enum comparison ignores the
         // contents of fields, so we just
         // fill them in with garbage here.
@@ -3852,7 +3862,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 //
                 // #41425 -- label the implicit `()` as being the
                 // "found type" here, rather than the "expected type".
-                if !self.diverges.get().always() {
+                if !self.diverges.get().is_always() {
                     // #50009 -- Do not point at the entire fn block span, point at the return type
                     // span, as it is the cause of the requirement, and
                     // `consider_hint_about_removing_semicolon` will point at the last expression

From 41e1128969adc0190c946ccbd8b6b89ad197bc34 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Wed, 18 Sep 2019 20:07:33 -0400
Subject: [PATCH 875/943] Use 'if let' instead of 'match'

---
 src/librustc_typeck/check/_match.rs | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 9481638fc14d8..50fd72f061319 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -173,17 +173,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // we can emit a better note. Rather than pointing
         // at a diverging expression in an arbitrary arm,
         // we can point at the entire `match` expression
-        match (all_arms_diverge, match_src) {
-            (Diverges::Always { .. }, hir::MatchSource::Normal) => {
-                all_arms_diverge = Diverges::Always {
-                    span: expr.span,
-                    custom_note: Some(
-                        "any code following this `match` expression is unreachable, \
-                        as all arms diverge"
-                    )
-                };
-            },
-            _ => {}
+        if let (Diverges::Always { .. }, hir::MatchSource::Normal) = (all_arms_diverge, match_src) {
+            all_arms_diverge = Diverges::Always {
+                span: expr.span,
+                custom_note: Some(
+                    "any code following this `match` expression is unreachable, as all arms diverge"
+                )
+            };
         }
 
         // We won't diverge unless the discriminant or all arms diverge.

From 034a8fd1dff9bff585a6152bf5c52e882a2bb28b Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Wed, 18 Sep 2019 20:14:56 -0400
Subject: [PATCH 876/943] Another formatting fix

Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
---
 src/librustc_typeck/check/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 410eef5e092d9..51381447fedca 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -471,7 +471,7 @@ pub enum Diverges {
 }
 
 impl Diverges {
-    /// Creates a `Diverges::Always` with the provided span and the default note message
+    /// Creates a `Diverges::Always` with the provided `span` and the default note message.
     fn always(span: Span) -> Diverges {
         Diverges::Always {
             span,

From 479ce39939014f0071f8600fa4ce150e33cb7d5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 25 Aug 2019 21:58:59 -0700
Subject: [PATCH 877/943] Add explanation to type mismatch involving type
 params and assoc types

---
 src/librustc/traits/mod.rs                    | 10 +-
 src/librustc/traits/util.rs                   | 27 +++---
 src/librustc/ty/error.rs                      | 96 ++++++++++++++++++-
 ...ssociated-const-generic-obligations.stderr |  2 +
 .../associated-types-eq-3.stderr              |  2 +
 .../associated-types-issue-20346.stderr       |  2 +
 ...ated-types-multiple-types-one-trait.stderr |  4 +
 .../reordered-type-param.stderr               |  2 +
 src/test/ui/hrtb/issue-62203-hrtb-ice.stderr  |  2 +
 .../bound-normalization-fail.stderr           |  4 +
 src/test/ui/impl-trait/equality2.stderr       |  2 +
 .../impl-generic-mismatch-ab.stderr           |  2 +
 .../universal-mismatched-type.stderr          |  2 +
 .../universal-two-impl-traits.stderr          |  2 +
 src/test/ui/issues/issue-13853.stderr         |  2 +
 src/test/ui/issues/issue-20225.stderr         |  6 ++
 src/test/ui/issues/issue-24204.stderr         |  1 +
 src/test/ui/issues/issue-2951.stderr          |  2 +
 src/test/ui/issues/issue-32323.stderr         |  2 +
 .../ui/mismatched_types/issue-35030.stderr    |  2 +
 .../specialization-default-projection.stderr  |  4 +
 .../specialization-default-types.stderr       |  4 +
 .../struct-path-self-type-mismatch.stderr     |  4 +
 .../enum-variant-generic-args.stderr          | 12 +++
 src/test/ui/type/type-parameter-names.stderr  |  2 +
 .../type-params-in-different-spaces-1.stderr  |  2 +
 .../type-params-in-different-spaces-3.stderr  |  2 +
 27 files changed, 181 insertions(+), 23 deletions(-)

diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index d2683090add40..7154962b59295 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -655,11 +655,11 @@ pub struct VtableTraitAliasData<'tcx, N> {
 }
 
 /// Creates predicate obligations from the generic bounds.
-pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
-                                     param_env: ty::ParamEnv<'tcx>,
-                                     generic_bounds: &ty::InstantiatedPredicates<'tcx>)
-                                     -> PredicateObligations<'tcx>
-{
+pub fn predicates_for_generics<'tcx>(
+    cause: ObligationCause<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    generic_bounds: &ty::InstantiatedPredicates<'tcx>,
+) -> PredicateObligations<'tcx> {
     util::predicates_for_generics(cause, 0, param_env, generic_bounds)
 }
 
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index 3d36790c94b8c..3e5520dd46557 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -513,20 +513,19 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>(
 }
 
 /// See [`super::obligations_for_generics`].
-pub fn predicates_for_generics<'tcx>(cause: ObligationCause<'tcx>,
-                                     recursion_depth: usize,
-                                     param_env: ty::ParamEnv<'tcx>,
-                                     generic_bounds: &ty::InstantiatedPredicates<'tcx>)
-                                     -> Vec<PredicateObligation<'tcx>>
-{
-    debug!("predicates_for_generics(generic_bounds={:?})",
-           generic_bounds);
-
-    generic_bounds.predicates.iter().map(|predicate| {
-        Obligation { cause: cause.clone(),
-                     recursion_depth,
-                     param_env,
-                     predicate: predicate.clone() }
+pub fn predicates_for_generics<'tcx>(
+    cause: ObligationCause<'tcx>,
+    recursion_depth: usize,
+    param_env: ty::ParamEnv<'tcx>,
+    generic_bounds: &ty::InstantiatedPredicates<'tcx>,
+) -> Vec<PredicateObligation<'tcx>> {
+    debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds);
+
+    generic_bounds.predicates.iter().map(|predicate| Obligation {
+        cause: cause.clone(),
+        recursion_depth,
+        param_env,
+        predicate: predicate.clone(),
     }).collect()
 }
 
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 62910ec320494..993d627d6e176 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -275,10 +275,10 @@ impl<'tcx> TyCtxt<'tcx> {
                                  `.await`ing on both of them");
                     }
                 }
-                if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) =
-                       (&values.found.sty, &values.expected.sty) // Issue #53280
-                {
-                    if let Ok(snippet) = self.sess.source_map().span_to_snippet(sp) {
+                match (&values.expected.sty, &values.found.sty) {
+                    (ty::Float(_), ty::Infer(ty::IntVar(_))) => if let Ok( // Issue #53280
+                        snippet,
+                    ) = self.sess.source_map().span_to_snippet(sp) {
                         if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
                             db.span_suggestion(
                                 sp,
@@ -287,8 +287,96 @@ impl<'tcx> TyCtxt<'tcx> {
                                 Applicability::MachineApplicable
                             );
                         }
+                    },
+                    (ty::Param(_), ty::Param(_)) => {
+                        db.note("a type parameter was expected, but a different one was found; \
+                                 you might be missing a type parameter or trait bound");
+                        db.note("for more information, visit \
+                                 https://doc.rust-lang.org/book/ch10-02-traits.html\
+                                 #traits-as-parameters");
+                    }
+                    (ty::Projection(_), ty::Projection(_)) => {
+                        db.note("an associated type was expected, but a different one was found");
+                    }
+                    (ty::Param(_), ty::Projection(_)) | (ty::Projection(_), ty::Param(_)) => {
+                        db.note("you might be missing a type parameter or trait bound");
+                    }
+                    (ty::Param(_), _) | (_, ty::Param(_)) => {
+                        db.help("type parameters must be constrained to match other types");
+                        if self.sess.teach(&db.get_code().unwrap()) {
+                            db.help("given a type parameter `T` and a method `foo`:
+```
+trait Trait<T> { fn foo(&self) -> T; }
+```
+the only ways to implement method `foo` are:
+- constrain `T` with an explicit type:
+```
+impl Trait<String> for X {
+    fn foo(&self) -> String { String::new() }
+}
+```
+- add a trait bound to `T` and call a method on that trait that returns `Self`:
+```
+impl<T: std::default::Default> Trait<T> for X {
+    fn foo(&self) -> T { <T as std::default::Default>::default() }
+}
+```
+- change `foo` to return an argument of type `T`:
+```
+impl<T> Trait<T> for X {
+    fn foo(&self, x: T) -> T { x }
+}
+```");
+                        }
+                        db.note("for more information, visit \
+                                 https://doc.rust-lang.org/book/ch10-02-traits.html\
+                                 #traits-as-parameters");
+                    }
+                    (ty::Projection(_), _) => {
+                        db.note(&format!(
+                            "consider constraining the associated type `{}` to `{}` or calling a \
+                             method that returns `{}`",
+                            values.expected,
+                            values.found,
+                            values.expected,
+                        ));
+                        if self.sess.teach(&db.get_code().unwrap()) {
+                            db.help("given an associated type `T` and a method `foo`:
+```
+trait Trait {
+    type T;
+    fn foo(&self) -> Self::T;
+}
+```
+the only way of implementing method `foo` is to constrain `T` with an explicit associated type:
+```
+impl Trait for X {
+    type T = String;
+    fn foo(&self) -> Self::T { String::new() }
+}
+```");
+                        }
+                        db.note("for more information, visit \
+                                 https://doc.rust-lang.org/book/ch19-03-advanced-traits.html");
+                    }
+                    (_, ty::Projection(_)) => {
+                        db.note(&format!(
+                            "consider constraining the associated type `{}` to `{}`",
+                            values.found,
+                            values.expected,
+                        ));
+                        db.note("for more information, visit \
+                                 https://doc.rust-lang.org/book/ch19-03-advanced-traits.html");
                     }
+                    _ => {}
                 }
+                debug!(
+                    "note_and_explain_type_err expected={:?} ({:?}) found={:?} ({:?})",
+                    values.expected,
+                    values.expected.sty,
+                    values.found,
+                    values.found.sty,
+                );
             },
             CyclicTy(ty) => {
                 // Watch out for various cases of cyclic types and try to explain.
diff --git a/src/test/ui/associated-const/associated-const-generic-obligations.stderr b/src/test/ui/associated-const/associated-const-generic-obligations.stderr
index eeee26a75671f..ca6118cb3ba98 100644
--- a/src/test/ui/associated-const/associated-const-generic-obligations.stderr
+++ b/src/test/ui/associated-const/associated-const-generic-obligations.stderr
@@ -9,6 +9,8 @@ LL |     const FROM: &'static str = "foo";
    |
    = note: expected type `<T as Foo>::Out`
               found type `&'static str`
+   = note: consider constraining the associated type `<T as Foo>::Out` to `&'static str` or calling a method that returns `<T as Foo>::Out`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr
index 0f8c5257d445f..c9d88b7af0753 100644
--- a/src/test/ui/associated-types/associated-types-eq-3.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-3.stderr
@@ -6,6 +6,8 @@ LL |     let _: Bar = x.boo();
    |
    = note: expected type `Bar`
               found type `<I as Foo>::A`
+   = note: consider constraining the associated type `<I as Foo>::A` to `Bar`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
   --> $DIR/associated-types-eq-3.rs:38:5
diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr
index 7d6c025d69d55..e037bd851ca21 100644
--- a/src/test/ui/associated-types/associated-types-issue-20346.stderr
+++ b/src/test/ui/associated-types/associated-types-issue-20346.stderr
@@ -9,6 +9,8 @@ LL |     is_iterator_of::<Option<T>, _>(&adapter);
    |
    = note: expected type `T`
               found type `std::option::Option<T>`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
index 4a2a6d03c607f..d6328a64c7c74 100644
--- a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
+++ b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
@@ -9,6 +9,8 @@ LL | fn want_y<T:Foo<Y=i32>>(t: &T) { }
    |
    = note: expected type `<T as Foo>::Y`
               found type `i32`
+   = note: consider constraining the associated type `<T as Foo>::Y` to `i32` or calling a method that returns `<T as Foo>::Y`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `<T as Foo>::X == u32`
   --> $DIR/associated-types-multiple-types-one-trait.rs:18:5
@@ -21,6 +23,8 @@ LL | fn want_x<T:Foo<X=u32>>(t: &T) { }
    |
    = note: expected type `<T as Foo>::X`
               found type `u32`
+   = note: consider constraining the associated type `<T as Foo>::X` to `u32` or calling a method that returns `<T as Foo>::X`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/compare-method/reordered-type-param.stderr b/src/test/ui/compare-method/reordered-type-param.stderr
index a33908c01c842..8176e96d6de1f 100644
--- a/src/test/ui/compare-method/reordered-type-param.stderr
+++ b/src/test/ui/compare-method/reordered-type-param.stderr
@@ -9,6 +9,8 @@ LL |   fn b<F:Clone,G>(&self, _x: G) -> G { panic!() }
    |
    = note: expected type `fn(&E, F) -> F`
               found type `fn(&E, G) -> G`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
index c2d0e0c2a26bc..fd6fce938b2c7 100644
--- a/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
+++ b/src/test/ui/hrtb/issue-62203-hrtb-ice.stderr
@@ -6,6 +6,8 @@ LL |     let v = Unit2.m(
    |
    = note: expected type `Unit4`
               found type `<_ as Ty<'_>>::V`
+   = note: consider constraining the associated type `<_ as Ty<'_>>::V` to `Unit4`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0271]: type mismatch resolving `<[closure@$DIR/issue-62203-hrtb-ice.rs:42:17: 42:39] as std::ops::FnOnce<((&u8,),)>>::Output == Unit3`
   --> $DIR/issue-62203-hrtb-ice.rs:38:19
diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr
index 2c4c61a0957f9..99c6a8cdd6daf 100644
--- a/src/test/ui/impl-trait/bound-normalization-fail.stderr
+++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr
@@ -14,6 +14,8 @@ LL |     fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> {
    |
    = note: expected type `()`
               found type `<T as impl_trait::Trait>::Assoc`
+   = note: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
    = note: the return type of a function must have a statically known size
 
 error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
@@ -30,6 +32,8 @@ LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> {
    |
    = note: expected type `()`
               found type `<T as lifetimes::Trait<'static>>::Assoc`
+   = note: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
    = note: the return type of a function must have a statically known size
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr
index 3e6181adec026..e30e2626e9f34 100644
--- a/src/test/ui/impl-trait/equality2.stderr
+++ b/src/test/ui/impl-trait/equality2.stderr
@@ -15,6 +15,8 @@ LL |     let _: i32 = Leak::leak(hide(0_i32));
    |
    = note: expected type `i32`
               found type `<impl Foo as Leak>::T`
+   = note: consider constraining the associated type `<impl Foo as Leak>::T` to `i32`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0308]: mismatched types
   --> $DIR/equality2.rs:38:10
diff --git a/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr b/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr
index 357e6b026e2a3..e4d0a731ebfe5 100644
--- a/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr
+++ b/src/test/ui/impl-trait/impl-generic-mismatch-ab.stderr
@@ -9,6 +9,8 @@ LL |     fn foo<B: Debug>(&self, a: &impl Debug, b: &B) { }
    |
    = note: expected type `fn(&(), &B, &impl Debug)`
               found type `fn(&(), &impl Debug, &B)`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/universal-mismatched-type.stderr b/src/test/ui/impl-trait/universal-mismatched-type.stderr
index d223b9672cfdc..d92c3f034e5a2 100644
--- a/src/test/ui/impl-trait/universal-mismatched-type.stderr
+++ b/src/test/ui/impl-trait/universal-mismatched-type.stderr
@@ -8,6 +8,8 @@ LL |     x
    |
    = note: expected type `std::string::String`
               found type `impl Debug`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/universal-two-impl-traits.stderr b/src/test/ui/impl-trait/universal-two-impl-traits.stderr
index 145d6a8431bf4..98a70f268cf72 100644
--- a/src/test/ui/impl-trait/universal-two-impl-traits.stderr
+++ b/src/test/ui/impl-trait/universal-two-impl-traits.stderr
@@ -6,6 +6,8 @@ LL |     a = y;
    |
    = note: expected type `impl Debug` (type parameter)
               found type `impl Debug` (type parameter)
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-13853.stderr b/src/test/ui/issues/issue-13853.stderr
index c57ca3e25d99f..3f2d0aa87adc1 100644
--- a/src/test/ui/issues/issue-13853.stderr
+++ b/src/test/ui/issues/issue-13853.stderr
@@ -9,6 +9,8 @@ LL |         self.iter()
    |
    = note: expected type `I`
               found type `std::slice::Iter<'_, N>`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0599]: no method named `iter` found for type `&G` in the current scope
   --> $DIR/issue-13853.rs:27:23
diff --git a/src/test/ui/issues/issue-20225.stderr b/src/test/ui/issues/issue-20225.stderr
index 5ab23cb55bcc4..4c464e6d4f685 100644
--- a/src/test/ui/issues/issue-20225.stderr
+++ b/src/test/ui/issues/issue-20225.stderr
@@ -6,6 +6,8 @@ LL |   extern "rust-call" fn call(&self, (_,): (T,)) {}
    |
    = note: expected type `extern "rust-call" fn(&Foo, (&'a T,))`
               found type `extern "rust-call" fn(&Foo, (T,))`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0053]: method `call_mut` has an incompatible type for trait
   --> $DIR/issue-20225.rs:12:3
@@ -15,6 +17,8 @@ LL |   extern "rust-call" fn call_mut(&mut self, (_,): (T,)) {}
    |
    = note: expected type `extern "rust-call" fn(&mut Foo, (&'a T,))`
               found type `extern "rust-call" fn(&mut Foo, (T,))`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0053]: method `call_once` has an incompatible type for trait
   --> $DIR/issue-20225.rs:20:3
@@ -24,6 +28,8 @@ LL |   extern "rust-call" fn call_once(self, (_,): (T,)) {}
    |
    = note: expected type `extern "rust-call" fn(Foo, (&'a T,))`
               found type `extern "rust-call" fn(Foo, (T,))`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-24204.stderr b/src/test/ui/issues/issue-24204.stderr
index eb9aada389f8f..9658f6980be2f 100644
--- a/src/test/ui/issues/issue-24204.stderr
+++ b/src/test/ui/issues/issue-24204.stderr
@@ -9,6 +9,7 @@ LL | fn test<T: Trait<B=i32>>(b: i32) -> T where T::A: MultiDispatch<i32> { T::n
    |
    = note: expected type `<<T as Trait>::A as MultiDispatch<i32>>::O`
               found type `T`
+   = note: you might be missing a type parameter or trait bound
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-2951.stderr b/src/test/ui/issues/issue-2951.stderr
index 58e28c1a9dc83..a6ccc4835fa68 100644
--- a/src/test/ui/issues/issue-2951.stderr
+++ b/src/test/ui/issues/issue-2951.stderr
@@ -6,6 +6,8 @@ LL |     xx = y;
    |
    = note: expected type `T`
               found type `U`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-32323.stderr b/src/test/ui/issues/issue-32323.stderr
index 6256dc0c55022..9c11a02923c8c 100644
--- a/src/test/ui/issues/issue-32323.stderr
+++ b/src/test/ui/issues/issue-32323.stderr
@@ -8,6 +8,8 @@ LL | pub fn f<'a, T: Tr<'a>>() -> <T as Tr<'a>>::Out {}
    |
    = note: expected type `<T as Tr<'a>>::Out`
               found type `()`
+   = note: consider constraining the associated type `<T as Tr<'a>>::Out` to `()` or calling a method that returns `<T as Tr<'a>>::Out`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mismatched_types/issue-35030.stderr b/src/test/ui/mismatched_types/issue-35030.stderr
index f030670161343..4a9afb9d2494e 100644
--- a/src/test/ui/mismatched_types/issue-35030.stderr
+++ b/src/test/ui/mismatched_types/issue-35030.stderr
@@ -6,6 +6,8 @@ LL |         Some(true)
    |
    = note: expected type `bool` (type parameter)
               found type `bool` (bool)
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/specialization/specialization-default-projection.stderr b/src/test/ui/specialization/specialization-default-projection.stderr
index ab0bdc44cff1a..43cebd7f9c245 100644
--- a/src/test/ui/specialization/specialization-default-projection.stderr
+++ b/src/test/ui/specialization/specialization-default-projection.stderr
@@ -9,6 +9,8 @@ LL |     ()
    |
    = note: expected type `<T as Foo>::Assoc`
               found type `()`
+   = note: consider constraining the associated type `<T as Foo>::Assoc` to `()` or calling a method that returns `<T as Foo>::Assoc`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0308]: mismatched types
   --> $DIR/specialization-default-projection.rs:28:5
@@ -23,6 +25,8 @@ LL |     generic::<()>()
    |
    = note: expected type `()`
               found type `<() as Foo>::Assoc`
+   = note: consider constraining the associated type `<() as Foo>::Assoc` to `()`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/specialization/specialization-default-types.stderr b/src/test/ui/specialization/specialization-default-types.stderr
index 1192b0e5cfa53..932087421fbcb 100644
--- a/src/test/ui/specialization/specialization-default-types.stderr
+++ b/src/test/ui/specialization/specialization-default-types.stderr
@@ -8,6 +8,8 @@ LL |         Box::new(self)
    |
    = note: expected type `<T as Example>::Output`
               found type `std::boxed::Box<T>`
+   = note: consider constraining the associated type `<T as Example>::Output` to `std::boxed::Box<T>` or calling a method that returns `<T as Example>::Output`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error[E0308]: mismatched types
   --> $DIR/specialization-default-types.rs:25:5
@@ -19,6 +21,8 @@ LL |     Example::generate(t)
    |
    = note: expected type `std::boxed::Box<T>`
               found type `<T as Example>::Output`
+   = note: consider constraining the associated type `<T as Example>::Output` to `std::boxed::Box<T>`
+   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/structs/struct-path-self-type-mismatch.stderr b/src/test/ui/structs/struct-path-self-type-mismatch.stderr
index 72c6d7ae22b4b..b905cd1a294cc 100644
--- a/src/test/ui/structs/struct-path-self-type-mismatch.stderr
+++ b/src/test/ui/structs/struct-path-self-type-mismatch.stderr
@@ -12,6 +12,8 @@ LL |             inner: u
    |
    = note: expected type `T`
               found type `U`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0308]: mismatched types
   --> $DIR/struct-path-self-type-mismatch.rs:13:9
@@ -27,6 +29,8 @@ LL | |         }
    |
    = note: expected type `Foo<U>`
               found type `Foo<T>`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
index ee73622cb7bd1..a0a617fdbbc35 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-generic-args.stderr
@@ -6,6 +6,8 @@ LL |         Self::TSVariant(());
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:15:27
@@ -27,6 +29,8 @@ LL |         Self::<()>::TSVariant(());
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:20:16
@@ -48,6 +52,8 @@ LL |         Self::SVariant { v: () };
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:28:26
@@ -63,6 +69,8 @@ LL |         Self::SVariant::<()> { v: () };
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:31:16
@@ -78,6 +86,8 @@ LL |         Self::<()>::SVariant { v: () };
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:34:16
@@ -99,6 +109,8 @@ LL |         Self::<()>::SVariant::<()> { v: () };
    |
    = note: expected type `T`
               found type `()`
+   = help: type parameters must be constrained to match other types
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error[E0109]: type arguments are not allowed for this type
   --> $DIR/enum-variant-generic-args.rs:41:26
diff --git a/src/test/ui/type/type-parameter-names.stderr b/src/test/ui/type/type-parameter-names.stderr
index 9acae5c376d5b..3397eec9e050b 100644
--- a/src/test/ui/type/type-parameter-names.stderr
+++ b/src/test/ui/type/type-parameter-names.stderr
@@ -8,6 +8,8 @@ LL |     x
    |
    = note: expected type `Bar`
               found type `Foo`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type/type-params-in-different-spaces-1.stderr b/src/test/ui/type/type-params-in-different-spaces-1.stderr
index 0448a28ea8e27..a10bf4e0b7787 100644
--- a/src/test/ui/type/type-params-in-different-spaces-1.stderr
+++ b/src/test/ui/type/type-params-in-different-spaces-1.stderr
@@ -6,6 +6,8 @@ LL |         *self + rhs
    |
    = note: expected type `Self`
               found type `T`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/type/type-params-in-different-spaces-3.stderr b/src/test/ui/type/type-params-in-different-spaces-3.stderr
index e25f79947c732..9f0fa5a0ea1fe 100644
--- a/src/test/ui/type/type-params-in-different-spaces-3.stderr
+++ b/src/test/ui/type/type-params-in-different-spaces-3.stderr
@@ -8,6 +8,8 @@ LL |         u
    |
    = note: expected type `Self`
               found type `X`
+   = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
+   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
 
 error: aborting due to previous error
 

From d440e136e753210882d930c6f4884a43984f6ba0 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Mon, 16 Sep 2019 14:45:40 -0400
Subject: [PATCH 878/943] Update Cargo

This pulls in https://github.com/rust-lang/cargo/pull/7159, which
ensures that documenting proc macros works correctly.
---
 Cargo.lock                                | 32 ++++++++++++++++++++---
 src/tools/cargo                           |  2 +-
 src/tools/rustc-workspace-hack/Cargo.toml |  1 +
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 0fe3138427468..894dcf937de50 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -272,6 +272,7 @@ dependencies = [
  "atty",
  "bytesize",
  "cargo-test-macro",
+ "cargo-test-support",
  "clap",
  "core-foundation",
  "crates-io",
@@ -288,8 +289,9 @@ dependencies = [
  "git2",
  "git2-curl",
  "glob",
- "hex",
+ "hex 0.4.0",
  "home",
+ "humantime",
  "ignore",
  "im-rc",
  "jobserver",
@@ -329,6 +331,23 @@ dependencies = [
 name = "cargo-test-macro"
 version = "0.1.0"
 
+[[package]]
+name = "cargo-test-support"
+version = "0.1.0"
+dependencies = [
+ "cargo",
+ "cargo-test-macro",
+ "filetime",
+ "flate2",
+ "git2",
+ "glob",
+ "lazy_static 1.3.0",
+ "remove_dir_all",
+ "serde_json",
+ "tar",
+ "url 2.1.0",
+]
+
 [[package]]
 name = "cargo_metadata"
 version = "0.8.0"
@@ -700,7 +719,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4"
 dependencies = [
  "commoncrypto",
- "hex",
+ "hex 0.3.2",
  "openssl",
  "winapi 0.3.6",
 ]
@@ -1262,6 +1281,12 @@ version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
 
+[[package]]
+name = "hex"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e"
+
 [[package]]
 name = "home"
 version = "0.5.0"
@@ -2064,7 +2089,7 @@ dependencies = [
  "directories",
  "env_logger",
  "getrandom",
- "hex",
+ "hex 0.3.2",
  "log",
  "num-traits",
  "rand 0.7.0",
@@ -3259,6 +3284,7 @@ dependencies = [
  "serde",
  "serde_json",
  "smallvec",
+ "url 2.1.0",
  "winapi 0.3.6",
 ]
 
diff --git a/src/tools/cargo b/src/tools/cargo
index 9655d70af8a6d..3596cb86b2e87 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit 9655d70af8a6dddac238e3afa2fec75088c9226f
+Subproject commit 3596cb86b2e87dd9b9c1bb90d4a9d73ec2c1512f
diff --git a/src/tools/rustc-workspace-hack/Cargo.toml b/src/tools/rustc-workspace-hack/Cargo.toml
index 930279c0ca27b..980c9753761ed 100644
--- a/src/tools/rustc-workspace-hack/Cargo.toml
+++ b/src/tools/rustc-workspace-hack/Cargo.toml
@@ -62,6 +62,7 @@ crossbeam-utils = { version = "0.6.5", features = ["nightly"] }
 serde = { version = "1.0.82", features = ['derive'] }
 serde_json = { version = "1.0.31", features = ["raw_value"] }
 smallvec = { version = "0.6", features = ['union', 'may_dangle'] }
+url = { version = "2.0", features = ['serde'] }
 
 
 [target.'cfg(not(windows))'.dependencies]

From d67528ff7dbbe226fa583b9585cee2138533770e Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Wed, 18 Sep 2019 21:57:50 -0400
Subject: [PATCH 879/943] Merge inherent impl blocks for `Diverges

---
 src/librustc_typeck/check/mod.rs | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 51381447fedca..1d68d79db8856 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -470,16 +470,6 @@ pub enum Diverges {
     WarnedAlways
 }
 
-impl Diverges {
-    /// Creates a `Diverges::Always` with the provided `span` and the default note message.
-    fn always(span: Span) -> Diverges {
-        Diverges::Always {
-            span,
-            custom_note: None
-        }
-    }
-}
-
 // Convenience impls for combinig `Diverges`.
 
 impl ops::BitAnd for Diverges {
@@ -509,6 +499,14 @@ impl ops::BitOrAssign for Diverges {
 }
 
 impl Diverges {
+    /// Creates a `Diverges::Always` with the provided `span` and the default note message.
+    fn always(span: Span) -> Diverges {
+        Diverges::Always {
+            span,
+            custom_note: None
+        }
+    }
+
     fn is_always(self) -> bool {
         // Enum comparison ignores the
         // contents of fields, so we just

From 37bafeafe73cff935bb444b6736a958a9a752669 Mon Sep 17 00:00:00 2001
From: Joshua Groves <josh@joshgroves.com>
Date: Wed, 18 Sep 2019 23:17:36 -0600
Subject: [PATCH 880/943] Fix backticks in documentation

---
 src/librustc/middle/region.rs                          | 2 +-
 src/librustc/ty/query/on_disk_cache.rs                 | 2 +-
 src/libsyntax/source_map.rs                            | 4 ++--
 src/test/ui/borrowck/two-phase-surprise-no-conflict.rs | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index b9d8a4ec68fad..87470140e3148 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -1136,7 +1136,7 @@ fn resolve_local<'tcx>(
     // Rule A. `let (ref x, ref y) = (foo().x, 44)`. The rvalue `(22, 44)`
     // would have an extended lifetime, but not `foo()`.
     //
-    // Rule B. `let x = &foo().x`. The rvalue ``foo()` would have extended
+    // Rule B. `let x = &foo().x`. The rvalue `foo()` would have extended
     // lifetime.
     //
     // In some cases, multiple rules may apply (though not to the same
diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs
index 4cef6a09925ad..c20e758688959 100644
--- a/src/librustc/ty/query/on_disk_cache.rs
+++ b/src/librustc/ty/query/on_disk_cache.rs
@@ -643,7 +643,7 @@ impl<'a, 'tcx> SpecializedDecoder<DefIndex> for CacheDecoder<'a, 'tcx> {
 
 // Both the `CrateNum` and the `DefIndex` of a `DefId` can change in between two
 // compilation sessions. We use the `DefPathHash`, which is stable across
-// sessions, to map the old DefId`` to the new one.
+// sessions, to map the old `DefId` to the new one.
 impl<'a, 'tcx> SpecializedDecoder<DefId> for CacheDecoder<'a, 'tcx> {
     #[inline]
     fn specialized_decode(&mut self) -> Result<DefId, Self::Error> {
diff --git a/src/libsyntax/source_map.rs b/src/libsyntax/source_map.rs
index d7ea799e00459..7d0d2392945e5 100644
--- a/src/libsyntax/source_map.rs
+++ b/src/libsyntax/source_map.rs
@@ -3,7 +3,7 @@
 //! of source parsed during crate parsing (typically files, in-memory strings,
 //! or various bits of macro expansion) cover a continuous range of bytes in the
 //! `SourceMap` and are represented by `SourceFile`s. Byte positions are stored in
-//! `Span`` and used pervasively in the compiler. They are absolute positions
+//! `Span` and used pervasively in the compiler. They are absolute positions
 //! within the `SourceMap`, which upon request can be converted to line and column
 //! information, source code snippets, etc.
 
@@ -645,7 +645,7 @@ impl SourceMap {
     }
 
     /// Given a `Span`, tries to get a shorter span ending before the first occurrence of `char`
-    /// ``c`.
+    /// `c`.
     pub fn span_until_char(&self, sp: Span, c: char) -> Span {
         match self.span_to_snippet(sp) {
             Ok(snippet) => {
diff --git a/src/test/ui/borrowck/two-phase-surprise-no-conflict.rs b/src/test/ui/borrowck/two-phase-surprise-no-conflict.rs
index 3fd24bbf290b5..6d37d1ded6400 100644
--- a/src/test/ui/borrowck/two-phase-surprise-no-conflict.rs
+++ b/src/test/ui/borrowck/two-phase-surprise-no-conflict.rs
@@ -31,7 +31,7 @@ impl <'a> SpanlessHash<'a> {
                 //
                 // Not okay without two-phase borrows: the implicit
                 // `&mut self` of the receiver is evaluated first, and
-                // that conflicts with the `self.cx`` access during
+                // that conflicts with the `self.cx` access during
                 // argument evaluation, as demonstrated in `fn demo`
                 // above.
                 //

From 5384a199c70de3d93558b42ba8ed742cf03da5f4 Mon Sep 17 00:00:00 2001
From: Pietro Albini <pietro@pietroalbini.org>
Date: Wed, 18 Sep 2019 11:10:46 +0200
Subject: [PATCH 881/943] ci: split aws credentials in two separate users with
 scoped perms

This commit changes our CI to use two separate IAM users to
authenticate with AWS:

* ci--rust-lang--rust--sccache: has access to the rust-lang-ci-sccache2
  S3 bucket and its credentials are available during the whole build.
* ci--rust-lang--rust--upload: has access to the rust-lang-ci2 S3 bucket
  and its credentials are available just during the upload step.

The new tokens are available in the `prod-credentials` library.
---
 src/ci/azure-pipelines/auto.yml      |  2 +-
 src/ci/azure-pipelines/master.yml    |  2 +-
 src/ci/azure-pipelines/steps/run.yml | 11 +++++++----
 src/ci/azure-pipelines/try.yml       |  2 +-
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/src/ci/azure-pipelines/auto.yml b/src/ci/azure-pipelines/auto.yml
index 1656066eb29c9..5f7761297095c 100644
--- a/src/ci/azure-pipelines/auto.yml
+++ b/src/ci/azure-pipelines/auto.yml
@@ -7,7 +7,7 @@ trigger:
   - auto
 
 variables:
-- group: real-prod-credentials
+- group: prod-credentials
 
 jobs:
 - job: Linux
diff --git a/src/ci/azure-pipelines/master.yml b/src/ci/azure-pipelines/master.yml
index 9742c71965851..e2baa923d99f7 100644
--- a/src/ci/azure-pipelines/master.yml
+++ b/src/ci/azure-pipelines/master.yml
@@ -7,7 +7,7 @@ trigger:
   - master
 
 variables:
-- group: real-prod-credentials
+- group: prod-credentials
 
 pool:
   vmImage: ubuntu-16.04
diff --git a/src/ci/azure-pipelines/steps/run.yml b/src/ci/azure-pipelines/steps/run.yml
index da0a899ac85eb..15a2499e4609e 100644
--- a/src/ci/azure-pipelines/steps/run.yml
+++ b/src/ci/azure-pipelines/steps/run.yml
@@ -175,7 +175,8 @@ steps:
   env:
     CI: true
     SRC: .
-    AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)
+    AWS_ACCESS_KEY_ID: $(SCCACHE_AWS_ACCESS_KEY_ID)
+    AWS_SECRET_ACCESS_KEY: $(SCCACHE_AWS_SECRET_ACCESS_KEY)
     TOOLSTATE_REPO_ACCESS_TOKEN: $(TOOLSTATE_REPO_ACCESS_TOKEN)
   condition: and(succeeded(), not(variables.SKIP_JOB))
   displayName: Run build
@@ -199,7 +200,8 @@ steps:
     fi
     retry aws s3 cp --no-progress --recursive --acl public-read ./$upload_dir s3://$DEPLOY_BUCKET/$deploy_dir/$BUILD_SOURCEVERSION
   env:
-    AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)
+    AWS_ACCESS_KEY_ID: $(UPLOAD_AWS_ACCESS_KEY_ID)
+    AWS_SECRET_ACCESS_KEY: $(UPLOAD_AWS_SECRET_ACCESS_KEY)
   condition: and(succeeded(), not(variables.SKIP_JOB), or(eq(variables.DEPLOY, '1'), eq(variables.DEPLOY_ALT, '1')))
   displayName: Upload artifacts
 
@@ -208,7 +210,8 @@ steps:
 # errors here ever fail the build since this is just informational.
 - bash: aws s3 cp --acl public-read cpu-usage.csv s3://$DEPLOY_BUCKET/rustc-builds/$BUILD_SOURCEVERSION/cpu-$CI_JOB_NAME.csv
   env:
-    AWS_SECRET_ACCESS_KEY: $(AWS_SECRET_ACCESS_KEY)
-  condition: variables['AWS_SECRET_ACCESS_KEY']
+    AWS_ACCESS_KEY_ID: $(UPLOAD_AWS_ACCESS_KEY_ID)
+    AWS_SECRET_ACCESS_KEY: $(UPLOAD_AWS_SECRET_ACCESS_KEY)
+  condition: variables['UPLOAD_AWS_SECRET_ACCESS_KEY']
   continueOnError: true
   displayName: Upload CPU usage statistics
diff --git a/src/ci/azure-pipelines/try.yml b/src/ci/azure-pipelines/try.yml
index 0df6c6c951f24..c919b1023a0eb 100644
--- a/src/ci/azure-pipelines/try.yml
+++ b/src/ci/azure-pipelines/try.yml
@@ -3,7 +3,7 @@ trigger:
 - try
 
 variables:
-- group: real-prod-credentials
+- group: prod-credentials
 
 jobs:
 - job: Linux

From 1de533ac1a3bddd6bf61791f4ee6cf52cb186fdf Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Thu, 19 Sep 2019 09:02:45 +0200
Subject: [PATCH 882/943] first determine if the variant is a niche-variant,
 then compute absolute variant

---
 src/librustc_mir/interpret/operand.rs | 29 ++++++++++++++-------------
 src/librustc_mir/interpret/place.rs   |  3 ++-
 2 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 9e7ae32f1eacf..dd214c4a031f7 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -1,7 +1,7 @@
 //! Functions concerning immediate values and operands, and reading from operands.
 //! All high-level functions to read from memory work on operands as sources.
 
-use std::convert::TryInto;
+use std::convert::{TryInto, TryFrom};
 
 use rustc::{mir, ty};
 use rustc::ty::layout::{
@@ -671,8 +671,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 ref niche_variants,
                 niche_start,
             } => {
-                let variants_start = niche_variants.start().as_u32() as u128;
-                let variants_end = niche_variants.end().as_u32() as u128;
+                let variants_start = niche_variants.start().as_u32();
+                let variants_end = niche_variants.end().as_u32();
                 let raw_discr = raw_discr.not_undef().map_err(|_| {
                     err_unsup!(InvalidDiscriminant(ScalarMaybeUndef::Undef))
                 })?;
@@ -687,7 +687,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         (dataful_variant.as_u32() as u128, dataful_variant)
                     },
                     Ok(raw_discr) => {
-                        // We need to use machine arithmetic to get the relative variant idx.
+                        // We need to use machine arithmetic to get the relative variant idx:
+                        // variant_index_relative = discr_val - niche_start_val
                         let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
                         let discr_val = ImmTy::from_uint(raw_discr, discr_layout);
                         let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
@@ -699,21 +700,21 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         let variant_index_relative = variant_index_relative_val
                             .to_scalar()?
                             .assert_bits(discr_val.layout.size);
-                        // Then computing the absolute variant idx should not overflow any more.
-                        let variant_index = variants_start
-                            .checked_add(variant_index_relative)
-                            .expect("oveflow computing absolute variant idx");
                         // Check if this is in the range that indicates an actual discriminant.
-                        if variants_start <= variant_index && variant_index <= variants_end {
-                            let index = variant_index as usize;
-                            assert_eq!(index as u128, variant_index);
-                            assert!(index < rval.layout.ty
+                        if variant_index_relative <= u128::from(variants_end - variants_start) {
+                            let variant_index_relative = u32::try_from(variant_index_relative)
+                                .expect("we checked that this fits into a u32");
+                            // Then computing the absolute variant idx should not overflow any more.
+                            let variant_index = variants_start
+                                .checked_add(variant_index_relative)
+                                .expect("oveflow computing absolute variant idx");
+                            assert!((variant_index as usize) < rval.layout.ty
                                 .ty_adt_def()
                                 .expect("tagged layout for non adt")
                                 .variants.len());
-                            (variant_index, VariantIdx::from_usize(index))
+                            (u128::from(variant_index), VariantIdx::from_u32(variant_index))
                         } else {
-                            (dataful_variant.as_u32() as u128, dataful_variant)
+                            (u128::from(dataful_variant.as_u32()), dataful_variant)
                         }
                     },
                 }
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 5f4903d61e3b2..c3660fb7a2e28 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -1064,7 +1064,8 @@ where
                     let variant_index_relative = variant_index.as_u32()
                         .checked_sub(variants_start)
                         .expect("overflow computing relative variant idx");
-                    // We need to use machine arithmetic when taking into account `niche_start`.
+                    // We need to use machine arithmetic when taking into account `niche_start`:
+                    // discr_val = variant_index_relative + niche_start_val
                     let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?;
                     let niche_start_val = ImmTy::from_uint(niche_start, discr_layout);
                     let variant_index_relative_val =

From c23e78a38b9643f15b008393b2506a813e7ee2ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrian=20Heine=20n=C3=A9=20Lang?= <mail@adrianheine.de>
Date: Thu, 19 Sep 2019 13:36:10 +0200
Subject: [PATCH 883/943] Remove unnecessary `mut` in doc example

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

diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index b8d57cfafea0a..c6dc02fea2d84 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -935,7 +935,7 @@ impl Stdio {
     ///     .expect("Failed to spawn child process");
     ///
     /// {
-    ///     let mut stdin = child.stdin.as_mut().expect("Failed to open stdin");
+    ///     let stdin = child.stdin.as_mut().expect("Failed to open stdin");
     ///     stdin.write_all("Hello, world!".as_bytes()).expect("Failed to write to stdin");
     /// }
     ///

From 9a447a232e3d17d7dea7eeeda51cbc9a28d497dc Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Thu, 19 Sep 2019 10:07:50 -0400
Subject: [PATCH 884/943] replace boolean with lazy iteration

Should probably check how this performs, but it's always nicer to
track just a bit less mutable state.
---
 src/librustc_mir/build/scope.rs | 39 +++++++++++++++++----------------
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index ee6d42de388d9..3c735c8cb09d7 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -104,19 +104,6 @@ struct Scope {
     /// the span of that region_scope
     region_scope_span: Span,
 
-    /// Whether there's anything to do for the cleanup path, that is,
-    /// when unwinding through this scope. This includes destructors,
-    /// but not StorageDead statements, which don't get emitted at all
-    /// for unwinding, for several reasons:
-    ///  * clang doesn't emit llvm.lifetime.end for C++ unwinding
-    ///  * LLVM's memory dependency analysis can't handle it atm
-    ///  * polluting the cleanup MIR with StorageDead creates
-    ///    landing pads even though there's no actual destructors
-    ///  * freeing up stack space has no effect during unwinding
-    /// Note that for generators we do emit StorageDeads, for the
-    /// use of optimizations in the MIR generator transform.
-    needs_cleanup: bool,
-
     /// set of places to drop when exiting this scope. This starts
     /// out empty but grows as variables are declared during the
     /// building process. This is a stack, so we always drop from the
@@ -261,6 +248,25 @@ impl Scope {
             scope: self.source_scope
         }
     }
+
+
+    /// Whether there's anything to do for the cleanup path, that is,
+    /// when unwinding through this scope. This includes destructors,
+    /// but not StorageDead statements, which don't get emitted at all
+    /// for unwinding, for several reasons:
+    ///  * clang doesn't emit llvm.lifetime.end for C++ unwinding
+    ///  * LLVM's memory dependency analysis can't handle it atm
+    ///  * polluting the cleanup MIR with StorageDead creates
+    ///    landing pads even though there's no actual destructors
+    ///  * freeing up stack space has no effect during unwinding
+    /// Note that for generators we do emit StorageDeads, for the
+    /// use of optimizations in the MIR generator transform.
+    fn needs_cleanup(&self) -> bool {
+        self.drops.iter().any(|drop| match drop.kind {
+            DropKind::Value => true,
+            DropKind::Storage => false,
+        })
+    }
 }
 
 impl<'tcx> Scopes<'tcx> {
@@ -274,7 +280,6 @@ impl<'tcx> Scopes<'tcx> {
             source_scope: vis_scope,
             region_scope: region_scope.0,
             region_scope_span: region_scope.1.span,
-            needs_cleanup: false,
             drops: vec![],
             cached_generator_drop: None,
             cached_exits: Default::default(),
@@ -295,7 +300,7 @@ impl<'tcx> Scopes<'tcx> {
 
     fn may_panic(&self, scope_count: usize) -> bool {
         let len = self.len();
-        self.scopes[(len - scope_count)..].iter().any(|s| s.needs_cleanup)
+        self.scopes[(len - scope_count)..].iter().any(|s| s.needs_cleanup())
     }
 
     /// Finds the breakable scope for a given label. This is used for
@@ -801,10 +806,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             // cache of outer scope stays intact.
             scope.invalidate_cache(!needs_drop, self.is_generator, this_scope);
             if this_scope {
-                if let DropKind::Value = drop_kind {
-                    scope.needs_cleanup = true;
-                }
-
                 let region_scope_span = region_scope.span(self.hir.tcx(),
                                                           &self.hir.region_scope_tree);
                 // Attribute scope exit drops to scope's closing brace.

From 72ea960056d40f1fcb5efb42d5914b35f908f63e Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Tue, 17 Sep 2019 07:40:27 -0700
Subject: [PATCH 885/943] azure: Convert Windows installations scripts to
 `bash`

Looks like `script`, which uses `cmd.exe`, doesn't have fail-fast
behavior and if a leading command fails the script doesn't actually fail
so long as the last command succeeds. We instead want the opposite
behavior where if any step fails the whole script fails.

I don't really know `cmd.exe` that well, nor powershell, so I've opted
to move everything to `bash` which should be a good common denominator
amongst all platforms to work with. Additionally I know that `set -e`
works to cause scripts to fail fast.

Note that some scripts remain as `script` since they don't appear to
work in` bash`. I'm not really sure why but I reorganized them slightly
to have the "meaty command" run at the end.
---
 .../steps/install-windows-build-deps.yml      | 77 ++++++++++---------
 1 file changed, 39 insertions(+), 38 deletions(-)

diff --git a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
index 9aaeb4b79d634..bd4f1ed0cea43 100644
--- a/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
+++ b/src/ci/azure-pipelines/steps/install-windows-build-deps.yml
@@ -18,9 +18,9 @@ steps:
 # one is MSI installers and one is EXE, but they're not used so frequently at
 # this point anyway so perhaps it's a wash!
 - script: |
-    powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf is-install.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-08-22-is.exe"
-    is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
     echo ##vso[task.prependpath]C:\Program Files (x86)\Inno Setup 5
+    curl.exe -o is-install.exe https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-08-22-is.exe
+    is-install.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-
   displayName: Install InnoSetup
   condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
 
@@ -43,24 +43,18 @@ steps:
 # FIXME: we should probe the default azure image and see if we can use the MSYS2
 # toolchain there. (if there's even one there). For now though this gets the job
 # done.
-- script: |
-    set MSYS_PATH=%CD%\citools\msys64
-    choco install msys2 --params="/InstallDir:%MSYS_PATH% /NoPath" -y
-    set PATH=%MSYS_PATH%\usr\bin;%PATH%
-    pacman -S --noconfirm --needed base-devel ca-certificates make diffutils tar
-    IF "%MINGW_URL%"=="" (
-      IF "%MSYS_BITS%"=="32" pacman -S --noconfirm --needed mingw-w64-i686-toolchain mingw-w64-i686-cmake mingw-w64-i686-gcc mingw-w64-i686-python2
-      IF "%MSYS_BITS%"=="64" pacman -S --noconfirm --needed mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-gcc mingw-w64-x86_64-python2
-    )
-    where rev
-    rev --help
-    where make
-
-    echo ##vso[task.setvariable variable=MSYS_PATH]%MSYS_PATH%
-    echo ##vso[task.prependpath]%MSYS_PATH%\usr\bin
+- bash: |
+    set -e
+    choco install msys2 --params="/InstallDir:$(System.Workfolder)/msys2 /NoPath" -y --no-progress
+    echo "##vso[task.prependpath]$(System.Workfolder)/msys2/usr/bin"
+    mkdir -p "$(System.Workfolder)/msys2/home/$USERNAME"
   displayName: Install msys2
   condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
 
+- bash: pacman -S --noconfirm --needed base-devel ca-certificates make diffutils tar
+  displayName: Install msys2 base deps
+  condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
+
 # If we need to download a custom MinGW, do so here and set the path
 # appropriately.
 #
@@ -81,39 +75,46 @@ steps:
 #
 # Note that we don't literally overwrite the gdb.exe binary because it appears
 # to just use gdborig.exe, so that's the binary we deal with instead.
-- script: |
-    powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf %MINGW_ARCHIVE% %MINGW_URL%/%MINGW_ARCHIVE%"
-    7z x -y %MINGW_ARCHIVE% > nul
-    powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf 2017-04-20-%MSYS_BITS%bit-gdborig.exe %MINGW_URL%/2017-04-20-%MSYS_BITS%bit-gdborig.exe"
-    mv 2017-04-20-%MSYS_BITS%bit-gdborig.exe %MINGW_DIR%\bin\gdborig.exe
-    echo ##vso[task.prependpath]%CD%\%MINGW_DIR%\bin
+- bash: |
+    set -e
+    curl -o mingw.7z $MINGW_URL/$MINGW_ARCHIVE
+    7z x -y mingw.7z > /dev/null
+    curl -o $MINGW_DIR/bin/gdborig.exe $MINGW_URL/2017-04-20-${MSYS_BITS}bit-gdborig.exe
+    echo "##vso[task.prependpath]`pwd`/$MINGW_DIR/bin"
   condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), ne(variables['MINGW_URL'],''))
   displayName: Download custom MinGW
 
-# Otherwise pull in the MinGW installed on appveyor
-- script: |
-    echo ##vso[task.prependpath]%MSYS_PATH%\mingw%MSYS_BITS%\bin
+# Otherwise install MinGW through `pacman`
+- bash: |
+    set -e
+    arch=i686
+    if [ "$MSYS_BITS" = "64" ]; then
+      arch=x86_64
+    fi
+    pacman -S --noconfirm --needed mingw-w64-$arch-toolchain mingw-w64-$arch-cmake mingw-w64-$arch-gcc mingw-w64-$arch-python2
+    echo "##vso[task.prependpath]$(System.Workfolder)/msys2/mingw$MSYS_BITS/bin"
   condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['MINGW_URL'],''))
-  displayName: Add MinGW to path
+  displayName: Download standard MinGW
 
 # Make sure we use the native python interpreter instead of some msys equivalent
 # one way or another. The msys interpreters seem to have weird path conversions
 # baked in which break LLVM's build system one way or another, so let's use the
 # native version which keeps everything as native as possible.
-- script: |
-    copy C:\Python27amd64\python.exe C:\Python27amd64\python2.7.exe
-    echo ##vso[task.prependpath]C:\Python27amd64
+- bash: |
+    set -e
+    cp C:/Python27amd64/python.exe C:/Python27amd64/python2.7.exe
+    echo "##vso[task.prependpath]C:/Python27amd64"
   displayName: Prefer the "native" Python as LLVM has trouble building with MSYS sometimes
   condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
 
 # Note that this is originally from the github releases patch of Ninja
-- script: |
-    md ninja
-    powershell -Command "$ProgressPreference = 'SilentlyContinue'; iwr -outf 2017-03-15-ninja-win.zip https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-03-15-ninja-win.zip"
-    7z x -oninja 2017-03-15-ninja-win.zip
-    del 2017-03-15-ninja-win.zip
-    set RUST_CONFIGURE_ARGS=%RUST_CONFIGURE_ARGS% --enable-ninja
-    echo ##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]%RUST_CONFIGURE_ARGS%
-    echo ##vso[task.prependpath]%CD%\ninja
+- bash: |
+    set -e
+    mkdir ninja
+    curl -o ninja.zip https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/2017-03-15-ninja-win.zip
+    7z x -oninja ninja.zip
+    rm ninja.zip
+    echo "##vso[task.setvariable variable=RUST_CONFIGURE_ARGS]$RUST_CONFIGURE_ARGS --enable-ninja"
+    echo "##vso[task.prependpath]`pwd`/ninja"
   displayName: Download and install ninja
   condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))

From e35698371d36da83d3aca8322ad812fa5512b90f Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Thu, 19 Sep 2019 10:30:46 -0400
Subject: [PATCH 886/943] make clear that `invalidate` just replaces with
 `default`

---
 src/librustc_mir/build/scope.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 3c735c8cb09d7..9c1acb3faae0f 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -189,8 +189,7 @@ pub enum BreakableTarget {
 
 impl CachedBlock {
     fn invalidate(&mut self) {
-        self.generator_drop = None;
-        self.unwind = None;
+        *self = CachedBlock::default();
     }
 
     fn get(&self, generator_drop: bool) -> Option<BasicBlock> {

From 2fff78038cf3eb38f2bd3fecbab123bccb59c1a8 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Thu, 19 Sep 2019 07:46:24 -0700
Subject: [PATCH 887/943] rustbuild: Don't package libstd twice

Looks like the packaging step for the standard library was happening
twice on CI, but it only needs to happen once! The `Analysis` packaging
step accidentally packaged `Std` instead of relying on compiling `Std`,
which meant that we ended up packaging it twice erroneously.
---
 src/bootstrap/dist.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 076bcd878df71..e27a6bf7da0ac 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -762,7 +762,7 @@ impl Step for Analysis {
             return distdir(builder).join(format!("{}-{}.tar.gz", name, target));
         }
 
-        builder.ensure(Std { compiler, target });
+        builder.ensure(compile::Std { compiler, target });
 
         let image = tmpdir(builder).join(format!("{}-{}-image", name, target));
 

From d7f64749c0d32f3d63c0ee5d0999fce99f222553 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Thu, 19 Sep 2019 07:48:04 -0700
Subject: [PATCH 888/943] rustbuild: Copy crate doc files fewer times

Previously when building documentation for the standard library we'd
copy all the files 5 times, and these files include libcore/libstd docs
which are huge! This commit instead only copies the files after rustdoc
has been run for each crate, reducing the number of redundant copies
we're making.
---
 src/bootstrap/doc.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 6faedc80ad3f5..873a3c31d1535 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -476,11 +476,11 @@ impl Step for Std {
                  .arg("--index-page").arg(&builder.src.join("src/doc/index.md"));
 
             builder.run(&mut cargo);
-            builder.cp_r(&my_out, &out);
         };
         for krate in &["alloc", "core", "std", "proc_macro", "test"] {
             run_cargo_rustdoc_for(krate);
         }
+        builder.cp_r(&my_out, &out);
     }
 }
 

From b2c51c24c96f8827eefc6f0de29636cc4cb6ff2c Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Thu, 19 Sep 2019 11:41:10 -0400
Subject: [PATCH 889/943] avoid generating drops for moved operands of calls

Currently, after a CALL terminator is created in MIR, we insert DROP
statements for all of its operands -- even though they were just moved
shortly before! These spurious drops are later removed, but not before
causing borrow check errors.

This PR series modifies the drop code to track operands that were
moved and avoid creating drops for them.

Right now, I'm only using this mechanism for calls, but it seems
likely it could be used in more places.
---
 src/librustc/mir/mod.rs                       |  9 ++
 src/librustc_mir/build/expr/into.rs           |  3 +
 src/librustc_mir/build/scope.rs               | 93 ++++++++++++++++++-
 .../ui/async-await/issues/issue-64391-2.rs    | 17 ++++
 src/test/ui/async-await/issues/issue-64433.rs | 29 ++++++
 5 files changed, 147 insertions(+), 4 deletions(-)
 create mode 100644 src/test/ui/async-await/issues/issue-64391-2.rs
 create mode 100644 src/test/ui/async-await/issues/issue-64433.rs

diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 0ebc70750a6bb..92efcf44dea36 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1917,6 +1917,15 @@ impl<'tcx> Place<'tcx> {
         }
     }
 
+    /// If this place represents a local variable like `_X` with no
+    /// projections, return `Some(_X)`.
+    pub fn as_local(&self) -> Option<Local> {
+        match self {
+            Place { projection: box [], base: PlaceBase::Local(l) } => Some(*l),
+            _ => None,
+        }
+    }
+
     pub fn as_ref(&self) -> PlaceRef<'_, 'tcx> {
         PlaceRef {
             base: &self.base,
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index 45f4a16853606..30d53502b11ff 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -244,6 +244,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                     let success = this.cfg.start_new_block();
                     let cleanup = this.diverge_cleanup();
+
+                    this.record_operands_moved(&args);
+
                     this.cfg.terminate(
                         block,
                         source_info,
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 9c1acb3faae0f..13d94262b6c53 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -110,6 +110,8 @@ struct Scope {
     /// end of the vector (top of the stack) first.
     drops: Vec<DropData>,
 
+    moved_locals: Vec<Local>,
+
     /// The cache for drop chain on “normal” exit into a particular BasicBlock.
     cached_exits: FxHashMap<(BasicBlock, region::Scope), BasicBlock>,
 
@@ -159,7 +161,7 @@ struct CachedBlock {
     generator_drop: Option<BasicBlock>,
 }
 
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Eq)]
 pub(crate) enum DropKind {
     Value,
     Storage,
@@ -280,6 +282,7 @@ impl<'tcx> Scopes<'tcx> {
             region_scope: region_scope.0,
             region_scope_span: region_scope.1.span,
             drops: vec![],
+            moved_locals: vec![],
             cached_generator_drop: None,
             cached_exits: Default::default(),
             cached_unwind: CachedBlock::default(),
@@ -484,7 +487,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             block,
             unwind_to,
             self.arg_count,
-            false,
+            false, // not generator
+            false, // not unwind path
         ));
 
         block.unit()
@@ -576,7 +580,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 block,
                 unwind_to,
                 self.arg_count,
-                false,
+                false, // not generator
+                false, // not unwind path
             ));
 
             scope = next_scope;
@@ -626,7 +631,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 block,
                 unwind_to,
                 self.arg_count,
-                true,
+                true, // is generator
+                true, // is cached path
             ));
         }
 
@@ -822,6 +828,75 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         span_bug!(span, "region scope {:?} not in scope to drop {:?}", region_scope, local);
     }
 
+    /// Indicates that the "local operand" stored in `local` is
+    /// *moved* at some point during execution (see `local_scope` for
+    /// more information about what a "local operand" is -- in short,
+    /// it's an intermediate operand created as part of preparing some
+    /// MIR instruction). We use this information to suppress
+    /// redundant drops on the non-unwind paths. This results in less
+    /// MIR, but also avoids spurious borrow check errors
+    /// (c.f. #64391).
+    ///
+    /// Example: when compiling the call to `foo` here:
+    ///
+    /// ```rust
+    /// foo(bar(), ...)
+    /// ```
+    ///
+    /// we would evaluate `bar()` to an operand `_X`. We would also
+    /// schedule `_X` to be dropped when the expression scope for
+    /// `foo(bar())` is exited. This is relevant, for example, if the
+    /// later arguments should unwind (it would ensure that `_X` gets
+    /// dropped). However, if no unwind occurs, then `_X` will be
+    /// unconditionally consumed by the `call`:
+    ///
+    /// ```
+    /// bb {
+    ///   ...
+    ///   _R = CALL(foo, _X, ...)
+    /// }
+    /// ```
+    ///
+    /// However, `_X` is still registered to be dropped, and so if we
+    /// do nothing else, we would generate a `DROP(_X)` that occurs
+    /// after the call. This will later be optimized out by the
+    /// drop-elaboation code, but in the meantime it can lead to
+    /// spurious borrow-check errors -- the problem, ironically, is
+    /// not the `DROP(_X)` itself, but the (spurious) unwind pathways
+    /// that it creates. See #64391 for an example.
+    pub fn record_operands_moved(
+        &mut self,
+        operands: &[Operand<'tcx>],
+    ) {
+        let scope = match self.local_scope() {
+            None => {
+                // if there is no local scope, operands won't be dropped anyway
+                return;
+            }
+
+            Some(local_scope) => {
+                self.scopes.iter_mut().find(|scope| scope.region_scope == local_scope)
+                    .unwrap_or_else(|| bug!("scope {:?} not found in scope list!", local_scope))
+            }
+        };
+
+        // look for moves of a local variable, like `MOVE(_X)`
+        let locals_moved = operands.iter().flat_map(|operand| match operand {
+            Operand::Copy(_) | Operand::Constant(_) => None,
+            Operand::Move(place) => place.as_local(),
+        });
+
+        for local in locals_moved {
+            // check if we have a Drop for this operand and -- if so
+            // -- add it to the list of moved operands. Note that this
+            // local might not have been an operand created for this
+            // call, it could come from other places too.
+            if scope.drops.iter().any(|drop| drop.local == local && drop.kind == DropKind::Value) {
+                scope.moved_locals.push(local);
+            }
+        }
+    }
+
     // Other
     // =====
     /// Branch based on a boolean condition.
@@ -1020,6 +1095,7 @@ fn build_scope_drops<'tcx>(
     last_unwind_to: BasicBlock,
     arg_count: usize,
     generator_drop: bool,
+    is_cached_path: bool,
 ) -> BlockAnd<()> {
     debug!("build_scope_drops({:?} -> {:?})", block, scope);
 
@@ -1046,6 +1122,15 @@ fn build_scope_drops<'tcx>(
         let drop_data = &scope.drops[drop_idx];
         let source_info = scope.source_info(drop_data.span);
         let local = drop_data.local;
+
+        // If the operand has been moved, and we are not on an unwind
+        // path, then don't generate the drop. (We only take this into
+        // account for non-unwind paths so as not to disturb the
+        // caching mechanism.)
+        if !is_cached_path && scope.moved_locals.iter().any(|&o| o == local) {
+            continue;
+        }
+
         match drop_data.kind {
             DropKind::Value => {
                 let unwind_to = get_unwind_to(scope, is_generator, drop_idx, generator_drop)
diff --git a/src/test/ui/async-await/issues/issue-64391-2.rs b/src/test/ui/async-await/issues/issue-64391-2.rs
new file mode 100644
index 0000000000000..528704c0e45c3
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-64391-2.rs
@@ -0,0 +1,17 @@
+// Regression test for #64391
+//
+// As described on the issue, the (spurious) `DROP` inserted for the
+// `"".to_string()` value was causing a (spurious) unwind path that
+// led us to believe that the future might be dropped after `config`
+// had been dropped. This cannot, in fact, happen.
+
+async fn connect() {
+    let config = 666;
+    connect2(&config, "".to_string()).await
+}
+
+async fn connect2(_config: &u32, _tls: String) {
+    unimplemented!()
+}
+
+fn main() { }
diff --git a/src/test/ui/async-await/issues/issue-64433.rs b/src/test/ui/async-await/issues/issue-64433.rs
new file mode 100644
index 0000000000000..ca819e78fb8cb
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-64433.rs
@@ -0,0 +1,29 @@
+// Regression test for issue #64433.
+//
+// See issue-64391-2.rs for more details, as that was fixed by the
+// same PR.
+//
+// check-pass
+
+#[derive(Debug)]
+struct A<'a> {
+    inner: Vec<&'a str>,
+}
+
+struct B {}
+
+impl B {
+    async fn something_with_a(&mut self, a: A<'_>) -> Result<(), String> {
+        println!("{:?}", a);
+        Ok(())
+    }
+}
+
+async fn can_error(some_string: &str) -> Result<(), String> {
+    let a = A { inner: vec![some_string, "foo"] };
+    let mut b = B {};
+    Ok(b.something_with_a(a).await.map(|_| ())?)
+}
+
+fn main() {
+}

From 8112f71fc91bc7618d91bb3180fe80b8fafe1069 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Thu, 19 Sep 2019 09:24:42 -0700
Subject: [PATCH 890/943] rustbuild: Turn down compression on exe installers

The Windows dist builders are the slowest builders right now, and the
distribution phase of them is enormously slow clocking in at around 20
minutes to build all the related installers. This commit starts to
optimize these by turning down the compression level in the `exe`
installers. These aren't super heavily used so there's no great need for
them to be so ultra-compressed, so let's dial back the compression
parameters to get closer to the rest of our xz archives. This brings the
installer in line with the gz tarball installer locally, and also brings
the compression settings on par with the rest of our xz installers.
---
 src/etc/installer/exe/rust.iss | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/etc/installer/exe/rust.iss b/src/etc/installer/exe/rust.iss
index c22d60b6c5df1..70648beac38b0 100644
--- a/src/etc/installer/exe/rust.iss
+++ b/src/etc/installer/exe/rust.iss
@@ -25,9 +25,9 @@ SourceDir=.\
 OutputBaseFilename={#CFG_PACKAGE_NAME}-{#CFG_BUILD}
 DefaultDirName={sd}\Rust
 
-Compression=lzma2/ultra
-InternalCompressLevel=ultra
-SolidCompression=true
+Compression=lzma2/normal
+InternalCompressLevel=normal
+SolidCompression=no
 
 ChangesEnvironment=true
 ChangesAssociations=no

From 1ab5593f951c07a6f0ed05fbbfe8f262863158a0 Mon Sep 17 00:00:00 2001
From: gaolei <gaolei@zhihu.com>
Date: Thu, 19 Sep 2019 15:13:40 +0800
Subject: [PATCH 891/943] factor out pluralisation remains after #64280

---
 src/librustc/lint/builtin.rs                |  4 ++--
 src/librustc/middle/resolve_lifetime.rs     |  4 ++--
 src/librustc/traits/error_reporting.rs      |  4 ++--
 src/librustc/ty/error.rs                    |  2 +-
 src/librustc_lint/unused.rs                 | 22 ++++++++++++++-------
 src/librustc_resolve/check_unused.rs        |  4 +++-
 src/librustc_resolve/resolve_imports.rs     |  4 ++--
 src/librustc_typeck/astconv.rs              |  2 +-
 src/librustc_typeck/check/expr.rs           |  4 ++--
 src/librustc_typeck/check/method/suggest.rs |  4 ++--
 src/librustc_typeck/check/mod.rs            |  4 ++--
 src/librustc_typeck/check/pat.rs            | 14 ++++++-------
 src/libsyntax/ext/tt/transcribe.rs          |  5 +++--
 src/libsyntax/parse/diagnostics.rs          |  8 ++++----
 src/libsyntax/parse/parser/path.rs          |  7 +++----
 src/libsyntax/parse/parser/ty.rs            |  6 +++---
 src/libsyntax_ext/format.rs                 |  3 ++-
 17 files changed, 56 insertions(+), 45 deletions(-)

diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index dd290572d7bb7..5906a6388a8bd 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -7,7 +7,7 @@
 use crate::lint::{LintPass, LateLintPass, LintArray};
 use crate::middle::stability;
 use crate::session::Session;
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use syntax::ast;
 use syntax::source_map::Span;
 use syntax::symbol::Symbol;
@@ -524,7 +524,7 @@ pub(crate) fn add_elided_lifetime_in_path_suggestion(
     };
     db.span_suggestion(
         replace_span,
-        &format!("indicate the anonymous lifetime{}", if n >= 2 { "s" } else { "" }),
+        &format!("indicate the anonymous lifetime{}", pluralise!(n)),
         suggestion,
         Applicability::MachineApplicable
     );
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 8836a632a7ca8..d833a34385b2d 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -17,7 +17,7 @@ use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
 use crate::rustc::lint;
 use crate::session::Session;
 use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet};
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use rustc_macros::HashStable;
 use std::borrow::Cow;
 use std::cell::Cell;
@@ -3047,7 +3047,7 @@ pub fn report_missing_lifetime_specifiers(
         span,
         E0106,
         "missing lifetime specifier{}",
-        if count > 1 { "s" } else { "" }
+        pluralise!(count)
     )
 }
 
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 03cc00d87e3cd..0b06ec0703811 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -33,7 +33,7 @@ use crate::ty::subst::Subst;
 use crate::ty::SubtypePredicate;
 use crate::util::nodemap::{FxHashMap, FxHashSet};
 
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use std::fmt;
 use syntax::ast;
 use syntax::symbol::{sym, kw};
@@ -1186,7 +1186,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 _ => format!("{} {}argument{}",
                              arg_length,
                              if distinct && arg_length > 1 { "distinct " } else { "" },
-                             if arg_length == 1 { "" } else { "s" }),
+                             pluralise!(arg_length))
             }
         };
 
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 62910ec320494..5409cbc4129f0 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -196,7 +196,7 @@ impl<'tcx> ty::TyS<'tcx> {
                 let n = tcx.lift_to_global(&n).unwrap();
                 match n.try_eval_usize(tcx, ty::ParamEnv::empty()) {
                     Some(n) => {
-                        format!("array of {} element{}", n, if n != 1 { "s" } else { "" }).into()
+                        format!("array of {} element{}", n, pluralise!(n)).into()
                     }
                     None => "array".into(),
                 }
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index c3975098351af..2d4af2f606a2c 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -9,7 +9,7 @@ use lint::{LintPass, EarlyLintPass, LateLintPass};
 
 use syntax::ast;
 use syntax::attr;
-use syntax::errors::Applicability;
+use syntax::errors::{Applicability, pluralise};
 use syntax::feature_gate::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use syntax::print::pprust;
 use syntax::symbol::{kw, sym};
@@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
         }
 
         let ty = cx.tables.expr_ty(&expr);
-        let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", false);
+        let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", 1);
 
         let mut fn_warned = false;
         let mut op_warned = false;
@@ -135,7 +135,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
             span: Span,
             descr_pre: &str,
             descr_post: &str,
-            plural: bool,
+            plural_len: usize,
         ) -> bool {
             if ty.is_unit() || cx.tcx.is_ty_uninhabited_from(
                 cx.tcx.hir().get_module_parent(expr.hir_id), ty)
@@ -143,13 +143,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                 return true;
             }
 
-            let plural_suffix = if plural { "s" } else { "" };
+            let plural_suffix = pluralise!(plural_len);
 
             match ty.sty {
                 ty::Adt(..) if ty.is_box() => {
                     let boxed_ty = ty.boxed_ty();
                     let descr_pre = &format!("{}boxed ", descr_pre);
-                    check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural)
+                    check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural_len)
                 }
                 ty::Adt(def, _) => {
                     check_must_use_def(cx, def.did, span, descr_pre, descr_post)
@@ -202,7 +202,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                     for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() {
                         let descr_post = &format!(" in tuple element {}", i);
                         let span = *spans.get(i).unwrap_or(&span);
-                        if check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, plural) {
+                        if check_must_use_ty(
+                            cx,
+                            ty,
+                            expr,
+                            span,
+                            descr_pre,
+                            descr_post,
+                            plural_len
+                        ) {
                             has_emitted = true;
                         }
                     }
@@ -216,7 +224,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                             descr_pre,
                             plural_suffix,
                         );
-                        check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, true)
+                        check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, n as usize + 1)
                     }
                     // Otherwise, we don't lint, to avoid false positives.
                     _ => false,
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index 96d44b4b4c0dc..0d85be83e12e0 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -26,6 +26,8 @@
 use crate::Resolver;
 use crate::resolve_imports::ImportDirectiveSubclass;
 
+use errors::pluralise;
+
 use rustc::util::nodemap::NodeMap;
 use rustc::{lint, ty};
 use rustc_data_structures::fx::FxHashSet;
@@ -295,7 +297,7 @@ impl Resolver<'_> {
                 }).collect::<Vec<String>>();
             span_snippets.sort();
             let msg = format!("unused import{}{}",
-                            if len > 1 { "s" } else { "" },
+                            pluralise!(len),
                             if !span_snippets.is_empty() {
                                 format!(": {}", span_snippets.join(", "))
                             } else {
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index e77e8290f1faa..360343169bc3d 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -11,7 +11,7 @@ use crate::{Resolver, ResolutionError, Segment, ModuleKind};
 use crate::{names_to_string, module_to_string};
 use crate::diagnostics::Suggestion;
 
-use errors::Applicability;
+use errors::{Applicability, pluralise};
 
 use rustc_data_structures::ptr_key::PtrKey;
 use rustc::ty;
@@ -728,7 +728,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
             let msg = format!(
                 "unresolved import{} {}",
-                if paths.len() > 1 { "s" } else { "" },
+                pluralise!(paths.len()),
                 paths.join(", "),
             );
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 09e6b76900396..718d12484f741 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1346,7 +1346,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 span,
                 E0191,
                 "the value of the associated type{} {} must be specified",
-                if associated_types.len() == 1 { "" } else { "s" },
+                pluralise!(associated_types.len()),
                 names,
             );
             let (suggest, potential_assoc_types_spans) =
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 56bd903040ab4..ef3f40dfdd987 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -17,7 +17,7 @@ use crate::util::common::ErrorReported;
 use crate::util::nodemap::FxHashMap;
 use crate::astconv::AstConv as _;
 
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use syntax::ast;
 use syntax::symbol::{Symbol, kw, sym};
 use syntax::source_map::Span;
@@ -1178,7 +1178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             struct_span_err!(tcx.sess, span, E0063,
                              "missing field{} {}{} in initializer of `{}`",
-                             if remaining_fields.len() == 1 { "" } else { "s" },
+                             pluralise!(remaining_fields.len()),
                              remaining_fields_names,
                              truncated_fields_error,
                              adt_ty)
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 3e45b1e98d4ec..74e4f28255b16 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -5,7 +5,7 @@ use crate::check::FnCtxt;
 use crate::middle::lang_items::FnOnceTraitLangItem;
 use crate::namespace::Namespace;
 use crate::util::nodemap::FxHashSet;
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use rustc::hir::{self, ExprKind, Node, QPath};
 use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
@@ -560,7 +560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let help = format!("{an}other candidate{s} {were} found in the following \
                                         trait{s}, perhaps add a `use` for {one_of_them}:",
                                     an = if candidates.len() == 1 {"an" } else { "" },
-                                    s = if candidates.len() == 1 { "" } else { "s" },
+                                    s = pluralise!(candidates.len()),
                                     were = if candidates.len() == 1 { "was" } else { "were" },
                                     one_of_them = if candidates.len() == 1 {
                                         "it"
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 1197160fa9501..bd6586aa0777e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -88,7 +88,7 @@ pub mod intrinsic;
 mod op;
 
 use crate::astconv::{AstConv, PathSeg};
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise};
 use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
 use rustc::hir::def::{CtorOf, Res, DefKind};
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -4843,5 +4843,5 @@ fn fatally_break_rust(sess: &Session) {
 }
 
 fn potentially_plural_count(count: usize, word: &str) -> String {
-    format!("{} {}{}", count, word, if count == 1 { "" } else { "s" })
+    format!("{} {}{}", count, word, pluralise!(count))
 }
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 8502b89de1469..d93a4052cd393 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -1,6 +1,6 @@
 use crate::check::FnCtxt;
 use crate::util::nodemap::FxHashMap;
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use rustc::hir::{self, PatKind, Pat, HirId};
 use rustc::hir::def::{Res, DefKind, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@@ -684,8 +684,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     fn e0023(&self, pat_span: Span, res: Res, subpats: &'tcx [P<Pat>], fields: &[ty::FieldDef]) {
-        let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
-        let fields_ending = if fields.len() == 1 { "" } else { "s" };
+        let subpats_ending = pluralise!(subpats.len());
+        let fields_ending = pluralise!(fields.len());
         let res_span = self.tcx.def_span(res.def_id());
         struct_span_err!(
             self.tcx.sess,
@@ -1103,10 +1103,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             E0527,
             "pattern requires {} element{} but array has {}",
             min_len,
-            if min_len != 1 { "s" } else { "" },
+            pluralise!(min_len),
             size,
         )
-        .span_label(span, format!("expected {} element{}", size, if size != 1 { "s" } else { "" }))
+        .span_label(span, format!("expected {} element{}", size, pluralise!(size)))
         .emit();
     }
 
@@ -1117,14 +1117,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             E0528,
             "pattern requires at least {} element{} but array has {}",
             min_len,
-            if min_len != 1 { "s" } else { "" },
+            pluralise!(min_len),
             size,
         ).span_label(
             span,
             format!(
                 "pattern cannot match array of {} element{}",
                 size,
-                if size != 1 { "s" } else { "" },
+                pluralise!(size),
             ),
         ).emit();
     }
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 23735727fe8cf..f9c07e3a2e4ff 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -8,6 +8,7 @@ use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 
 use smallvec::{smallvec, SmallVec};
 
+use errors::pluralise;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::hygiene::{ExpnId, Transparency};
@@ -348,10 +349,10 @@ impl LockstepIterSize {
                         "meta-variable `{}` repeats {} time{}, but `{}` repeats {} time{}",
                         l_id,
                         l_len,
-                        if l_len != 1 { "s" } else { "" },
+                        pluralise!(l_len),
                         r_id,
                         r_len,
-                        if r_len != 1 { "s" } else { "" },
+                        pluralise!(r_len),
                     );
                     LockstepIterSize::Contradiction(msg)
                 }
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index b74f2492c351f..2d7f4f71ca4ee 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -11,7 +11,7 @@ use crate::ptr::P;
 use crate::symbol::{kw, sym};
 use crate::ThinVec;
 use crate::util::parser::AssocOp;
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise};
 use rustc_data_structures::fx::FxHashSet;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError};
 use log::{debug, trace};
@@ -532,15 +532,15 @@ impl<'a> Parser<'a> {
             self.eat_to_tokens(&[&end]);
             let span = lo.until(self.token.span);
 
-            let plural = number_of_gt > 1 || number_of_shr >= 1;
+            let total_num_of_gt = number_of_gt + number_of_shr * 2;
             self.diagnostic()
                 .struct_span_err(
                     span,
-                    &format!("unmatched angle bracket{}", if plural { "s" } else { "" }),
+                    &format!("unmatched angle bracket{}", pluralise!(total_num_of_gt)),
                 )
                 .span_suggestion(
                     span,
-                    &format!("remove extra angle bracket{}", if plural { "s" } else { "" }),
+                    &format!("remove extra angle bracket{}", pluralise!(total_num_of_gt)),
                     String::new(),
                     Applicability::MachineApplicable,
                 )
diff --git a/src/libsyntax/parse/parser/path.rs b/src/libsyntax/parse/parser/path.rs
index d4b13cc2e0121..dcd3c64801742 100644
--- a/src/libsyntax/parse/parser/path.rs
+++ b/src/libsyntax/parse/parser/path.rs
@@ -9,7 +9,7 @@ use crate::symbol::kw;
 
 use std::mem;
 use log::debug;
-use errors::{Applicability};
+use errors::{Applicability, pluralise};
 
 /// Specifies how to parse a path.
 #[derive(Copy, Clone, PartialEq)]
@@ -347,20 +347,19 @@ impl<'a> Parser<'a> {
                 let span = lo.with_hi(
                     lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count)
                 );
-                let plural = snapshot.unmatched_angle_bracket_count > 1;
                 self.diagnostic()
                     .struct_span_err(
                         span,
                         &format!(
                             "unmatched angle bracket{}",
-                            if plural { "s" } else { "" }
+                            pluralise!(snapshot.unmatched_angle_bracket_count)
                         ),
                     )
                     .span_suggestion(
                         span,
                         &format!(
                             "remove extra angle bracket{}",
-                            if plural { "s" } else { "" }
+                            pluralise!(snapshot.unmatched_angle_bracket_count)
                         ),
                         String::new(),
                         Applicability::MachineApplicable,
diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs
index 465e31ac57e64..5697edd8e4867 100644
--- a/src/libsyntax/parse/parser/ty.rs
+++ b/src/libsyntax/parse/parser/ty.rs
@@ -11,7 +11,7 @@ use crate::symbol::{kw};
 
 use rustc_target::spec::abi::Abi;
 
-use errors::{Applicability};
+use errors::{Applicability, pluralise};
 
 /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
 /// `IDENT<<u8 as Trait>::AssocTy>`.
@@ -397,7 +397,7 @@ impl<'a> Parser<'a> {
         }
 
         if !negative_bounds.is_empty() || was_negative {
-            let plural = negative_bounds.len() > 1;
+            let negative_bounds_len = negative_bounds.len();
             let last_span = negative_bounds.last().map(|sp| *sp);
             let mut err = self.struct_span_err(
                 negative_bounds,
@@ -420,7 +420,7 @@ impl<'a> Parser<'a> {
                 }
                 err.span_suggestion_hidden(
                     bound_list,
-                    &format!("remove the trait bound{}", if plural { "s" } else { "" }),
+                    &format!("remove the trait bound{}", pluralise!(negative_bounds_len)),
                     new_bound_list,
                     Applicability::MachineApplicable,
                 );
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 46c7cbb83de90..26455df17b896 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -5,6 +5,7 @@ use fmt_macros as parse;
 
 use errors::DiagnosticBuilder;
 use errors::Applicability;
+use errors::pluralise;
 
 use syntax::ast;
 use syntax::ext::base::{self, *};
@@ -299,7 +300,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 &format!(
                     "{} positional argument{} in format string, but {}",
                     count,
-                    if count != 1 { "s" } else { "" },
+                    pluralise!(count),
                     self.describe_num_args(),
                 ),
             );

From fde8cfe130db3826b88247318551d34d2bb63276 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Thu, 19 Sep 2019 09:24:42 -0700
Subject: [PATCH 892/943] rustbuild: Turn down compression on msi installers

This is the same as #64615 except applied to our MSI installers. The
same fix is applied effectively bringing these installers in line with
the gz tarball installers, which are about 3x faster to produce locally
and likely much faster to produce on CI.
---
 src/etc/installer/msi/rust.wxs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/etc/installer/msi/rust.wxs b/src/etc/installer/msi/rust.wxs
index a471ccc6f5b48..a2e378f7b1db4 100644
--- a/src/etc/installer/msi/rust.wxs
+++ b/src/etc/installer/msi/rust.wxs
@@ -152,7 +152,7 @@
         </Upgrade>
 
         <!-- Specifies a single cab file to be embedded in the installer's .msi. -->
-        <MediaTemplate EmbedCab="yes" CompressionLevel="high" />
+        <MediaTemplate EmbedCab="yes" CompressionLevel="mszip" />
 
         <!-- Send a WM_SETTINGCHANGE message to tell processes like explorer to update their
              environments so any new command prompts get the updated %PATH% -->

From 265566334549bbe38e775af092f9b991e91076e1 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Thu, 19 Sep 2019 13:15:54 -0400
Subject: [PATCH 893/943] fix tests for 2018

---
 src/test/ui/async-await/issues/issue-64391-2.rs | 3 +++
 src/test/ui/async-await/issues/issue-64433.rs   | 1 +
 2 files changed, 4 insertions(+)

diff --git a/src/test/ui/async-await/issues/issue-64391-2.rs b/src/test/ui/async-await/issues/issue-64391-2.rs
index 528704c0e45c3..eef2c1fb20ab4 100644
--- a/src/test/ui/async-await/issues/issue-64391-2.rs
+++ b/src/test/ui/async-await/issues/issue-64391-2.rs
@@ -4,6 +4,9 @@
 // `"".to_string()` value was causing a (spurious) unwind path that
 // led us to believe that the future might be dropped after `config`
 // had been dropped. This cannot, in fact, happen.
+//
+// check-pass
+// edition:2018
 
 async fn connect() {
     let config = 666;
diff --git a/src/test/ui/async-await/issues/issue-64433.rs b/src/test/ui/async-await/issues/issue-64433.rs
index ca819e78fb8cb..802e09c8a1f00 100644
--- a/src/test/ui/async-await/issues/issue-64433.rs
+++ b/src/test/ui/async-await/issues/issue-64433.rs
@@ -4,6 +4,7 @@
 // same PR.
 //
 // check-pass
+// edition:2018
 
 #[derive(Debug)]
 struct A<'a> {

From c78a00991b57bdeec0f55452d14b9e4a0ccc97c4 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Thu, 19 Sep 2019 13:42:46 -0400
Subject: [PATCH 894/943] whoops, only trigger this path for avoiding DROP, not
 StorageDead

---
 src/librustc_mir/build/scope.rs | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 13d94262b6c53..a26ec72584bda 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -1123,16 +1123,16 @@ fn build_scope_drops<'tcx>(
         let source_info = scope.source_info(drop_data.span);
         let local = drop_data.local;
 
-        // If the operand has been moved, and we are not on an unwind
-        // path, then don't generate the drop. (We only take this into
-        // account for non-unwind paths so as not to disturb the
-        // caching mechanism.)
-        if !is_cached_path && scope.moved_locals.iter().any(|&o| o == local) {
-            continue;
-        }
-
         match drop_data.kind {
             DropKind::Value => {
+                // If the operand has been moved, and we are not on an unwind
+                // path, then don't generate the drop. (We only take this into
+                // account for non-unwind paths so as not to disturb the
+                // caching mechanism.)
+                if !is_cached_path && scope.moved_locals.iter().any(|&o| o == local) {
+                    continue;
+                }
+
                 let unwind_to = get_unwind_to(scope, is_generator, drop_idx, generator_drop)
                     .unwrap_or(last_unwind_to);
 

From 255dd3ff42aecdc36da800e5bbfe0c09e83fa066 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Thu, 19 Sep 2019 11:22:55 -0700
Subject: [PATCH 895/943] rustbuild: Improve output of `dist` step

* Pass `/Q` to `iscc` on Windows to supress the thousands of lines of
  output about compressing documentation.
* Print out what's happening before long steps
* Use `timeit` to print out timing information for long-running
  installer assemblies.
---
 src/bootstrap/dist.rs | 66 ++++++++++++++++++++++++++++++-------------
 1 file changed, 47 insertions(+), 19 deletions(-)

diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 076bcd878df71..50b20763c43d2 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -18,7 +18,7 @@ use build_helper::{output, t};
 
 use crate::{Compiler, Mode, LLVM_TOOLS};
 use crate::channel;
-use crate::util::{is_dylib, exe};
+use crate::util::{is_dylib, exe, timeit};
 use crate::builder::{Builder, RunConfig, ShouldRun, Step};
 use crate::compile;
 use crate::tool::{self, Tool};
@@ -91,14 +91,15 @@ impl Step for Docs {
 
         let name = pkgname(builder, "rust-docs");
 
-        builder.info(&format!("Dist docs ({})", host));
         if !builder.config.docs {
-            builder.info("\tskipping - docs disabled");
             return distdir(builder).join(format!("{}-{}.tar.gz", name, host));
         }
 
         builder.default_doc(None);
 
+        builder.info(&format!("Dist docs ({})", host));
+        let _time = timeit(builder);
+
         let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
         let _ = fs::remove_dir_all(&image);
 
@@ -151,9 +152,7 @@ impl Step for RustcDocs {
 
         let name = pkgname(builder, "rustc-docs");
 
-        builder.info(&format!("Dist compiler docs ({})", host));
         if !builder.config.compiler_docs {
-            builder.info("\tskipping - compiler docs disabled");
             return distdir(builder).join(format!("{}-{}.tar.gz", name, host));
         }
 
@@ -179,6 +178,9 @@ impl Step for RustcDocs {
            .arg("--component-name=rustc-docs")
            .arg("--legacy-manifest-dirs=rustlib,cargo")
            .arg("--bulk-dirs=share/doc/rust/html");
+
+        builder.info(&format!("Dist compiler docs ({})", host));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         builder.remove_dir(&image);
 
@@ -350,6 +352,7 @@ impl Step for Mingw {
         }
 
         builder.info(&format!("Dist mingw ({})", host));
+        let _time = timeit(builder);
         let name = pkgname(builder, "rust-mingw");
         let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
         let _ = fs::remove_dir_all(&image);
@@ -403,7 +406,6 @@ impl Step for Rustc {
         let compiler = self.compiler;
         let host = self.compiler.host;
 
-        builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host));
         let name = pkgname(builder, "rustc");
         let image = tmpdir(builder).join(format!("{}-{}-image", name, host));
         let _ = fs::remove_dir_all(&image);
@@ -460,6 +462,9 @@ impl Step for Rustc {
            .arg(format!("--package-name={}-{}", name, host))
            .arg("--component-name=rustc")
            .arg("--legacy-manifest-dirs=rustlib,cargo");
+
+        builder.info(&format!("Dist rustc stage{} ({})", compiler.stage, host));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         builder.remove_dir(&image);
         builder.remove_dir(&overlay);
@@ -662,8 +667,6 @@ impl Step for Std {
         let target = self.target;
 
         let name = pkgname(builder, "rust-std");
-        builder.info(&format!("Dist std stage{} ({} -> {})",
-            compiler.stage, &compiler.host, target));
 
         // The only true set of target libraries came from the build triple, so
         // let's reduce redundant work by only producing archives from that host.
@@ -714,6 +717,10 @@ impl Step for Std {
            .arg(format!("--package-name={}-{}", name, target))
            .arg(format!("--component-name=rust-std-{}", target))
            .arg("--legacy-manifest-dirs=rustlib,cargo");
+
+        builder.info(&format!("Dist std stage{} ({} -> {})",
+            compiler.stage, &compiler.host, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         builder.remove_dir(&image);
         distdir(builder).join(format!("{}-{}.tar.gz", name, target))
@@ -754,11 +761,9 @@ impl Step for Analysis {
         let compiler = self.compiler;
         let target = self.target;
         assert!(builder.config.extended);
-        builder.info("Dist analysis");
         let name = pkgname(builder, "rust-analysis");
 
         if &compiler.host != builder.config.build {
-            builder.info("\tskipping, not a build host");
             return distdir(builder).join(format!("{}-{}.tar.gz", name, target));
         }
 
@@ -786,6 +791,9 @@ impl Step for Analysis {
            .arg(format!("--package-name={}-{}", name, target))
            .arg(format!("--component-name=rust-analysis-{}", target))
            .arg("--legacy-manifest-dirs=rustlib,cargo");
+
+        builder.info("Dist analysis");
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         builder.remove_dir(&image);
         distdir(builder).join(format!("{}-{}.tar.gz", name, target))
@@ -874,8 +882,6 @@ impl Step for Src {
 
     /// Creates the `rust-src` installer component
     fn run(self, builder: &Builder<'_>) -> PathBuf {
-        builder.info("Dist src");
-
         let name = pkgname(builder, "rust-src");
         let image = tmpdir(builder).join(format!("{}-image", name));
         let _ = fs::remove_dir_all(&image);
@@ -930,6 +936,9 @@ impl Step for Src {
            .arg(format!("--package-name={}", name))
            .arg("--component-name=rust-src")
            .arg("--legacy-manifest-dirs=rustlib,cargo");
+
+        builder.info("Dist src");
+        let _time = timeit(builder);
         builder.run(&mut cmd);
 
         builder.remove_dir(&image);
@@ -957,8 +966,6 @@ impl Step for PlainSourceTarball {
 
     /// Creates the plain source tarball
     fn run(self, builder: &Builder<'_>) -> PathBuf {
-        builder.info("Create plain source tarball");
-
         // Make sure that the root folder of tarball has the correct name
         let plain_name = format!("{}-src", pkgname(builder, "rustc"));
         let plain_dst_src = tmpdir(builder).join(&plain_name);
@@ -1020,6 +1027,9 @@ impl Step for PlainSourceTarball {
            .arg("--output").arg(&tarball)
            .arg("--work-dir=.")
            .current_dir(tmpdir(builder));
+
+        builder.info("Create plain source tarball");
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         distdir(builder).join(&format!("{}.tar.gz", plain_name))
     }
@@ -1073,7 +1083,6 @@ impl Step for Cargo {
         let compiler = self.compiler;
         let target = self.target;
 
-        builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target));
         let src = builder.src.join("src/tools/cargo");
         let etc = src.join("src/etc");
         let release_num = builder.release_num("cargo");
@@ -1126,6 +1135,9 @@ impl Step for Cargo {
            .arg(format!("--package-name={}-{}", name, target))
            .arg("--component-name=cargo")
            .arg("--legacy-manifest-dirs=rustlib,cargo");
+
+        builder.info(&format!("Dist cargo stage{} ({})", compiler.stage, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         distdir(builder).join(format!("{}-{}.tar.gz", name, target))
     }
@@ -1161,7 +1173,6 @@ impl Step for Rls {
         let target = self.target;
         assert!(builder.config.extended);
 
-        builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target));
         let src = builder.src.join("src/tools/rls");
         let release_num = builder.release_num("rls");
         let name = pkgname(builder, "rls");
@@ -1210,6 +1221,8 @@ impl Step for Rls {
            .arg("--legacy-manifest-dirs=rustlib,cargo")
            .arg("--component-name=rls-preview");
 
+        builder.info(&format!("Dist RLS stage{} ({})", compiler.stage, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
     }
@@ -1245,7 +1258,6 @@ impl Step for Clippy {
         let target = self.target;
         assert!(builder.config.extended);
 
-        builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target));
         let src = builder.src.join("src/tools/clippy");
         let release_num = builder.release_num("clippy");
         let name = pkgname(builder, "clippy");
@@ -1299,6 +1311,8 @@ impl Step for Clippy {
            .arg("--legacy-manifest-dirs=rustlib,cargo")
            .arg("--component-name=clippy-preview");
 
+        builder.info(&format!("Dist clippy stage{} ({})", compiler.stage, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
     }
@@ -1334,7 +1348,6 @@ impl Step for Miri {
         let target = self.target;
         assert!(builder.config.extended);
 
-        builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target));
         let src = builder.src.join("src/tools/miri");
         let release_num = builder.release_num("miri");
         let name = pkgname(builder, "miri");
@@ -1389,6 +1402,8 @@ impl Step for Miri {
            .arg("--legacy-manifest-dirs=rustlib,cargo")
            .arg("--component-name=miri-preview");
 
+        builder.info(&format!("Dist miri stage{} ({})", compiler.stage, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
     }
@@ -1423,7 +1438,6 @@ impl Step for Rustfmt {
         let compiler = self.compiler;
         let target = self.target;
 
-        builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target));
         let src = builder.src.join("src/tools/rustfmt");
         let release_num = builder.release_num("rustfmt");
         let name = pkgname(builder, "rustfmt");
@@ -1476,6 +1490,8 @@ impl Step for Rustfmt {
            .arg("--legacy-manifest-dirs=rustlib,cargo")
            .arg("--component-name=rustfmt-preview");
 
+        builder.info(&format!("Dist Rustfmt stage{} ({})", compiler.stage, target));
+        let _time = timeit(builder);
         builder.run(&mut cmd);
         Some(distdir(builder).join(format!("{}-{}.tar.gz", name, target)))
     }
@@ -1576,6 +1592,7 @@ impl Step for Extended {
             input_tarballs.push(tarball);
         }
 
+        builder.info("building combined installer");
         let mut cmd = rust_installer(builder);
         cmd.arg("combine")
             .arg("--product-name=Rust")
@@ -1587,7 +1604,9 @@ impl Step for Extended {
             .arg("--legacy-manifest-dirs=rustlib,cargo")
             .arg("--input-tarballs").arg(input_tarballs)
             .arg("--non-installed-overlay").arg(&overlay);
+        let time = timeit(&builder);
         builder.run(&mut cmd);
+        drop(time);
 
         let mut license = String::new();
         license += &builder.read(&builder.src.join("COPYRIGHT"));
@@ -1643,6 +1662,7 @@ impl Step for Extended {
         };
 
         if target.contains("apple-darwin") {
+            builder.info("building pkg installer");
             let pkg = tmp.join("pkg");
             let _ = fs::remove_dir_all(&pkg);
 
@@ -1692,6 +1712,7 @@ impl Step for Extended {
                                                     pkgname(builder, "rust"),
                                                     target)))
                 .arg("--package-path").arg(&pkg);
+            let _time = timeit(builder);
             builder.run(&mut cmd);
         }
 
@@ -1742,14 +1763,18 @@ impl Step for Extended {
             builder.create(&exe.join("LICENSE.txt"), &license);
 
             // Generate exe installer
+            builder.info("building `exe` installer with `iscc`");
             let mut cmd = Command::new("iscc");
             cmd.arg("rust.iss")
+                .arg("/Q")
                 .current_dir(&exe);
             if target.contains("windows-gnu") {
                 cmd.arg("/dMINGW");
             }
             add_env(builder, &mut cmd, target);
+            let time = timeit(builder);
             builder.run(&mut cmd);
+            drop(time);
             builder.install(&exe.join(format!("{}-{}.exe", pkgname(builder, "rust"), target)),
                     &distdir(builder),
                     0o755);
@@ -1914,6 +1939,7 @@ impl Step for Extended {
             builder.install(&etc.join("gfx/banner.bmp"), &exe, 0o644);
             builder.install(&etc.join("gfx/dialogbg.bmp"), &exe, 0o644);
 
+            builder.info(&format!("building `msi` installer with {:?}", light));
             let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target);
             let mut cmd = Command::new(&light);
             cmd.arg("-nologo")
@@ -1946,6 +1972,7 @@ impl Step for Extended {
             // ICE57 wrongly complains about the shortcuts
             cmd.arg("-sice:ICE57");
 
+            let _time = timeit(builder);
             builder.run(&mut cmd);
 
             if !builder.config.dry_run {
@@ -2114,6 +2141,7 @@ impl Step for LlvmTools {
         }
 
         builder.info(&format!("Dist LlvmTools ({})", target));
+        let _time = timeit(builder);
         let src = builder.src.join("src/llvm-project/llvm");
         let name = pkgname(builder, "llvm-tools");
 

From 1962d75c10363e1754df5526ed8fa01d22e42f24 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Thu, 19 Sep 2019 14:30:05 -0400
Subject: [PATCH 896/943] fix mir-opt tests

---
 src/test/mir-opt/box_expr.rs                  | 15 +++--------
 .../mir-opt/generator-storage-dead-unwind.rs  | 26 +++++++++----------
 2 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/src/test/mir-opt/box_expr.rs b/src/test/mir-opt/box_expr.rs
index d9fa3d3d4736d..8dc6b73edf6d4 100644
--- a/src/test/mir-opt/box_expr.rs
+++ b/src/test/mir-opt/box_expr.rs
@@ -57,25 +57,18 @@ impl Drop for S {
 //     }
 //
 //     bb5: {
-//         drop(_4) -> [return: bb8, unwind: bb6];
+//         StorageDead(_4);
+//         StorageDead(_3);
+//         _0 = ();
+//         drop(_1) -> bb8;
 //     }
-//
 //     bb6 (cleanup): {
 //         drop(_1) -> bb1;
 //     }
-//
 //     bb7 (cleanup): {
 //         drop(_4) -> bb6;
 //     }
-//
 //     bb8: {
-//         StorageDead(_4);
-//         StorageDead(_3);
-//         _0 = ();
-//         drop(_1) -> bb9;
-//     }
-//
-//     bb9: {
 //         StorageDead(_1);
 //         return;
 //     }
diff --git a/src/test/mir-opt/generator-storage-dead-unwind.rs b/src/test/mir-opt/generator-storage-dead-unwind.rs
index bcdb937542716..109304d6d22cc 100644
--- a/src/test/mir-opt/generator-storage-dead-unwind.rs
+++ b/src/test/mir-opt/generator-storage-dead-unwind.rs
@@ -57,7 +57,7 @@ fn main() {
 //     StorageLive(_6);
 //     StorageLive(_7);
 //     _7 = move _2;
-//     _6 = const take::<Foo>(move _7) -> [return: bb9, unwind: bb8];
+//     _6 = const take::<Foo>(move _7) -> [return: bb7, unwind: bb9];
 // }
 // bb3 (cleanup): {
 //     StorageDead(_2);
@@ -75,17 +75,7 @@ fn main() {
 // bb6: {
 //     generator_drop;
 // }
-// bb7 (cleanup): {
-//     StorageDead(_3);
-//     StorageDead(_2);
-//     drop(_1) -> bb1;
-// }
-// bb8 (cleanup): {
-//     StorageDead(_7);
-//     StorageDead(_6);
-//     goto -> bb7;
-// }
-// bb9: {
+// bb7: {
 //     StorageDead(_7);
 //     StorageDead(_6);
 //     StorageLive(_8);
@@ -93,6 +83,16 @@ fn main() {
 //     _9 = move _3;
 //     _8 = const take::<Bar>(move _9) -> [return: bb10, unwind: bb11];
 // }
+// bb8 (cleanup): {
+//     StorageDead(_3);
+//     StorageDead(_2);
+//     drop(_1) -> bb1;
+// }
+// bb9 (cleanup): {
+//     StorageDead(_7);
+//     StorageDead(_6);
+//     goto -> bb8;
+// }
 // bb10: {
 //     StorageDead(_9);
 //     StorageDead(_8);
@@ -104,7 +104,7 @@ fn main() {
 // bb11 (cleanup): {
 //     StorageDead(_9);
 //     StorageDead(_8);
-//     goto -> bb7;
+//     goto -> bb8;
 // }
 // bb12: {
 //     return;

From 02e3fb89a7e0c7944ed8237f5d307322879b6fcc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 15 Sep 2019 21:58:20 -0700
Subject: [PATCH 897/943] When possible point at argument causing item
 obligation failure

---
 src/librustc_typeck/check/mod.rs              |  40 ++-
 src/librustc_typeck/check/wfcheck.rs          |  10 +-
 .../associated-types-bound-failure.stderr     |   4 +-
 .../incorrect-syntax-suggestions.rs           |   3 +-
 .../incorrect-syntax-suggestions.stderr       |  75 ++--
 src/test/ui/closure-expected.stderr           |   4 +-
 .../ui/closures/closure-bounds-subtype.stderr |   4 +-
 .../core-traits-no-impls-length-33.stderr     |   4 +-
 src/test/ui/derives/deriving-copyclone.stderr |  12 +-
 .../issue-39802-show-5-trait-impls.stderr     |  12 +-
 src/test/ui/error-codes/E0277.stderr          |   4 +-
 .../ui/error-should-say-copy-not-pod.stderr   |   4 +-
 .../ui/extern/extern-wrong-value-type.stderr  |   4 +-
 src/test/ui/fn/fn-trait-formatting.stderr     |   4 +-
 src/test/ui/for/for-c-in-str.rs               |   3 +
 src/test/ui/generator/static-not-unpin.stderr |   4 +-
 ...igher-ranker-supertraits-transitive.stderr |   4 +-
 .../hrtb-higher-ranker-supertraits.stderr     |   8 +-
 src/test/ui/issues/issue-17651.rs             |   1 +
 src/test/ui/issues/issue-17651.stderr         |  15 +-
 src/test/ui/issues/issue-23966.stderr         |   4 +-
 src/test/ui/issues/issue-25076.stderr         |   4 +-
 src/test/ui/issues/issue-28098.rs             |   2 +
 src/test/ui/issues/issue-28098.stderr         |  36 +-
 src/test/ui/issues/issue-47706-trait.stderr   |   4 +-
 src/test/ui/issues/issue-47706.stderr         |   8 +-
 src/test/ui/issues/issue-60283.stderr         |  10 +-
 .../kindck/kindck-impl-type-params-2.stderr   |   4 +-
 .../kindck/kindck-inherited-copy-bound.stderr |   4 +-
 src/test/ui/mismatched_types/E0631.stderr     |   8 +-
 .../mismatched_types/closure-arg-count.stderr |  20 +-
 .../closure-arg-type-mismatch.stderr          |  10 +-
 .../ui/mismatched_types/fn-variance-1.stderr  |   8 +-
 .../unboxed-closures-vtable-mismatch.stderr   |   4 +-
 src/test/ui/mutexguard-sync.stderr            |   4 +-
 src/test/ui/namespace/namespace-mix.stderr    | 176 +++++-----
 src/test/ui/no_send-rc.stderr                 |   4 +-
 src/test/ui/no_send-struct.stderr             |   4 +-
 src/test/ui/no_share-struct.stderr            |   4 +-
 src/test/ui/object-does-not-impl-trait.stderr |   4 +-
 .../ui/on-unimplemented/multiple-impls.stderr |  46 +--
 src/test/ui/on-unimplemented/on-impl.stderr   |   6 +-
 src/test/ui/phantom-oibit.stderr              |   8 +-
 .../disallowed-positions.rs                   |  24 +-
 .../disallowed-positions.stderr               | 319 +++++++++++-------
 src/test/ui/str/str-idx.stderr                |   8 +-
 src/test/ui/str/str-mut-idx.stderr            |   8 +-
 ...rg-where-it-should-have-been-called.stderr |   4 +-
 ...rg-where-it-should-have-been-called.stderr |   4 +-
 src/test/ui/suggestions/issue-62843.stderr    |   4 +-
 ...inductive-overflow-supertrait-oibit.stderr |   4 +-
 .../ui/traits/traits-negative-impls.stderr    |  24 +-
 .../trivial-bounds/trivial-bounds-leak.stderr |   8 +-
 src/test/ui/try-operator-on-main.rs           |   4 +-
 src/test/ui/try-operator-on-main.stderr       |  31 +-
 src/test/ui/type/type-check-defaults.stderr   |  32 +-
 .../typeck/typeck-unsafe-always-share.stderr  |  12 +-
 .../unboxed-closures-fnmut-as-fn.stderr       |   4 +-
 .../unboxed-closures-unsafe-extern-fn.stderr  |  20 +-
 .../unboxed-closures-wrong-abi.stderr         |  20 +-
 ...d-closures-wrong-arg-type-extern-fn.stderr |  20 +-
 src/test/ui/unsized3.stderr                   |  20 +-
 src/test/ui/vtable-res-trait-param.stderr     |   4 +-
 ...traints-are-local-for-inherent-impl.stderr |   4 +-
 ...onstraints-are-local-for-trait-impl.stderr |   4 +-
 .../where-clauses-method-unsatisfied.stderr   |   4 +-
 66 files changed, 674 insertions(+), 513 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 1197160fa9501..90489bd8d897d 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3253,6 +3253,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             formal_tys.clone()
         };
 
+        let mut final_arg_types: Vec<(usize, Ty<'_>)> = vec![];
+
         // Check the arguments.
         // We do this in a pretty awful way: first we type-check any arguments
         // that are not closures, then we type-check the closures. This is so
@@ -3265,7 +3267,32 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // an "opportunistic" vtable resolution of any trait bounds on
             // the call. This helps coercions.
             if check_closures {
-                self.select_obligations_where_possible(false);
+                // We don't use `select_obligations_where_possible` to try to figure out if the
+                // obligation is comming from a single fn call argument, and if it is, we point
+                // at the expression corresponding to that argument, instead of the call.
+                if let Err(
+                    mut errors,
+                ) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
+                    for error in &mut errors {
+                        if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
+                            let mut referenced_in = vec![];
+                            for (i, ty) in &final_arg_types {
+                                let ty = self.resolve_vars_if_possible(ty);
+                                info!("final ty {} {:?}", i, ty);
+                                for ty in ty.walk() {
+                                    info!("walk {:?}", ty);
+                                    if ty == predicate.skip_binder().self_ty() {
+                                        referenced_in.push(*i);
+                                    }
+                                }
+                            }
+                            if referenced_in.len() == 1 {
+                                error.obligation.cause.span = args[referenced_in[0]].span;
+                            }
+                        }
+                    }
+                    self.report_fulfillment_errors(&errors, self.inh.body_id, false);
+                }
             }
 
             // For C-variadic functions, we don't have a declared type for all of
@@ -3311,6 +3338,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // We're processing function arguments so we definitely want to use
                 // two-phase borrows.
                 self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
+                final_arg_types.push((i, coerce_ty));
 
                 // 3. Relate the expected type and the formal one,
                 //    if the expected type was used for the coercion.
@@ -3514,8 +3542,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             // Check bounds on type arguments used in the path.
             let bounds = self.instantiate_bounds(path_span, did, substs);
-            let cause = traits::ObligationCause::new(path_span, self.body_id,
-                                                     traits::ItemObligation(did));
+            let cause = traits::ObligationCause::new(
+                path_span,
+                self.body_id,
+                traits::ItemObligation(did),
+            );
             self.add_obligations_for_parameters(cause, &bounds);
 
             Some((variant, ty))
@@ -4639,7 +4670,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let bounds = self.instantiate_bounds(span, def_id, &substs);
         self.add_obligations_for_parameters(
             traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
-            &bounds);
+            &bounds,
+        );
 
         // Substitute the values for the type parameters into the type of
         // the referenced item.
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index ac8ee43dd0801..b0e886a2aa2eb 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -506,7 +506,7 @@ fn check_where_clauses<'tcx, 'fcx>(
     });
 
     // Now we build the substituted predicates.
-    let default_obligations = predicates.predicates.iter().flat_map(|&(pred, _)| {
+    let default_obligations = predicates.predicates.iter().flat_map(|&(pred, sp)| {
         #[derive(Default)]
         struct CountParams { params: FxHashSet<u32> }
         impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams {
@@ -539,9 +539,9 @@ fn check_where_clauses<'tcx, 'fcx>(
             // Avoid duplication of predicates that contain no parameters, for example.
             None
         } else {
-            Some(substituted_pred)
+            Some((substituted_pred, sp))
         }
-    }).map(|pred| {
+    }).map(|(pred, sp)| {
         // Convert each of those into an obligation. So if you have
         // something like `struct Foo<T: Copy = String>`, we would
         // take that predicate `T: Copy`, substitute to `String: Copy`
@@ -551,8 +551,8 @@ fn check_where_clauses<'tcx, 'fcx>(
         // Note the subtle difference from how we handle `predicates`
         // below: there, we are not trying to prove those predicates
         // to be *true* but merely *well-formed*.
-        let pred = fcx.normalize_associated_types_in(span, &pred);
-        let cause = traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def_id));
+        let pred = fcx.normalize_associated_types_in(sp, &pred);
+        let cause = traits::ObligationCause::new(sp, fcx.body_id, traits::ItemObligation(def_id));
         traits::Obligation::new(cause, fcx.param_env, pred)
     });
 
diff --git a/src/test/ui/associated-types/associated-types-bound-failure.stderr b/src/test/ui/associated-types/associated-types-bound-failure.stderr
index 54654b95edd90..85acf134d51d5 100644
--- a/src/test/ui/associated-types/associated-types-bound-failure.stderr
+++ b/src/test/ui/associated-types/associated-types-bound-failure.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `<G as GetToInt>::R: ToInt` is not satisfied
-  --> $DIR/associated-types-bound-failure.rs:17:5
+  --> $DIR/associated-types-bound-failure.rs:17:19
    |
 LL |     fn to_int(&self) -> isize;
    |     -------------------------- required by `ToInt::to_int`
 ...
 LL |     ToInt::to_int(&g.get())
-   |     ^^^^^^^^^^^^^ the trait `ToInt` is not implemented for `<G as GetToInt>::R`
+   |                   ^^^^^^^^ the trait `ToInt` is not implemented for `<G as GetToInt>::R`
    |
    = help: consider adding a `where <G as GetToInt>::R: ToInt` bound
 
diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
index 22bcbb1064dd7..13cc5ba1184ee 100644
--- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
+++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
@@ -14,7 +14,8 @@ async fn foo2() -> Result<(), ()> {
 }
 async fn foo3() -> Result<(), ()> {
     let _ = await bar()?; //~ ERROR incorrect use of `await`
-    //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
+    //~^ ERROR the trait bound `impl std::future::Future: std::ops::Try` is not satisfied
+    //~| ERROR the trait bound `impl std::future::Future: std::ops::Try` is not satisfied
     Ok(())
 }
 async fn foo21() -> Result<(), ()> {
diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
index 7caa9f26bc2f8..a7ff14f01d4c3 100644
--- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
+++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
@@ -17,103 +17,103 @@ LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:21:13
+  --> $DIR/incorrect-syntax-suggestions.rs:22:13
    |
 LL |     let _ = await { bar() };
    |             ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:25:13
+  --> $DIR/incorrect-syntax-suggestions.rs:26:13
    |
 LL |     let _ = await(bar());
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `(bar()).await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:29:13
+  --> $DIR/incorrect-syntax-suggestions.rs:30:13
    |
 LL |     let _ = await { bar() }?;
    |             ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:33:14
+  --> $DIR/incorrect-syntax-suggestions.rs:34:14
    |
 LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:37:24
+  --> $DIR/incorrect-syntax-suggestions.rs:38:24
    |
 LL |     let _ = bar().await();
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:41:24
+  --> $DIR/incorrect-syntax-suggestions.rs:42:24
    |
 LL |     let _ = bar().await()?;
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:53:13
+  --> $DIR/incorrect-syntax-suggestions.rs:54:13
    |
 LL |     let _ = await bar();
    |             ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:58:13
+  --> $DIR/incorrect-syntax-suggestions.rs:59:13
    |
 LL |     let _ = await? bar();
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:63:13
+  --> $DIR/incorrect-syntax-suggestions.rs:64:13
    |
 LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:68:14
+  --> $DIR/incorrect-syntax-suggestions.rs:69:14
    |
 LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:73:24
+  --> $DIR/incorrect-syntax-suggestions.rs:74:24
    |
 LL |     let _ = bar().await();
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:78:24
+  --> $DIR/incorrect-syntax-suggestions.rs:79:24
    |
 LL |     let _ = bar().await()?;
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:106:13
+  --> $DIR/incorrect-syntax-suggestions.rs:107:13
    |
 LL |     let _ = await!(bar());
    |             ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:110:13
+  --> $DIR/incorrect-syntax-suggestions.rs:111:13
    |
 LL |     let _ = await!(bar())?;
    |             ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:115:17
+  --> $DIR/incorrect-syntax-suggestions.rs:116:17
    |
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:123:17
+  --> $DIR/incorrect-syntax-suggestions.rs:124:17
    |
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: expected expression, found `=>`
-  --> $DIR/incorrect-syntax-suggestions.rs:131:25
+  --> $DIR/incorrect-syntax-suggestions.rs:132:25
    |
 LL |     match await { await => () }
    |                   ----- ^^ expected expression
@@ -121,13 +121,13 @@ LL |     match await { await => () }
    |                   while parsing this incorrect await expression
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:131:11
+  --> $DIR/incorrect-syntax-suggestions.rs:132:11
    |
 LL |     match await { await => () }
    |           ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
 
 error: expected one of `.`, `?`, `{`, or an operator, found `}`
-  --> $DIR/incorrect-syntax-suggestions.rs:134:1
+  --> $DIR/incorrect-syntax-suggestions.rs:135:1
    |
 LL |     match await { await => () }
    |     -----                      - expected one of `.`, `?`, `{`, or an operator here
@@ -138,7 +138,7 @@ LL | }
    | ^ unexpected token
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:53:13
+  --> $DIR/incorrect-syntax-suggestions.rs:54:13
    |
 LL | fn foo9() -> Result<(), ()> {
    |    ---- this is not `async`
@@ -146,7 +146,7 @@ LL |     let _ = await bar();
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:58:13
+  --> $DIR/incorrect-syntax-suggestions.rs:59:13
    |
 LL | fn foo10() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -154,7 +154,7 @@ LL |     let _ = await? bar();
    |             ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:63:13
+  --> $DIR/incorrect-syntax-suggestions.rs:64:13
    |
 LL | fn foo11() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -162,7 +162,7 @@ LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:68:14
+  --> $DIR/incorrect-syntax-suggestions.rs:69:14
    |
 LL | fn foo12() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -170,7 +170,7 @@ LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:73:13
+  --> $DIR/incorrect-syntax-suggestions.rs:74:13
    |
 LL | fn foo13() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -178,7 +178,7 @@ LL |     let _ = bar().await();
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:78:13
+  --> $DIR/incorrect-syntax-suggestions.rs:79:13
    |
 LL | fn foo14() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -186,7 +186,7 @@ LL |     let _ = bar().await()?;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:83:13
+  --> $DIR/incorrect-syntax-suggestions.rs:84:13
    |
 LL | fn foo15() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -194,7 +194,7 @@ LL |     let _ = bar().await;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:87:13
+  --> $DIR/incorrect-syntax-suggestions.rs:88:13
    |
 LL | fn foo16() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -202,7 +202,7 @@ LL |     let _ = bar().await?;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:92:17
+  --> $DIR/incorrect-syntax-suggestions.rs:93:17
    |
 LL |     fn foo() -> Result<(), ()> {
    |        --- this is not `async`
@@ -210,7 +210,7 @@ LL |         let _ = bar().await?;
    |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:99:17
+  --> $DIR/incorrect-syntax-suggestions.rs:100:17
    |
 LL |     let foo = || {
    |               -- this is not `async`
@@ -218,7 +218,7 @@ LL |         let _ = bar().await?;
    |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:115:17
+  --> $DIR/incorrect-syntax-suggestions.rs:116:17
    |
 LL |     fn foo() -> Result<(), ()> {
    |        --- this is not `async`
@@ -226,22 +226,27 @@ LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:123:17
+  --> $DIR/incorrect-syntax-suggestions.rs:124:17
    |
 LL |     let foo = || {
    |               -- this is not `async`
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
-error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+error[E0277]: the trait bound `impl std::future::Future: std::ops::Try` is not satisfied
   --> $DIR/incorrect-syntax-suggestions.rs:16:19
    |
 LL |     let _ = await bar()?;
-   |                   ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future`
+   |                   ^^^^^ the trait `std::ops::Try` is not implemented for `impl std::future::Future`
    |
-   = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
    = note: required by `std::ops::Try::into_result`
 
-error: aborting due to 35 previous errors
+error[E0277]: the trait bound `impl std::future::Future: std::ops::Try` is not satisfied
+  --> $DIR/incorrect-syntax-suggestions.rs:16:19
+   |
+LL |     let _ = await bar()?;
+   |                   ^^^^^^ the trait `std::ops::Try` is not implemented for `impl std::future::Future`
+
+error: aborting due to 36 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/closure-expected.stderr b/src/test/ui/closure-expected.stderr
index ff77423577db6..ae4f4d69b5ef5 100644
--- a/src/test/ui/closure-expected.stderr
+++ b/src/test/ui/closure-expected.stderr
@@ -1,8 +1,8 @@
 error[E0277]: expected a `std::ops::FnOnce<()>` closure, found `{integer}`
-  --> $DIR/closure-expected.rs:3:15
+  --> $DIR/closure-expected.rs:3:23
    |
 LL |     let y = x.or_else(4);
-   |               ^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}`
+   |                       ^ expected an `FnOnce<()>` closure, found `{integer}`
    |
    = help: the trait `std::ops::FnOnce<()>` is not implemented for `{integer}`
    = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }
diff --git a/src/test/ui/closures/closure-bounds-subtype.stderr b/src/test/ui/closures/closure-bounds-subtype.stderr
index 4958bd06d9b16..e9b34e05ac2e2 100644
--- a/src/test/ui/closures/closure-bounds-subtype.stderr
+++ b/src/test/ui/closures/closure-bounds-subtype.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `F` cannot be shared between threads safely
-  --> $DIR/closure-bounds-subtype.rs:13:5
+  --> $DIR/closure-bounds-subtype.rs:13:22
    |
 LL | fn take_const_owned<F>(_: F) where F: FnOnce() + Sync + Send {
    | ------------------------------------------------------------ required by `take_const_owned`
 ...
 LL |     take_const_owned(f);
-   |     ^^^^^^^^^^^^^^^^ `F` cannot be shared between threads safely
+   |                      ^ `F` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `F`
    = help: consider adding a `where F: std::marker::Sync` bound
diff --git a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr
index 09652d99e8ea5..594a0d4b5d844 100644
--- a/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr
+++ b/src/test/ui/const-generics/array-impls/core-traits-no-impls-length-33.stderr
@@ -8,10 +8,10 @@ LL |     println!("{:?}", [0_usize; 33]);
    = note: required by `std::fmt::Debug::fmt`
 
 error[E0277]: arrays only have std trait implementations for lengths 0..=32
-  --> $DIR/core-traits-no-impls-length-33.rs:9:9
+  --> $DIR/core-traits-no-impls-length-33.rs:9:16
    |
 LL |     set.insert([0_usize; 33]);
-   |         ^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]`
+   |                ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[usize; 33]`
    |
    = note: required because of the requirements on the impl of `std::cmp::Eq` for `[usize; 33]`
 
diff --git a/src/test/ui/derives/deriving-copyclone.stderr b/src/test/ui/derives/deriving-copyclone.stderr
index 46b6a0d337695..f142257604cc8 100644
--- a/src/test/ui/derives/deriving-copyclone.stderr
+++ b/src/test/ui/derives/deriving-copyclone.stderr
@@ -1,33 +1,33 @@
 error[E0277]: the trait bound `C: std::marker::Copy` is not satisfied
-  --> $DIR/deriving-copyclone.rs:31:5
+  --> $DIR/deriving-copyclone.rs:31:13
    |
 LL | fn is_copy<T: Copy>(_: T) {}
    | ------------------------- required by `is_copy`
 ...
 LL |     is_copy(B { a: 1, b: C });
-   |     ^^^^^^^ the trait `std::marker::Copy` is not implemented for `C`
+   |             ^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `C`
    |
    = note: required because of the requirements on the impl of `std::marker::Copy` for `B<C>`
 
 error[E0277]: the trait bound `C: std::clone::Clone` is not satisfied
-  --> $DIR/deriving-copyclone.rs:32:5
+  --> $DIR/deriving-copyclone.rs:32:14
    |
 LL | fn is_clone<T: Clone>(_: T) {}
    | --------------------------- required by `is_clone`
 ...
 LL |     is_clone(B { a: 1, b: C });
-   |     ^^^^^^^^ the trait `std::clone::Clone` is not implemented for `C`
+   |              ^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `C`
    |
    = note: required because of the requirements on the impl of `std::clone::Clone` for `B<C>`
 
 error[E0277]: the trait bound `D: std::marker::Copy` is not satisfied
-  --> $DIR/deriving-copyclone.rs:35:5
+  --> $DIR/deriving-copyclone.rs:35:13
    |
 LL | fn is_copy<T: Copy>(_: T) {}
    | ------------------------- required by `is_copy`
 ...
 LL |     is_copy(B { a: 1, b: D });
-   |     ^^^^^^^ the trait `std::marker::Copy` is not implemented for `D`
+   |             ^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `D`
    |
    = note: required because of the requirements on the impl of `std::marker::Copy` for `B<D>`
 
diff --git a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
index ea2017f485a7b..1bd4543f2316c 100644
--- a/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
+++ b/src/test/ui/did_you_mean/issue-39802-show-5-trait-impls.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `i8: Foo<i32>` is not satisfied
-  --> $DIR/issue-39802-show-5-trait-impls.rs:24:5
+  --> $DIR/issue-39802-show-5-trait-impls.rs:24:21
    |
 LL |     fn bar(&self){}
    |     ------------- required by `Foo::bar`
 ...
 LL |     Foo::<i32>::bar(&1i8);
-   |     ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `i8`
+   |                     ^^^^ the trait `Foo<i32>` is not implemented for `i8`
    |
    = help: the following implementations were found:
              <i8 as Foo<bool>>
@@ -15,13 +15,13 @@ LL |     Foo::<i32>::bar(&1i8);
              <i8 as Foo<u8>>
 
 error[E0277]: the trait bound `u8: Foo<i32>` is not satisfied
-  --> $DIR/issue-39802-show-5-trait-impls.rs:25:5
+  --> $DIR/issue-39802-show-5-trait-impls.rs:25:21
    |
 LL |     fn bar(&self){}
    |     ------------- required by `Foo::bar`
 ...
 LL |     Foo::<i32>::bar(&1u8);
-   |     ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `u8`
+   |                     ^^^^ the trait `Foo<i32>` is not implemented for `u8`
    |
    = help: the following implementations were found:
              <u8 as Foo<bool>>
@@ -30,13 +30,13 @@ LL |     Foo::<i32>::bar(&1u8);
              <u8 as Foo<u64>>
 
 error[E0277]: the trait bound `bool: Foo<i32>` is not satisfied
-  --> $DIR/issue-39802-show-5-trait-impls.rs:26:5
+  --> $DIR/issue-39802-show-5-trait-impls.rs:26:21
    |
 LL |     fn bar(&self){}
    |     ------------- required by `Foo::bar`
 ...
 LL |     Foo::<i32>::bar(&true);
-   |     ^^^^^^^^^^^^^^^ the trait `Foo<i32>` is not implemented for `bool`
+   |                     ^^^^^ the trait `Foo<i32>` is not implemented for `bool`
    |
    = help: the following implementations were found:
              <bool as Foo<bool>>
diff --git a/src/test/ui/error-codes/E0277.stderr b/src/test/ui/error-codes/E0277.stderr
index 352102dd38629..9cd0dc7a68e7c 100644
--- a/src/test/ui/error-codes/E0277.stderr
+++ b/src/test/ui/error-codes/E0277.stderr
@@ -11,13 +11,13 @@ LL | fn f(p: Path) { }
    = help: unsized locals are gated as an unstable feature
 
 error[E0277]: the trait bound `i32: Foo` is not satisfied
-  --> $DIR/E0277.rs:17:5
+  --> $DIR/E0277.rs:17:15
    |
 LL | fn some_func<T: Foo>(foo: T) {
    | ---------------------------- required by `some_func`
 ...
 LL |     some_func(5i32);
-   |     ^^^^^^^^^ the trait `Foo` is not implemented for `i32`
+   |               ^^^^ the trait `Foo` is not implemented for `i32`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/error-should-say-copy-not-pod.stderr b/src/test/ui/error-should-say-copy-not-pod.stderr
index 78d54c3836db4..df79aeea054ca 100644
--- a/src/test/ui/error-should-say-copy-not-pod.stderr
+++ b/src/test/ui/error-should-say-copy-not-pod.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
-  --> $DIR/error-should-say-copy-not-pod.rs:6:5
+  --> $DIR/error-should-say-copy-not-pod.rs:6:17
    |
 LL | fn check_bound<T:Copy>(_: T) {}
    | ---------------------------- required by `check_bound`
 ...
 LL |     check_bound("nocopy".to_string());
-   |     ^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
+   |                 ^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/extern/extern-wrong-value-type.stderr b/src/test/ui/extern/extern-wrong-value-type.stderr
index 52fcb90e6de0c..f2468895d21d1 100644
--- a/src/test/ui/extern/extern-wrong-value-type.stderr
+++ b/src/test/ui/extern/extern-wrong-value-type.stderr
@@ -1,11 +1,11 @@
 error[E0277]: expected a `std::ops::Fn<()>` closure, found `extern "C" fn() {f}`
-  --> $DIR/extern-wrong-value-type.rs:9:5
+  --> $DIR/extern-wrong-value-type.rs:9:11
    |
 LL | fn is_fn<F>(_: F) where F: Fn() {}
    | ------------------------------- required by `is_fn`
 ...
 LL |     is_fn(f);
-   |     ^^^^^ expected an `Fn<()>` closure, found `extern "C" fn() {f}`
+   |           ^ expected an `Fn<()>` closure, found `extern "C" fn() {f}`
    |
    = help: the trait `std::ops::Fn<()>` is not implemented for `extern "C" fn() {f}`
    = note: wrap the `extern "C" fn() {f}` in a closure with no arguments: `|| { /* code */ }
diff --git a/src/test/ui/fn/fn-trait-formatting.stderr b/src/test/ui/fn/fn-trait-formatting.stderr
index 20d7d9ea5b7a8..4d610b49dff8e 100644
--- a/src/test/ui/fn/fn-trait-formatting.stderr
+++ b/src/test/ui/fn/fn-trait-formatting.stderr
@@ -26,13 +26,13 @@ LL |     let _: () = (box || -> isize { unimplemented!() }) as Box<dyn FnMut() -
               found type `std::boxed::Box<dyn std::ops::FnMut() -> isize>`
 
 error[E0277]: expected a `std::ops::Fn<(isize,)>` closure, found `{integer}`
-  --> $DIR/fn-trait-formatting.rs:19:5
+  --> $DIR/fn-trait-formatting.rs:19:14
    |
 LL | fn needs_fn<F>(x: F) where F: Fn(isize) -> isize {}
    | ------------------------------------------------ required by `needs_fn`
 ...
 LL |     needs_fn(1);
-   |     ^^^^^^^^ expected an `Fn<(isize,)>` closure, found `{integer}`
+   |              ^ expected an `Fn<(isize,)>` closure, found `{integer}`
    |
    = help: the trait `std::ops::Fn<(isize,)>` is not implemented for `{integer}`
 
diff --git a/src/test/ui/for/for-c-in-str.rs b/src/test/ui/for/for-c-in-str.rs
index 0fbc796d7c0d3..1871cf9d2386e 100644
--- a/src/test/ui/for/for-c-in-str.rs
+++ b/src/test/ui/for/for-c-in-str.rs
@@ -6,6 +6,9 @@ fn main() {
     //~| NOTE `&str` is not an iterator
     //~| HELP the trait `std::iter::Iterator` is not implemented for `&str`
     //~| NOTE required by `std::iter::IntoIterator::into_iter`
+    //~| NOTE in this expansion of desugaring of `for` loop
+    //~| NOTE in this expansion of desugaring of `for` loop
+    //~| NOTE in this expansion of desugaring of `for` loop
         println!();
     }
 }
diff --git a/src/test/ui/generator/static-not-unpin.stderr b/src/test/ui/generator/static-not-unpin.stderr
index 28a6fac5b85e3..b7871ee3478a4 100644
--- a/src/test/ui/generator/static-not-unpin.stderr
+++ b/src/test/ui/generator/static-not-unpin.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]: std::marker::Unpin` is not satisfied
-  --> $DIR/static-not-unpin.rs:14:5
+  --> $DIR/static-not-unpin.rs:14:18
    |
 LL | fn assert_unpin<T: Unpin>(_: T) {
    | ------------------------------- required by `assert_unpin`
 ...
 LL |     assert_unpin(generator);
-   |     ^^^^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]`
+   |                  ^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
index 0cddd353d679e..18f49089302e5 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
+++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
-  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5
+  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26
    |
 LL | / fn want_bar_for_any_ccx<B>(b: &B)
 LL | |     where B : for<'ccx> Bar<'ccx>
@@ -8,7 +8,7 @@ LL | | }
    | |_- required by `want_bar_for_any_ccx`
 ...
 LL |       want_bar_for_any_ccx(b);
-   |       ^^^^^^^^^^^^^^^^^^^^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+   |                            ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
    |
    = help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound
 
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
index 6df486ebaff38..7857ab6e86a20 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
+++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:18:5
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:18:26
    |
 LL |       want_foo_for_any_tcx(f);
-   |       ^^^^^^^^^^^^^^^^^^^^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
+   |                            ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
 ...
 LL | / fn want_foo_for_any_tcx<F>(f: &F)
 LL | |     where F : for<'tcx> Foo<'tcx>
@@ -15,10 +15,10 @@ LL | | }
    = help: consider adding a `where for<'tcx> F: Foo<'tcx>` bound
 
 error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:35:5
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:35:26
    |
 LL |       want_bar_for_any_ccx(b);
-   |       ^^^^^^^^^^^^^^^^^^^^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+   |                            ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
 ...
 LL | / fn want_bar_for_any_ccx<B>(b: &B)
 LL | |     where B : for<'ccx> Bar<'ccx>
diff --git a/src/test/ui/issues/issue-17651.rs b/src/test/ui/issues/issue-17651.rs
index 7629a5a3be1ea..08f352c11fa12 100644
--- a/src/test/ui/issues/issue-17651.rs
+++ b/src/test/ui/issues/issue-17651.rs
@@ -4,4 +4,5 @@
 fn main() {
     (|| Box::new(*(&[0][..])))();
     //~^ ERROR the size for values of type
+    //~| ERROR the size for values of type
 }
diff --git a/src/test/ui/issues/issue-17651.stderr b/src/test/ui/issues/issue-17651.stderr
index ce9af1524b087..c3445024c3752 100644
--- a/src/test/ui/issues/issue-17651.stderr
+++ b/src/test/ui/issues/issue-17651.stderr
@@ -1,3 +1,13 @@
+error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time
+  --> $DIR/issue-17651.rs:5:18
+   |
+LL |     (|| Box::new(*(&[0][..])))();
+   |                  ^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `[{integer}]`
+   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
+   = note: required by `std::boxed::Box::<T>::new`
+
 error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time
   --> $DIR/issue-17651.rs:5:9
    |
@@ -6,8 +16,9 @@ LL |     (|| Box::new(*(&[0][..])))();
    |
    = help: the trait `std::marker::Sized` is not implemented for `[{integer}]`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
-   = note: required by `std::boxed::Box::<T>::new`
+   = note: all function arguments must have a statically known size
+   = help: unsized locals are gated as an unstable feature
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-23966.stderr b/src/test/ui/issues/issue-23966.stderr
index ac64067db1099..c2fe6d92b910a 100644
--- a/src/test/ui/issues/issue-23966.stderr
+++ b/src/test/ui/issues/issue-23966.stderr
@@ -1,8 +1,8 @@
 error[E0277]: expected a `std::ops::FnMut<(_, char)>` closure, found `()`
-  --> $DIR/issue-23966.rs:2:16
+  --> $DIR/issue-23966.rs:2:32
    |
 LL |     "".chars().fold(|_, _| (), ());
-   |                ^^^^ expected an `FnMut<(_, char)>` closure, found `()`
+   |                                ^^ expected an `FnMut<(_, char)>` closure, found `()`
    |
    = help: the trait `std::ops::FnMut<(_, char)>` is not implemented for `()`
 
diff --git a/src/test/ui/issues/issue-25076.stderr b/src/test/ui/issues/issue-25076.stderr
index b583a6b54bf9f..a7b6626b16a1c 100644
--- a/src/test/ui/issues/issue-25076.stderr
+++ b/src/test/ui/issues/issue-25076.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `(): InOut<_>` is not satisfied
-  --> $DIR/issue-25076.rs:10:5
+  --> $DIR/issue-25076.rs:10:20
    |
 LL | fn do_fold<B, F: InOut<B, Out=B>>(init: B, f: F) {}
    | ------------------------------------------------ required by `do_fold`
 ...
 LL |     do_fold(bot(), ());
-   |     ^^^^^^^ the trait `InOut<_>` is not implemented for `()`
+   |                    ^^ the trait `InOut<_>` is not implemented for `()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-28098.rs b/src/test/ui/issues/issue-28098.rs
index c4addaccefc10..62a90d90d12de 100644
--- a/src/test/ui/issues/issue-28098.rs
+++ b/src/test/ui/issues/issue-28098.rs
@@ -1,6 +1,7 @@
 fn main() {
     let _ = Iterator::next(&mut ());
     //~^ ERROR `()` is not an iterator
+    //~| ERROR `()` is not an iterator
 
     for _ in false {}
     //~^ ERROR `bool` is not an iterator
@@ -16,6 +17,7 @@ pub fn other() {
 
     let _ = Iterator::next(&mut ());
     //~^ ERROR `()` is not an iterator
+    //~| ERROR `()` is not an iterator
 
     let _ = Iterator::next(&mut ());
     //~^ ERROR `()` is not an iterator
diff --git a/src/test/ui/issues/issue-28098.stderr b/src/test/ui/issues/issue-28098.stderr
index 30f7819b96daf..8b724b9331dd6 100644
--- a/src/test/ui/issues/issue-28098.stderr
+++ b/src/test/ui/issues/issue-28098.stderr
@@ -1,14 +1,14 @@
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:2:13
+  --> $DIR/issue-28098.rs:2:28
    |
 LL |     let _ = Iterator::next(&mut ());
-   |             ^^^^^^^^^^^^^^ `()` is not an iterator
+   |                            ^^^^^^^ `()` is not an iterator
    |
    = help: the trait `std::iter::Iterator` is not implemented for `()`
    = note: required by `std::iter::Iterator::next`
 
 error[E0277]: `bool` is not an iterator
-  --> $DIR/issue-28098.rs:5:14
+  --> $DIR/issue-28098.rs:6:14
    |
 LL |     for _ in false {}
    |              ^^^^^ `bool` is not an iterator
@@ -17,34 +17,42 @@ LL |     for _ in false {}
    = note: required by `std::iter::IntoIterator::into_iter`
 
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:8:13
+  --> $DIR/issue-28098.rs:9:28
    |
 LL |     let _ = Iterator::next(&mut ());
-   |             ^^^^^^^^^^^^^^ `()` is not an iterator
+   |                            ^^^^^^^ `()` is not an iterator
    |
    = help: the trait `std::iter::Iterator` is not implemented for `()`
    = note: required by `std::iter::Iterator::next`
 
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:17:13
+  --> $DIR/issue-28098.rs:2:13
    |
 LL |     let _ = Iterator::next(&mut ());
    |             ^^^^^^^^^^^^^^ `()` is not an iterator
    |
    = help: the trait `std::iter::Iterator` is not implemented for `()`
+
+error[E0277]: `()` is not an iterator
+  --> $DIR/issue-28098.rs:18:28
+   |
+LL |     let _ = Iterator::next(&mut ());
+   |                            ^^^^^^^ `()` is not an iterator
+   |
+   = help: the trait `std::iter::Iterator` is not implemented for `()`
    = note: required by `std::iter::Iterator::next`
 
 error[E0277]: `()` is not an iterator
-  --> $DIR/issue-28098.rs:20:13
+  --> $DIR/issue-28098.rs:22:28
    |
 LL |     let _ = Iterator::next(&mut ());
-   |             ^^^^^^^^^^^^^^ `()` is not an iterator
+   |                            ^^^^^^^ `()` is not an iterator
    |
    = help: the trait `std::iter::Iterator` is not implemented for `()`
    = note: required by `std::iter::Iterator::next`
 
 error[E0277]: `bool` is not an iterator
-  --> $DIR/issue-28098.rs:23:14
+  --> $DIR/issue-28098.rs:25:14
    |
 LL |     for _ in false {}
    |              ^^^^^ `bool` is not an iterator
@@ -52,6 +60,14 @@ LL |     for _ in false {}
    = help: the trait `std::iter::Iterator` is not implemented for `bool`
    = note: required by `std::iter::IntoIterator::into_iter`
 
-error: aborting due to 6 previous errors
+error[E0277]: `()` is not an iterator
+  --> $DIR/issue-28098.rs:18:13
+   |
+LL |     let _ = Iterator::next(&mut ());
+   |             ^^^^^^^^^^^^^^ `()` is not an iterator
+   |
+   = help: the trait `std::iter::Iterator` is not implemented for `()`
+
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/issues/issue-47706-trait.stderr b/src/test/ui/issues/issue-47706-trait.stderr
index 5f8f8564249c8..8a6a199148c39 100644
--- a/src/test/ui/issues/issue-47706-trait.stderr
+++ b/src/test/ui/issues/issue-47706-trait.stderr
@@ -1,10 +1,10 @@
 error[E0593]: function is expected to take a single 0-tuple as argument, but it takes 2 distinct arguments
-  --> $DIR/issue-47706-trait.rs:3:20
+  --> $DIR/issue-47706-trait.rs:3:24
    |
 LL |     fn f(&self, _: ()) {
    |     ------------------ takes 2 distinct arguments
 LL |         None::<()>.map(Self::f);
-   |                    ^^^ expected function that takes a single 0-tuple as argument
+   |                        ^^^^^^^ expected function that takes a single 0-tuple as argument
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-47706.stderr b/src/test/ui/issues/issue-47706.stderr
index c47eebb8e5c07..4f64a643fe57d 100644
--- a/src/test/ui/issues/issue-47706.stderr
+++ b/src/test/ui/issues/issue-47706.stderr
@@ -1,14 +1,14 @@
 error[E0593]: function is expected to take 1 argument, but it takes 2 arguments
-  --> $DIR/issue-47706.rs:11:18
+  --> $DIR/issue-47706.rs:11:22
    |
 LL |     pub fn new(foo: Option<i32>, _: ()) -> Foo {
    |     ------------------------------------------ takes 2 arguments
 ...
 LL |         self.foo.map(Foo::new)
-   |                  ^^^ expected function that takes 1 argument
+   |                      ^^^^^^^^ expected function that takes 1 argument
 
 error[E0593]: function is expected to take 0 arguments, but it takes 1 argument
-  --> $DIR/issue-47706.rs:27:5
+  --> $DIR/issue-47706.rs:27:9
    |
 LL |       Bar(i32),
    |       -------- takes 1 argument
@@ -21,7 +21,7 @@ LL | | }
    | |_- required by `foo`
 ...
 LL |       foo(Qux::Bar);
-   |       ^^^ expected function that takes 0 arguments
+   |           ^^^^^^^^ expected function that takes 0 arguments
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-60283.stderr b/src/test/ui/issues/issue-60283.stderr
index a977ba392769f..2b01a64d39a9b 100644
--- a/src/test/ui/issues/issue-60283.stderr
+++ b/src/test/ui/issues/issue-60283.stderr
@@ -1,5 +1,5 @@
 error[E0631]: type mismatch in function arguments
-  --> $DIR/issue-60283.rs:14:5
+  --> $DIR/issue-60283.rs:14:13
    |
 LL | / pub fn foo<T, F>(_: T, _: F)
 LL | | where T: for<'a> Trait<'a>,
@@ -7,10 +7,10 @@ LL | |       F: for<'a> FnMut(<T as Trait<'a>>::Item) {}
    | |_________________________________________________- required by `foo`
 ...
 LL |       foo((), drop)
-   |       ^^^
-   |       |
-   |       expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
-   |       found signature of `fn(_) -> _`
+   |               ^^^^
+   |               |
+   |               expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
+   |               found signature of `fn(_) -> _`
 
 error[E0271]: type mismatch resolving `for<'a> <fn(_) {std::mem::drop::<_>} as std::ops::FnOnce<(<() as Trait<'a>>::Item,)>>::Output == ()`
   --> $DIR/issue-60283.rs:14:5
diff --git a/src/test/ui/kindck/kindck-impl-type-params-2.stderr b/src/test/ui/kindck/kindck-impl-type-params-2.stderr
index 6d599423d2548..5e6eca6f0571b 100644
--- a/src/test/ui/kindck/kindck-impl-type-params-2.stderr
+++ b/src/test/ui/kindck/kindck-impl-type-params-2.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `std::boxed::Box<{integer}>: std::marker::Copy` is not satisfied
-  --> $DIR/kindck-impl-type-params-2.rs:13:5
+  --> $DIR/kindck-impl-type-params-2.rs:13:16
    |
 LL | fn take_param<T:Foo>(foo: &T) { }
    | ----------------------------- required by `take_param`
 ...
 LL |     take_param(&x);
-   |     ^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<{integer}>`
+   |                ^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<{integer}>`
    |
    = note: required because of the requirements on the impl of `Foo` for `std::boxed::Box<{integer}>`
 
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.stderr
index a53063157fc8e..9f548083e73d1 100644
--- a/src/test/ui/kindck/kindck-inherited-copy-bound.stderr
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `std::boxed::Box<{integer}>: std::marker::Copy` is not satisfied
-  --> $DIR/kindck-inherited-copy-bound.rs:18:5
+  --> $DIR/kindck-inherited-copy-bound.rs:18:16
    |
 LL | fn take_param<T:Foo>(foo: &T) { }
    | ----------------------------- required by `take_param`
 ...
 LL |     take_param(&x);
-   |     ^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<{integer}>`
+   |                ^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<{integer}>`
    |
    = note: required because of the requirements on the impl of `Foo` for `std::boxed::Box<{integer}>`
 
diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr
index 319eb86480af5..64ddf1deb0639 100644
--- a/src/test/ui/mismatched_types/E0631.stderr
+++ b/src/test/ui/mismatched_types/E0631.stderr
@@ -21,7 +21,7 @@ LL |     bar(|_: isize| {});
    |     expected signature of `fn(usize) -> _`
 
 error[E0631]: type mismatch in function arguments
-  --> $DIR/E0631.rs:9:5
+  --> $DIR/E0631.rs:9:9
    |
 LL | fn foo<F: Fn(usize)>(_: F) {}
    | -------------------------- required by `foo`
@@ -30,10 +30,10 @@ LL |     fn f(_: u64) {}
    |     ------------ found signature of `fn(u64) -> _`
 ...
 LL |     foo(f);
-   |     ^^^ expected signature of `fn(usize) -> _`
+   |         ^ expected signature of `fn(usize) -> _`
 
 error[E0631]: type mismatch in function arguments
-  --> $DIR/E0631.rs:10:5
+  --> $DIR/E0631.rs:10:9
    |
 LL | fn bar<F: Fn<usize>>(_: F) {}
    | -------------------------- required by `bar`
@@ -42,7 +42,7 @@ LL |     fn f(_: u64) {}
    |     ------------ found signature of `fn(u64) -> _`
 ...
 LL |     bar(f);
-   |     ^^^ expected signature of `fn(usize) -> _`
+   |         ^ expected signature of `fn(usize) -> _`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr
index b7b5b50b0b4e4..12ae8acaee5cf 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-count.stderr
@@ -105,42 +105,42 @@ LL |     let _it = vec![1, 2, 3].into_iter().enumerate().map(|i, x, y| i);
    |                                                     expected closure that takes a single 2-tuple as argument
 
 error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments
-  --> $DIR/closure-arg-count.rs:24:53
+  --> $DIR/closure-arg-count.rs:24:57
    |
 LL |     let _it = vec![1, 2, 3].into_iter().enumerate().map(foo);
-   |                                                     ^^^ expected function that takes a single 2-tuple as argument
+   |                                                         ^^^ expected function that takes a single 2-tuple as argument
 ...
 LL | fn foo() {}
    | -------- takes 0 arguments
 
 error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments
-  --> $DIR/closure-arg-count.rs:27:53
+  --> $DIR/closure-arg-count.rs:27:57
    |
 LL |     let bar = |i, x, y| i;
    |               --------- takes 3 distinct arguments
 LL |     let _it = vec![1, 2, 3].into_iter().enumerate().map(bar);
-   |                                                     ^^^ expected closure that takes a single 2-tuple as argument
+   |                                                         ^^^ expected closure that takes a single 2-tuple as argument
 
 error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments
-  --> $DIR/closure-arg-count.rs:29:53
+  --> $DIR/closure-arg-count.rs:29:57
    |
 LL |     let _it = vec![1, 2, 3].into_iter().enumerate().map(qux);
-   |                                                     ^^^ expected function that takes a single 2-tuple as argument
+   |                                                         ^^^ expected function that takes a single 2-tuple as argument
 ...
 LL | fn qux(x: usize, y: usize) {}
    | -------------------------- takes 2 distinct arguments
 
 error[E0593]: function is expected to take 1 argument, but it takes 2 arguments
-  --> $DIR/closure-arg-count.rs:32:41
+  --> $DIR/closure-arg-count.rs:32:45
    |
 LL |     let _it = vec![1, 2, 3].into_iter().map(usize::checked_add);
-   |                                         ^^^ expected function that takes 1 argument
+   |                                             ^^^^^^^^^^^^^^^^^^ expected function that takes 1 argument
 
 error[E0593]: function is expected to take 0 arguments, but it takes 1 argument
-  --> $DIR/closure-arg-count.rs:35:5
+  --> $DIR/closure-arg-count.rs:35:10
    |
 LL |     call(Foo);
-   |     ^^^^ expected function that takes 0 arguments
+   |          ^^^ expected function that takes 0 arguments
 ...
 LL | fn call<F, R>(_: F) where F: FnOnce() -> R {}
    | ------------------------------------------ required by `call`
diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
index 2a65759dd17f8..68bc17b4966f1 100644
--- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
@@ -23,16 +23,16 @@ LL |     a.iter().map(|_: (u16, u16)| 45);
    |              expected signature of `fn(&(u32, u32)) -> _`
 
 error[E0631]: type mismatch in function arguments
-  --> $DIR/closure-arg-type-mismatch.rs:10:5
+  --> $DIR/closure-arg-type-mismatch.rs:10:9
    |
 LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
    | ------------------------------ required by `baz`
 LL | fn _test<'a>(f: fn(*mut &'a u32)) {
 LL |     baz(f);
-   |     ^^^
-   |     |
-   |     expected signature of `for<'r> fn(*mut &'r u32) -> _`
-   |     found signature of `fn(*mut &'a u32) -> _`
+   |         ^
+   |         |
+   |         expected signature of `for<'r> fn(*mut &'r u32) -> _`
+   |         found signature of `fn(*mut &'a u32) -> _`
 
 error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::FnOnce<(*mut &'r u32,)>>::Output == ()`
   --> $DIR/closure-arg-type-mismatch.rs:10:5
diff --git a/src/test/ui/mismatched_types/fn-variance-1.stderr b/src/test/ui/mismatched_types/fn-variance-1.stderr
index d4db7bda06e7e..6342ee770ddaf 100644
--- a/src/test/ui/mismatched_types/fn-variance-1.stderr
+++ b/src/test/ui/mismatched_types/fn-variance-1.stderr
@@ -1,5 +1,5 @@
 error[E0631]: type mismatch in function arguments
-  --> $DIR/fn-variance-1.rs:11:5
+  --> $DIR/fn-variance-1.rs:11:15
    |
 LL | fn takes_mut(x: &mut isize) { }
    | --------------------------- found signature of `for<'r> fn(&'r mut isize) -> _`
@@ -8,10 +8,10 @@ LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
    | --------------------------------------------- required by `apply`
 ...
 LL |     apply(&3, takes_mut);
-   |     ^^^^^ expected signature of `fn(&{integer}) -> _`
+   |               ^^^^^^^^^ expected signature of `fn(&{integer}) -> _`
 
 error[E0631]: type mismatch in function arguments
-  --> $DIR/fn-variance-1.rs:15:5
+  --> $DIR/fn-variance-1.rs:15:19
    |
 LL | fn takes_imm(x: &isize) { }
    | ----------------------- found signature of `for<'r> fn(&'r isize) -> _`
@@ -20,7 +20,7 @@ LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
    | --------------------------------------------- required by `apply`
 ...
 LL |     apply(&mut 3, takes_imm);
-   |     ^^^^^ expected signature of `fn(&mut {integer}) -> _`
+   |                   ^^^^^^^^^ expected signature of `fn(&mut {integer}) -> _`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
index 53c9fcd70a23d..139d87d58b640 100644
--- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
+++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/unboxed-closures-vtable-mismatch.rs:15:13
+  --> $DIR/unboxed-closures-vtable-mismatch.rs:15:24
    |
 LL | fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize {
    | -------------------------------------------------------------------- required by `call_it`
@@ -8,7 +8,7 @@ LL |     let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
    |                       ----------------------------- found signature of `fn(usize, isize) -> _`
 LL |
 LL |     let z = call_it(3, f);
-   |             ^^^^^^^ expected signature of `fn(isize, isize) -> _`
+   |                        ^ expected signature of `fn(isize, isize) -> _`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mutexguard-sync.stderr b/src/test/ui/mutexguard-sync.stderr
index 4a93c9f09b788..1cda2da5061a5 100644
--- a/src/test/ui/mutexguard-sync.stderr
+++ b/src/test/ui/mutexguard-sync.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
-  --> $DIR/mutexguard-sync.rs:11:5
+  --> $DIR/mutexguard-sync.rs:11:15
    |
 LL | fn test_sync<T: Sync>(_t: T) {}
    | ---------------------------- required by `test_sync`
 ...
 LL |     test_sync(guard);
-   |     ^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
+   |               ^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
    = note: required because of the requirements on the impl of `std::marker::Sync` for `std::sync::MutexGuard<'_, std::cell::Cell<i32>>`
diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr
index 39aaddb390caa..249ad1c584421 100644
--- a/src/test/ui/namespace/namespace-mix.stderr
+++ b/src/test/ui/namespace/namespace-mix.stderr
@@ -67,400 +67,400 @@ LL | use namespace_mix::xm8::V;
    |
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:33:5
+  --> $DIR/namespace-mix.rs:33:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m1::S{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `c::S: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:35:5
+  --> $DIR/namespace-mix.rs:35:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m2::S{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::S`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `c::S`
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:36:5
+  --> $DIR/namespace-mix.rs:36:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m2::S);
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:39:5
+  --> $DIR/namespace-mix.rs:39:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm1::S{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error[E0277]: the trait bound `namespace_mix::c::S: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:41:5
+  --> $DIR/namespace-mix.rs:41:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm2::S{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::S`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::S`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:42:5
+  --> $DIR/namespace-mix.rs:42:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm2::S);
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:55:5
+  --> $DIR/namespace-mix.rs:55:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m3::TS{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `fn() -> c::TS {c::TS}: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:56:5
+  --> $DIR/namespace-mix.rs:56:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m3::TS);
-   |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> c::TS {c::TS}`
+   |           ^^^^^^ the trait `Impossible` is not implemented for `fn() -> c::TS {c::TS}`
 
 error[E0277]: the trait bound `c::TS: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:57:5
+  --> $DIR/namespace-mix.rs:57:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m4::TS{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::TS`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::TS`
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:58:5
+  --> $DIR/namespace-mix.rs:58:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m4::TS);
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:61:5
+  --> $DIR/namespace-mix.rs:61:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm3::TS{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error[E0277]: the trait bound `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:62:5
+  --> $DIR/namespace-mix.rs:62:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm3::TS);
-   |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}`
 
 error[E0277]: the trait bound `namespace_mix::c::TS: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:63:5
+  --> $DIR/namespace-mix.rs:63:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm4::TS{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::TS`
+   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::TS`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:64:5
+  --> $DIR/namespace-mix.rs:64:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm4::TS);
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:77:5
+  --> $DIR/namespace-mix.rs:77:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m5::US{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `c::US: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:78:5
+  --> $DIR/namespace-mix.rs:78:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m5::US);
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::US`
+   |           ^^^^^^ the trait `Impossible` is not implemented for `c::US`
 
 error[E0277]: the trait bound `c::US: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:79:5
+  --> $DIR/namespace-mix.rs:79:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m6::US{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::US`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::US`
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:80:5
+  --> $DIR/namespace-mix.rs:80:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m6::US);
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:83:5
+  --> $DIR/namespace-mix.rs:83:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm5::US{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error[E0277]: the trait bound `namespace_mix::c::US: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:84:5
+  --> $DIR/namespace-mix.rs:84:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm5::US);
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
 
 error[E0277]: the trait bound `namespace_mix::c::US: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:85:5
+  --> $DIR/namespace-mix.rs:85:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm6::US{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
+   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:86:5
+  --> $DIR/namespace-mix.rs:86:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm6::US);
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:99:5
+  --> $DIR/namespace-mix.rs:99:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m7::V{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `c::E: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:101:5
+  --> $DIR/namespace-mix.rs:101:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m8::V{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `c::E`
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:102:5
+  --> $DIR/namespace-mix.rs:102:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m8::V);
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:105:5
+  --> $DIR/namespace-mix.rs:105:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm7::V{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:107:5
+  --> $DIR/namespace-mix.rs:107:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm8::V{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:108:5
+  --> $DIR/namespace-mix.rs:108:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm8::V);
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:121:5
+  --> $DIR/namespace-mix.rs:121:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m9::TV{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `fn() -> c::E {c::E::TV}: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:122:5
+  --> $DIR/namespace-mix.rs:122:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(m9::TV);
-   |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> c::E {c::E::TV}`
+   |           ^^^^^^ the trait `Impossible` is not implemented for `fn() -> c::E {c::E::TV}`
 
 error[E0277]: the trait bound `c::E: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:123:5
+  --> $DIR/namespace-mix.rs:123:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(mA::TV{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::E`
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:124:5
+  --> $DIR/namespace-mix.rs:124:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(mA::TV);
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:127:5
+  --> $DIR/namespace-mix.rs:127:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm9::TV{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error[E0277]: the trait bound `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:128:5
+  --> $DIR/namespace-mix.rs:128:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xm9::TV);
-   |     ^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}`
 
 error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:129:5
+  --> $DIR/namespace-mix.rs:129:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xmA::TV{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:130:5
+  --> $DIR/namespace-mix.rs:130:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xmA::TV);
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:143:5
+  --> $DIR/namespace-mix.rs:143:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(mB::UV{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `c::E: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:144:5
+  --> $DIR/namespace-mix.rs:144:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(mB::UV);
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |           ^^^^^^ the trait `Impossible` is not implemented for `c::E`
 
 error[E0277]: the trait bound `c::E: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:145:5
+  --> $DIR/namespace-mix.rs:145:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(mC::UV{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::E`
+   |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::E`
 
 error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:146:5
+  --> $DIR/namespace-mix.rs:146:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(mC::UV);
-   |     ^^^^^ the trait `Impossible` is not implemented for `c::Item`
+   |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:149:5
+  --> $DIR/namespace-mix.rs:149:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xmB::UV{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:150:5
+  --> $DIR/namespace-mix.rs:150:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xmB::UV);
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
 
 error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:151:5
+  --> $DIR/namespace-mix.rs:151:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xmC::UV{});
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
+   |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
 
 error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisfied
-  --> $DIR/namespace-mix.rs:152:5
+  --> $DIR/namespace-mix.rs:152:11
    |
 LL | fn check<T: Impossible>(_: T) {}
    | ----------------------------- required by `check`
 ...
 LL |     check(xmC::UV);
-   |     ^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
+   |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
 
 error: aborting due to 48 previous errors
 
diff --git a/src/test/ui/no_send-rc.stderr b/src/test/ui/no_send-rc.stderr
index eaf3103060eff..de08634e16ac4 100644
--- a/src/test/ui/no_send-rc.stderr
+++ b/src/test/ui/no_send-rc.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `std::rc::Rc<{integer}>` cannot be sent between threads safely
-  --> $DIR/no_send-rc.rs:7:5
+  --> $DIR/no_send-rc.rs:7:9
    |
 LL | fn bar<T: Send>(_: T) {}
    | --------------------- required by `bar`
 ...
 LL |     bar(x);
-   |     ^^^ `std::rc::Rc<{integer}>` cannot be sent between threads safely
+   |         ^ `std::rc::Rc<{integer}>` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `std::rc::Rc<{integer}>`
 
diff --git a/src/test/ui/no_send-struct.stderr b/src/test/ui/no_send-struct.stderr
index 1808cef45f184..3865971fcfdd1 100644
--- a/src/test/ui/no_send-struct.stderr
+++ b/src/test/ui/no_send-struct.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `Foo` cannot be sent between threads safely
-  --> $DIR/no_send-struct.rs:15:5
+  --> $DIR/no_send-struct.rs:15:9
    |
 LL | fn bar<T: Send>(_: T) {}
    | --------------------- required by `bar`
 ...
 LL |     bar(x);
-   |     ^^^ `Foo` cannot be sent between threads safely
+   |         ^ `Foo` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `Foo`
 
diff --git a/src/test/ui/no_share-struct.stderr b/src/test/ui/no_share-struct.stderr
index c12ee7c5eae85..13de5bd6fe84b 100644
--- a/src/test/ui/no_share-struct.stderr
+++ b/src/test/ui/no_share-struct.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `Foo` cannot be shared between threads safely
-  --> $DIR/no_share-struct.rs:12:5
+  --> $DIR/no_share-struct.rs:12:9
    |
 LL | fn bar<T: Sync>(_: T) {}
    | --------------------- required by `bar`
 ...
 LL |     bar(x);
-   |     ^^^ `Foo` cannot be shared between threads safely
+   |         ^ `Foo` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `Foo`
 
diff --git a/src/test/ui/object-does-not-impl-trait.stderr b/src/test/ui/object-does-not-impl-trait.stderr
index d3add6398bd98..83ca9a7212b22 100644
--- a/src/test/ui/object-does-not-impl-trait.stderr
+++ b/src/test/ui/object-does-not-impl-trait.stderr
@@ -1,10 +1,10 @@
 error[E0277]: the trait bound `std::boxed::Box<dyn Foo>: Foo` is not satisfied
-  --> $DIR/object-does-not-impl-trait.rs:6:35
+  --> $DIR/object-does-not-impl-trait.rs:6:44
    |
 LL | fn take_foo<F:Foo>(f: F) {}
    | ------------------------ required by `take_foo`
 LL | fn take_object(f: Box<dyn Foo>) { take_foo(f); }
-   |                                   ^^^^^^^^ the trait `Foo` is not implemented for `std::boxed::Box<dyn Foo>`
+   |                                            ^ the trait `Foo` is not implemented for `std::boxed::Box<dyn Foo>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/on-unimplemented/multiple-impls.stderr b/src/test/ui/on-unimplemented/multiple-impls.stderr
index b286265bf01c0..f0651c4cdef0e 100644
--- a/src/test/ui/on-unimplemented/multiple-impls.stderr
+++ b/src/test/ui/on-unimplemented/multiple-impls.stderr
@@ -1,57 +1,57 @@
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
-  --> $DIR/multiple-impls.rs:33:5
+  --> $DIR/multiple-impls.rs:33:18
    |
 LL |     fn index(&self, index: Idx) -> &Self::Output;
    |     --------------------------------------------- required by `Index::index`
 ...
 LL |     Index::index(&[] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^ trait message
-   |
-   = help: the trait `Index<u32>` is not implemented for `[i32]`
-
-error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
-  --> $DIR/multiple-impls.rs:33:5
-   |
-LL |     Index::index(&[] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ trait message
+   |                  ^^^^^^^^^^^^^ trait message
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
 
 error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:36:5
+  --> $DIR/multiple-impls.rs:36:18
    |
 LL |     fn index(&self, index: Idx) -> &Self::Output;
    |     --------------------------------------------- required by `Index::index`
 ...
 LL |     Index::index(&[] as &[i32], Foo(2u32));
-   |     ^^^^^^^^^^^^ on impl for Foo
-   |
-   = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
-
-error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:36:5
-   |
-LL |     Index::index(&[] as &[i32], Foo(2u32));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Foo
+   |                  ^^^^^^^^^^^^^ on impl for Foo
    |
    = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
 
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
-  --> $DIR/multiple-impls.rs:39:5
+  --> $DIR/multiple-impls.rs:39:18
    |
 LL |     fn index(&self, index: Idx) -> &Self::Output;
    |     --------------------------------------------- required by `Index::index`
 ...
 LL |     Index::index(&[] as &[i32], Bar(2u32));
-   |     ^^^^^^^^^^^^ on impl for Bar
+   |                  ^^^^^^^^^^^^^ on impl for Bar
    |
    = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
 
+error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
+  --> $DIR/multiple-impls.rs:33:5
+   |
+LL |     Index::index(&[] as &[i32], 2u32);
+   |     ^^^^^^^^^^^^ trait message
+   |
+   = help: the trait `Index<u32>` is not implemented for `[i32]`
+
+error[E0277]: the trait bound `[i32]: Index<Foo<u32>>` is not satisfied
+  --> $DIR/multiple-impls.rs:36:5
+   |
+LL |     Index::index(&[] as &[i32], Foo(2u32));
+   |     ^^^^^^^^^^^^ on impl for Foo
+   |
+   = help: the trait `Index<Foo<u32>>` is not implemented for `[i32]`
+
 error[E0277]: the trait bound `[i32]: Index<Bar<u32>>` is not satisfied
   --> $DIR/multiple-impls.rs:39:5
    |
 LL |     Index::index(&[] as &[i32], Bar(2u32));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ on impl for Bar
+   |     ^^^^^^^^^^^^ on impl for Bar
    |
    = help: the trait `Index<Bar<u32>>` is not implemented for `[i32]`
 
diff --git a/src/test/ui/on-unimplemented/on-impl.stderr b/src/test/ui/on-unimplemented/on-impl.stderr
index 78dc9a53761c5..f19fa8a07fe64 100644
--- a/src/test/ui/on-unimplemented/on-impl.stderr
+++ b/src/test/ui/on-unimplemented/on-impl.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
-  --> $DIR/on-impl.rs:22:5
+  --> $DIR/on-impl.rs:22:25
    |
 LL |     fn index(&self, index: Idx) -> &Self::Output;
    |     --------------------------------------------- required by `Index::index`
 ...
 LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
+   |                         ^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
 
@@ -13,7 +13,7 @@ error[E0277]: the trait bound `[i32]: Index<u32>` is not satisfied
   --> $DIR/on-impl.rs:22:5
    |
 LL |     Index::<u32>::index(&[1, 2, 3] as &[i32], 2u32);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
+   |     ^^^^^^^^^^^^^^^^^^^ a usize is required to index into a slice
    |
    = help: the trait `Index<u32>` is not implemented for `[i32]`
 
diff --git a/src/test/ui/phantom-oibit.stderr b/src/test/ui/phantom-oibit.stderr
index 284102a6df028..c1b60e0823fd4 100644
--- a/src/test/ui/phantom-oibit.stderr
+++ b/src/test/ui/phantom-oibit.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `T` cannot be shared between threads safely
-  --> $DIR/phantom-oibit.rs:21:5
+  --> $DIR/phantom-oibit.rs:21:12
    |
 LL | fn is_zen<T: Zen>(_: T) {}
    | ----------------------- required by `is_zen`
 ...
 LL |     is_zen(x)
-   |     ^^^^^^ `T` cannot be shared between threads safely
+   |            ^ `T` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `T`
    = help: consider adding a `where T: std::marker::Sync` bound
@@ -14,13 +14,13 @@ LL |     is_zen(x)
    = note: required because it appears within the type `Guard<'_, T>`
 
 error[E0277]: `T` cannot be shared between threads safely
-  --> $DIR/phantom-oibit.rs:26:5
+  --> $DIR/phantom-oibit.rs:26:12
    |
 LL | fn is_zen<T: Zen>(_: T) {}
    | ----------------------- required by `is_zen`
 ...
 LL |     is_zen(x)
-   |     ^^^^^^ `T` cannot be shared between threads safely
+   |            ^ `T` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `T`
    = help: consider adding a `where T: std::marker::Sync` bound
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
index 7d1e5c3d64df3..a856420c347b5 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
@@ -40,12 +40,14 @@ fn nested_within_if_expr() {
 
     fn _check_try_binds_tighter() -> Result<(), ()> {
         if let 0 = 0? {}
-        //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
+        //~^ ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
+        //~| ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
         Ok(())
     }
     if (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
-    //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
-    //~| ERROR the `?` operator can only be used in a function that returns `Result`
+    //~^ ERROR the trait bound `bool: std::ops::Try` is not satisfied
+    //~| ERROR the trait bound `bool: std::ops::Try` is not satisfied
+    //~| ERROR the `?` operator can only be used in a function that returns `Result` or `Option`
 
     if true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
     if (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
@@ -104,12 +106,14 @@ fn nested_within_while_expr() {
 
     fn _check_try_binds_tighter() -> Result<(), ()> {
         while let 0 = 0? {}
-        //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
+        //~^ ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
+        //~| ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
         Ok(())
     }
     while (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
-    //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
-    //~| ERROR the `?` operator can only be used in a function that returns `Result`
+    //~^ ERROR the trait bound `bool: std::ops::Try` is not satisfied
+    //~| ERROR the trait bound `bool: std::ops::Try` is not satisfied
+    //~| ERROR the `?` operator can only be used in a function that returns `Result` or `Option`
 
     while true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
     while (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
@@ -177,12 +181,14 @@ fn outside_if_and_while_expr() {
 
     fn _check_try_binds_tighter() -> Result<(), ()> {
         let 0 = 0?;
-        //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
+        //~^ ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
+        //~| ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
         Ok(())
     }
     (let 0 = 0)?; //~ ERROR `let` expressions are not supported here
-    //~^ ERROR the `?` operator can only be used in a function that returns `Result`
-    //~| ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
+    //~^ ERROR the trait bound `bool: std::ops::Try` is not satisfied
+    //~| ERROR the trait bound `bool: std::ops::Try` is not satisfied
+    //~| ERROR the `?` operator can only be used in a function that returns `Result` or `Option`
 
     true || let 0 = 0; //~ ERROR `let` expressions are not supported here
     (true || let 0 = 0); //~ ERROR `let` expressions are not supported here
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index 4edc00efc7e72..e06d81923f1ad 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -1,5 +1,5 @@
 error: expected one of `,` or `>`, found `&&`
-  --> $DIR/disallowed-positions.rs:242:14
+  --> $DIR/disallowed-positions.rs:248:14
    |
 LL |         true && let 1 = 1
    |              ^^ expected one of `,` or `>` here
@@ -41,7 +41,7 @@ LL |     if -let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:46:9
+  --> $DIR/disallowed-positions.rs:47:9
    |
 LL |     if (let 0 = 0)? {}
    |         ^^^^^^^^^
@@ -50,7 +50,7 @@ LL |     if (let 0 = 0)? {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:50:16
+  --> $DIR/disallowed-positions.rs:52:16
    |
 LL |     if true || let 0 = 0 {}
    |                ^^^^^^^^^
@@ -59,7 +59,7 @@ LL |     if true || let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:51:17
+  --> $DIR/disallowed-positions.rs:53:17
    |
 LL |     if (true || let 0 = 0) {}
    |                 ^^^^^^^^^
@@ -68,7 +68,7 @@ LL |     if (true || let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:52:25
+  --> $DIR/disallowed-positions.rs:54:25
    |
 LL |     if true && (true || let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -77,7 +77,7 @@ LL |     if true && (true || let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:53:25
+  --> $DIR/disallowed-positions.rs:55:25
    |
 LL |     if true || (true && let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -86,7 +86,7 @@ LL |     if true || (true && let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:56:12
+  --> $DIR/disallowed-positions.rs:58:12
    |
 LL |     if x = let 0 = 0 {}
    |            ^^^^^^^^^
@@ -95,7 +95,7 @@ LL |     if x = let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:59:15
+  --> $DIR/disallowed-positions.rs:61:15
    |
 LL |     if true..(let 0 = 0) {}
    |               ^^^^^^^^^
@@ -104,7 +104,7 @@ LL |     if true..(let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:61:11
+  --> $DIR/disallowed-positions.rs:63:11
    |
 LL |     if ..(let 0 = 0) {}
    |           ^^^^^^^^^
@@ -113,7 +113,7 @@ LL |     if ..(let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:63:9
+  --> $DIR/disallowed-positions.rs:65:9
    |
 LL |     if (let 0 = 0).. {}
    |         ^^^^^^^^^
@@ -122,7 +122,7 @@ LL |     if (let 0 = 0).. {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:67:8
+  --> $DIR/disallowed-positions.rs:69:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -131,7 +131,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:71:8
+  --> $DIR/disallowed-positions.rs:73:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -140,7 +140,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:78:8
+  --> $DIR/disallowed-positions.rs:80:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -149,7 +149,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:86:8
+  --> $DIR/disallowed-positions.rs:88:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -158,7 +158,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:92:19
+  --> $DIR/disallowed-positions.rs:94:19
    |
 LL |     if let true = let true = true {}
    |                   ^^^^^^^^^^^^^^^
@@ -167,7 +167,7 @@ LL |     if let true = let true = true {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:96:12
+  --> $DIR/disallowed-positions.rs:98:12
    |
 LL |     while &let 0 = 0 {}
    |            ^^^^^^^^^
@@ -176,7 +176,7 @@ LL |     while &let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:99:12
+  --> $DIR/disallowed-positions.rs:101:12
    |
 LL |     while !let 0 = 0 {}
    |            ^^^^^^^^^
@@ -185,7 +185,7 @@ LL |     while !let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:100:12
+  --> $DIR/disallowed-positions.rs:102:12
    |
 LL |     while *let 0 = 0 {}
    |            ^^^^^^^^^
@@ -194,7 +194,7 @@ LL |     while *let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:102:12
+  --> $DIR/disallowed-positions.rs:104:12
    |
 LL |     while -let 0 = 0 {}
    |            ^^^^^^^^^
@@ -203,7 +203,7 @@ LL |     while -let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:110:12
+  --> $DIR/disallowed-positions.rs:113:12
    |
 LL |     while (let 0 = 0)? {}
    |            ^^^^^^^^^
@@ -212,7 +212,7 @@ LL |     while (let 0 = 0)? {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:114:19
+  --> $DIR/disallowed-positions.rs:118:19
    |
 LL |     while true || let 0 = 0 {}
    |                   ^^^^^^^^^
@@ -221,7 +221,7 @@ LL |     while true || let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:115:20
+  --> $DIR/disallowed-positions.rs:119:20
    |
 LL |     while (true || let 0 = 0) {}
    |                    ^^^^^^^^^
@@ -230,7 +230,7 @@ LL |     while (true || let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:116:28
+  --> $DIR/disallowed-positions.rs:120:28
    |
 LL |     while true && (true || let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -239,7 +239,7 @@ LL |     while true && (true || let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:117:28
+  --> $DIR/disallowed-positions.rs:121:28
    |
 LL |     while true || (true && let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -248,7 +248,7 @@ LL |     while true || (true && let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:120:15
+  --> $DIR/disallowed-positions.rs:124:15
    |
 LL |     while x = let 0 = 0 {}
    |               ^^^^^^^^^
@@ -257,7 +257,7 @@ LL |     while x = let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:123:18
+  --> $DIR/disallowed-positions.rs:127:18
    |
 LL |     while true..(let 0 = 0) {}
    |                  ^^^^^^^^^
@@ -266,7 +266,7 @@ LL |     while true..(let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:125:14
+  --> $DIR/disallowed-positions.rs:129:14
    |
 LL |     while ..(let 0 = 0) {}
    |              ^^^^^^^^^
@@ -275,7 +275,7 @@ LL |     while ..(let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:127:12
+  --> $DIR/disallowed-positions.rs:131:12
    |
 LL |     while (let 0 = 0).. {}
    |            ^^^^^^^^^
@@ -284,7 +284,7 @@ LL |     while (let 0 = 0).. {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:131:11
+  --> $DIR/disallowed-positions.rs:135:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -293,7 +293,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:135:11
+  --> $DIR/disallowed-positions.rs:139:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -302,7 +302,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:142:11
+  --> $DIR/disallowed-positions.rs:146:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -311,7 +311,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:150:11
+  --> $DIR/disallowed-positions.rs:154:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -320,7 +320,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:156:22
+  --> $DIR/disallowed-positions.rs:160:22
    |
 LL |     while let true = let true = true {}
    |                      ^^^^^^^^^^^^^^^
@@ -329,7 +329,7 @@ LL |     while let true = let true = true {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:170:6
+  --> $DIR/disallowed-positions.rs:174:6
    |
 LL |     &let 0 = 0;
    |      ^^^^^^^^^
@@ -338,7 +338,7 @@ LL |     &let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:172:6
+  --> $DIR/disallowed-positions.rs:176:6
    |
 LL |     !let 0 = 0;
    |      ^^^^^^^^^
@@ -347,7 +347,7 @@ LL |     !let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:173:6
+  --> $DIR/disallowed-positions.rs:177:6
    |
 LL |     *let 0 = 0;
    |      ^^^^^^^^^
@@ -356,7 +356,7 @@ LL |     *let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:175:6
+  --> $DIR/disallowed-positions.rs:179:6
    |
 LL |     -let 0 = 0;
    |      ^^^^^^^^^
@@ -365,7 +365,7 @@ LL |     -let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:183:6
+  --> $DIR/disallowed-positions.rs:188:6
    |
 LL |     (let 0 = 0)?;
    |      ^^^^^^^^^
@@ -374,7 +374,7 @@ LL |     (let 0 = 0)?;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:187:13
+  --> $DIR/disallowed-positions.rs:193:13
    |
 LL |     true || let 0 = 0;
    |             ^^^^^^^^^
@@ -383,7 +383,7 @@ LL |     true || let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:188:14
+  --> $DIR/disallowed-positions.rs:194:14
    |
 LL |     (true || let 0 = 0);
    |              ^^^^^^^^^
@@ -392,7 +392,7 @@ LL |     (true || let 0 = 0);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:189:22
+  --> $DIR/disallowed-positions.rs:195:22
    |
 LL |     true && (true || let 0 = 0);
    |                      ^^^^^^^^^
@@ -401,7 +401,7 @@ LL |     true && (true || let 0 = 0);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:192:9
+  --> $DIR/disallowed-positions.rs:198:9
    |
 LL |     x = let 0 = 0;
    |         ^^^^^^^^^
@@ -410,7 +410,7 @@ LL |     x = let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:194:12
+  --> $DIR/disallowed-positions.rs:200:12
    |
 LL |     true..(let 0 = 0);
    |            ^^^^^^^^^
@@ -419,7 +419,7 @@ LL |     true..(let 0 = 0);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:195:8
+  --> $DIR/disallowed-positions.rs:201:8
    |
 LL |     ..(let 0 = 0);
    |        ^^^^^^^^^
@@ -428,7 +428,7 @@ LL |     ..(let 0 = 0);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:196:6
+  --> $DIR/disallowed-positions.rs:202:6
    |
 LL |     (let 0 = 0)..;
    |      ^^^^^^^^^
@@ -437,7 +437,7 @@ LL |     (let 0 = 0)..;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:198:6
+  --> $DIR/disallowed-positions.rs:204:6
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -446,7 +446,7 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:202:6
+  --> $DIR/disallowed-positions.rs:208:6
    |
 LL |     (let true = let true = true);
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -455,7 +455,7 @@ LL |     (let true = let true = true);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:202:17
+  --> $DIR/disallowed-positions.rs:208:17
    |
 LL |     (let true = let true = true);
    |                 ^^^^^^^^^^^^^^^
@@ -464,7 +464,7 @@ LL |     (let true = let true = true);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:207:6
+  --> $DIR/disallowed-positions.rs:213:6
    |
 LL |     &let 0 = 0
    |      ^^^^^^^^^
@@ -473,7 +473,7 @@ LL |     &let 0 = 0
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:218:17
+  --> $DIR/disallowed-positions.rs:224:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -482,7 +482,7 @@ LL |         true && let 1 = 1
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:224:17
+  --> $DIR/disallowed-positions.rs:230:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -491,7 +491,7 @@ LL |         true && let 1 = 1
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:230:17
+  --> $DIR/disallowed-positions.rs:236:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -536,17 +536,16 @@ LL |     if -let 0 = 0 {}
    |
    = note: an implementation of `std::ops::Neg` might be missing for `bool`
 
-error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
-  --> $DIR/disallowed-positions.rs:46:8
+error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
+  --> $DIR/disallowed-positions.rs:47:8
    |
 LL |     if (let 0 = 0)? {}
-   |        ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
+   |        ^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
    |
-   = help: the trait `std::ops::Try` is not implemented for `bool`
    = note: required by `std::ops::Try::into_result`
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
-  --> $DIR/disallowed-positions.rs:46:8
+  --> $DIR/disallowed-positions.rs:47:8
    |
 LL |     if (let 0 = 0)? {}
    |        ^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
@@ -555,7 +554,7 @@ LL |     if (let 0 = 0)? {}
    = note: required by `std::ops::Try::from_error`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:56:8
+  --> $DIR/disallowed-positions.rs:58:8
    |
 LL |     if x = let 0 = 0 {}
    |        ^^^^^^^^^^^^^
@@ -567,7 +566,7 @@ LL |     if x = let 0 = 0 {}
               found type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:59:8
+  --> $DIR/disallowed-positions.rs:61:8
    |
 LL |     if true..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -576,7 +575,7 @@ LL |     if true..(let 0 = 0) {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:61:8
+  --> $DIR/disallowed-positions.rs:63:8
    |
 LL |     if ..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^ expected bool, found struct `std::ops::RangeTo`
@@ -585,7 +584,7 @@ LL |     if ..(let 0 = 0) {}
               found type `std::ops::RangeTo<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:63:8
+  --> $DIR/disallowed-positions.rs:65:8
    |
 LL |     if (let 0 = 0).. {}
    |        ^^^^^^^^^^^^^ expected bool, found struct `std::ops::RangeFrom`
@@ -594,7 +593,7 @@ LL |     if (let 0 = 0).. {}
               found type `std::ops::RangeFrom<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:67:12
+  --> $DIR/disallowed-positions.rs:69:12
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this match expression has type `bool`
@@ -605,7 +604,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:67:8
+  --> $DIR/disallowed-positions.rs:69:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -614,7 +613,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:71:12
+  --> $DIR/disallowed-positions.rs:73:12
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this match expression has type `bool`
@@ -625,7 +624,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:71:8
+  --> $DIR/disallowed-positions.rs:73:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -634,7 +633,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:78:12
+  --> $DIR/disallowed-positions.rs:80:12
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found struct `std::ops::Range`
@@ -643,16 +642,16 @@ LL |     if let Range { start: F, end } = F..|| true {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:78:41
+  --> $DIR/disallowed-positions.rs:80:41
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |                                         ^^^^^^^ expected bool, found closure
    |
    = note: expected type `bool`
-              found type `[closure@$DIR/disallowed-positions.rs:78:41: 78:48]`
+              found type `[closure@$DIR/disallowed-positions.rs:80:41: 80:48]`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:78:8
+  --> $DIR/disallowed-positions.rs:80:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -661,7 +660,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:86:12
+  --> $DIR/disallowed-positions.rs:88:12
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this match expression has type `bool`
@@ -672,7 +671,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:86:44
+  --> $DIR/disallowed-positions.rs:88:44
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |                                            ^^^^^^^ expected bool, found &&bool
@@ -681,7 +680,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
               found type `&&bool`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:86:8
+  --> $DIR/disallowed-positions.rs:88:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -689,17 +688,41 @@ LL |     if let Range { start: true, end } = t..&&false {}
    = note: expected type `bool`
               found type `std::ops::Range<bool>`
 
-error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
+  --> $DIR/disallowed-positions.rs:47:8
+   |
+LL |     if (let 0 = 0)? {}
+   |        ^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
+
+error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
   --> $DIR/disallowed-positions.rs:42:20
    |
 LL |         if let 0 = 0? {}
-   |                    ^^ the `?` operator cannot be applied to type `{integer}`
-   |
-   = help: the trait `std::ops::Try` is not implemented for `{integer}`
+   |                    ^ the trait `std::ops::Try` is not implemented for `{integer}`
+   |
+   = help: the following implementations were found:
+             <std::iter::LoopState<C, B> as std::ops::Try>
+             <std::option::Option<T> as std::ops::Try>
+             <std::result::Result<T, E> as std::ops::Try>
+             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
+             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
    = note: required by `std::ops::Try::into_result`
 
+error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
+  --> $DIR/disallowed-positions.rs:42:20
+   |
+LL |         if let 0 = 0? {}
+   |                    ^^ the trait `std::ops::Try` is not implemented for `{integer}`
+   |
+   = help: the following implementations were found:
+             <std::iter::LoopState<C, B> as std::ops::Try>
+             <std::option::Option<T> as std::ops::Try>
+             <std::result::Result<T, E> as std::ops::Try>
+             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
+             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
+
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:96:11
+  --> $DIR/disallowed-positions.rs:98:11
    |
 LL |     while &let 0 = 0 {}
    |           ^^^^^^^^^^ expected bool, found &bool
@@ -708,30 +731,29 @@ LL |     while &let 0 = 0 {}
               found type `&bool`
 
 error[E0614]: type `bool` cannot be dereferenced
-  --> $DIR/disallowed-positions.rs:100:11
+  --> $DIR/disallowed-positions.rs:102:11
    |
 LL |     while *let 0 = 0 {}
    |           ^^^^^^^^^^
 
 error[E0600]: cannot apply unary operator `-` to type `bool`
-  --> $DIR/disallowed-positions.rs:102:11
+  --> $DIR/disallowed-positions.rs:104:11
    |
 LL |     while -let 0 = 0 {}
    |           ^^^^^^^^^^ cannot apply unary operator `-`
    |
    = note: an implementation of `std::ops::Neg` might be missing for `bool`
 
-error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
-  --> $DIR/disallowed-positions.rs:110:11
+error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
+  --> $DIR/disallowed-positions.rs:113:11
    |
 LL |     while (let 0 = 0)? {}
-   |           ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
+   |           ^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
    |
-   = help: the trait `std::ops::Try` is not implemented for `bool`
    = note: required by `std::ops::Try::into_result`
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
-  --> $DIR/disallowed-positions.rs:110:11
+  --> $DIR/disallowed-positions.rs:113:11
    |
 LL |     while (let 0 = 0)? {}
    |           ^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
@@ -740,7 +762,7 @@ LL |     while (let 0 = 0)? {}
    = note: required by `std::ops::Try::from_error`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:120:11
+  --> $DIR/disallowed-positions.rs:124:11
    |
 LL |     while x = let 0 = 0 {}
    |           ^^^^^^^^^^^^^
@@ -752,7 +774,7 @@ LL |     while x = let 0 = 0 {}
               found type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:123:11
+  --> $DIR/disallowed-positions.rs:127:11
    |
 LL |     while true..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -761,7 +783,7 @@ LL |     while true..(let 0 = 0) {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:125:11
+  --> $DIR/disallowed-positions.rs:129:11
    |
 LL |     while ..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^ expected bool, found struct `std::ops::RangeTo`
@@ -770,7 +792,7 @@ LL |     while ..(let 0 = 0) {}
               found type `std::ops::RangeTo<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:127:11
+  --> $DIR/disallowed-positions.rs:131:11
    |
 LL |     while (let 0 = 0).. {}
    |           ^^^^^^^^^^^^^ expected bool, found struct `std::ops::RangeFrom`
@@ -779,7 +801,7 @@ LL |     while (let 0 = 0).. {}
               found type `std::ops::RangeFrom<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:131:15
+  --> $DIR/disallowed-positions.rs:135:15
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this match expression has type `bool`
@@ -790,7 +812,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:131:11
+  --> $DIR/disallowed-positions.rs:135:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -799,7 +821,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:135:15
+  --> $DIR/disallowed-positions.rs:139:15
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this match expression has type `bool`
@@ -810,7 +832,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:135:11
+  --> $DIR/disallowed-positions.rs:139:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -819,7 +841,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:142:15
+  --> $DIR/disallowed-positions.rs:146:15
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found struct `std::ops::Range`
@@ -828,16 +850,16 @@ LL |     while let Range { start: F, end } = F..|| true {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:142:44
+  --> $DIR/disallowed-positions.rs:146:44
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |                                            ^^^^^^^ expected bool, found closure
    |
    = note: expected type `bool`
-              found type `[closure@$DIR/disallowed-positions.rs:142:44: 142:51]`
+              found type `[closure@$DIR/disallowed-positions.rs:146:44: 146:51]`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:142:11
+  --> $DIR/disallowed-positions.rs:146:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -846,7 +868,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:150:15
+  --> $DIR/disallowed-positions.rs:154:15
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this match expression has type `bool`
@@ -857,7 +879,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:150:47
+  --> $DIR/disallowed-positions.rs:154:47
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |                                               ^^^^^^^ expected bool, found &&bool
@@ -866,7 +888,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
               found type `&&bool`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:150:11
+  --> $DIR/disallowed-positions.rs:154:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -874,40 +896,63 @@ LL |     while let Range { start: true, end } = t..&&false {}
    = note: expected type `bool`
               found type `std::ops::Range<bool>`
 
-error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
-  --> $DIR/disallowed-positions.rs:106:23
+error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
+  --> $DIR/disallowed-positions.rs:113:11
    |
-LL |         while let 0 = 0? {}
-   |                       ^^ the `?` operator cannot be applied to type `{integer}`
+LL |     while (let 0 = 0)? {}
+   |           ^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
+
+error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
+  --> $DIR/disallowed-positions.rs:108:23
    |
-   = help: the trait `std::ops::Try` is not implemented for `{integer}`
+LL |         while let 0 = 0? {}
+   |                       ^ the trait `std::ops::Try` is not implemented for `{integer}`
+   |
+   = help: the following implementations were found:
+             <std::iter::LoopState<C, B> as std::ops::Try>
+             <std::option::Option<T> as std::ops::Try>
+             <std::result::Result<T, E> as std::ops::Try>
+             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
+             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
    = note: required by `std::ops::Try::into_result`
 
+error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
+  --> $DIR/disallowed-positions.rs:108:23
+   |
+LL |         while let 0 = 0? {}
+   |                       ^^ the trait `std::ops::Try` is not implemented for `{integer}`
+   |
+   = help: the following implementations were found:
+             <std::iter::LoopState<C, B> as std::ops::Try>
+             <std::option::Option<T> as std::ops::Try>
+             <std::result::Result<T, E> as std::ops::Try>
+             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
+             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
+
 error[E0614]: type `bool` cannot be dereferenced
-  --> $DIR/disallowed-positions.rs:173:5
+  --> $DIR/disallowed-positions.rs:177:5
    |
 LL |     *let 0 = 0;
    |     ^^^^^^^^^^
 
 error[E0600]: cannot apply unary operator `-` to type `bool`
-  --> $DIR/disallowed-positions.rs:175:5
+  --> $DIR/disallowed-positions.rs:179:5
    |
 LL |     -let 0 = 0;
    |     ^^^^^^^^^^ cannot apply unary operator `-`
    |
    = note: an implementation of `std::ops::Neg` might be missing for `bool`
 
-error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
-  --> $DIR/disallowed-positions.rs:183:5
+error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
+  --> $DIR/disallowed-positions.rs:188:5
    |
 LL |     (let 0 = 0)?;
-   |     ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
+   |     ^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
    |
-   = help: the trait `std::ops::Try` is not implemented for `bool`
    = note: required by `std::ops::Try::into_result`
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
-  --> $DIR/disallowed-positions.rs:183:5
+  --> $DIR/disallowed-positions.rs:188:5
    |
 LL |     (let 0 = 0)?;
    |     ^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
@@ -916,7 +961,7 @@ LL |     (let 0 = 0)?;
    = note: required by `std::ops::Try::from_error`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:198:10
+  --> $DIR/disallowed-positions.rs:204:10
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this match expression has type `bool`
@@ -927,7 +972,7 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:207:5
+  --> $DIR/disallowed-positions.rs:213:5
    |
 LL | fn outside_if_and_while_expr() {
    |                                - help: try adding a return type: `-> &bool`
@@ -938,52 +983,76 @@ LL |     &let 0 = 0
    = note: expected type `()`
               found type `&bool`
 
-error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
-  --> $DIR/disallowed-positions.rs:179:17
+error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
+  --> $DIR/disallowed-positions.rs:188:5
    |
-LL |         let 0 = 0?;
-   |                 ^^ the `?` operator cannot be applied to type `{integer}`
+LL |     (let 0 = 0)?;
+   |     ^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
+
+error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
+  --> $DIR/disallowed-positions.rs:183:17
    |
-   = help: the trait `std::ops::Try` is not implemented for `{integer}`
+LL |         let 0 = 0?;
+   |                 ^ the trait `std::ops::Try` is not implemented for `{integer}`
+   |
+   = help: the following implementations were found:
+             <std::iter::LoopState<C, B> as std::ops::Try>
+             <std::option::Option<T> as std::ops::Try>
+             <std::result::Result<T, E> as std::ops::Try>
+             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
+             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
    = note: required by `std::ops::Try::into_result`
 
+error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
+  --> $DIR/disallowed-positions.rs:183:17
+   |
+LL |         let 0 = 0?;
+   |                 ^^ the trait `std::ops::Try` is not implemented for `{integer}`
+   |
+   = help: the following implementations were found:
+             <std::iter::LoopState<C, B> as std::ops::Try>
+             <std::option::Option<T> as std::ops::Try>
+             <std::result::Result<T, E> as std::ops::Try>
+             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
+             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
+
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:218:25
+  --> $DIR/disallowed-positions.rs:224:25
    |
 LL |         true && let 1 = 1
    |                         ^
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:218:21
+  --> $DIR/disallowed-positions.rs:224:21
    |
 LL |         true && let 1 = 1
    |                     ^
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:224:25
+  --> $DIR/disallowed-positions.rs:230:25
    |
 LL |         true && let 1 = 1
    |                         ^
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:224:21
+  --> $DIR/disallowed-positions.rs:230:21
    |
 LL |         true && let 1 = 1
    |                     ^
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:230:25
+  --> $DIR/disallowed-positions.rs:236:25
    |
 LL |         true && let 1 = 1
    |                         ^
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:230:21
+  --> $DIR/disallowed-positions.rs:236:21
    |
 LL |         true && let 1 = 1
    |                     ^
 
-error: aborting due to 109 previous errors
+error: aborting due to 115 previous errors
 
 Some errors have detailed explanations: E0019, E0277, E0308, E0600, E0614.
 For more information about an error, try `rustc --explain E0019`.
diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr
index e388534f132d2..9f21aaaebad58 100644
--- a/src/test/ui/str/str-idx.stderr
+++ b/src/test/ui/str/str-idx.stderr
@@ -10,20 +10,20 @@ LL |     let _: u8 = s[4];
    = note: required because of the requirements on the impl of `std::ops::Index<{integer}>` for `str`
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
-  --> $DIR/str-idx.rs:4:15
+  --> $DIR/str-idx.rs:4:19
    |
 LL |     let _ = s.get(4);
-   |               ^^^ string indices are ranges of `usize`
+   |                   ^ string indices are ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
-  --> $DIR/str-idx.rs:5:15
+  --> $DIR/str-idx.rs:5:29
    |
 LL |     let _ = s.get_unchecked(4);
-   |               ^^^^^^^^^^^^^ string indices are ranges of `usize`
+   |                             ^ string indices are ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr
index 08baa478b8bfa..372077a465e4a 100644
--- a/src/test/ui/str/str-mut-idx.stderr
+++ b/src/test/ui/str/str-mut-idx.stderr
@@ -30,20 +30,20 @@ LL |     s[1usize] = bot();
    = note: required because of the requirements on the impl of `std::ops::Index<usize>` for `str`
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
-  --> $DIR/str-mut-idx.rs:9:7
+  --> $DIR/str-mut-idx.rs:9:15
    |
 LL |     s.get_mut(1);
-   |       ^^^^^^^ string indices are ranges of `usize`
+   |               ^ string indices are ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
            see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>
 
 error[E0277]: the type `str` cannot be indexed by `{integer}`
-  --> $DIR/str-mut-idx.rs:11:7
+  --> $DIR/str-mut-idx.rs:11:25
    |
 LL |     s.get_unchecked_mut(1);
-   |       ^^^^^^^^^^^^^^^^^ string indices are ranges of `usize`
+   |                         ^ string indices are ranges of `usize`
    |
    = help: the trait `std::slice::SliceIndex<str>` is not implemented for `{integer}`
    = note: you can use `.chars().nth()` or `.bytes().nth()`
diff --git a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index 3141b1b65f9ba..4df639b55e5ce 100644
--- a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::future::Future` is not satisfied
-  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:5
+  --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:9
    |
 LL | fn bar(f: impl Future<Output=()>) {}
    | --------------------------------- required by `bar`
 ...
 LL |     bar(foo);
-   |     ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
+   |         ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
    |
    = help: use parentheses to call the function: `foo()`
 
diff --git a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index 2cc4653fabe2d..f51f1a8215cb5 100644
--- a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `fn() -> impl T {foo}: T` is not satisfied
-  --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:17:5
+  --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:17:9
    |
 LL | fn bar(f: impl T<O=()>) {}
    | ----------------------- required by `bar`
 ...
 LL |     bar(foo);
-   |     ^^^ the trait `T` is not implemented for `fn() -> impl T {foo}`
+   |         ^^^ the trait `T` is not implemented for `fn() -> impl T {foo}`
    |
    = help: use parentheses to call the function: `foo()`
 
diff --git a/src/test/ui/suggestions/issue-62843.stderr b/src/test/ui/suggestions/issue-62843.stderr
index cc27b5b49b67d..b5801e9162fb3 100644
--- a/src/test/ui/suggestions/issue-62843.stderr
+++ b/src/test/ui/suggestions/issue-62843.stderr
@@ -1,8 +1,8 @@
 error[E0277]: expected a `std::ops::FnMut<(char,)>` closure, found `std::string::String`
-  --> $DIR/issue-62843.rs:4:27
+  --> $DIR/issue-62843.rs:4:32
    |
 LL |     println!("{:?}", line.find(pattern));
-   |                           ^^^^ expected an `FnMut<(char,)>` closure, found `std::string::String`
+   |                                ^^^^^^^ expected an `FnMut<(char,)>` closure, found `std::string::String`
    |
    = help: the trait `std::ops::FnMut<(char,)>` is not implemented for `std::string::String`
    = note: borrowing the `std::string::String` might fix the problem
diff --git a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr
index 0b543616d7c9a..76d486a51e5cc 100644
--- a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr
+++ b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr
@@ -5,13 +5,13 @@ LL | auto trait Magic: Copy {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `NoClone: std::marker::Copy` is not satisfied
-  --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:15:18
+  --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:15:23
    |
 LL | fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
    | --------------------------------- required by `copy`
 ...
 LL |     let (a, b) = copy(NoClone);
-   |                  ^^^^ the trait `std::marker::Copy` is not implemented for `NoClone`
+   |                       ^^^^^^^ the trait `std::marker::Copy` is not implemented for `NoClone`
    |
    = note: required because of the requirements on the impl of `Magic` for `NoClone`
 
diff --git a/src/test/ui/traits/traits-negative-impls.stderr b/src/test/ui/traits/traits-negative-impls.stderr
index 23bd334a3e776..022b12d256cc3 100644
--- a/src/test/ui/traits/traits-negative-impls.stderr
+++ b/src/test/ui/traits/traits-negative-impls.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `dummy::TestType` cannot be sent between threads safely
-  --> $DIR/traits-negative-impls.rs:23:5
+  --> $DIR/traits-negative-impls.rs:23:11
    |
 LL | struct Outer<T: Send>(T);
    | ------------------------- required by `Outer`
 ...
 LL |     Outer(TestType);
-   |     ^^^^^ `dummy::TestType` cannot be sent between threads safely
+   |           ^^^^^^^^ `dummy::TestType` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `dummy::TestType`
 
@@ -21,49 +21,49 @@ LL |     Outer(TestType);
    = help: the trait `std::marker::Send` is not implemented for `dummy::TestType`
 
 error[E0277]: `dummy1b::TestType` cannot be sent between threads safely
-  --> $DIR/traits-negative-impls.rs:32:5
+  --> $DIR/traits-negative-impls.rs:32:13
    |
 LL | fn is_send<T: Send>(_: T) {}
    | ------------------------- required by `is_send`
 ...
 LL |     is_send(TestType);
-   |     ^^^^^^^ `dummy1b::TestType` cannot be sent between threads safely
+   |             ^^^^^^^^ `dummy1b::TestType` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `dummy1b::TestType`
 
 error[E0277]: `dummy1c::TestType` cannot be sent between threads safely
-  --> $DIR/traits-negative-impls.rs:40:5
+  --> $DIR/traits-negative-impls.rs:40:13
    |
 LL | fn is_send<T: Send>(_: T) {}
    | ------------------------- required by `is_send`
 ...
 LL |     is_send((8, TestType));
-   |     ^^^^^^^ `dummy1c::TestType` cannot be sent between threads safely
+   |             ^^^^^^^^^^^^^ `dummy1c::TestType` cannot be sent between threads safely
    |
    = help: within `({integer}, dummy1c::TestType)`, the trait `std::marker::Send` is not implemented for `dummy1c::TestType`
    = note: required because it appears within the type `({integer}, dummy1c::TestType)`
 
 error[E0277]: `dummy2::TestType` cannot be sent between threads safely
-  --> $DIR/traits-negative-impls.rs:48:5
+  --> $DIR/traits-negative-impls.rs:48:13
    |
 LL | fn is_send<T: Send>(_: T) {}
    | ------------------------- required by `is_send`
 ...
 LL |     is_send(Box::new(TestType));
-   |     ^^^^^^^ `dummy2::TestType` cannot be sent between threads safely
+   |             ^^^^^^^^^^^^^^^^^^ `dummy2::TestType` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `dummy2::TestType`
    = note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<dummy2::TestType>`
    = note: required because it appears within the type `std::boxed::Box<dummy2::TestType>`
 
 error[E0277]: `dummy3::TestType` cannot be sent between threads safely
-  --> $DIR/traits-negative-impls.rs:56:5
+  --> $DIR/traits-negative-impls.rs:56:13
    |
 LL | fn is_send<T: Send>(_: T) {}
    | ------------------------- required by `is_send`
 ...
 LL |     is_send(Box::new(Outer2(TestType)));
-   |     ^^^^^^^ `dummy3::TestType` cannot be sent between threads safely
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ `dummy3::TestType` cannot be sent between threads safely
    |
    = help: within `Outer2<dummy3::TestType>`, the trait `std::marker::Send` is not implemented for `dummy3::TestType`
    = note: required because it appears within the type `Outer2<dummy3::TestType>`
@@ -71,13 +71,13 @@ LL |     is_send(Box::new(Outer2(TestType)));
    = note: required because it appears within the type `std::boxed::Box<Outer2<dummy3::TestType>>`
 
 error[E0277]: `main::TestType` cannot be sent between threads safely
-  --> $DIR/traits-negative-impls.rs:66:5
+  --> $DIR/traits-negative-impls.rs:66:13
    |
 LL | fn is_sync<T: Sync>(_: T) {}
    | ------------------------- required by `is_sync`
 ...
 LL |     is_sync(Outer2(TestType));
-   |     ^^^^^^^ `main::TestType` cannot be sent between threads safely
+   |             ^^^^^^^^^^^^^^^^ `main::TestType` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `main::TestType`
    = note: required because of the requirements on the impl of `std::marker::Sync` for `Outer2<main::TestType>`
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
index d172d5ecc4b70..49393a8678ef8 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
+++ b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
@@ -19,19 +19,19 @@ LL |     3i32.test();
            candidate #1: `Foo`
 
 error[E0277]: the trait bound `i32: Foo` is not satisfied
-  --> $DIR/trivial-bounds-leak.rs:25:5
+  --> $DIR/trivial-bounds-leak.rs:25:15
    |
 LL |     fn test(&self);
    |     --------------- required by `Foo::test`
 ...
 LL |     Foo::test(&4i32);
-   |     ^^^^^^^^^ the trait `Foo` is not implemented for `i32`
+   |               ^^^^^ the trait `Foo` is not implemented for `i32`
 
 error[E0277]: the trait bound `i32: Foo` is not satisfied
-  --> $DIR/trivial-bounds-leak.rs:26:5
+  --> $DIR/trivial-bounds-leak.rs:26:22
    |
 LL |     generic_function(5i32);
-   |     ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `i32`
+   |                      ^^^^ the trait `Foo` is not implemented for `i32`
 ...
 LL | fn generic_function<T: Foo>(t: T) {}
    | --------------------------------- required by `generic_function`
diff --git a/src/test/ui/try-operator-on-main.rs b/src/test/ui/try-operator-on-main.rs
index 3b48194eb44fd..3372fac5707bd 100644
--- a/src/test/ui/try-operator-on-main.rs
+++ b/src/test/ui/try-operator-on-main.rs
@@ -10,6 +10,7 @@ fn main() {
 
     // a non-`Try` type on a non-`Try` fn
     ()?; //~ ERROR the `?` operator can only
+    //~^ ERROR the trait bound `(): std::ops::Try` is not satisfied
 
     // an unrelated use of `Try`
     try_trait_generic::<()>(); //~ ERROR the trait bound
@@ -19,7 +20,8 @@ fn main() {
 
 fn try_trait_generic<T: Try>() -> T {
     // and a non-`Try` object on a `Try` fn.
-    ()?; //~ ERROR the `?` operator can only
+    ()?; //~ ERROR the trait bound `(): std::ops::Try` is not satisfied
+    //~^ ERROR the trait bound `(): std::ops::Try` is not satisfied
 
     loop {}
 }
diff --git a/src/test/ui/try-operator-on-main.stderr b/src/test/ui/try-operator-on-main.stderr
index 6878cd80629bc..07d99c16dbfc2 100644
--- a/src/test/ui/try-operator-on-main.stderr
+++ b/src/test/ui/try-operator-on-main.stderr
@@ -7,17 +7,25 @@ LL |     std::fs::File::open("foo")?;
    = help: the trait `std::ops::Try` is not implemented for `()`
    = note: required by `std::ops::Try::from_error`
 
-error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
   --> $DIR/try-operator-on-main.rs:12:5
    |
 LL |     ()?;
-   |     ^^^ the `?` operator cannot be applied to type `()`
+   |     ^^ the trait `std::ops::Try` is not implemented for `()`
    |
-   = help: the trait `std::ops::Try` is not implemented for `()`
    = note: required by `std::ops::Try::into_result`
 
+error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
+  --> $DIR/try-operator-on-main.rs:12:5
+   |
+LL |     ()?;
+   |     ^^^ cannot use the `?` operator in a function that returns `()`
+   |
+   = help: the trait `std::ops::Try` is not implemented for `()`
+   = note: required by `std::ops::Try::from_error`
+
 error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
-  --> $DIR/try-operator-on-main.rs:15:5
+  --> $DIR/try-operator-on-main.rs:16:5
    |
 LL |     try_trait_generic::<()>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()`
@@ -25,15 +33,20 @@ LL |     try_trait_generic::<()>();
 LL | fn try_trait_generic<T: Try>() -> T {
    | ----------------------------------- required by `try_trait_generic`
 
-error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
-  --> $DIR/try-operator-on-main.rs:22:5
+error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
+  --> $DIR/try-operator-on-main.rs:23:5
    |
 LL |     ()?;
-   |     ^^^ the `?` operator cannot be applied to type `()`
+   |     ^^ the trait `std::ops::Try` is not implemented for `()`
    |
-   = help: the trait `std::ops::Try` is not implemented for `()`
    = note: required by `std::ops::Try::into_result`
 
-error: aborting due to 4 previous errors
+error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
+  --> $DIR/try-operator-on-main.rs:23:5
+   |
+LL |     ()?;
+   |     ^^^ the trait `std::ops::Try` is not implemented for `()`
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type/type-check-defaults.stderr b/src/test/ui/type/type-check-defaults.stderr
index 42cca76451fd1..742a709958fa0 100644
--- a/src/test/ui/type/type-check-defaults.stderr
+++ b/src/test/ui/type/type-check-defaults.stderr
@@ -20,30 +20,30 @@ LL | struct WellFormedNoBounds<Z:?Sized = Foo<i32, i32>>(Z);
    = help: the trait `std::iter::FromIterator<i32>` is not implemented for `i32`
 
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
-  --> $DIR/type-check-defaults.rs:11:1
+  --> $DIR/type-check-defaults.rs:11:17
    |
 LL | struct Bounds<T:Copy=String>(T);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   | |
-   | the trait `std::marker::Copy` is not implemented for `std::string::String`
+   | ----------------^^^^------------
+   | |               |
+   | |               the trait `std::marker::Copy` is not implemented for `std::string::String`
    | required by `Bounds`
 
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
-  --> $DIR/type-check-defaults.rs:14:1
+  --> $DIR/type-check-defaults.rs:14:42
    |
 LL | struct WhereClause<T=String>(T) where T: Copy;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   | |
-   | the trait `std::marker::Copy` is not implemented for `std::string::String`
+   | -----------------------------------------^^^^-
+   | |                                        |
+   | |                                        the trait `std::marker::Copy` is not implemented for `std::string::String`
    | required by `WhereClause`
 
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
-  --> $DIR/type-check-defaults.rs:17:1
+  --> $DIR/type-check-defaults.rs:17:20
    |
 LL | trait TraitBound<T:Copy=String> {}
-   | -------------------------------^^^
-   | |
-   | the trait `std::marker::Copy` is not implemented for `std::string::String`
+   | -------------------^^^^--------
+   | |                  |
+   | |                  the trait `std::marker::Copy` is not implemented for `std::string::String`
    | required by `TraitBound`
 
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
@@ -57,12 +57,12 @@ LL | trait Base<T = String>: Super<T> { }
    = help: consider adding a `where T: std::marker::Copy` bound
 
 error[E0277]: cannot add `u8` to `i32`
-  --> $DIR/type-check-defaults.rs:24:1
+  --> $DIR/type-check-defaults.rs:24:66
    |
 LL | trait ProjectionPred<T:Iterator = IntoIter<i32>> where T::Item : Add<u8> {}
-   | ------------------------------------------------------------------------^^^
-   | |
-   | no implementation for `i32 + u8`
+   | -----------------------------------------------------------------^^^^^^^
+   | |                                                                |
+   | |                                                                no implementation for `i32 + u8`
    | required by `ProjectionPred`
    |
    = help: the trait `std::ops::Add<u8>` is not implemented for `i32`
diff --git a/src/test/ui/typeck/typeck-unsafe-always-share.stderr b/src/test/ui/typeck/typeck-unsafe-always-share.stderr
index 7ed85a14259aa..8b3032b088d0e 100644
--- a/src/test/ui/typeck/typeck-unsafe-always-share.stderr
+++ b/src/test/ui/typeck/typeck-unsafe-always-share.stderr
@@ -1,22 +1,22 @@
 error[E0277]: `std::cell::UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely
-  --> $DIR/typeck-unsafe-always-share.rs:19:5
+  --> $DIR/typeck-unsafe-always-share.rs:19:10
    |
 LL | fn test<T: Sync>(s: T) {}
    | ---------------------- required by `test`
 ...
 LL |     test(us);
-   |     ^^^^ `std::cell::UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely
+   |          ^^ `std::cell::UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::UnsafeCell<MySync<{integer}>>`
 
 error[E0277]: `std::cell::UnsafeCell<NoSync>` cannot be shared between threads safely
-  --> $DIR/typeck-unsafe-always-share.rs:23:5
+  --> $DIR/typeck-unsafe-always-share.rs:23:10
    |
 LL | fn test<T: Sync>(s: T) {}
    | ---------------------- required by `test`
 ...
 LL |     test(uns);
-   |     ^^^^ `std::cell::UnsafeCell<NoSync>` cannot be shared between threads safely
+   |          ^^^ `std::cell::UnsafeCell<NoSync>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::UnsafeCell<NoSync>`
 
@@ -33,13 +33,13 @@ LL |     test(ms);
    = note: required because it appears within the type `MySync<NoSync>`
 
 error[E0277]: `NoSync` cannot be shared between threads safely
-  --> $DIR/typeck-unsafe-always-share.rs:30:5
+  --> $DIR/typeck-unsafe-always-share.rs:30:10
    |
 LL | fn test<T: Sync>(s: T) {}
    | ---------------------- required by `test`
 ...
 LL |     test(NoSync);
-   |     ^^^^ `NoSync` cannot be shared between threads safely
+   |          ^^^^^^ `NoSync` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `NoSync`
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr
index d64e54a548442..d03397e42445c 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr
@@ -1,11 +1,11 @@
 error[E0277]: expected a `std::ops::Fn<(isize,)>` closure, found `S`
-  --> $DIR/unboxed-closures-fnmut-as-fn.rs:28:13
+  --> $DIR/unboxed-closures-fnmut-as-fn.rs:28:21
    |
 LL | fn call_it<F:Fn(isize)->isize>(f: &F, x: isize) -> isize {
    | -------------------------------------------------------- required by `call_it`
 ...
 LL |     let x = call_it(&S, 22);
-   |             ^^^^^^^ expected an `Fn<(isize,)>` closure, found `S`
+   |                     ^^ expected an `Fn<(isize,)>` closure, found `S`
    |
    = help: the trait `std::ops::Fn<(isize,)>` is not implemented for `S`
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
index 3d20b5df1e3f3..bde30729a3ca3 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
@@ -1,55 +1,55 @@
 error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:13
+  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
    | --------------------------------------------------------- required by `call_it`
 ...
 LL |     let x = call_it(&square, 22);
-   |             ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:13
+  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
    | --------------------------------------------------------- required by `call_it`
 ...
 LL |     let x = call_it(&square, 22);
-   |             ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   |                     ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:13
+  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
    | -------------------------------------------------------------------- required by `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
-   |             ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:13
+  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
    | -------------------------------------------------------------------- required by `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
-   |             ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   |                         ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:24:13
+  --> $DIR/unboxed-closures-unsafe-extern-fn.rs:24:26
    |
 LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
    | ----------------------------------------------------------------- required by `call_it_once`
 ...
 LL |     let z = call_it_once(square, 22);
-   |             ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
+   |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> unsafe fn(&'r isize) -> isize {square}`
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
index f435a05e04901..7b393b35f298d 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
@@ -1,55 +1,55 @@
 error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-abi.rs:12:13
+  --> $DIR/unboxed-closures-wrong-abi.rs:12:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
    | --------------------------------------------------------- required by `call_it`
 ...
 LL |     let x = call_it(&square, 22);
-   |             ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-abi.rs:12:13
+  --> $DIR/unboxed-closures-wrong-abi.rs:12:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
    | --------------------------------------------------------- required by `call_it`
 ...
 LL |     let x = call_it(&square, 22);
-   |             ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   |                     ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-abi.rs:18:13
+  --> $DIR/unboxed-closures-wrong-abi.rs:18:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
    | -------------------------------------------------------------------- required by `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
-   |             ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-abi.rs:18:13
+  --> $DIR/unboxed-closures-wrong-abi.rs:18:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
    | -------------------------------------------------------------------- required by `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
-   |             ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   |                         ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-abi.rs:24:13
+  --> $DIR/unboxed-closures-wrong-abi.rs:24:26
    |
 LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
    | ----------------------------------------------------------------- required by `call_it_once`
 ...
 LL |     let z = call_it_once(square, 22);
-   |             ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
+   |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `for<'r> extern "C" fn(&'r isize) -> isize {square}`
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
index efdb2e8efa4e8..68fc0d45b9a8c 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
@@ -1,55 +1,55 @@
 error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:13
+  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
    | --------------------------------------------------------- required by `call_it`
 ...
 LL |     let x = call_it(&square, 22);
-   |             ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
+   |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::Fn<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:13
+  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
    | --------------------------------------------------------- required by `call_it`
 ...
 LL |     let x = call_it(&square, 22);
-   |             ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
+   |                     ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:13
+  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
    | -------------------------------------------------------------------- required by `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
-   |             ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
+   |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
    = help: the trait `for<'r> std::ops::FnMut<(&'r isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:13
+  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
    | -------------------------------------------------------------------- required by `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
-   |             ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
+   |                         ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
 
 error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
-  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:25:13
+  --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:25:26
    |
 LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
    | ----------------------------------------------------------------- required by `call_it_once`
 ...
 LL |     let z = call_it_once(square, 22);
-   |             ^^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
+   |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
    |
    = help: the trait `std::ops::FnOnce<(&isize,)>` is not implemented for `unsafe fn(isize) -> isize {square}`
 
diff --git a/src/test/ui/unsized3.stderr b/src/test/ui/unsized3.stderr
index 9064aa14d429f..f381cacadf9c0 100644
--- a/src/test/ui/unsized3.stderr
+++ b/src/test/ui/unsized3.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the size for values of type `X` cannot be known at compilation time
-  --> $DIR/unsized3.rs:7:5
+  --> $DIR/unsized3.rs:7:13
    |
 LL |     f2::<X>(x);
-   |     ^^^^^^^ doesn't have a size known at compile-time
+   |             ^ doesn't have a size known at compile-time
 ...
 LL | fn f2<X>(x: &X) {
    | --------------- required by `f2`
@@ -12,10 +12,10 @@ LL | fn f2<X>(x: &X) {
    = help: consider adding a `where X: std::marker::Sized` bound
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
-  --> $DIR/unsized3.rs:18:5
+  --> $DIR/unsized3.rs:18:13
    |
 LL |     f4::<X>(x);
-   |     ^^^^^^^ doesn't have a size known at compile-time
+   |             ^ doesn't have a size known at compile-time
 ...
 LL | fn f4<X: T>(x: &X) {
    | ------------------ required by `f4`
@@ -25,13 +25,13 @@ LL | fn f4<X: T>(x: &X) {
    = help: consider adding a `where X: std::marker::Sized` bound
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
-  --> $DIR/unsized3.rs:33:5
+  --> $DIR/unsized3.rs:33:8
    |
 LL | fn f5<Y>(x: &Y) {}
    | --------------- required by `f5`
 ...
 LL |     f5(x1);
-   |     ^^ doesn't have a size known at compile-time
+   |        ^^ doesn't have a size known at compile-time
    |
    = help: within `S<X>`, the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
@@ -39,10 +39,10 @@ LL |     f5(x1);
    = note: required because it appears within the type `S<X>`
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
-  --> $DIR/unsized3.rs:40:5
+  --> $DIR/unsized3.rs:40:8
    |
 LL |     f5(&(*x1, 34));
-   |     ^^ doesn't have a size known at compile-time
+   |        ^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `S<X>`, the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
@@ -64,13 +64,13 @@ LL |     f5(&(32, *x1));
    = note: tuples must have a statically known size to be initialized
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
-  --> $DIR/unsized3.rs:45:5
+  --> $DIR/unsized3.rs:45:8
    |
 LL | fn f5<Y>(x: &Y) {}
    | --------------- required by `f5`
 ...
 LL |     f5(&(32, *x1));
-   |     ^^ doesn't have a size known at compile-time
+   |        ^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: within `({integer}, S<X>)`, the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
diff --git a/src/test/ui/vtable-res-trait-param.stderr b/src/test/ui/vtable-res-trait-param.stderr
index 58a88979b2faf..bff64813268ce 100644
--- a/src/test/ui/vtable-res-trait-param.stderr
+++ b/src/test/ui/vtable-res-trait-param.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `{integer}: TraitA` is not satisfied
-  --> $DIR/vtable-res-trait-param.rs:17:7
+  --> $DIR/vtable-res-trait-param.rs:17:18
    |
 LL |     b.gimme_an_a(y)
-   |       ^^^^^^^^^^ the trait `TraitA` is not implemented for `{integer}`
+   |                  ^ the trait `TraitA` is not implemented for `{integer}`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
index f923c6798829f..118caf8cccec7 100644
--- a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
+++ b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
-  --> $DIR/where-clause-constraints-are-local-for-inherent-impl.rs:13:9
+  --> $DIR/where-clause-constraints-are-local-for-inherent-impl.rs:13:22
    |
 LL | fn require_copy<T: Copy>(x: T) {}
    | ------------------------------ required by `require_copy`
 ...
 LL |         require_copy(self.x);
-   |         ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
+   |                      ^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
 
diff --git a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
index 32736836ef8a3..d1cb4e1cc7d1d 100644
--- a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
+++ b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
-  --> $DIR/where-clause-constraints-are-local-for-trait-impl.rs:18:9
+  --> $DIR/where-clause-constraints-are-local-for-trait-impl.rs:18:22
    |
 LL | fn require_copy<T: Copy>(x: T) {}
    | ------------------------------ required by `require_copy`
 ...
 LL |         require_copy(self.x);
-   |         ^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
+   |                      ^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
    |
    = help: consider adding a `where T: std::marker::Copy` bound
 
diff --git a/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr b/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr
index 60bcba09e976c..6fd38728777e4 100644
--- a/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr
+++ b/src/test/ui/where-clauses/where-clauses-method-unsatisfied.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `Bar: std::cmp::Eq` is not satisfied
-  --> $DIR/where-clauses-method-unsatisfied.rs:18:7
+  --> $DIR/where-clauses-method-unsatisfied.rs:18:14
    |
 LL |     x.equals(&x);
-   |       ^^^^^^ the trait `std::cmp::Eq` is not implemented for `Bar`
+   |              ^^ the trait `std::cmp::Eq` is not implemented for `Bar`
 
 error: aborting due to previous error
 

From fa496c9ded0ca63d34d1402c1b737db908094ea4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 16 Sep 2019 08:49:53 -0700
Subject: [PATCH 898/943] Ignore obligations coming from desugared call spans

---
 src/librustc_typeck/check/mod.rs              |  28 +-
 .../incorrect-syntax-suggestions.rs           |   3 +-
 .../incorrect-syntax-suggestions.stderr       |  75 ++--
 .../disallowed-positions.rs                   |  24 +-
 .../disallowed-positions.stderr               | 319 +++++++-----------
 src/test/ui/try-operator-on-main.rs           |   4 +-
 src/test/ui/try-operator-on-main.stderr       |  31 +-
 7 files changed, 195 insertions(+), 289 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 90489bd8d897d..4db289a1824c8 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3273,21 +3273,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if let Err(
                     mut errors,
                 ) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
-                    for error in &mut errors {
-                        if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
-                            let mut referenced_in = vec![];
-                            for (i, ty) in &final_arg_types {
-                                let ty = self.resolve_vars_if_possible(ty);
-                                info!("final ty {} {:?}", i, ty);
-                                for ty in ty.walk() {
-                                    info!("walk {:?}", ty);
-                                    if ty == predicate.skip_binder().self_ty() {
-                                        referenced_in.push(*i);
+                    if !sp.desugaring_kind().is_some() {
+                        // We *do not* do this for desugared call spans to keep good diagnostics
+                        // involving try.
+                        for error in &mut errors {
+                            if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
+                                let mut referenced_in = vec![];
+                                for (i, ty) in &final_arg_types {
+                                    let ty = self.resolve_vars_if_possible(ty);
+                                    for ty in ty.walk() {
+                                        if ty == predicate.skip_binder().self_ty() {
+                                            referenced_in.push(*i);
+                                        }
                                     }
                                 }
-                            }
-                            if referenced_in.len() == 1 {
-                                error.obligation.cause.span = args[referenced_in[0]].span;
+                                if referenced_in.len() == 1 {
+                                    error.obligation.cause.span = args[referenced_in[0]].span;
+                                }
                             }
                         }
                     }
diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
index 13cc5ba1184ee..22bcbb1064dd7 100644
--- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
+++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs
@@ -14,8 +14,7 @@ async fn foo2() -> Result<(), ()> {
 }
 async fn foo3() -> Result<(), ()> {
     let _ = await bar()?; //~ ERROR incorrect use of `await`
-    //~^ ERROR the trait bound `impl std::future::Future: std::ops::Try` is not satisfied
-    //~| ERROR the trait bound `impl std::future::Future: std::ops::Try` is not satisfied
+    //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
     Ok(())
 }
 async fn foo21() -> Result<(), ()> {
diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
index a7ff14f01d4c3..7caa9f26bc2f8 100644
--- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
+++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr
@@ -17,103 +17,103 @@ LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:22:13
+  --> $DIR/incorrect-syntax-suggestions.rs:21:13
    |
 LL |     let _ = await { bar() };
    |             ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:26:13
+  --> $DIR/incorrect-syntax-suggestions.rs:25:13
    |
 LL |     let _ = await(bar());
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `(bar()).await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:30:13
+  --> $DIR/incorrect-syntax-suggestions.rs:29:13
    |
 LL |     let _ = await { bar() }?;
    |             ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:34:14
+  --> $DIR/incorrect-syntax-suggestions.rs:33:14
    |
 LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:38:24
+  --> $DIR/incorrect-syntax-suggestions.rs:37:24
    |
 LL |     let _ = bar().await();
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:42:24
+  --> $DIR/incorrect-syntax-suggestions.rs:41:24
    |
 LL |     let _ = bar().await()?;
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:54:13
+  --> $DIR/incorrect-syntax-suggestions.rs:53:13
    |
 LL |     let _ = await bar();
    |             ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:59:13
+  --> $DIR/incorrect-syntax-suggestions.rs:58:13
    |
 LL |     let _ = await? bar();
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:64:13
+  --> $DIR/incorrect-syntax-suggestions.rs:63:13
    |
 LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:69:14
+  --> $DIR/incorrect-syntax-suggestions.rs:68:14
    |
 LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:74:24
+  --> $DIR/incorrect-syntax-suggestions.rs:73:24
    |
 LL |     let _ = bar().await();
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:79:24
+  --> $DIR/incorrect-syntax-suggestions.rs:78:24
    |
 LL |     let _ = bar().await()?;
    |                        ^^ help: `await` is not a method call, remove the parentheses
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:107:13
+  --> $DIR/incorrect-syntax-suggestions.rs:106:13
    |
 LL |     let _ = await!(bar());
    |             ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:111:13
+  --> $DIR/incorrect-syntax-suggestions.rs:110:13
    |
 LL |     let _ = await!(bar())?;
    |             ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:116:17
+  --> $DIR/incorrect-syntax-suggestions.rs:115:17
    |
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:124:17
+  --> $DIR/incorrect-syntax-suggestions.rs:123:17
    |
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await`
 
 error: expected expression, found `=>`
-  --> $DIR/incorrect-syntax-suggestions.rs:132:25
+  --> $DIR/incorrect-syntax-suggestions.rs:131:25
    |
 LL |     match await { await => () }
    |                   ----- ^^ expected expression
@@ -121,13 +121,13 @@ LL |     match await { await => () }
    |                   while parsing this incorrect await expression
 
 error: incorrect use of `await`
-  --> $DIR/incorrect-syntax-suggestions.rs:132:11
+  --> $DIR/incorrect-syntax-suggestions.rs:131:11
    |
 LL |     match await { await => () }
    |           ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await`
 
 error: expected one of `.`, `?`, `{`, or an operator, found `}`
-  --> $DIR/incorrect-syntax-suggestions.rs:135:1
+  --> $DIR/incorrect-syntax-suggestions.rs:134:1
    |
 LL |     match await { await => () }
    |     -----                      - expected one of `.`, `?`, `{`, or an operator here
@@ -138,7 +138,7 @@ LL | }
    | ^ unexpected token
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:54:13
+  --> $DIR/incorrect-syntax-suggestions.rs:53:13
    |
 LL | fn foo9() -> Result<(), ()> {
    |    ---- this is not `async`
@@ -146,7 +146,7 @@ LL |     let _ = await bar();
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:59:13
+  --> $DIR/incorrect-syntax-suggestions.rs:58:13
    |
 LL | fn foo10() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -154,7 +154,7 @@ LL |     let _ = await? bar();
    |             ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:64:13
+  --> $DIR/incorrect-syntax-suggestions.rs:63:13
    |
 LL | fn foo11() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -162,7 +162,7 @@ LL |     let _ = await bar()?;
    |             ^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:69:14
+  --> $DIR/incorrect-syntax-suggestions.rs:68:14
    |
 LL | fn foo12() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -170,7 +170,7 @@ LL |     let _ = (await bar())?;
    |              ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:74:13
+  --> $DIR/incorrect-syntax-suggestions.rs:73:13
    |
 LL | fn foo13() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -178,7 +178,7 @@ LL |     let _ = bar().await();
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:79:13
+  --> $DIR/incorrect-syntax-suggestions.rs:78:13
    |
 LL | fn foo14() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -186,7 +186,7 @@ LL |     let _ = bar().await()?;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:84:13
+  --> $DIR/incorrect-syntax-suggestions.rs:83:13
    |
 LL | fn foo15() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -194,7 +194,7 @@ LL |     let _ = bar().await;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:88:13
+  --> $DIR/incorrect-syntax-suggestions.rs:87:13
    |
 LL | fn foo16() -> Result<(), ()> {
    |    ----- this is not `async`
@@ -202,7 +202,7 @@ LL |     let _ = bar().await?;
    |             ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:93:17
+  --> $DIR/incorrect-syntax-suggestions.rs:92:17
    |
 LL |     fn foo() -> Result<(), ()> {
    |        --- this is not `async`
@@ -210,7 +210,7 @@ LL |         let _ = bar().await?;
    |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:100:17
+  --> $DIR/incorrect-syntax-suggestions.rs:99:17
    |
 LL |     let foo = || {
    |               -- this is not `async`
@@ -218,7 +218,7 @@ LL |         let _ = bar().await?;
    |                 ^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:116:17
+  --> $DIR/incorrect-syntax-suggestions.rs:115:17
    |
 LL |     fn foo() -> Result<(), ()> {
    |        --- this is not `async`
@@ -226,27 +226,22 @@ LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/incorrect-syntax-suggestions.rs:124:17
+  --> $DIR/incorrect-syntax-suggestions.rs:123:17
    |
 LL |     let foo = || {
    |               -- this is not `async`
 LL |         let _ = await!(bar())?;
    |                 ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
-error[E0277]: the trait bound `impl std::future::Future: std::ops::Try` is not satisfied
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
   --> $DIR/incorrect-syntax-suggestions.rs:16:19
    |
 LL |     let _ = await bar()?;
-   |                   ^^^^^ the trait `std::ops::Try` is not implemented for `impl std::future::Future`
+   |                   ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future`
    |
+   = help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
    = note: required by `std::ops::Try::into_result`
 
-error[E0277]: the trait bound `impl std::future::Future: std::ops::Try` is not satisfied
-  --> $DIR/incorrect-syntax-suggestions.rs:16:19
-   |
-LL |     let _ = await bar()?;
-   |                   ^^^^^^ the trait `std::ops::Try` is not implemented for `impl std::future::Future`
-
-error: aborting due to 36 previous errors
+error: aborting due to 35 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
index a856420c347b5..7d1e5c3d64df3 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs
@@ -40,14 +40,12 @@ fn nested_within_if_expr() {
 
     fn _check_try_binds_tighter() -> Result<(), ()> {
         if let 0 = 0? {}
-        //~^ ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
-        //~| ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
+        //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
         Ok(())
     }
     if (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
-    //~^ ERROR the trait bound `bool: std::ops::Try` is not satisfied
-    //~| ERROR the trait bound `bool: std::ops::Try` is not satisfied
-    //~| ERROR the `?` operator can only be used in a function that returns `Result` or `Option`
+    //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
+    //~| ERROR the `?` operator can only be used in a function that returns `Result`
 
     if true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
     if (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
@@ -106,14 +104,12 @@ fn nested_within_while_expr() {
 
     fn _check_try_binds_tighter() -> Result<(), ()> {
         while let 0 = 0? {}
-        //~^ ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
-        //~| ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
+        //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
         Ok(())
     }
     while (let 0 = 0)? {} //~ ERROR `let` expressions are not supported here
-    //~^ ERROR the trait bound `bool: std::ops::Try` is not satisfied
-    //~| ERROR the trait bound `bool: std::ops::Try` is not satisfied
-    //~| ERROR the `?` operator can only be used in a function that returns `Result` or `Option`
+    //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
+    //~| ERROR the `?` operator can only be used in a function that returns `Result`
 
     while true || let 0 = 0 {} //~ ERROR `let` expressions are not supported here
     while (true || let 0 = 0) {} //~ ERROR `let` expressions are not supported here
@@ -181,14 +177,12 @@ fn outside_if_and_while_expr() {
 
     fn _check_try_binds_tighter() -> Result<(), ()> {
         let 0 = 0?;
-        //~^ ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
-        //~| ERROR the trait bound `{integer}: std::ops::Try` is not satisfied
+        //~^ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
         Ok(())
     }
     (let 0 = 0)?; //~ ERROR `let` expressions are not supported here
-    //~^ ERROR the trait bound `bool: std::ops::Try` is not satisfied
-    //~| ERROR the trait bound `bool: std::ops::Try` is not satisfied
-    //~| ERROR the `?` operator can only be used in a function that returns `Result` or `Option`
+    //~^ ERROR the `?` operator can only be used in a function that returns `Result`
+    //~| ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
 
     true || let 0 = 0; //~ ERROR `let` expressions are not supported here
     (true || let 0 = 0); //~ ERROR `let` expressions are not supported here
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index e06d81923f1ad..4edc00efc7e72 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -1,5 +1,5 @@
 error: expected one of `,` or `>`, found `&&`
-  --> $DIR/disallowed-positions.rs:248:14
+  --> $DIR/disallowed-positions.rs:242:14
    |
 LL |         true && let 1 = 1
    |              ^^ expected one of `,` or `>` here
@@ -41,7 +41,7 @@ LL |     if -let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:47:9
+  --> $DIR/disallowed-positions.rs:46:9
    |
 LL |     if (let 0 = 0)? {}
    |         ^^^^^^^^^
@@ -50,7 +50,7 @@ LL |     if (let 0 = 0)? {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:52:16
+  --> $DIR/disallowed-positions.rs:50:16
    |
 LL |     if true || let 0 = 0 {}
    |                ^^^^^^^^^
@@ -59,7 +59,7 @@ LL |     if true || let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:53:17
+  --> $DIR/disallowed-positions.rs:51:17
    |
 LL |     if (true || let 0 = 0) {}
    |                 ^^^^^^^^^
@@ -68,7 +68,7 @@ LL |     if (true || let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:54:25
+  --> $DIR/disallowed-positions.rs:52:25
    |
 LL |     if true && (true || let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -77,7 +77,7 @@ LL |     if true && (true || let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:55:25
+  --> $DIR/disallowed-positions.rs:53:25
    |
 LL |     if true || (true && let 0 = 0) {}
    |                         ^^^^^^^^^
@@ -86,7 +86,7 @@ LL |     if true || (true && let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:58:12
+  --> $DIR/disallowed-positions.rs:56:12
    |
 LL |     if x = let 0 = 0 {}
    |            ^^^^^^^^^
@@ -95,7 +95,7 @@ LL |     if x = let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:61:15
+  --> $DIR/disallowed-positions.rs:59:15
    |
 LL |     if true..(let 0 = 0) {}
    |               ^^^^^^^^^
@@ -104,7 +104,7 @@ LL |     if true..(let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:63:11
+  --> $DIR/disallowed-positions.rs:61:11
    |
 LL |     if ..(let 0 = 0) {}
    |           ^^^^^^^^^
@@ -113,7 +113,7 @@ LL |     if ..(let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:65:9
+  --> $DIR/disallowed-positions.rs:63:9
    |
 LL |     if (let 0 = 0).. {}
    |         ^^^^^^^^^
@@ -122,7 +122,7 @@ LL |     if (let 0 = 0).. {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:69:8
+  --> $DIR/disallowed-positions.rs:67:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -131,7 +131,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:73:8
+  --> $DIR/disallowed-positions.rs:71:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -140,7 +140,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:80:8
+  --> $DIR/disallowed-positions.rs:78:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -149,7 +149,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:88:8
+  --> $DIR/disallowed-positions.rs:86:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -158,7 +158,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:94:19
+  --> $DIR/disallowed-positions.rs:92:19
    |
 LL |     if let true = let true = true {}
    |                   ^^^^^^^^^^^^^^^
@@ -167,7 +167,7 @@ LL |     if let true = let true = true {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:98:12
+  --> $DIR/disallowed-positions.rs:96:12
    |
 LL |     while &let 0 = 0 {}
    |            ^^^^^^^^^
@@ -176,7 +176,7 @@ LL |     while &let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:101:12
+  --> $DIR/disallowed-positions.rs:99:12
    |
 LL |     while !let 0 = 0 {}
    |            ^^^^^^^^^
@@ -185,7 +185,7 @@ LL |     while !let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:102:12
+  --> $DIR/disallowed-positions.rs:100:12
    |
 LL |     while *let 0 = 0 {}
    |            ^^^^^^^^^
@@ -194,7 +194,7 @@ LL |     while *let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:104:12
+  --> $DIR/disallowed-positions.rs:102:12
    |
 LL |     while -let 0 = 0 {}
    |            ^^^^^^^^^
@@ -203,7 +203,7 @@ LL |     while -let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:113:12
+  --> $DIR/disallowed-positions.rs:110:12
    |
 LL |     while (let 0 = 0)? {}
    |            ^^^^^^^^^
@@ -212,7 +212,7 @@ LL |     while (let 0 = 0)? {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:118:19
+  --> $DIR/disallowed-positions.rs:114:19
    |
 LL |     while true || let 0 = 0 {}
    |                   ^^^^^^^^^
@@ -221,7 +221,7 @@ LL |     while true || let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:119:20
+  --> $DIR/disallowed-positions.rs:115:20
    |
 LL |     while (true || let 0 = 0) {}
    |                    ^^^^^^^^^
@@ -230,7 +230,7 @@ LL |     while (true || let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:120:28
+  --> $DIR/disallowed-positions.rs:116:28
    |
 LL |     while true && (true || let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -239,7 +239,7 @@ LL |     while true && (true || let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:121:28
+  --> $DIR/disallowed-positions.rs:117:28
    |
 LL |     while true || (true && let 0 = 0) {}
    |                            ^^^^^^^^^
@@ -248,7 +248,7 @@ LL |     while true || (true && let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:124:15
+  --> $DIR/disallowed-positions.rs:120:15
    |
 LL |     while x = let 0 = 0 {}
    |               ^^^^^^^^^
@@ -257,7 +257,7 @@ LL |     while x = let 0 = 0 {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:127:18
+  --> $DIR/disallowed-positions.rs:123:18
    |
 LL |     while true..(let 0 = 0) {}
    |                  ^^^^^^^^^
@@ -266,7 +266,7 @@ LL |     while true..(let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:129:14
+  --> $DIR/disallowed-positions.rs:125:14
    |
 LL |     while ..(let 0 = 0) {}
    |              ^^^^^^^^^
@@ -275,7 +275,7 @@ LL |     while ..(let 0 = 0) {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:131:12
+  --> $DIR/disallowed-positions.rs:127:12
    |
 LL |     while (let 0 = 0).. {}
    |            ^^^^^^^^^
@@ -284,7 +284,7 @@ LL |     while (let 0 = 0).. {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:135:11
+  --> $DIR/disallowed-positions.rs:131:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -293,7 +293,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:139:11
+  --> $DIR/disallowed-positions.rs:135:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -302,7 +302,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:146:11
+  --> $DIR/disallowed-positions.rs:142:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -311,7 +311,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:154:11
+  --> $DIR/disallowed-positions.rs:150:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -320,7 +320,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:160:22
+  --> $DIR/disallowed-positions.rs:156:22
    |
 LL |     while let true = let true = true {}
    |                      ^^^^^^^^^^^^^^^
@@ -329,7 +329,7 @@ LL |     while let true = let true = true {}
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:174:6
+  --> $DIR/disallowed-positions.rs:170:6
    |
 LL |     &let 0 = 0;
    |      ^^^^^^^^^
@@ -338,7 +338,7 @@ LL |     &let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:176:6
+  --> $DIR/disallowed-positions.rs:172:6
    |
 LL |     !let 0 = 0;
    |      ^^^^^^^^^
@@ -347,7 +347,7 @@ LL |     !let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:177:6
+  --> $DIR/disallowed-positions.rs:173:6
    |
 LL |     *let 0 = 0;
    |      ^^^^^^^^^
@@ -356,7 +356,7 @@ LL |     *let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:179:6
+  --> $DIR/disallowed-positions.rs:175:6
    |
 LL |     -let 0 = 0;
    |      ^^^^^^^^^
@@ -365,7 +365,7 @@ LL |     -let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:188:6
+  --> $DIR/disallowed-positions.rs:183:6
    |
 LL |     (let 0 = 0)?;
    |      ^^^^^^^^^
@@ -374,7 +374,7 @@ LL |     (let 0 = 0)?;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:193:13
+  --> $DIR/disallowed-positions.rs:187:13
    |
 LL |     true || let 0 = 0;
    |             ^^^^^^^^^
@@ -383,7 +383,7 @@ LL |     true || let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:194:14
+  --> $DIR/disallowed-positions.rs:188:14
    |
 LL |     (true || let 0 = 0);
    |              ^^^^^^^^^
@@ -392,7 +392,7 @@ LL |     (true || let 0 = 0);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:195:22
+  --> $DIR/disallowed-positions.rs:189:22
    |
 LL |     true && (true || let 0 = 0);
    |                      ^^^^^^^^^
@@ -401,7 +401,7 @@ LL |     true && (true || let 0 = 0);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:198:9
+  --> $DIR/disallowed-positions.rs:192:9
    |
 LL |     x = let 0 = 0;
    |         ^^^^^^^^^
@@ -410,7 +410,7 @@ LL |     x = let 0 = 0;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:200:12
+  --> $DIR/disallowed-positions.rs:194:12
    |
 LL |     true..(let 0 = 0);
    |            ^^^^^^^^^
@@ -419,7 +419,7 @@ LL |     true..(let 0 = 0);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:201:8
+  --> $DIR/disallowed-positions.rs:195:8
    |
 LL |     ..(let 0 = 0);
    |        ^^^^^^^^^
@@ -428,7 +428,7 @@ LL |     ..(let 0 = 0);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:202:6
+  --> $DIR/disallowed-positions.rs:196:6
    |
 LL |     (let 0 = 0)..;
    |      ^^^^^^^^^
@@ -437,7 +437,7 @@ LL |     (let 0 = 0)..;
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:204:6
+  --> $DIR/disallowed-positions.rs:198:6
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -446,7 +446,7 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:208:6
+  --> $DIR/disallowed-positions.rs:202:6
    |
 LL |     (let true = let true = true);
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -455,7 +455,7 @@ LL |     (let true = let true = true);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:208:17
+  --> $DIR/disallowed-positions.rs:202:17
    |
 LL |     (let true = let true = true);
    |                 ^^^^^^^^^^^^^^^
@@ -464,7 +464,7 @@ LL |     (let true = let true = true);
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:213:6
+  --> $DIR/disallowed-positions.rs:207:6
    |
 LL |     &let 0 = 0
    |      ^^^^^^^^^
@@ -473,7 +473,7 @@ LL |     &let 0 = 0
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:224:17
+  --> $DIR/disallowed-positions.rs:218:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -482,7 +482,7 @@ LL |         true && let 1 = 1
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:230:17
+  --> $DIR/disallowed-positions.rs:224:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -491,7 +491,7 @@ LL |         true && let 1 = 1
    = note: as well as when nested within `&&` and parenthesis in those conditions
 
 error: `let` expressions are not supported here
-  --> $DIR/disallowed-positions.rs:236:17
+  --> $DIR/disallowed-positions.rs:230:17
    |
 LL |         true && let 1 = 1
    |                 ^^^^^^^^^
@@ -536,16 +536,17 @@ LL |     if -let 0 = 0 {}
    |
    = note: an implementation of `std::ops::Neg` might be missing for `bool`
 
-error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
-  --> $DIR/disallowed-positions.rs:47:8
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+  --> $DIR/disallowed-positions.rs:46:8
    |
 LL |     if (let 0 = 0)? {}
-   |        ^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
+   |        ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
    |
+   = help: the trait `std::ops::Try` is not implemented for `bool`
    = note: required by `std::ops::Try::into_result`
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
-  --> $DIR/disallowed-positions.rs:47:8
+  --> $DIR/disallowed-positions.rs:46:8
    |
 LL |     if (let 0 = 0)? {}
    |        ^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
@@ -554,7 +555,7 @@ LL |     if (let 0 = 0)? {}
    = note: required by `std::ops::Try::from_error`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:58:8
+  --> $DIR/disallowed-positions.rs:56:8
    |
 LL |     if x = let 0 = 0 {}
    |        ^^^^^^^^^^^^^
@@ -566,7 +567,7 @@ LL |     if x = let 0 = 0 {}
               found type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:61:8
+  --> $DIR/disallowed-positions.rs:59:8
    |
 LL |     if true..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -575,7 +576,7 @@ LL |     if true..(let 0 = 0) {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:63:8
+  --> $DIR/disallowed-positions.rs:61:8
    |
 LL |     if ..(let 0 = 0) {}
    |        ^^^^^^^^^^^^^ expected bool, found struct `std::ops::RangeTo`
@@ -584,7 +585,7 @@ LL |     if ..(let 0 = 0) {}
               found type `std::ops::RangeTo<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:65:8
+  --> $DIR/disallowed-positions.rs:63:8
    |
 LL |     if (let 0 = 0).. {}
    |        ^^^^^^^^^^^^^ expected bool, found struct `std::ops::RangeFrom`
@@ -593,7 +594,7 @@ LL |     if (let 0 = 0).. {}
               found type `std::ops::RangeFrom<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:69:12
+  --> $DIR/disallowed-positions.rs:67:12
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this match expression has type `bool`
@@ -604,7 +605,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:69:8
+  --> $DIR/disallowed-positions.rs:67:8
    |
 LL |     if let Range { start: _, end: _ } = true..true && false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -613,7 +614,7 @@ LL |     if let Range { start: _, end: _ } = true..true && false {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:73:12
+  --> $DIR/disallowed-positions.rs:71:12
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this match expression has type `bool`
@@ -624,7 +625,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:73:8
+  --> $DIR/disallowed-positions.rs:71:8
    |
 LL |     if let Range { start: _, end: _ } = true..true || false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -633,7 +634,7 @@ LL |     if let Range { start: _, end: _ } = true..true || false {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:80:12
+  --> $DIR/disallowed-positions.rs:78:12
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found struct `std::ops::Range`
@@ -642,16 +643,16 @@ LL |     if let Range { start: F, end } = F..|| true {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:80:41
+  --> $DIR/disallowed-positions.rs:78:41
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |                                         ^^^^^^^ expected bool, found closure
    |
    = note: expected type `bool`
-              found type `[closure@$DIR/disallowed-positions.rs:80:41: 80:48]`
+              found type `[closure@$DIR/disallowed-positions.rs:78:41: 78:48]`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:80:8
+  --> $DIR/disallowed-positions.rs:78:8
    |
 LL |     if let Range { start: F, end } = F..|| true {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -660,7 +661,7 @@ LL |     if let Range { start: F, end } = F..|| true {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:88:12
+  --> $DIR/disallowed-positions.rs:86:12
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this match expression has type `bool`
@@ -671,7 +672,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:88:44
+  --> $DIR/disallowed-positions.rs:86:44
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |                                            ^^^^^^^ expected bool, found &&bool
@@ -680,7 +681,7 @@ LL |     if let Range { start: true, end } = t..&&false {}
               found type `&&bool`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:88:8
+  --> $DIR/disallowed-positions.rs:86:8
    |
 LL |     if let Range { start: true, end } = t..&&false {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -688,41 +689,17 @@ LL |     if let Range { start: true, end } = t..&&false {}
    = note: expected type `bool`
               found type `std::ops::Range<bool>`
 
-error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
-  --> $DIR/disallowed-positions.rs:47:8
-   |
-LL |     if (let 0 = 0)? {}
-   |        ^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
-
-error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
-  --> $DIR/disallowed-positions.rs:42:20
-   |
-LL |         if let 0 = 0? {}
-   |                    ^ the trait `std::ops::Try` is not implemented for `{integer}`
-   |
-   = help: the following implementations were found:
-             <std::iter::LoopState<C, B> as std::ops::Try>
-             <std::option::Option<T> as std::ops::Try>
-             <std::result::Result<T, E> as std::ops::Try>
-             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
-             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
-   = note: required by `std::ops::Try::into_result`
-
-error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
   --> $DIR/disallowed-positions.rs:42:20
    |
 LL |         if let 0 = 0? {}
-   |                    ^^ the trait `std::ops::Try` is not implemented for `{integer}`
+   |                    ^^ the `?` operator cannot be applied to type `{integer}`
    |
-   = help: the following implementations were found:
-             <std::iter::LoopState<C, B> as std::ops::Try>
-             <std::option::Option<T> as std::ops::Try>
-             <std::result::Result<T, E> as std::ops::Try>
-             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
-             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
+   = help: the trait `std::ops::Try` is not implemented for `{integer}`
+   = note: required by `std::ops::Try::into_result`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:98:11
+  --> $DIR/disallowed-positions.rs:96:11
    |
 LL |     while &let 0 = 0 {}
    |           ^^^^^^^^^^ expected bool, found &bool
@@ -731,29 +708,30 @@ LL |     while &let 0 = 0 {}
               found type `&bool`
 
 error[E0614]: type `bool` cannot be dereferenced
-  --> $DIR/disallowed-positions.rs:102:11
+  --> $DIR/disallowed-positions.rs:100:11
    |
 LL |     while *let 0 = 0 {}
    |           ^^^^^^^^^^
 
 error[E0600]: cannot apply unary operator `-` to type `bool`
-  --> $DIR/disallowed-positions.rs:104:11
+  --> $DIR/disallowed-positions.rs:102:11
    |
 LL |     while -let 0 = 0 {}
    |           ^^^^^^^^^^ cannot apply unary operator `-`
    |
    = note: an implementation of `std::ops::Neg` might be missing for `bool`
 
-error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
-  --> $DIR/disallowed-positions.rs:113:11
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+  --> $DIR/disallowed-positions.rs:110:11
    |
 LL |     while (let 0 = 0)? {}
-   |           ^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
+   |           ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
    |
+   = help: the trait `std::ops::Try` is not implemented for `bool`
    = note: required by `std::ops::Try::into_result`
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
-  --> $DIR/disallowed-positions.rs:113:11
+  --> $DIR/disallowed-positions.rs:110:11
    |
 LL |     while (let 0 = 0)? {}
    |           ^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
@@ -762,7 +740,7 @@ LL |     while (let 0 = 0)? {}
    = note: required by `std::ops::Try::from_error`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:124:11
+  --> $DIR/disallowed-positions.rs:120:11
    |
 LL |     while x = let 0 = 0 {}
    |           ^^^^^^^^^^^^^
@@ -774,7 +752,7 @@ LL |     while x = let 0 = 0 {}
               found type `()`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:127:11
+  --> $DIR/disallowed-positions.rs:123:11
    |
 LL |     while true..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -783,7 +761,7 @@ LL |     while true..(let 0 = 0) {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:129:11
+  --> $DIR/disallowed-positions.rs:125:11
    |
 LL |     while ..(let 0 = 0) {}
    |           ^^^^^^^^^^^^^ expected bool, found struct `std::ops::RangeTo`
@@ -792,7 +770,7 @@ LL |     while ..(let 0 = 0) {}
               found type `std::ops::RangeTo<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:131:11
+  --> $DIR/disallowed-positions.rs:127:11
    |
 LL |     while (let 0 = 0).. {}
    |           ^^^^^^^^^^^^^ expected bool, found struct `std::ops::RangeFrom`
@@ -801,7 +779,7 @@ LL |     while (let 0 = 0).. {}
               found type `std::ops::RangeFrom<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:135:15
+  --> $DIR/disallowed-positions.rs:131:15
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this match expression has type `bool`
@@ -812,7 +790,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:135:11
+  --> $DIR/disallowed-positions.rs:131:11
    |
 LL |     while let Range { start: _, end: _ } = true..true && false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -821,7 +799,7 @@ LL |     while let Range { start: _, end: _ } = true..true && false {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:139:15
+  --> $DIR/disallowed-positions.rs:135:15
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this match expression has type `bool`
@@ -832,7 +810,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:139:11
+  --> $DIR/disallowed-positions.rs:135:11
    |
 LL |     while let Range { start: _, end: _ } = true..true || false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -841,7 +819,7 @@ LL |     while let Range { start: _, end: _ } = true..true || false {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:146:15
+  --> $DIR/disallowed-positions.rs:142:15
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found struct `std::ops::Range`
@@ -850,16 +828,16 @@ LL |     while let Range { start: F, end } = F..|| true {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:146:44
+  --> $DIR/disallowed-positions.rs:142:44
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |                                            ^^^^^^^ expected bool, found closure
    |
    = note: expected type `bool`
-              found type `[closure@$DIR/disallowed-positions.rs:146:44: 146:51]`
+              found type `[closure@$DIR/disallowed-positions.rs:142:44: 142:51]`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:146:11
+  --> $DIR/disallowed-positions.rs:142:11
    |
 LL |     while let Range { start: F, end } = F..|| true {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -868,7 +846,7 @@ LL |     while let Range { start: F, end } = F..|| true {}
               found type `std::ops::Range<bool>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:154:15
+  --> $DIR/disallowed-positions.rs:150:15
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^   - this match expression has type `bool`
@@ -879,7 +857,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:154:47
+  --> $DIR/disallowed-positions.rs:150:47
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |                                               ^^^^^^^ expected bool, found &&bool
@@ -888,7 +866,7 @@ LL |     while let Range { start: true, end } = t..&&false {}
               found type `&&bool`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:154:11
+  --> $DIR/disallowed-positions.rs:150:11
    |
 LL |     while let Range { start: true, end } = t..&&false {}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected bool, found struct `std::ops::Range`
@@ -896,63 +874,40 @@ LL |     while let Range { start: true, end } = t..&&false {}
    = note: expected type `bool`
               found type `std::ops::Range<bool>`
 
-error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
-  --> $DIR/disallowed-positions.rs:113:11
-   |
-LL |     while (let 0 = 0)? {}
-   |           ^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
-
-error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
-  --> $DIR/disallowed-positions.rs:108:23
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+  --> $DIR/disallowed-positions.rs:106:23
    |
 LL |         while let 0 = 0? {}
-   |                       ^ the trait `std::ops::Try` is not implemented for `{integer}`
-   |
-   = help: the following implementations were found:
-             <std::iter::LoopState<C, B> as std::ops::Try>
-             <std::option::Option<T> as std::ops::Try>
-             <std::result::Result<T, E> as std::ops::Try>
-             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
-             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
-   = note: required by `std::ops::Try::into_result`
-
-error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
-  --> $DIR/disallowed-positions.rs:108:23
-   |
-LL |         while let 0 = 0? {}
-   |                       ^^ the trait `std::ops::Try` is not implemented for `{integer}`
+   |                       ^^ the `?` operator cannot be applied to type `{integer}`
    |
-   = help: the following implementations were found:
-             <std::iter::LoopState<C, B> as std::ops::Try>
-             <std::option::Option<T> as std::ops::Try>
-             <std::result::Result<T, E> as std::ops::Try>
-             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
-             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
+   = help: the trait `std::ops::Try` is not implemented for `{integer}`
+   = note: required by `std::ops::Try::into_result`
 
 error[E0614]: type `bool` cannot be dereferenced
-  --> $DIR/disallowed-positions.rs:177:5
+  --> $DIR/disallowed-positions.rs:173:5
    |
 LL |     *let 0 = 0;
    |     ^^^^^^^^^^
 
 error[E0600]: cannot apply unary operator `-` to type `bool`
-  --> $DIR/disallowed-positions.rs:179:5
+  --> $DIR/disallowed-positions.rs:175:5
    |
 LL |     -let 0 = 0;
    |     ^^^^^^^^^^ cannot apply unary operator `-`
    |
    = note: an implementation of `std::ops::Neg` might be missing for `bool`
 
-error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
-  --> $DIR/disallowed-positions.rs:188:5
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+  --> $DIR/disallowed-positions.rs:183:5
    |
 LL |     (let 0 = 0)?;
-   |     ^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
+   |     ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool`
    |
+   = help: the trait `std::ops::Try` is not implemented for `bool`
    = note: required by `std::ops::Try::into_result`
 
 error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
-  --> $DIR/disallowed-positions.rs:188:5
+  --> $DIR/disallowed-positions.rs:183:5
    |
 LL |     (let 0 = 0)?;
    |     ^^^^^^^^^^^^ cannot use the `?` operator in a function that returns `()`
@@ -961,7 +916,7 @@ LL |     (let 0 = 0)?;
    = note: required by `std::ops::Try::from_error`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:204:10
+  --> $DIR/disallowed-positions.rs:198:10
    |
 LL |     (let Range { start: _, end: _ } = true..true || false);
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^   ---- this match expression has type `bool`
@@ -972,7 +927,7 @@ LL |     (let Range { start: _, end: _ } = true..true || false);
               found type `std::ops::Range<_>`
 
 error[E0308]: mismatched types
-  --> $DIR/disallowed-positions.rs:213:5
+  --> $DIR/disallowed-positions.rs:207:5
    |
 LL | fn outside_if_and_while_expr() {
    |                                - help: try adding a return type: `-> &bool`
@@ -983,76 +938,52 @@ LL |     &let 0 = 0
    = note: expected type `()`
               found type `&bool`
 
-error[E0277]: the trait bound `bool: std::ops::Try` is not satisfied
-  --> $DIR/disallowed-positions.rs:188:5
-   |
-LL |     (let 0 = 0)?;
-   |     ^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `bool`
-
-error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
-  --> $DIR/disallowed-positions.rs:183:17
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+  --> $DIR/disallowed-positions.rs:179:17
    |
 LL |         let 0 = 0?;
-   |                 ^ the trait `std::ops::Try` is not implemented for `{integer}`
-   |
-   = help: the following implementations were found:
-             <std::iter::LoopState<C, B> as std::ops::Try>
-             <std::option::Option<T> as std::ops::Try>
-             <std::result::Result<T, E> as std::ops::Try>
-             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
-             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
-   = note: required by `std::ops::Try::into_result`
-
-error[E0277]: the trait bound `{integer}: std::ops::Try` is not satisfied
-  --> $DIR/disallowed-positions.rs:183:17
+   |                 ^^ the `?` operator cannot be applied to type `{integer}`
    |
-LL |         let 0 = 0?;
-   |                 ^^ the trait `std::ops::Try` is not implemented for `{integer}`
-   |
-   = help: the following implementations were found:
-             <std::iter::LoopState<C, B> as std::ops::Try>
-             <std::option::Option<T> as std::ops::Try>
-             <std::result::Result<T, E> as std::ops::Try>
-             <std::task::Poll<std::option::Option<std::result::Result<T, E>>> as std::ops::Try>
-             <std::task::Poll<std::result::Result<T, E>> as std::ops::Try>
+   = help: the trait `std::ops::Try` is not implemented for `{integer}`
+   = note: required by `std::ops::Try::into_result`
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:224:25
+  --> $DIR/disallowed-positions.rs:218:25
    |
 LL |         true && let 1 = 1
    |                         ^
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:224:21
+  --> $DIR/disallowed-positions.rs:218:21
    |
 LL |         true && let 1 = 1
    |                     ^
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:230:25
+  --> $DIR/disallowed-positions.rs:224:25
    |
 LL |         true && let 1 = 1
    |                         ^
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:230:21
+  --> $DIR/disallowed-positions.rs:224:21
    |
 LL |         true && let 1 = 1
    |                     ^
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:236:25
+  --> $DIR/disallowed-positions.rs:230:25
    |
 LL |         true && let 1 = 1
    |                         ^
 
 error[E0019]: constant contains unimplemented expression type
-  --> $DIR/disallowed-positions.rs:236:21
+  --> $DIR/disallowed-positions.rs:230:21
    |
 LL |         true && let 1 = 1
    |                     ^
 
-error: aborting due to 115 previous errors
+error: aborting due to 109 previous errors
 
 Some errors have detailed explanations: E0019, E0277, E0308, E0600, E0614.
 For more information about an error, try `rustc --explain E0019`.
diff --git a/src/test/ui/try-operator-on-main.rs b/src/test/ui/try-operator-on-main.rs
index 3372fac5707bd..602c3c5c3593b 100644
--- a/src/test/ui/try-operator-on-main.rs
+++ b/src/test/ui/try-operator-on-main.rs
@@ -10,7 +10,6 @@ fn main() {
 
     // a non-`Try` type on a non-`Try` fn
     ()?; //~ ERROR the `?` operator can only
-    //~^ ERROR the trait bound `(): std::ops::Try` is not satisfied
 
     // an unrelated use of `Try`
     try_trait_generic::<()>(); //~ ERROR the trait bound
@@ -20,8 +19,7 @@ fn main() {
 
 fn try_trait_generic<T: Try>() -> T {
     // and a non-`Try` object on a `Try` fn.
-    ()?; //~ ERROR the trait bound `(): std::ops::Try` is not satisfied
-    //~^ ERROR the trait bound `(): std::ops::Try` is not satisfied
+    ()?; //~ ERROR the `?` operator can only be applied to values that implement `std::ops::Try`
 
     loop {}
 }
diff --git a/src/test/ui/try-operator-on-main.stderr b/src/test/ui/try-operator-on-main.stderr
index 07d99c16dbfc2..6878cd80629bc 100644
--- a/src/test/ui/try-operator-on-main.stderr
+++ b/src/test/ui/try-operator-on-main.stderr
@@ -7,25 +7,17 @@ LL |     std::fs::File::open("foo")?;
    = help: the trait `std::ops::Try` is not implemented for `()`
    = note: required by `std::ops::Try::from_error`
 
-error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
-  --> $DIR/try-operator-on-main.rs:12:5
-   |
-LL |     ()?;
-   |     ^^ the trait `std::ops::Try` is not implemented for `()`
-   |
-   = note: required by `std::ops::Try::into_result`
-
-error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
   --> $DIR/try-operator-on-main.rs:12:5
    |
 LL |     ()?;
-   |     ^^^ cannot use the `?` operator in a function that returns `()`
+   |     ^^^ the `?` operator cannot be applied to type `()`
    |
    = help: the trait `std::ops::Try` is not implemented for `()`
-   = note: required by `std::ops::Try::from_error`
+   = note: required by `std::ops::Try::into_result`
 
 error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
-  --> $DIR/try-operator-on-main.rs:16:5
+  --> $DIR/try-operator-on-main.rs:15:5
    |
 LL |     try_trait_generic::<()>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()`
@@ -33,20 +25,15 @@ LL |     try_trait_generic::<()>();
 LL | fn try_trait_generic<T: Try>() -> T {
    | ----------------------------------- required by `try_trait_generic`
 
-error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
-  --> $DIR/try-operator-on-main.rs:23:5
+error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
+  --> $DIR/try-operator-on-main.rs:22:5
    |
 LL |     ()?;
-   |     ^^ the trait `std::ops::Try` is not implemented for `()`
+   |     ^^^ the `?` operator cannot be applied to type `()`
    |
+   = help: the trait `std::ops::Try` is not implemented for `()`
    = note: required by `std::ops::Try::into_result`
 
-error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
-  --> $DIR/try-operator-on-main.rs:23:5
-   |
-LL |     ()?;
-   |     ^^^ the trait `std::ops::Try` is not implemented for `()`
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.

From 5976e0eecf8e3f3a9d37f16a902cbb70a23d09c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 16 Sep 2019 10:15:17 -0700
Subject: [PATCH 899/943] Review comment: move to its own method

---
 src/librustc_typeck/check/mod.rs | 55 ++++++++++++++++++++------------
 1 file changed, 35 insertions(+), 20 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 4db289a1824c8..c98f3373d3975 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3273,26 +3273,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if let Err(
                     mut errors,
                 ) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
-                    if !sp.desugaring_kind().is_some() {
-                        // We *do not* do this for desugared call spans to keep good diagnostics
-                        // involving try.
-                        for error in &mut errors {
-                            if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
-                                let mut referenced_in = vec![];
-                                for (i, ty) in &final_arg_types {
-                                    let ty = self.resolve_vars_if_possible(ty);
-                                    for ty in ty.walk() {
-                                        if ty == predicate.skip_binder().self_ty() {
-                                            referenced_in.push(*i);
-                                        }
-                                    }
-                                }
-                                if referenced_in.len() == 1 {
-                                    error.obligation.cause.span = args[referenced_in[0]].span;
-                                }
-                            }
-                        }
-                    }
+                    self.point_at_arg_instead_of_call_if_possible(
+                        &mut errors,
+                        &final_arg_types[..],
+                        sp,
+                        &args,
+                    );
                     self.report_fulfillment_errors(&errors, self.inh.body_id, false);
                 }
             }
@@ -3387,6 +3373,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         vec![self.tcx.types.err; len]
     }
 
+    fn point_at_arg_instead_of_call_if_possible(
+        &self,
+        errors: &mut Vec<traits::FulfillmentError<'_>>,
+        final_arg_types: &[(usize, Ty<'tcx>)],
+        call_sp: Span,
+        args: &'tcx [hir::Expr],
+    ) {
+        if !call_sp.desugaring_kind().is_some() {
+            // We *do not* do this for desugared call spans to keep good diagnostics when involving
+            // the `?` operator.
+            for error in errors {
+                if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
+                    let mut referenced_in = vec![];
+                    for (i, ty) in final_arg_types {
+                        let ty = self.resolve_vars_if_possible(ty);
+                        for ty in ty.walk() {
+                            if ty == predicate.skip_binder().self_ty() {
+                                referenced_in.push(*i);
+                            }
+                        }
+                    }
+                    if referenced_in.len() == 1 {
+                        error.obligation.cause.span = args[referenced_in[0]].span;
+                    }
+                }
+            }
+        }
+    }
+
     // AST fragment checking
     fn check_lit(&self,
                  lit: &hir::Lit,

From 2fbd6927a5116e856aa7085bbcab27e87271bb91 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 16 Sep 2019 15:54:31 -0700
Subject: [PATCH 900/943] When possible, suggest fn call

---
 src/librustc/traits/chalk_fulfill.rs          |  3 +
 src/librustc/traits/error_reporting.rs        | 70 +++++++++++++------
 src/librustc/traits/mod.rs                    |  5 +-
 .../borrow_check/nll/type_check/mod.rs        |  1 +
 src/librustc_typeck/check/coercion.rs         |  2 +-
 src/librustc_typeck/check/mod.rs              |  1 +
 ...rg-where-it-should-have-been-called.stderr |  7 +-
 ...rg-where-it-should-have-been-called.stderr |  7 +-
 8 files changed, 64 insertions(+), 32 deletions(-)

diff --git a/src/librustc/traits/chalk_fulfill.rs b/src/librustc/traits/chalk_fulfill.rs
index 0c7c94b684a9f..a7e1f2a6a73a7 100644
--- a/src/librustc/traits/chalk_fulfill.rs
+++ b/src/librustc/traits/chalk_fulfill.rs
@@ -81,6 +81,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
                 .map(|obligation| FulfillmentError {
                     obligation: obligation.goal.clone(),
                     code: FulfillmentErrorCode::CodeAmbiguity,
+                    points_at_arg_span: false,
                 })
                 .collect();
             Err(errors)
@@ -129,6 +130,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
                                     code: FulfillmentErrorCode::CodeSelectionError(
                                         SelectionError::Unimplemented
                                     ),
+                                    points_at_arg_span: false,
                                 }),
                             }
                         } else {
@@ -142,6 +144,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
                         code: FulfillmentErrorCode::CodeSelectionError(
                             SelectionError::Unimplemented
                         ),
+                        points_at_arg_span: false,
                     })
                 }
             }
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 03cc00d87e3cd..e52451b2fdc4d 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -119,11 +119,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
     // returns if `cond` not occurring implies that `error` does not occur - i.e., that
     // `error` occurring implies that `cond` occurs.
-    fn error_implies(&self,
-                     cond: &ty::Predicate<'tcx>,
-                     error: &ty::Predicate<'tcx>)
-                     -> bool
-    {
+    fn error_implies(
+        &self,
+        cond: &ty::Predicate<'tcx>,
+        error: &ty::Predicate<'tcx>,
+    ) -> bool {
         if cond == error {
             return true
         }
@@ -155,13 +155,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         false
     }
 
-    fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>,
-                                body_id: Option<hir::BodyId>,
-                                fallback_has_occurred: bool) {
+    fn report_fulfillment_error(
+        &self,
+        error: &FulfillmentError<'tcx>,
+        body_id: Option<hir::BodyId>,
+        fallback_has_occurred: bool,
+    ) {
         debug!("report_fulfillment_errors({:?})", error);
         match error.code {
-            FulfillmentErrorCode::CodeSelectionError(ref e) => {
-                self.report_selection_error(&error.obligation, e, fallback_has_occurred);
+            FulfillmentErrorCode::CodeSelectionError(ref selection_error) => {
+                self.report_selection_error(
+                    &error.obligation,
+                    selection_error,
+                    fallback_has_occurred,
+                    error.points_at_arg_span,
+                );
             }
             FulfillmentErrorCode::CodeProjectionError(ref e) => {
                 self.report_projection_error(&error.obligation, e);
@@ -170,19 +178,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 self.maybe_report_ambiguity(&error.obligation, body_id);
             }
             FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => {
-                self.report_mismatched_types(&error.obligation.cause,
-                                             expected_found.expected,
-                                             expected_found.found,
-                                             err.clone())
-                    .emit();
+                self.report_mismatched_types(
+                    &error.obligation.cause,
+                    expected_found.expected,
+                    expected_found.found,
+                    err.clone(),
+                ).emit();
             }
         }
     }
 
-    fn report_projection_error(&self,
-                               obligation: &PredicateObligation<'tcx>,
-                               error: &MismatchedProjectionTypes<'tcx>)
-    {
+    fn report_projection_error(
+        &self,
+        obligation: &PredicateObligation<'tcx>,
+        error: &MismatchedProjectionTypes<'tcx>,
+    ) {
         let predicate =
             self.resolve_vars_if_possible(&obligation.predicate);
 
@@ -603,6 +613,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         obligation: &PredicateObligation<'tcx>,
         error: &SelectionError<'tcx>,
         fallback_has_occurred: bool,
+        points_at_arg: bool,
     ) {
         let span = obligation.cause.span;
 
@@ -690,7 +701,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                         }
 
                         self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err);
-                        self.suggest_fn_call(&obligation, &mut err, &trait_ref);
+                        self.suggest_fn_call(&obligation, &mut err, &trait_ref, points_at_arg);
                         self.suggest_remove_reference(&obligation, &mut err, &trait_ref);
                         self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref);
 
@@ -963,6 +974,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         obligation: &PredicateObligation<'tcx>,
         err: &mut DiagnosticBuilder<'tcx>,
         trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
+        points_at_arg: bool,
     ) {
         let self_ty = trait_ref.self_ty();
         match self_ty.sty {
@@ -991,15 +1003,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                             ..
                         })) = self.tcx.hir().get_if_local(def_id) {
                             let body = self.tcx.hir().body(*body_id);
-                            err.help(&format!(
-                                "use parentheses to call the function: `{}({})`",
+                            let msg = "use parentheses to call the function";
+                            let snippet = format!(
+                                "{}({})",
                                 ident,
                                 body.params.iter()
                                     .map(|arg| match &arg.pat.node {
                                         hir::PatKind::Binding(_, _, ident, None)
                                         if ident.name != kw::SelfLower => ident.to_string(),
                                         _ => "_".to_string(),
-                                    }).collect::<Vec<_>>().join(", ")));
+                                    }).collect::<Vec<_>>().join(", "),
+                            );
+                            if points_at_arg {
+                                err.span_suggestion(
+                                    obligation.cause.span,
+                                    msg,
+                                    snippet,
+                                    Applicability::HasPlaceholders,
+                                );
+                            } else {
+                                err.help(&format!("{}: `{}`", msg, snippet));
+                            }
                         }
                     }
                     _ => {}
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index d2683090add40..b7db7c2520662 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -484,7 +484,8 @@ EnumTypeFoldableImpl! {
 
 pub struct FulfillmentError<'tcx> {
     pub obligation: PredicateObligation<'tcx>,
-    pub code: FulfillmentErrorCode<'tcx>
+    pub code: FulfillmentErrorCode<'tcx>,
+    pub points_at_arg_span: bool,
 }
 
 #[derive(Clone)]
@@ -1183,7 +1184,7 @@ impl<'tcx> FulfillmentError<'tcx> {
            code: FulfillmentErrorCode<'tcx>)
            -> FulfillmentError<'tcx>
     {
-        FulfillmentError { obligation: obligation, code: code }
+        FulfillmentError { obligation: obligation, code: code, points_at_arg_span: false }
     }
 }
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 62bff3421a078..6a764b19c4ddf 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -1999,6 +1999,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                             ),
                             &traits::SelectionError::Unimplemented,
                             false,
+                            false,
                         );
                     }
                 }
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index f2e1a6e29d6fc..ee4f0a868c10a 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -617,7 +617,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
                 // Object safety violations or miscellaneous.
                 Err(err) => {
-                    self.report_selection_error(&obligation, &err, false);
+                    self.report_selection_error(&obligation, &err, false, false);
                     // Treat this like an obligation and follow through
                     // with the unsizing - the lack of a coercion should
                     // be silent, as it causes a type mismatch later.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c98f3373d3975..df9955d6ba015 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3396,6 +3396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
                     if referenced_in.len() == 1 {
                         error.obligation.cause.span = args[referenced_in[0]].span;
+                        error.points_at_arg_span = true;
                     }
                 }
             }
diff --git a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index 4df639b55e5ce..6bb6533899669 100644
--- a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -5,9 +5,10 @@ LL | fn bar(f: impl Future<Output=()>) {}
    | --------------------------------- required by `bar`
 ...
 LL |     bar(foo);
-   |         ^^^ the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
-   |
-   = help: use parentheses to call the function: `foo()`
+   |         ^^^
+   |         |
+   |         the trait `std::future::Future` is not implemented for `fn() -> impl std::future::Future {foo}`
+   |         help: use parentheses to call the function: `foo()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index f51f1a8215cb5..59726c82c2377 100644
--- a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -5,9 +5,10 @@ LL | fn bar(f: impl T<O=()>) {}
    | ----------------------- required by `bar`
 ...
 LL |     bar(foo);
-   |         ^^^ the trait `T` is not implemented for `fn() -> impl T {foo}`
-   |
-   = help: use parentheses to call the function: `foo()`
+   |         ^^^
+   |         |
+   |         the trait `T` is not implemented for `fn() -> impl T {foo}`
+   |         help: use parentheses to call the function: `foo()`
 
 error: aborting due to previous error
 

From c1ed4399eb3b68a2df0abda9483826f4a0e83046 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 18 Sep 2019 12:05:37 -0700
Subject: [PATCH 901/943] review comments

---
 src/librustc/traits/error_reporting.rs |  4 +++
 src/librustc/traits/mod.rs             |  3 ++
 src/librustc_typeck/check/mod.rs       | 42 +++++++++++++++-----------
 src/librustc_typeck/check/op.rs        |  2 +-
 4 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index e52451b2fdc4d..1d87484ef09be 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1014,6 +1014,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                                         _ => "_".to_string(),
                                     }).collect::<Vec<_>>().join(", "),
                             );
+                            // When the obligation error has been ensured to have been caused by
+                            // an argument, the `obligation.cause.span` points at the expression
+                            // of the argument, so we can provide a suggestion. This is signaled
+                            // by `points_at_arg`. Otherwise, we give a more general note.
                             if points_at_arg {
                                 err.span_suggestion(
                                     obligation.cause.span,
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index b7db7c2520662..c53f4e49971bf 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -485,6 +485,9 @@ EnumTypeFoldableImpl! {
 pub struct FulfillmentError<'tcx> {
     pub obligation: PredicateObligation<'tcx>,
     pub code: FulfillmentErrorCode<'tcx>,
+    /// Diagnostics only: we opportunistically change the `code.span` when we encounter an
+    /// obligation error caused by a call argument. When this is the case, we also signal that in
+    /// this field to ensure accuracy of suggestions.
     pub points_at_arg_span: bool,
 }
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index df9955d6ba015..430e57810d961 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -885,12 +885,12 @@ fn typeck_tables_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::TypeckTables<'_> {
         };
 
         // All type checking constraints were added, try to fallback unsolved variables.
-        fcx.select_obligations_where_possible(false);
+        fcx.select_obligations_where_possible(false, |_| {});
         let mut fallback_has_occurred = false;
         for ty in &fcx.unsolved_variables() {
             fallback_has_occurred |= fcx.fallback_if_possible(ty);
         }
-        fcx.select_obligations_where_possible(fallback_has_occurred);
+        fcx.select_obligations_where_possible(fallback_has_occurred, |_| {});
 
         // Even though coercion casts provide type hints, we check casts after fallback for
         // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
@@ -2356,7 +2356,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // possible. This can help substantially when there are
         // indirect dependencies that don't seem worth tracking
         // precisely.
-        self.select_obligations_where_possible(false);
+        self.select_obligations_where_possible(false, |_| {});
         ty = self.resolve_vars_if_possible(&ty);
 
         debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
@@ -2807,7 +2807,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn resolve_generator_interiors(&self, def_id: DefId) {
         let mut generators = self.deferred_generator_interiors.borrow_mut();
         for (body_id, interior, kind) in generators.drain(..) {
-            self.select_obligations_where_possible(false);
+            self.select_obligations_where_possible(false, |_| {});
             generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
         }
     }
@@ -2844,8 +2844,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Select as many obligations as we can at present.
-    fn select_obligations_where_possible(&self, fallback_has_occurred: bool) {
-        if let Err(errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
+    fn select_obligations_where_possible(
+        &self,
+        fallback_has_occurred: bool,
+        f: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
+    ) {
+        if let Err(mut errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
+            f(&mut errors);
             self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
         }
     }
@@ -3267,20 +3272,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // an "opportunistic" vtable resolution of any trait bounds on
             // the call. This helps coercions.
             if check_closures {
-                // We don't use `select_obligations_where_possible` to try to figure out if the
-                // obligation is comming from a single fn call argument, and if it is, we point
-                // at the expression corresponding to that argument, instead of the call.
-                if let Err(
-                    mut errors,
-                ) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
+                self.select_obligations_where_possible(false, |errors| {
                     self.point_at_arg_instead_of_call_if_possible(
-                        &mut errors,
+                        errors,
                         &final_arg_types[..],
                         sp,
                         &args,
                     );
-                    self.report_fulfillment_errors(&errors, self.inh.body_id, false);
-                }
+                })
             }
 
             // For C-variadic functions, we don't have a declared type for all of
@@ -3394,8 +3393,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             }
                         }
                     }
-                    if referenced_in.len() == 1 {
-                        error.obligation.cause.span = args[referenced_in[0]].span;
+                    let mut referenced_in = final_arg_types.iter()
+                        .flat_map(|(i, ty)| {
+                            let ty = self.resolve_vars_if_possible(ty);
+                            ty.walk()
+                                .filter(|&ty| ty == predicate.skip_binder().self_ty())
+                                .map(move |_| *i)
+                        });
+                    if let (Some(ref_in), None) = (referenced_in.next(), referenced_in.next()) {
+                        // We make sure that only *one* argument matches the obligation failure
+                        // and thet the obligation's span to its expression's.
+                        error.obligation.cause.span = args[ref_in].span;
                         error.points_at_arg_span = true;
                     }
                 }
diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs
index 18b555dc037c2..956d04ff6229b 100644
--- a/src/librustc_typeck/check/op.rs
+++ b/src/librustc_typeck/check/op.rs
@@ -724,7 +724,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         match method {
             Some(ok) => {
                 let method = self.register_infer_ok_obligations(ok);
-                self.select_obligations_where_possible(false);
+                self.select_obligations_where_possible(false, |_| {});
 
                 Ok(method)
             }

From 09f05d2c41ced46ad01a7f6dbc27c56e967cd6e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 18 Sep 2019 17:33:15 -0700
Subject: [PATCH 902/943] review comments

---
 src/librustc_typeck/check/mod.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 430e57810d961..5c5bed8a3507c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2847,10 +2847,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn select_obligations_where_possible(
         &self,
         fallback_has_occurred: bool,
-        f: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
+        mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
     ) {
         if let Err(mut errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
-            f(&mut errors);
+            mutate_fullfillment_errors(&mut errors);
             self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
         }
     }

From d64c90d40b05c31404b7617d196b155f00ce999a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 19 Sep 2019 10:16:48 -0700
Subject: [PATCH 903/943] remove duplicated code

---
 src/librustc_typeck/check/mod.rs | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 5c5bed8a3507c..bc115ec4bfd2c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3384,15 +3384,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // the `?` operator.
             for error in errors {
                 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
-                    let mut referenced_in = vec![];
-                    for (i, ty) in final_arg_types {
-                        let ty = self.resolve_vars_if_possible(ty);
-                        for ty in ty.walk() {
-                            if ty == predicate.skip_binder().self_ty() {
-                                referenced_in.push(*i);
-                            }
-                        }
-                    }
                     let mut referenced_in = final_arg_types.iter()
                         .flat_map(|(i, ty)| {
                             let ty = self.resolve_vars_if_possible(ty);

From 77fd0a76491afb4c93359f6ceb33a9f79c4f4228 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Thu, 19 Sep 2019 16:12:48 -0400
Subject: [PATCH 904/943] add a mir-opt test that we don't add the spurious
 drop

---
 .../mir-opt/no-spurious-drop-after-call.rs    | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 src/test/mir-opt/no-spurious-drop-after-call.rs

diff --git a/src/test/mir-opt/no-spurious-drop-after-call.rs b/src/test/mir-opt/no-spurious-drop-after-call.rs
new file mode 100644
index 0000000000000..782bc31186ca5
--- /dev/null
+++ b/src/test/mir-opt/no-spurious-drop-after-call.rs
@@ -0,0 +1,24 @@
+// ignore-wasm32-bare compiled with panic=abort by default
+
+// Test that after the call to `std::mem::drop` we do not generate a
+// MIR drop of the argument. (We used to have a `DROP(_2)` in the code
+// below, as part of bb3.)
+
+fn main() {
+    std::mem::drop("".to_string());
+}
+
+// END RUST SOURCE
+// START rustc.main.ElaborateDrops.before.mir
+//    bb2: {
+//        StorageDead(_3);
+//        _1 = const std::mem::drop::<std::string::String>(move _2) -> [return: bb3, unwind: bb4];
+//    }
+//    bb3: {
+//        StorageDead(_2);
+//        StorageDead(_4);
+//        StorageDead(_1);
+//        _0 = ();
+//        return;
+//    }
+// END rustc.main.ElaborateDrops.before.mir

From 3db2c13d893865e8e6929d5259bbac7d89a7ba06 Mon Sep 17 00:00:00 2001
From: Erin Power <xampprocky@gmail.com>
Date: Thu, 19 Sep 2019 21:53:40 +0200
Subject: [PATCH 905/943] Add Compatibility Notes to RELEASES.md for 1.38.0

---
 RELEASES.md | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/RELEASES.md b/RELEASES.md
index d634feba33ac5..ecf49278f4b52 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -68,6 +68,13 @@ Misc
 - [`rustc` will now warn about some incorrect uses of
   `mem::{uninitialized, zeroed}` that are known to cause undefined behaviour.][63346]
 
+Compatibility Notes
+-------------------
+- Unfortunately the [`x86_64-unknown-uefi` platform can not be built][62785]
+  with rustc 1.39.0.
+- The [`armv7-unknown-linux-gnueabihf` platform is also known to have
+  issues][62896] for certain crates such as libc.
+
 [60260]: https://github.com/rust-lang/rust/pull/60260/
 [61457]: https://github.com/rust-lang/rust/pull/61457/
 [61491]: https://github.com/rust-lang/rust/pull/61491/
@@ -79,7 +86,9 @@ Misc
 [62735]: https://github.com/rust-lang/rust/pull/62735/
 [62766]: https://github.com/rust-lang/rust/pull/62766/
 [62784]: https://github.com/rust-lang/rust/pull/62784/
+[62785]: https://github.com/rust-lang/rust/issues/62785/
 [62814]: https://github.com/rust-lang/rust/pull/62814/
+[62896]: https://github.com/rust-lang/rust/issues/62896/
 [63000]: https://github.com/rust-lang/rust/pull/63000/
 [63056]: https://github.com/rust-lang/rust/pull/63056/
 [63107]: https://github.com/rust-lang/rust/pull/63107/

From c34d9e6a92fae416821f45d2b86c261f62aaf4f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 19 Sep 2019 14:52:38 -0700
Subject: [PATCH 906/943] add comments

---
 src/librustc_typeck/check/mod.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index bc115ec4bfd2c..0406d7a12d243 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3372,6 +3372,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         vec![self.tcx.types.err; len]
     }
 
+    /// Given a vec of evaluated `FullfillmentError`s and an `fn` call argument expressions, we
+    /// walk the resolved types for each argument to see if any of the `FullfillmentError`s
+    /// reference a type argument. If they do, and there's only *one* argument that does, we point
+    /// at the corresponding argument's expression span instead of the `fn` call path span.
     fn point_at_arg_instead_of_call_if_possible(
         &self,
         errors: &mut Vec<traits::FulfillmentError<'_>>,
@@ -3384,9 +3388,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // the `?` operator.
             for error in errors {
                 if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
+                    // Collect the argument position for all arguments that could have caused this
+                    // `FullfillmentError`.
                     let mut referenced_in = final_arg_types.iter()
                         .flat_map(|(i, ty)| {
                             let ty = self.resolve_vars_if_possible(ty);
+                            // We walk the argument type because the argument's type could have
+                            // been `Option<T>`, but the `FullfillmentError` references `T`.
                             ty.walk()
                                 .filter(|&ty| ty == predicate.skip_binder().self_ty())
                                 .map(move |_| *i)

From c3140bae633b265657c0094f6df6edf630d1d917 Mon Sep 17 00:00:00 2001
From: guanqun <guanqun.lu@gmail.com>
Date: Sat, 21 Sep 2019 00:22:43 +0800
Subject: [PATCH 907/943] remove the extra comma after the match arm

This would follow the same coding style as all the other match arms in this file.
---
 src/librustc_resolve/late/diagnostics.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 0c86d8494fde8..df8bd3fa75e14 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -424,7 +424,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
                 } else {
                     err.note("did you mean to use one of the enum's variants?");
                 }
-            },
+            }
             (Res::Def(DefKind::Struct, def_id), _) if ns == ValueNS => {
                 if let Some((ctor_def, ctor_vis))
                         = self.r.struct_constructors.get(&def_id).cloned() {

From 633ad73ef17c02e1893becbd030e2d188851042c Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Fri, 20 Sep 2019 09:36:03 -0700
Subject: [PATCH 908/943] Update to LLVM 9.0.0

---
 .gitmodules      | 2 +-
 src/llvm-project | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.gitmodules b/.gitmodules
index f64e21c5af0e4..3ff5af78097fa 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -43,7 +43,7 @@
 [submodule "src/llvm-project"]
 	path = src/llvm-project
 	url = https://github.com/rust-lang/llvm-project.git
-	branch = rustc/9.0-2019-07-12
+	branch = rustc/9.0-2019-09-19
 [submodule "src/doc/embedded-book"]
 	path = src/doc/embedded-book
 	url = https://github.com/rust-embedded/book.git
diff --git a/src/llvm-project b/src/llvm-project
index 71fe7ec06b85f..8adf9bdccfefb 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit 71fe7ec06b85f612fc0e4eb4134c7a7d0f23fac5
+Subproject commit 8adf9bdccfefb8d03f0e8db3b012fb41da1580a4

From 9cf9030e1cc4c6231419f5e9f7a5bd42eb1f55c1 Mon Sep 17 00:00:00 2001
From: gnzlbg <gonzalobg88@gmail.com>
Date: Fri, 20 Sep 2019 18:39:13 +0200
Subject: [PATCH 909/943] Allow using fn pointers in const fn behind
 const_fn_ptr gate

---
 src/librustc_mir/transform/qualify_consts.rs  | 20 ++++++++++---
 src/libsyntax/feature_gate/active.rs          |  3 ++
 src/libsyntax_pos/symbol.rs                   |  1 +
 src/test/ui/consts/const-eval/const_fn_ptr.rs | 21 ++++++++++++++
 .../ui/consts/const-eval/const_fn_ptr_fail.rs | 15 ++++++++++
 .../const-eval/const_fn_ptr_fail.stderr       | 20 +++++++++++++
 .../consts/const-eval/const_fn_ptr_fail2.rs   | 21 ++++++++++++++
 .../const-eval/const_fn_ptr_fail2.stderr      | 28 +++++++++++++++++++
 .../const-eval/feature-gate-const_fn_ptr.rs   | 11 ++++++++
 .../feature-gate-const_fn_ptr.stderr          | 12 ++++++++
 10 files changed, 148 insertions(+), 4 deletions(-)
 create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr.rs
 create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr_fail.rs
 create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr
 create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs
 create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
 create mode 100644 src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs
 create mode 100644 src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 7cc1e634cf812..3842942d97fbb 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1407,11 +1407,23 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                     }
                 }
                 ty::FnPtr(_) => {
+                    let unleash_miri = self
+                        .tcx
+                        .sess
+                        .opts
+                        .debugging_opts
+                        .unleash_the_miri_inside_of_you;
+                    let const_fn_ptr = self.tcx.features().const_fn_ptr;
                     if self.mode.requires_const_checking() {
-                        let mut err = self.tcx.sess.struct_span_err(
-                            self.span,
-                            &format!("function pointers are not allowed in const fn"));
-                        err.emit();
+                        if !(unleash_miri || const_fn_ptr) {
+                            emit_feature_err(
+                                &self.tcx.sess.parse_sess,
+                                sym::const_fn_ptr,
+                                self.span,
+                                GateIssue::Language,
+                                "function pointers in const fn are unstable",
+                            );
+                        }
                     }
                 }
                 _ => {
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index dd78777b56986..d1a17dc14bdf7 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -405,6 +405,9 @@ declare_features! (
     /// Allows macro invocations in `extern {}` blocks.
     (active, macros_in_extern, "1.27.0", Some(49476), None),
 
+    /// Allows calling function pointers inside `const` functions.
+    (active, const_fn_ptr, "1.27.0", Some(51909), None),
+
     /// Allows accessing fields of unions inside `const` functions.
     (active, const_fn_union, "1.27.0", Some(51909), None),
 
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 597ae83572cee..e6be8a2cb874a 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -198,6 +198,7 @@ symbols! {
         const_compare_raw_pointers,
         const_constructor,
         const_fn,
+        const_fn_ptr,
         const_fn_union,
         const_generics,
         const_indexing,
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.rs b/src/test/ui/consts/const-eval/const_fn_ptr.rs
new file mode 100644
index 0000000000000..1acb3d8ad1065
--- /dev/null
+++ b/src/test/ui/consts/const-eval/const_fn_ptr.rs
@@ -0,0 +1,21 @@
+// run-pass
+#![feature(const_fn)]
+#![feature(const_fn_ptr)]
+
+const fn double(x: usize) -> usize { x * 2 }
+const X: fn(usize) -> usize = double;
+
+const fn bar(x: usize) -> usize {
+    X(x)
+}
+
+const fn foo(x: fn(usize) -> usize, y: usize)  -> usize {
+    x(y)
+}
+
+fn main() {
+    const Y: usize = bar(2);
+    assert_eq!(Y, 4);
+    const Z: usize = foo(double, 2);
+    assert_eq!(Z, 4);
+}
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs
new file mode 100644
index 0000000000000..e8041e56c38fb
--- /dev/null
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+// FIXME: this should not pass
+
+#![feature(const_fn)]
+#![feature(const_fn_ptr)]
+
+fn double(x: usize) -> usize { x * 2 }
+const X: fn(usize) -> usize = double;
+
+const fn bar(x: usize) -> usize {
+    X(x)
+}
+
+fn main() {}
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr
new file mode 100644
index 0000000000000..b7f3a74cc44c0
--- /dev/null
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr
@@ -0,0 +1,20 @@
+warning: function is never used: `double`
+  --> $DIR/const_fn_ptr_fail.rs:8:1
+   |
+LL | fn double(x: usize) -> usize { x * 2 }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: constant item is never used: `X`
+  --> $DIR/const_fn_ptr_fail.rs:9:1
+   |
+LL | const X: fn(usize) -> usize = double;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: function is never used: `bar`
+  --> $DIR/const_fn_ptr_fail.rs:11:1
+   |
+LL | const fn bar(x: usize) -> usize {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs
new file mode 100644
index 0000000000000..66e01cae31452
--- /dev/null
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs
@@ -0,0 +1,21 @@
+#![feature(const_fn)]
+#![feature(const_fn_ptr)]
+
+fn double(x: usize) -> usize { x * 2 }
+const X: fn(usize) -> usize = double;
+
+const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
+    x(y)
+}
+
+const Y: usize = bar(X, 2);
+//~^ ERROR any use of this value will cause an error
+
+const Z: usize = bar(double, 2);
+//~^ ERROR any use of this value will cause an error
+
+
+fn main() {
+    assert_eq!(Y, 4);
+    assert_eq!(Z, 4);
+}
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
new file mode 100644
index 0000000000000..020889c2ca1a0
--- /dev/null
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
@@ -0,0 +1,28 @@
+error: any use of this value will cause an error
+  --> $DIR/const_fn_ptr_fail2.rs:8:5
+   |
+LL |     x(y)
+   |     ^^^^
+   |     |
+   |     calling non-const function `double`
+   |     inside call to `bar` at $DIR/const_fn_ptr_fail2.rs:11:18
+...
+LL | const Y: usize = bar(X, 2);
+   | ---------------------------
+   |
+   = note: `#[deny(const_err)]` on by default
+
+error: any use of this value will cause an error
+  --> $DIR/const_fn_ptr_fail2.rs:8:5
+   |
+LL |     x(y)
+   |     ^^^^
+   |     |
+   |     calling non-const function `double`
+   |     inside call to `bar` at $DIR/const_fn_ptr_fail2.rs:14:18
+...
+LL | const Z: usize = bar(double, 2);
+   | --------------------------------
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs
new file mode 100644
index 0000000000000..ea1ca05c31b8f
--- /dev/null
+++ b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs
@@ -0,0 +1,11 @@
+#![feature(const_fn)]
+
+fn main() {}
+
+const fn foo() {}
+const X: fn() = foo;
+
+const fn bar() {
+    X()
+    //~^ ERROR function pointers in const fn are unstable
+}
diff --git a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr
new file mode 100644
index 0000000000000..fe5956d06f2a0
--- /dev/null
+++ b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr
@@ -0,0 +1,12 @@
+error[E0658]: function pointers in const fn are unstable
+  --> $DIR/feature-gate-const_fn_ptr.rs:9:5
+   |
+LL |     X()
+   |     ^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/51909
+   = help: add `#![feature(const_fn_ptr)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.

From 491a0c6902b4ad86bdf7b1b0fdd2fc7d6d12a026 Mon Sep 17 00:00:00 2001
From: Baoshan Pang <baoshan.pang@windriver.com>
Date: Fri, 20 Sep 2019 13:25:57 -0700
Subject: [PATCH 910/943] No home directory on vxWorks

---
 src/libstd/sys/vxworks/os.rs | 23 +----------------------
 1 file changed, 1 insertion(+), 22 deletions(-)

diff --git a/src/libstd/sys/vxworks/os.rs b/src/libstd/sys/vxworks/os.rs
index 5dc35a6176bce..f4798da1876cf 100644
--- a/src/libstd/sys/vxworks/os.rs
+++ b/src/libstd/sys/vxworks/os.rs
@@ -287,28 +287,7 @@ pub fn temp_dir() -> PathBuf {
 }
 
 pub fn home_dir() -> Option<PathBuf> {
-    return crate::env::var_os("HOME").or_else(|| unsafe {
-        fallback()
-    }).map(PathBuf::from);
-
-    unsafe fn fallback() -> Option<OsString> {
-        let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) {
-            n if n < 0 => 512 as usize,
-            n => n as usize,
-        };
-        let mut buf = Vec::with_capacity(amt);
-        let mut passwd: libc::passwd = mem::zeroed();
-        let mut result = ptr::null_mut();
-        match libc::getpwuid_r(libc::getuid(), &mut passwd, buf.as_mut_ptr(),
-                                buf.capacity(), &mut result) {
-            0 if !result.is_null() => {
-                let ptr = passwd.pw_dir as *const _;
-                let bytes = CStr::from_ptr(ptr).to_bytes().to_vec();
-                Some(OsStringExt::from_vec(bytes))
-            },
-            _ => None,
-        }
-    }
+    None
 }
 
 pub fn exit(code: i32) -> ! {

From 9f374da46781cfe2d297636fe97b2fd9647cb1d9 Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Fri, 20 Sep 2019 15:39:34 -0700
Subject: [PATCH 911/943] Exempt extern "Rust" from improper_ctypes

It should be fine for Rust ABIs to involve any Rust type.
---
 src/liballoc/alloc.rs             |  2 +-
 src/libcore/panicking.rs          |  2 +-
 src/librustc_lint/types.rs        |  4 +++-
 src/test/ui/issues/issue-64593.rs | 12 ++++++++++++
 4 files changed, 17 insertions(+), 3 deletions(-)
 create mode 100644 src/test/ui/issues/issue-64593.rs

diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs
index dc7fd1adc2958..a39fcd5ad4c58 100644
--- a/src/liballoc/alloc.rs
+++ b/src/liballoc/alloc.rs
@@ -240,7 +240,7 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
 #[stable(feature = "global_alloc", since = "1.28.0")]
 #[rustc_allocator_nounwind]
 pub fn handle_alloc_error(layout: Layout) -> ! {
-    #[allow(improper_ctypes)]
+    #[cfg_attr(bootstrap, allow(improper_ctypes))]
     extern "Rust" {
         #[lang = "oom"]
         fn oom_impl(layout: Layout) -> !;
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 15b7d69c58d24..3d2bc24bf24a5 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -71,7 +71,7 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, file_line_col: &(&'static str, u32, u3
     }
 
     // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
-    #[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe
+    #[cfg_attr(boostrap_stdarch_ignore_this, allow(improper_ctypes))]
     extern "Rust" {
         #[lang = "panic_impl"]
         fn panic_impl(pi: &PanicInfo<'_>) -> !;
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 3b8c06ba154c6..40261f6d13739 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -975,7 +975,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
     fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) {
         let mut vis = ImproperCTypesVisitor { cx };
         let abi = cx.tcx.hir().get_foreign_abi(it.hir_id);
-        if abi != Abi::RustIntrinsic && abi != Abi::PlatformIntrinsic {
+        if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
+            // Don't worry about types in internal ABIs.
+        } else {
             match it.node {
                 hir::ForeignItemKind::Fn(ref decl, _, _) => {
                     vis.check_foreign_fn(it.hir_id, decl);
diff --git a/src/test/ui/issues/issue-64593.rs b/src/test/ui/issues/issue-64593.rs
new file mode 100644
index 0000000000000..9e787f638a998
--- /dev/null
+++ b/src/test/ui/issues/issue-64593.rs
@@ -0,0 +1,12 @@
+// check-pass
+#![deny(improper_ctypes)]
+
+pub struct Error(std::num::NonZeroU32);
+
+extern "Rust" {
+    fn foo(dest: &mut [u8]) -> Result<(), Error>;
+}
+
+fn main() {
+    let _ = unsafe { foo(&mut []) };
+}

From b956ae38e16a8f04b31d5cf5788f1d357617efbc Mon Sep 17 00:00:00 2001
From: Baoshan Pang <baoshan.pang@windriver.com>
Date: Fri, 20 Sep 2019 15:47:13 -0700
Subject: [PATCH 912/943] rust stat should call libc stat

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

diff --git a/src/libstd/sys/vxworks/fs.rs b/src/libstd/sys/vxworks/fs.rs
index d537d2258fda7..51fdb1c0e55ec 100644
--- a/src/libstd/sys/vxworks/fs.rs
+++ b/src/libstd/sys/vxworks/fs.rs
@@ -529,7 +529,7 @@ pub fn stat(p: &Path) -> io::Result<FileAttr> {
     let p = cstr(p)?;
     let mut stat: stat64 = unsafe { mem::zeroed() };
     cvt(unsafe {
-        libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _)
+        libc::stat(p.as_ptr(), &mut stat as *mut _ as *mut _)
     })?;
     Ok(FileAttr { stat })
 }

From c3f72d1c098a61f26271021460b5ae420ff28ae8 Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Fri, 20 Sep 2019 16:06:32 -0700
Subject: [PATCH 913/943] Fix the span used to suggest avoiding for-loop moves

It was using the snippet from the "use" span, which often renders the
same, but with closures that snippet is on the start of the closure
where the value is captured. We should be using the snippet from the
span where it was moved into the `for` loop, which is `move_span`.
---
 .../borrow_check/conflict_errors.rs            |  3 ++-
 src/test/ui/issues/issue-64559.rs              |  6 ++++++
 src/test/ui/issues/issue-64559.stderr          | 18 ++++++++++++++++++
 3 files changed, 26 insertions(+), 1 deletion(-)
 create mode 100644 src/test/ui/issues/issue-64559.rs
 create mode 100644 src/test/ui/issues/issue-64559.stderr

diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index 81359c6a46e99..599a0ad0d0c52 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -180,7 +180,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     );
                 }
                 if Some(DesugaringKind::ForLoop) == move_span.desugaring_kind() {
-                    if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
+                    let sess = self.infcx.tcx.sess;
+                    if let Ok(snippet) = sess.source_map().span_to_snippet(move_span) {
                         err.span_suggestion(
                             move_span,
                             "consider borrowing to avoid moving into the for loop",
diff --git a/src/test/ui/issues/issue-64559.rs b/src/test/ui/issues/issue-64559.rs
new file mode 100644
index 0000000000000..71e054b5d9876
--- /dev/null
+++ b/src/test/ui/issues/issue-64559.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let orig = vec![true];
+    for _val in orig {}
+    let _closure = || orig;
+    //~^ ERROR use of moved value: `orig`
+}
diff --git a/src/test/ui/issues/issue-64559.stderr b/src/test/ui/issues/issue-64559.stderr
new file mode 100644
index 0000000000000..3c685dc8d089a
--- /dev/null
+++ b/src/test/ui/issues/issue-64559.stderr
@@ -0,0 +1,18 @@
+error[E0382]: use of moved value: `orig`
+  --> $DIR/issue-64559.rs:4:20
+   |
+LL |     let orig = vec![true];
+   |         ---- move occurs because `orig` has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
+LL |     for _val in orig {}
+   |                 ----
+   |                 |
+   |                 value moved here
+   |                 help: consider borrowing to avoid moving into the for loop: `&orig`
+LL |     let _closure = || orig;
+   |                    ^^ ---- use occurs due to use in closure
+   |                    |
+   |                    value used here after move
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.

From d4344969731e55bd0acaee4ad6962a85c8e0f27a Mon Sep 17 00:00:00 2001
From: gnzlbg <gonzalobg88@gmail.com>
Date: Sat, 21 Sep 2019 16:09:38 +0200
Subject: [PATCH 914/943] remove feature

---
 src/librustc_mir/transform/qualify_consts.rs  |  17 +-
 src/libsyntax/feature_gate/active.rs          |   3 -
 src/libsyntax_pos/symbol.rs                   |   1 -
 src/test/ui/consts/const-eval/const_fn_ptr.rs |  24 ++-
 .../ui/consts/const-eval/const_fn_ptr.stderr  | 152 ++++++++++++++++++
 .../ui/consts/const-eval/const_fn_ptr_fail.rs |   8 +-
 .../const-eval/const_fn_ptr_fail.stderr       |  20 ---
 .../consts/const-eval/const_fn_ptr_fail2.rs   |  19 ++-
 .../const-eval/const_fn_ptr_fail2.stderr      |  93 ++++++++---
 .../const-eval/feature-gate-const_fn_ptr.rs   |  11 --
 .../feature-gate-const_fn_ptr.stderr          |  12 --
 11 files changed, 261 insertions(+), 99 deletions(-)
 create mode 100644 src/test/ui/consts/const-eval/const_fn_ptr.stderr
 delete mode 100644 src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr
 delete mode 100644 src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs
 delete mode 100644 src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 3842942d97fbb..60b88277715bc 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1413,17 +1413,12 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                         .opts
                         .debugging_opts
                         .unleash_the_miri_inside_of_you;
-                    let const_fn_ptr = self.tcx.features().const_fn_ptr;
-                    if self.mode.requires_const_checking() {
-                        if !(unleash_miri || const_fn_ptr) {
-                            emit_feature_err(
-                                &self.tcx.sess.parse_sess,
-                                sym::const_fn_ptr,
-                                self.span,
-                                GateIssue::Language,
-                                "function pointers in const fn are unstable",
-                            );
-                        }
+                    if self.mode.requires_const_checking() && !unleash_miri {
+                        let mut err = self.tcx.sess.struct_span_err(
+                            self.span,
+                            "function pointers in `const fn` are unstable",
+                        );
+                        err.emit();
                     }
                 }
                 _ => {
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index d1a17dc14bdf7..dd78777b56986 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -405,9 +405,6 @@ declare_features! (
     /// Allows macro invocations in `extern {}` blocks.
     (active, macros_in_extern, "1.27.0", Some(49476), None),
 
-    /// Allows calling function pointers inside `const` functions.
-    (active, const_fn_ptr, "1.27.0", Some(51909), None),
-
     /// Allows accessing fields of unions inside `const` functions.
     (active, const_fn_union, "1.27.0", Some(51909), None),
 
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index e6be8a2cb874a..597ae83572cee 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -198,7 +198,6 @@ symbols! {
         const_compare_raw_pointers,
         const_constructor,
         const_fn,
-        const_fn_ptr,
         const_fn_union,
         const_generics,
         const_indexing,
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.rs b/src/test/ui/consts/const-eval/const_fn_ptr.rs
index 1acb3d8ad1065..498f801db81b8 100644
--- a/src/test/ui/consts/const-eval/const_fn_ptr.rs
+++ b/src/test/ui/consts/const-eval/const_fn_ptr.rs
@@ -1,21 +1,37 @@
 // run-pass
+// compile-flags: -Zunleash-the-miri-inside-of-you
 #![feature(const_fn)]
-#![feature(const_fn_ptr)]
 
-const fn double(x: usize) -> usize { x * 2 }
+fn double(x: usize) -> usize { x * 2 }
+const fn double_const(x: usize) -> usize { x * 2 }
+
 const X: fn(usize) -> usize = double;
+const X_const: fn(usize) -> usize = double_const;
 
 const fn bar(x: usize) -> usize {
     X(x)
 }
 
+const fn bar_const(x: usize) -> usize {
+    X_const(x)
+}
+
 const fn foo(x: fn(usize) -> usize, y: usize)  -> usize {
     x(y)
 }
 
 fn main() {
-    const Y: usize = bar(2);
+    const Y: usize = bar_const(2);
     assert_eq!(Y, 4);
-    const Z: usize = foo(double, 2);
+    let y = bar_const(2);
+    assert_eq!(y, 4);
+    let y = bar(2);
+    assert_eq!(y, 4);
+
+    const Z: usize = foo(double_const, 2);
     assert_eq!(Z, 4);
+    let z = foo(double_const, 2);
+    assert_eq!(z, 4);
+    let z = foo(double, 2);
+    assert_eq!(z, 4);
 }
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr.stderr b/src/test/ui/consts/const-eval/const_fn_ptr.stderr
new file mode 100644
index 0000000000000..41452ee59eb94
--- /dev/null
+++ b/src/test/ui/consts/const-eval/const_fn_ptr.stderr
@@ -0,0 +1,152 @@
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:25:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:25:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:25:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:27:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:27:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:27:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:29:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:29:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:29:5
+   |
+LL |     assert_eq!(y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:32:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:32:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:32:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:34:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:34:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:34:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:36:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:36:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr.rs:36:5
+   |
+LL |     assert_eq!(z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: constant `X_const` should have an upper case name
+  --> $DIR/const_fn_ptr.rs:9:7
+   |
+LL | const X_const: fn(usize) -> usize = double_const;
+   |       ^^^^^^^ help: convert the identifier to upper case: `X_CONST`
+   |
+   = note: `#[warn(non_upper_case_globals)]` on by default
+
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs
index e8041e56c38fb..14bd6558e7f89 100644
--- a/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail.rs
@@ -1,15 +1,13 @@
 // run-pass
-
-// FIXME: this should not pass
-
+// compile-flags: -Zunleash-the-miri-inside-of-you
 #![feature(const_fn)]
-#![feature(const_fn_ptr)]
+#![allow(unused)]
 
 fn double(x: usize) -> usize { x * 2 }
 const X: fn(usize) -> usize = double;
 
 const fn bar(x: usize) -> usize {
-    X(x)
+    X(x) // FIXME: this should error someday
 }
 
 fn main() {}
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr
deleted file mode 100644
index b7f3a74cc44c0..0000000000000
--- a/src/test/ui/consts/const-eval/const_fn_ptr_fail.stderr
+++ /dev/null
@@ -1,20 +0,0 @@
-warning: function is never used: `double`
-  --> $DIR/const_fn_ptr_fail.rs:8:1
-   |
-LL | fn double(x: usize) -> usize { x * 2 }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(dead_code)]` on by default
-
-warning: constant item is never used: `X`
-  --> $DIR/const_fn_ptr_fail.rs:9:1
-   |
-LL | const X: fn(usize) -> usize = double;
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-warning: function is never used: `bar`
-  --> $DIR/const_fn_ptr_fail.rs:11:1
-   |
-LL | const fn bar(x: usize) -> usize {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs
index 66e01cae31452..74c60f9a2a58d 100644
--- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.rs
@@ -1,5 +1,6 @@
+// compile-flags: -Zunleash-the-miri-inside-of-you
 #![feature(const_fn)]
-#![feature(const_fn_ptr)]
+#![allow(const_err)]
 
 fn double(x: usize) -> usize { x * 2 }
 const X: fn(usize) -> usize = double;
@@ -8,14 +9,18 @@ const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
     x(y)
 }
 
-const Y: usize = bar(X, 2);
-//~^ ERROR any use of this value will cause an error
-
-const Z: usize = bar(double, 2);
-//~^ ERROR any use of this value will cause an error
-
+const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday
+const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday
 
 fn main() {
     assert_eq!(Y, 4);
+    //~^ ERROR evaluation of constant expression failed
+    //~^^ WARN skipping const checks
+    //~^^^ WARN skipping const checks
+    //~^^^^ WARN skipping const checks
     assert_eq!(Z, 4);
+    //~^ ERROR evaluation of constant expression failed
+    //~^^ WARN skipping const checks
+    //~^^^ WARN skipping const checks
+    //~^^^^ WARN skipping const checks
 }
diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
index 020889c2ca1a0..611cc5313c057 100644
--- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
+++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr
@@ -1,28 +1,71 @@
-error: any use of this value will cause an error
-  --> $DIR/const_fn_ptr_fail2.rs:8:5
-   |
-LL |     x(y)
-   |     ^^^^
-   |     |
-   |     calling non-const function `double`
-   |     inside call to `bar` at $DIR/const_fn_ptr_fail2.rs:11:18
-...
-LL | const Y: usize = bar(X, 2);
-   | ---------------------------
-   |
-   = note: `#[deny(const_err)]` on by default
-
-error: any use of this value will cause an error
-  --> $DIR/const_fn_ptr_fail2.rs:8:5
-   |
-LL |     x(y)
-   |     ^^^^
-   |     |
-   |     calling non-const function `double`
-   |     inside call to `bar` at $DIR/const_fn_ptr_fail2.rs:14:18
-...
-LL | const Z: usize = bar(double, 2);
-   | --------------------------------
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:16:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:16:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:16:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:21:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:21:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+warning: skipping const checks
+  --> $DIR/const_fn_ptr_fail2.rs:21:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: evaluation of constant expression failed
+  --> $DIR/const_fn_ptr_fail2.rs:16:5
+   |
+LL |     assert_eq!(Y, 4);
+   |     ^^^^^^^^^^^-^^^^^
+   |                |
+   |                referenced constant has errors
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: evaluation of constant expression failed
+  --> $DIR/const_fn_ptr_fail2.rs:21:5
+   |
+LL |     assert_eq!(Z, 4);
+   |     ^^^^^^^^^^^-^^^^^
+   |                |
+   |                referenced constant has errors
+   |
+   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs
deleted file mode 100644
index ea1ca05c31b8f..0000000000000
--- a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-#![feature(const_fn)]
-
-fn main() {}
-
-const fn foo() {}
-const X: fn() = foo;
-
-const fn bar() {
-    X()
-    //~^ ERROR function pointers in const fn are unstable
-}
diff --git a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr b/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr
deleted file mode 100644
index fe5956d06f2a0..0000000000000
--- a/src/test/ui/consts/const-eval/feature-gate-const_fn_ptr.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0658]: function pointers in const fn are unstable
-  --> $DIR/feature-gate-const_fn_ptr.rs:9:5
-   |
-LL |     X()
-   |     ^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/51909
-   = help: add `#![feature(const_fn_ptr)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.

From 9d4053f6921f3259076e2d88f983f9666a78ef4b Mon Sep 17 00:00:00 2001
From: gnzlbg <gonzalobg88@gmail.com>
Date: Sat, 21 Sep 2019 17:24:42 +0200
Subject: [PATCH 915/943] revert error message changes

---
 src/librustc_mir/transform/qualify_consts.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 60b88277715bc..795721f3b3f28 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1416,7 +1416,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
                     if self.mode.requires_const_checking() && !unleash_miri {
                         let mut err = self.tcx.sess.struct_span_err(
                             self.span,
-                            "function pointers in `const fn` are unstable",
+                            "function pointers are not allowed in const fn"
                         );
                         err.emit();
                     }

From e001c5f9d894a66722db061ecbbd224973dc0fb8 Mon Sep 17 00:00:00 2001
From: Guanqun Lu <guanqun.lu@gmail.com>
Date: Sat, 21 Sep 2019 23:36:12 +0800
Subject: [PATCH 916/943] unify errors for tuple/struct variants

fix #63983
---
 src/librustc_resolve/late/diagnostics.rs        |  6 ++++++
 src/test/ui/empty/empty-struct-tuple-pat.stderr |  7 ++++---
 src/test/ui/issues/issue-32004.stderr           |  5 +++--
 src/test/ui/issues/issue-63983.rs               | 15 +++++++++++++++
 src/test/ui/issues/issue-63983.stderr           | 15 +++++++++++++++
 5 files changed, 43 insertions(+), 5 deletions(-)
 create mode 100644 src/test/ui/issues/issue-63983.rs
 create mode 100644 src/test/ui/issues/issue-63983.stderr

diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 0c86d8494fde8..1d4fa77adcc1c 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -445,6 +445,12 @@ impl<'a> LateResolutionVisitor<'a, '_> {
             (Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => {
                 bad_struct_syntax_suggestion();
             }
+            (Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), _) if ns == ValueNS => {
+                err.span_label(
+                    span,
+                    format!("did you mean `{} ( /* fields */ )`?", path_str),
+                );
+            }
             (Res::SelfTy(..), _) if ns == ValueNS => {
                 err.span_label(span, fallback_label);
                 err.note("can't use `Self` as a constructor, you must use the implemented struct");
diff --git a/src/test/ui/empty/empty-struct-tuple-pat.stderr b/src/test/ui/empty/empty-struct-tuple-pat.stderr
index 777b9d4a4acd0..6c15e7bf282ce 100644
--- a/src/test/ui/empty/empty-struct-tuple-pat.stderr
+++ b/src/test/ui/empty/empty-struct-tuple-pat.stderr
@@ -20,15 +20,16 @@ error[E0532]: expected unit struct/variant or constant, found tuple variant `E::
   --> $DIR/empty-struct-tuple-pat.rs:29:9
    |
 LL |         E::Empty4 => ()
-   |         ^^^^^^^^^ not a unit struct/variant or constant
+   |         ^^^^^^^^^ did you mean `E::Empty4 ( /* fields */ )`?
 
 error[E0532]: expected unit struct/variant or constant, found tuple variant `XE::XEmpty5`
   --> $DIR/empty-struct-tuple-pat.rs:33:9
    |
 LL |         XE::XEmpty5 => (),
    |         ^^^^-------
-   |             |
-   |             help: a unit variant with a similar name exists: `XEmpty4`
+   |         |   |
+   |         |   help: a unit variant with a similar name exists: `XEmpty4`
+   |         did you mean `XE::XEmpty5 ( /* fields */ )`?
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/issues/issue-32004.stderr b/src/test/ui/issues/issue-32004.stderr
index f8c418b25a0e4..b56fa949acb7e 100644
--- a/src/test/ui/issues/issue-32004.stderr
+++ b/src/test/ui/issues/issue-32004.stderr
@@ -3,8 +3,9 @@ error[E0532]: expected unit struct/variant or constant, found tuple variant `Foo
    |
 LL |         Foo::Bar => {}
    |         ^^^^^---
-   |              |
-   |              help: a unit variant with a similar name exists: `Baz`
+   |         |    |
+   |         |    help: a unit variant with a similar name exists: `Baz`
+   |         did you mean `Foo::Bar ( /* fields */ )`?
 
 error[E0532]: expected tuple struct/variant, found unit struct `S`
   --> $DIR/issue-32004.rs:16:9
diff --git a/src/test/ui/issues/issue-63983.rs b/src/test/ui/issues/issue-63983.rs
new file mode 100644
index 0000000000000..c1c79091fc802
--- /dev/null
+++ b/src/test/ui/issues/issue-63983.rs
@@ -0,0 +1,15 @@
+enum MyEnum {
+    Tuple(i32),
+    Struct{ s: i32 },
+}
+
+fn foo(en: MyEnum) {
+    match en {
+        MyEnum::Tuple => "",
+        //~^ ERROR expected unit struct/variant or constant, found tuple variant `MyEnum::Tuple`
+        MyEnum::Struct => "",
+        //~^ ERROR expected unit struct/variant or constant, found struct variant `MyEnum::Struct`
+    };
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-63983.stderr b/src/test/ui/issues/issue-63983.stderr
new file mode 100644
index 0000000000000..67acd1d57c27a
--- /dev/null
+++ b/src/test/ui/issues/issue-63983.stderr
@@ -0,0 +1,15 @@
+error[E0532]: expected unit struct/variant or constant, found tuple variant `MyEnum::Tuple`
+  --> $DIR/issue-63983.rs:8:9
+   |
+LL |         MyEnum::Tuple => "",
+   |         ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple ( /* fields */ )`?
+
+error[E0532]: expected unit struct/variant or constant, found struct variant `MyEnum::Struct`
+  --> $DIR/issue-63983.rs:10:9
+   |
+LL |         MyEnum::Struct => "",
+   |         ^^^^^^^^^^^^^^ did you mean `MyEnum::Struct { /* fields */ }`?
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0532`.

From a2a57bc6cf383fc113335148296c7965bb29e9a2 Mon Sep 17 00:00:00 2001
From: Sam Radhakrishan <sk09idm@gmail.com>
Date: Thu, 19 Sep 2019 22:12:05 +0530
Subject: [PATCH 917/943] Fixes #63962. Hint about missing tuple parentheses in
 patterns

---
 src/librustc_typeck/check/pat.rs     | 41 +++++++++++++++++++++++-----
 src/test/ui/error-codes/E0023.rs     |  2 ++
 src/test/ui/error-codes/E0023.stderr | 21 +++++++++++---
 3 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index d93a4052cd393..d687a5084e231 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -676,18 +676,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         } else {
             // Pattern has wrong number of fields.
-            self.e0023(pat.span, res, &subpats, &variant.fields);
+            self.e0023(pat.span, res, &subpats, &variant.fields, expected);
             on_error();
             return tcx.types.err;
         }
         pat_ty
     }
 
-    fn e0023(&self, pat_span: Span, res: Res, subpats: &'tcx [P<Pat>], fields: &[ty::FieldDef]) {
+    fn e0023(
+        &self,
+        pat_span: Span,
+        res: Res,
+        subpats: &'tcx [P<Pat>],
+        fields: &[ty::FieldDef],
+        expected: Ty<'tcx>
+    ) {
         let subpats_ending = pluralise!(subpats.len());
         let fields_ending = pluralise!(fields.len());
+        let missing_parenthesis = match expected.sty {
+            ty::Adt(_, substs) if fields.len() == 1 => {
+                let field_ty = fields[0].ty(self.tcx, substs);
+                match field_ty.sty {
+                    ty::Tuple(_) => field_ty.tuple_fields().count() == subpats.len(),
+                    _ => false,
+                }
+            }
+            _ => false,
+        };
         let res_span = self.tcx.def_span(res.def_id());
-        struct_span_err!(
+        let mut err = struct_span_err!(
             self.tcx.sess,
             pat_span,
             E0023,
@@ -697,15 +714,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             res.descr(),
             fields.len(),
             fields_ending,
-        )
-            .span_label(pat_span, format!(
+        );
+        err.span_label(pat_span, format!(
                 "expected {} field{}, found {}",
                 fields.len(),
                 fields_ending,
                 subpats.len(),
             ))
-            .span_label(res_span, format!("{} defined here", res.descr()))
-            .emit();
+            .span_label(res_span, format!("{} defined here", res.descr()));
+
+        if missing_parenthesis {
+            err.multipart_suggestion(
+                "missing parenthesis",
+                vec![(subpats[0].span.shrink_to_lo(), "(".to_string()),
+                    (subpats[subpats.len()-1].span.shrink_to_hi(), ")".to_string())],
+                Applicability::MachineApplicable,
+            );
+        }
+
+        err.emit();
     }
 
     fn check_pat_tuple(
diff --git a/src/test/ui/error-codes/E0023.rs b/src/test/ui/error-codes/E0023.rs
index 2a97e9048a490..dc421e060e86f 100644
--- a/src/test/ui/error-codes/E0023.rs
+++ b/src/test/ui/error-codes/E0023.rs
@@ -1,6 +1,7 @@
 enum Fruit {
     Apple(String, String),
     Pear(u32),
+    Orange((String, String)),
 }
 
 
@@ -10,5 +11,6 @@ fn main() {
         Fruit::Apple(a) => {}, //~ ERROR E0023
         Fruit::Apple(a, b, c) => {}, //~ ERROR E0023
         Fruit::Pear(1, 2) => {}, //~ ERROR E0023
+        Fruit::Orange(a, b) => {}, //~ ERROR E0023
     }
 }
diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr
index d04e494c2585c..8ae7d01ed5f7e 100644
--- a/src/test/ui/error-codes/E0023.stderr
+++ b/src/test/ui/error-codes/E0023.stderr
@@ -1,5 +1,5 @@
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/E0023.rs:10:9
+  --> $DIR/E0023.rs:11:9
    |
 LL |     Apple(String, String),
    |     --------------------- tuple variant defined here
@@ -8,7 +8,7 @@ LL |         Fruit::Apple(a) => {},
    |         ^^^^^^^^^^^^^^^ expected 2 fields, found 1
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/E0023.rs:11:9
+  --> $DIR/E0023.rs:12:9
    |
 LL |     Apple(String, String),
    |     --------------------- tuple variant defined here
@@ -17,7 +17,7 @@ LL |         Fruit::Apple(a, b, c) => {},
    |         ^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
-  --> $DIR/E0023.rs:12:9
+  --> $DIR/E0023.rs:13:9
    |
 LL |     Pear(u32),
    |     --------- tuple variant defined here
@@ -25,6 +25,19 @@ LL |     Pear(u32),
 LL |         Fruit::Pear(1, 2) => {},
    |         ^^^^^^^^^^^^^^^^^ expected 1 field, found 2
 
-error: aborting due to 3 previous errors
+error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
+  --> $DIR/E0023.rs:14:9
+   |
+LL |     Orange((String, String)),
+   |     ------------------------ tuple variant defined here
+...
+LL |         Fruit::Orange(a, b) => {},
+   |         ^^^^^^^^^^^^^^^^^^^ expected 1 field, found 2
+help: missing parenthesis
+   |
+LL |         Fruit::Orange((a, b)) => {},
+   |                       ^    ^
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0023`.

From 53a6a2f3226652e212bba6fcf37166a2fe3ecfca Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Sat, 21 Sep 2019 21:33:37 +0300
Subject: [PATCH 918/943] fully remove AstBuilder

The mentioned Cargo test is fixed in https://github.com/rust-lang/cargo/pull/7210
---
 src/libsyntax/ext/build.rs | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index f1d0e0b68f735..60560ae96deb5 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -9,9 +9,6 @@ use crate::ThinVec;
 use rustc_target::spec::abi::Abi;
 use syntax_pos::{Pos, Span};
 
-// Left so that Cargo tests don't break, this can be removed once those no longer use it
-pub trait AstBuilder {}
-
 impl<'a> ExtCtxt<'a> {
     pub fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
         self.path_all(span, false, strs, vec![], vec![])

From 67d88f607ed831cf692387703c34441019b8db96 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 21 Sep 2019 15:01:10 -0400
Subject: [PATCH 919/943] Remove constraints argument from path_all

It was never used
---
 src/libsyntax/ext/build.rs                | 11 +++++------
 src/libsyntax_ext/deriving/clone.rs       |  2 +-
 src/libsyntax_ext/deriving/cmp/eq.rs      |  2 +-
 src/libsyntax_ext/deriving/generic/mod.rs |  2 +-
 src/libsyntax_ext/deriving/generic/ty.rs  |  8 ++++----
 src/libsyntax_ext/env.rs                  |  2 +-
 6 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index f1d0e0b68f735..84a27fcb7dd94 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -14,20 +14,19 @@ pub trait AstBuilder {}
 
 impl<'a> ExtCtxt<'a> {
     pub fn path(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
-        self.path_all(span, false, strs, vec![], vec![])
+        self.path_all(span, false, strs, vec![])
     }
     pub fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path {
         self.path(span, vec![id])
     }
     pub fn path_global(&self, span: Span, strs: Vec<ast::Ident> ) -> ast::Path {
-        self.path_all(span, true, strs, vec![], vec![])
+        self.path_all(span, true, strs, vec![])
     }
     pub fn path_all(&self,
                 span: Span,
                 global: bool,
                 mut idents: Vec<ast::Ident> ,
-                args: Vec<ast::GenericArg>,
-                constraints: Vec<ast::AssocTyConstraint> )
+                args: Vec<ast::GenericArg>)
                 -> ast::Path {
         assert!(!idents.is_empty());
         let add_root = global && !idents[0].is_path_segment_keyword();
@@ -39,8 +38,8 @@ impl<'a> ExtCtxt<'a> {
         segments.extend(idents.into_iter().map(|ident| {
             ast::PathSegment::from_ident(ident.with_span_pos(span))
         }));
-        let args = if !args.is_empty() || !constraints.is_empty() {
-            ast::AngleBracketedArgs { args, constraints, span }.into()
+        let args = if !args.is_empty() {
+            ast::AngleBracketedArgs { args, constraints: Vec::new(), span }.into()
         } else {
             None
         };
diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index 4dd0ecfebefd4..9a4c540dc6f1f 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -115,7 +115,7 @@ fn cs_clone_shallow(name: &str,
         let span = cx.with_def_site_ctxt(span);
         let assert_path = cx.path_all(span, true,
                                         cx.std_path(&[sym::clone, Symbol::intern(helper_name)]),
-                                        vec![GenericArg::Type(ty)], vec![]);
+                                        vec![GenericArg::Type(ty)]);
         stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
     }
     fn process_variant(cx: &mut ExtCtxt<'_>, stmts: &mut Vec<ast::Stmt>, variant: &VariantData) {
diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs
index 32ab47969ada4..471c92dd99949 100644
--- a/src/libsyntax_ext/deriving/cmp/eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/eq.rs
@@ -56,7 +56,7 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt<'_>,
         let span = cx.with_def_site_ctxt(span);
         let assert_path = cx.path_all(span, true,
                                         cx.std_path(&[sym::cmp, Symbol::intern(helper_name)]),
-                                        vec![GenericArg::Type(ty)], vec![]);
+                                        vec![GenericArg::Type(ty)]);
         stmts.push(cx.stmt_let_type_only(span, cx.ty_path(assert_path)));
     }
     fn process_variant(cx: &mut ExtCtxt<'_>,
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index aceee62e89b0c..5c332eccb62cc 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -664,7 +664,7 @@ impl<'a> TraitDef<'a> {
         }).collect();
 
         // Create the type of `self`.
-        let path = cx.path_all(self.span, false, vec![type_ident], self_params, vec![]);
+        let path = cx.path_all(self.span, false, vec![type_ident], self_params);
         let self_type = cx.ty_path(path);
 
         let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived));
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index b341a07675206..6ae02a5cab199 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -82,12 +82,12 @@ impl<'a> Path<'a> {
                        .collect();
 
         match self.kind {
-            PathKind::Global => cx.path_all(span, true, idents, params, Vec::new()),
-            PathKind::Local => cx.path_all(span, false, idents, params, Vec::new()),
+            PathKind::Global => cx.path_all(span, true, idents, params),
+            PathKind::Local => cx.path_all(span, false, idents, params),
             PathKind::Std => {
                 let def_site = cx.with_def_site_ctxt(DUMMY_SP);
                 idents.insert(0, Ident::new(kw::DollarCrate, def_site));
-                cx.path_all(span, false, idents, params, Vec::new())
+                cx.path_all(span, false, idents, params)
             }
         }
 
@@ -183,7 +183,7 @@ impl<'a> Ty<'a> {
                     }
                 }).collect();
 
-                cx.path_all(span, false, vec![self_ty], params, vec![])
+                cx.path_all(span, false, vec![self_ty], params)
             }
             Literal(ref p) => p.to_path(cx, span, self_ty, generics),
             Ptr(..) => cx.span_bug(span, "pointer in a path in generic `derive`"),
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 70e1fbe6af78a..02757bf6b1689 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -32,7 +32,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
                                                                  Ident::new(sym::str, sp)),
                                                      Some(lt),
                                                      ast::Mutability::Immutable))],
-                                     vec![]))
+                                     ))
         }
         Ok(s) => {
             cx.expr_call_global(sp,

From ea70fb75672645640303b29e3b4cb41ee7690f53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 21 Sep 2019 12:33:02 -0700
Subject: [PATCH 920/943] Do not trigger unreachable lint in async body and Use
 span labels

---
 src/librustc_typeck/check/mod.rs              |  9 ++--
 src/test/ui/dead-code-ret.stderr              |  9 ++--
 src/test/ui/if-ret.stderr                     |  9 ++--
 src/test/ui/issues/issue-2150.stderr          |  9 ++--
 src/test/ui/issues/issue-7246.stderr          |  9 ++--
 .../ui/lint/lint-attr-non-item-node.stderr    |  9 ++--
 src/test/ui/lint/unreachable-async-fn.rs      |  9 ++++
 src/test/ui/liveness/liveness-unused.stderr   |  9 ++--
 .../match-no-arms-unreachable-after.stderr    |  9 ++--
 src/test/ui/never-assign-dead-code.stderr     | 19 +++------
 src/test/ui/reachable/expr_add.stderr         | 10 ++---
 src/test/ui/reachable/expr_again.stderr       |  9 ++--
 src/test/ui/reachable/expr_array.stderr       | 20 ++++-----
 src/test/ui/reachable/expr_assign.stderr      | 30 +++++---------
 src/test/ui/reachable/expr_block.stderr       | 18 +++-----
 src/test/ui/reachable/expr_box.stderr         | 10 ++---
 src/test/ui/reachable/expr_call.stderr        | 19 +++------
 src/test/ui/reachable/expr_cast.stderr        | 10 ++---
 src/test/ui/reachable/expr_if.stderr          | 21 ++++------
 src/test/ui/reachable/expr_loop.stderr        | 27 ++++--------
 src/test/ui/reachable/expr_match.stderr       | 18 +++-----
 src/test/ui/reachable/expr_method.stderr      | 19 +++------
 src/test/ui/reachable/expr_repeat.stderr      | 10 ++---
 src/test/ui/reachable/expr_return.stderr      | 10 ++---
 .../ui/reachable/expr_return_in_macro.stderr  | 13 ++----
 src/test/ui/reachable/expr_struct.stderr      | 41 +++++++------------
 src/test/ui/reachable/expr_tup.stderr         | 20 ++++-----
 src/test/ui/reachable/expr_type.stderr        | 10 ++---
 src/test/ui/reachable/expr_unary.stderr       | 10 ++---
 src/test/ui/reachable/expr_while.stderr       | 23 ++++-------
 .../protect-precedences.stderr                |  9 ++--
 .../ui/unreachable/unreachable-code.stderr    | 10 ++---
 .../ui/unreachable/unreachable-in-call.stderr | 18 +++-----
 .../unreachable-try-pattern.stderr            | 10 ++---
 .../unwarned-match-on-never.stderr            | 30 +++++---------
 35 files changed, 191 insertions(+), 334 deletions(-)
 create mode 100644 src/test/ui/lint/unreachable-async-fn.rs

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 0eeeee01c82f1..5d8d5880c0fca 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2340,16 +2340,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
             // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
             // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
-            if !span.is_desugaring(DesugaringKind::CondTemporary) {
+            if !span.is_desugaring(DesugaringKind::CondTemporary) &&
+                !span.is_desugaring(DesugaringKind::Async)
+            {
                 self.diverges.set(Diverges::WarnedAlways);
 
                 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
 
                 let msg = format!("unreachable {}", kind);
                 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, &msg)
-                    .span_note(
+                    .span_label(span, &msg)
+                    .span_label(
                         orig_span,
-                        custom_note.unwrap_or("any code following this expression is unreachable")
+                        custom_note.unwrap_or("any code following this expression is unreachable"),
                     )
                     .emit();
             }
diff --git a/src/test/ui/dead-code-ret.stderr b/src/test/ui/dead-code-ret.stderr
index 0ce31ea40ddbb..83841131599b2 100644
--- a/src/test/ui/dead-code-ret.stderr
+++ b/src/test/ui/dead-code-ret.stderr
@@ -1,19 +1,16 @@
 error: unreachable statement
   --> $DIR/dead-code-ret.rs:7:5
    |
+LL |     return;
+   |     ------ any code following this expression is unreachable
 LL |     println!("Paul is dead");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
   --> $DIR/dead-code-ret.rs:3:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/dead-code-ret.rs:6:5
-   |
-LL |     return;
-   |     ^^^^^^
    = 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
diff --git a/src/test/ui/if-ret.stderr b/src/test/ui/if-ret.stderr
index 2df8f22944ee8..58cc707605423 100644
--- a/src/test/ui/if-ret.stderr
+++ b/src/test/ui/if-ret.stderr
@@ -2,12 +2,9 @@ warning: unreachable block in `if` expression
   --> $DIR/if-ret.rs:6:24
    |
 LL | fn foo() { if (return) { } }
-   |                        ^^^
+   |               -------- ^^^ unreachable block in `if` expression
+   |               |
+   |               any code following this expression is unreachable
    |
    = note: `#[warn(unreachable_code)]` on by default
-note: any code following this expression is unreachable
-  --> $DIR/if-ret.rs:6:15
-   |
-LL | fn foo() { if (return) { } }
-   |               ^^^^^^^^
 
diff --git a/src/test/ui/issues/issue-2150.stderr b/src/test/ui/issues/issue-2150.stderr
index 623f098d0b337..6e102ecb62fff 100644
--- a/src/test/ui/issues/issue-2150.stderr
+++ b/src/test/ui/issues/issue-2150.stderr
@@ -1,19 +1,16 @@
 error: unreachable statement
   --> $DIR/issue-2150.rs:8:5
    |
+LL |     panic!();
+   |     --------- any code following this expression is unreachable
 LL |     for x in &v { i += 1; }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
   --> $DIR/issue-2150.rs:1:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/issue-2150.rs:7:5
-   |
-LL |     panic!();
-   |     ^^^^^^^^^
    = 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
diff --git a/src/test/ui/issues/issue-7246.stderr b/src/test/ui/issues/issue-7246.stderr
index d1b23672dc7f4..a11ce1654cad8 100644
--- a/src/test/ui/issues/issue-7246.stderr
+++ b/src/test/ui/issues/issue-7246.stderr
@@ -1,19 +1,16 @@
 error: unreachable statement
   --> $DIR/issue-7246.rs:7:5
    |
+LL |     return;
+   |     ------ any code following this expression is unreachable
 LL |     if *ptr::null() {};
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
   --> $DIR/issue-7246.rs:1:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/issue-7246.rs:6:5
-   |
-LL |     return;
-   |     ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/lint-attr-non-item-node.stderr b/src/test/ui/lint/lint-attr-non-item-node.stderr
index e6c76c24c9110..0d428c256e7bc 100644
--- a/src/test/ui/lint/lint-attr-non-item-node.stderr
+++ b/src/test/ui/lint/lint-attr-non-item-node.stderr
@@ -1,19 +1,16 @@
 error: unreachable statement
   --> $DIR/lint-attr-non-item-node.rs:7:9
    |
+LL |         break;
+   |         ----- any code following this expression is unreachable
 LL |         "unreachable";
-   |         ^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
   --> $DIR/lint-attr-non-item-node.rs:4:12
    |
 LL |     #[deny(unreachable_code)]
    |            ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/lint-attr-non-item-node.rs:6:9
-   |
-LL |         break;
-   |         ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/unreachable-async-fn.rs b/src/test/ui/lint/unreachable-async-fn.rs
new file mode 100644
index 0000000000000..6e09c3136b5a0
--- /dev/null
+++ b/src/test/ui/lint/unreachable-async-fn.rs
@@ -0,0 +1,9 @@
+// run-pass
+// edition:2018
+#[allow(dead_code)]
+
+async fn foo () { // unreachable lint doesn't trigger
+   unimplemented!()
+}
+
+fn main() {}
diff --git a/src/test/ui/liveness/liveness-unused.stderr b/src/test/ui/liveness/liveness-unused.stderr
index 84e9b5bab99ff..6ea20081e5018 100644
--- a/src/test/ui/liveness/liveness-unused.stderr
+++ b/src/test/ui/liveness/liveness-unused.stderr
@@ -1,8 +1,10 @@
 warning: unreachable statement
   --> $DIR/liveness-unused.rs:92:9
    |
+LL |         continue;
+   |         -------- any code following this expression is unreachable
 LL |         drop(*x as i32);
-   |         ^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
   --> $DIR/liveness-unused.rs:1:9
@@ -10,11 +12,6 @@ note: lint level defined here
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]`
-note: any code following this expression is unreachable
-  --> $DIR/liveness-unused.rs:91:9
-   |
-LL |         continue;
-   |         ^^^^^^^^
 
 error: unused variable: `x`
   --> $DIR/liveness-unused.rs:8:7
diff --git a/src/test/ui/match/match-no-arms-unreachable-after.stderr b/src/test/ui/match/match-no-arms-unreachable-after.stderr
index 6c46b2473cce6..66e5c91ad2054 100644
--- a/src/test/ui/match/match-no-arms-unreachable-after.stderr
+++ b/src/test/ui/match/match-no-arms-unreachable-after.stderr
@@ -1,19 +1,16 @@
 error: unreachable statement
   --> $DIR/match-no-arms-unreachable-after.rs:8:5
    |
+LL |     match v { }
+   |     ----------- any code following this expression is unreachable
 LL |     let x = 2;
-   |     ^^^^^^^^^^
+   |     ^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
   --> $DIR/match-no-arms-unreachable-after.rs:2:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/match-no-arms-unreachable-after.rs:7:5
-   |
-LL |     match v { }
-   |     ^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/never-assign-dead-code.stderr b/src/test/ui/never-assign-dead-code.stderr
index 436c703e4b6b9..b887d580e68a9 100644
--- a/src/test/ui/never-assign-dead-code.stderr
+++ b/src/test/ui/never-assign-dead-code.stderr
@@ -1,8 +1,10 @@
 warning: unreachable statement
   --> $DIR/never-assign-dead-code.rs:10:5
    |
+LL |     let x: ! = panic!("aah");
+   |                ------------- any code following this expression is unreachable
 LL |     drop(x);
-   |     ^^^^^^^^
+   |     ^^^^^^^^ unreachable statement
    |
 note: lint level defined here
   --> $DIR/never-assign-dead-code.rs:5:9
@@ -10,24 +12,15 @@ note: lint level defined here
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]`
-note: any code following this expression is unreachable
-  --> $DIR/never-assign-dead-code.rs:9:16
-   |
-LL |     let x: ! = panic!("aah");
-   |                ^^^^^^^^^^^^^
    = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
 
 warning: unreachable call
   --> $DIR/never-assign-dead-code.rs:10:5
    |
 LL |     drop(x);
-   |     ^^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/never-assign-dead-code.rs:10:10
-   |
-LL |     drop(x);
-   |          ^
+   |     ^^^^ - any code following this expression is unreachable
+   |     |
+   |     unreachable call
 
 warning: unused variable: `x`
   --> $DIR/never-assign-dead-code.rs:9:9
diff --git a/src/test/ui/reachable/expr_add.stderr b/src/test/ui/reachable/expr_add.stderr
index 47b4e467abecb..880dea1cc3516 100644
--- a/src/test/ui/reachable/expr_add.stderr
+++ b/src/test/ui/reachable/expr_add.stderr
@@ -2,18 +2,16 @@ error: unreachable expression
   --> $DIR/expr_add.rs:17:13
    |
 LL |     let x = Foo + return;
-   |             ^^^^^^^^^^^^
+   |             ^^^^^^------
+   |             |     |
+   |             |     any code following this expression is unreachable
+   |             unreachable expression
    |
 note: lint level defined here
   --> $DIR/expr_add.rs:3:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_add.rs:17:19
-   |
-LL |     let x = Foo + return;
-   |                   ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_again.stderr b/src/test/ui/reachable/expr_again.stderr
index 8e246d940fd8d..95006884242f9 100644
--- a/src/test/ui/reachable/expr_again.stderr
+++ b/src/test/ui/reachable/expr_again.stderr
@@ -1,19 +1,16 @@
 error: unreachable statement
   --> $DIR/expr_again.rs:8:9
    |
+LL |         continue;
+   |         -------- any code following this expression is unreachable
 LL |         println!("hi");
-   |         ^^^^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
   --> $DIR/expr_again.rs:3:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_again.rs:7:9
-   |
-LL |         continue;
-   |         ^^^^^^^^
    = 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
diff --git a/src/test/ui/reachable/expr_array.stderr b/src/test/ui/reachable/expr_array.stderr
index 419a332e632f3..b3138d3c33fc0 100644
--- a/src/test/ui/reachable/expr_array.stderr
+++ b/src/test/ui/reachable/expr_array.stderr
@@ -2,30 +2,24 @@ error: unreachable expression
   --> $DIR/expr_array.rs:9:34
    |
 LL |     let x: [usize; 2] = [return, 22];
-   |                                  ^^
+   |                          ------  ^^ unreachable expression
+   |                          |
+   |                          any code following this expression is unreachable
    |
 note: lint level defined here
   --> $DIR/expr_array.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_array.rs:9:26
-   |
-LL |     let x: [usize; 2] = [return, 22];
-   |                          ^^^^^^
 
 error: unreachable expression
   --> $DIR/expr_array.rs:14:25
    |
 LL |     let x: [usize; 2] = [22, return];
-   |                         ^^^^^^^^^^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_array.rs:14:30
-   |
-LL |     let x: [usize; 2] = [22, return];
-   |                              ^^^^^^
+   |                         ^^^^^------^
+   |                         |    |
+   |                         |    any code following this expression is unreachable
+   |                         unreachable expression
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/reachable/expr_assign.stderr b/src/test/ui/reachable/expr_assign.stderr
index 7388fb4a6b9b2..3004da0406328 100644
--- a/src/test/ui/reachable/expr_assign.stderr
+++ b/src/test/ui/reachable/expr_assign.stderr
@@ -2,42 +2,32 @@ error: unreachable expression
   --> $DIR/expr_assign.rs:10:5
    |
 LL |     x = return;
-   |     ^^^^^^^^^^
+   |     ^^^^------
+   |     |   |
+   |     |   any code following this expression is unreachable
+   |     unreachable expression
    |
 note: lint level defined here
   --> $DIR/expr_assign.rs:5:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_assign.rs:10:9
-   |
-LL |     x = return;
-   |         ^^^^^^
 
 error: unreachable expression
   --> $DIR/expr_assign.rs:20:14
    |
 LL |         *p = return;
-   |              ^^^^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_assign.rs:20:9
-   |
-LL |         *p = return;
-   |         ^^
+   |         --   ^^^^^^ unreachable expression
+   |         |
+   |         any code following this expression is unreachable
 
 error: unreachable expression
   --> $DIR/expr_assign.rs:26:15
    |
 LL |     *{return; &mut i} = 22;
-   |               ^^^^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_assign.rs:26:7
-   |
-LL |     *{return; &mut i} = 22;
-   |       ^^^^^^
+   |       ------  ^^^^^^ unreachable expression
+   |       |
+   |       any code following this expression is unreachable
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/reachable/expr_block.stderr b/src/test/ui/reachable/expr_block.stderr
index 03a6139d688bb..44baddd1e5503 100644
--- a/src/test/ui/reachable/expr_block.stderr
+++ b/src/test/ui/reachable/expr_block.stderr
@@ -1,31 +1,25 @@
 error: unreachable expression
   --> $DIR/expr_block.rs:10:9
    |
+LL |         return;
+   |         ------ any code following this expression is unreachable
 LL |         22
-   |         ^^
+   |         ^^ unreachable expression
    |
 note: lint level defined here
   --> $DIR/expr_block.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_block.rs:9:9
-   |
-LL |         return;
-   |         ^^^^^^
 
 error: unreachable statement
   --> $DIR/expr_block.rs:25:9
    |
+LL |         return;
+   |         ------ any code following this expression is unreachable
 LL |         println!("foo");
-   |         ^^^^^^^^^^^^^^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_block.rs:24:9
+   |         ^^^^^^^^^^^^^^^^ unreachable statement
    |
-LL |         return;
-   |         ^^^^^^
    = 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 2 previous errors
diff --git a/src/test/ui/reachable/expr_box.stderr b/src/test/ui/reachable/expr_box.stderr
index d0f666d2be44b..b01a13e9df29a 100644
--- a/src/test/ui/reachable/expr_box.stderr
+++ b/src/test/ui/reachable/expr_box.stderr
@@ -2,18 +2,16 @@ error: unreachable expression
   --> $DIR/expr_box.rs:6:13
    |
 LL |     let x = box return;
-   |             ^^^^^^^^^^
+   |             ^^^^------
+   |             |   |
+   |             |   any code following this expression is unreachable
+   |             unreachable expression
    |
 note: lint level defined here
   --> $DIR/expr_box.rs:3:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_box.rs:6:17
-   |
-LL |     let x = box return;
-   |                 ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_call.stderr b/src/test/ui/reachable/expr_call.stderr
index 3fcea90e7cd87..ae8b4dd87b5b9 100644
--- a/src/test/ui/reachable/expr_call.stderr
+++ b/src/test/ui/reachable/expr_call.stderr
@@ -2,30 +2,23 @@ error: unreachable expression
   --> $DIR/expr_call.rs:13:17
    |
 LL |     foo(return, 22);
-   |                 ^^
+   |         ------  ^^ unreachable expression
+   |         |
+   |         any code following this expression is unreachable
    |
 note: lint level defined here
   --> $DIR/expr_call.rs:5:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_call.rs:13:9
-   |
-LL |     foo(return, 22);
-   |         ^^^^^^
 
 error: unreachable call
   --> $DIR/expr_call.rs:18:5
    |
 LL |     bar(return);
-   |     ^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_call.rs:18:9
-   |
-LL |     bar(return);
-   |         ^^^^^^
+   |     ^^^ ------ any code following this expression is unreachable
+   |     |
+   |     unreachable call
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/reachable/expr_cast.stderr b/src/test/ui/reachable/expr_cast.stderr
index d3ce0ca079f90..81813d1d71c3f 100644
--- a/src/test/ui/reachable/expr_cast.stderr
+++ b/src/test/ui/reachable/expr_cast.stderr
@@ -2,18 +2,16 @@ error: unreachable expression
   --> $DIR/expr_cast.rs:9:13
    |
 LL |     let x = {return} as !;
-   |             ^^^^^^^^^^^^^
+   |             ^------^^^^^^
+   |             ||
+   |             |any code following this expression is unreachable
+   |             unreachable expression
    |
 note: lint level defined here
   --> $DIR/expr_cast.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_cast.rs:9:14
-   |
-LL |     let x = {return} as !;
-   |              ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_if.stderr b/src/test/ui/reachable/expr_if.stderr
index 03284576086a7..ccd45ccec62c7 100644
--- a/src/test/ui/reachable/expr_if.stderr
+++ b/src/test/ui/reachable/expr_if.stderr
@@ -2,33 +2,28 @@ error: unreachable block in `if` expression
   --> $DIR/expr_if.rs:7:17
    |
 LL |       if {return} {
-   |  _________________^
+   |  _________------__^
+   | |         |
+   | |         any code following this expression is unreachable
 LL | |         println!("Hello, world!");
 LL | |     }
-   | |_____^
+   | |_____^ unreachable block in `if` expression
    |
 note: lint level defined here
   --> $DIR/expr_if.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_if.rs:7:9
-   |
-LL |     if {return} {
-   |         ^^^^^^
 
 error: unreachable statement
   --> $DIR/expr_if.rs:27:5
    |
+LL |         return;
+   |         ------ any code following this expression is unreachable
+...
 LL |     println!("But I am.");
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
-note: any code following this expression is unreachable
-  --> $DIR/expr_if.rs:21:9
-   |
-LL |         return;
-   |         ^^^^^^
    = 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 2 previous errors
diff --git a/src/test/ui/reachable/expr_loop.stderr b/src/test/ui/reachable/expr_loop.stderr
index a4cf8cfcfd9e6..5f279c9630d30 100644
--- a/src/test/ui/reachable/expr_loop.stderr
+++ b/src/test/ui/reachable/expr_loop.stderr
@@ -1,45 +1,36 @@
 error: unreachable statement
   --> $DIR/expr_loop.rs:8:5
    |
+LL |     loop { return; }
+   |            ------ any code following this expression is unreachable
 LL |     println!("I am dead.");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
   --> $DIR/expr_loop.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_loop.rs:7:12
-   |
-LL |     loop { return; }
-   |            ^^^^^^
    = 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: unreachable statement
   --> $DIR/expr_loop.rs:21:5
    |
+LL |     loop { return; }
+   |            ------ any code following this expression is unreachable
 LL |     println!("I am dead.");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_loop.rs:20:12
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
-LL |     loop { return; }
-   |            ^^^^^^
    = 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: unreachable statement
   --> $DIR/expr_loop.rs:32:5
    |
+LL |     loop { 'middle: loop { loop { break 'middle; } } }
+   |     -------------------------------------------------- any code following this expression is unreachable
 LL |     println!("I am dead.");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
-note: any code following this expression is unreachable
-  --> $DIR/expr_loop.rs:31:5
-   |
-LL |     loop { 'middle: loop { loop { break 'middle; } } }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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 3 previous errors
diff --git a/src/test/ui/reachable/expr_match.stderr b/src/test/ui/reachable/expr_match.stderr
index f587e524d350d..d39acdc290926 100644
--- a/src/test/ui/reachable/expr_match.stderr
+++ b/src/test/ui/reachable/expr_match.stderr
@@ -1,32 +1,26 @@
 error: unreachable statement
   --> $DIR/expr_match.rs:8:5
    |
+LL |     match () { () => return }
+   |     ------------------------- any code following this `match` expression is unreachable, as all arms diverge
 LL |     println!("I am dead");
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
   --> $DIR/expr_match.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this `match` expression is unreachable, as all arms diverge
-  --> $DIR/expr_match.rs:7:5
-   |
-LL |     match () { () => return }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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: unreachable statement
   --> $DIR/expr_match.rs:19:5
    |
+LL |     match () { () if false => return, () => return }
+   |     ------------------------------------------------ any code following this `match` expression is unreachable, as all arms diverge
 LL |     println!("I am dead");
-   |     ^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: any code following this `match` expression is unreachable, as all arms diverge
-  --> $DIR/expr_match.rs:18:5
+   |     ^^^^^^^^^^^^^^^^^^^^^^ unreachable statement
    |
-LL |     match () { () if false => return, () => return }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = 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 2 previous errors
diff --git a/src/test/ui/reachable/expr_method.stderr b/src/test/ui/reachable/expr_method.stderr
index 7ad279c9f487a..82a0745f0629f 100644
--- a/src/test/ui/reachable/expr_method.stderr
+++ b/src/test/ui/reachable/expr_method.stderr
@@ -2,30 +2,23 @@ error: unreachable expression
   --> $DIR/expr_method.rs:16:21
    |
 LL |     Foo.foo(return, 22);
-   |                     ^^
+   |             ------  ^^ unreachable expression
+   |             |
+   |             any code following this expression is unreachable
    |
 note: lint level defined here
   --> $DIR/expr_method.rs:5:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_method.rs:16:13
-   |
-LL |     Foo.foo(return, 22);
-   |             ^^^^^^
 
 error: unreachable call
   --> $DIR/expr_method.rs:21:9
    |
 LL |     Foo.bar(return);
-   |         ^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_method.rs:21:13
-   |
-LL |     Foo.bar(return);
-   |             ^^^^^^
+   |         ^^^ ------ any code following this expression is unreachable
+   |         |
+   |         unreachable call
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/reachable/expr_repeat.stderr b/src/test/ui/reachable/expr_repeat.stderr
index 3ff6be76daea5..34129936fd762 100644
--- a/src/test/ui/reachable/expr_repeat.stderr
+++ b/src/test/ui/reachable/expr_repeat.stderr
@@ -2,18 +2,16 @@ error: unreachable expression
   --> $DIR/expr_repeat.rs:9:25
    |
 LL |     let x: [usize; 2] = [return; 2];
-   |                         ^^^^^^^^^^^
+   |                         ^------^^^^
+   |                         ||
+   |                         |any code following this expression is unreachable
+   |                         unreachable expression
    |
 note: lint level defined here
   --> $DIR/expr_repeat.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_repeat.rs:9:26
-   |
-LL |     let x: [usize; 2] = [return; 2];
-   |                          ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_return.stderr b/src/test/ui/reachable/expr_return.stderr
index 31f7ebe7618ea..c0a94746d08eb 100644
--- a/src/test/ui/reachable/expr_return.stderr
+++ b/src/test/ui/reachable/expr_return.stderr
@@ -2,18 +2,16 @@ error: unreachable expression
   --> $DIR/expr_return.rs:10:22
    |
 LL |     let x = {return {return {return;}}};
-   |                      ^^^^^^^^^^^^^^^^
+   |                      ^^^^^^^^------^^
+   |                      |       |
+   |                      |       any code following this expression is unreachable
+   |                      unreachable expression
    |
 note: lint level defined here
   --> $DIR/expr_return.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_return.rs:10:30
-   |
-LL |     let x = {return {return {return;}}};
-   |                              ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_return_in_macro.stderr b/src/test/ui/reachable/expr_return_in_macro.stderr
index ff3abb5551f92..2bc6a763cfaea 100644
--- a/src/test/ui/reachable/expr_return_in_macro.stderr
+++ b/src/test/ui/reachable/expr_return_in_macro.stderr
@@ -1,22 +1,17 @@
 error: unreachable expression
   --> $DIR/expr_return_in_macro.rs:13:5
    |
+LL |         return ()
+   |         --------- any code following this expression is unreachable
+...
 LL |     return early_return!();
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^ unreachable expression
    |
 note: lint level defined here
   --> $DIR/expr_return_in_macro.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_return_in_macro.rs:8:9
-   |
-LL |         return ()
-   |         ^^^^^^^^^
-...
-LL |     return early_return!();
-   |            --------------- in this macro invocation
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_struct.stderr b/src/test/ui/reachable/expr_struct.stderr
index d08bcc4f0d1ae..b3ca06eada3d5 100644
--- a/src/test/ui/reachable/expr_struct.stderr
+++ b/src/test/ui/reachable/expr_struct.stderr
@@ -2,54 +2,41 @@ error: unreachable expression
   --> $DIR/expr_struct.rs:14:13
    |
 LL |     let x = Foo { a: 22, b: 33, ..return };
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^------^^
+   |             |                     |
+   |             |                     any code following this expression is unreachable
+   |             unreachable expression
    |
 note: lint level defined here
   --> $DIR/expr_struct.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_struct.rs:14:35
-   |
-LL |     let x = Foo { a: 22, b: 33, ..return };
-   |                                   ^^^^^^
 
 error: unreachable expression
   --> $DIR/expr_struct.rs:19:33
    |
 LL |     let x = Foo { a: return, b: 33, ..return };
-   |                                 ^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_struct.rs:19:22
-   |
-LL |     let x = Foo { a: return, b: 33, ..return };
-   |                      ^^^^^^
+   |                      ------     ^^ unreachable expression
+   |                      |
+   |                      any code following this expression is unreachable
 
 error: unreachable expression
   --> $DIR/expr_struct.rs:24:39
    |
 LL |     let x = Foo { a: 22, b: return, ..return };
-   |                                       ^^^^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_struct.rs:24:29
-   |
-LL |     let x = Foo { a: 22, b: return, ..return };
-   |                             ^^^^^^
+   |                             ------    ^^^^^^ unreachable expression
+   |                             |
+   |                             any code following this expression is unreachable
 
 error: unreachable expression
   --> $DIR/expr_struct.rs:29:13
    |
 LL |     let x = Foo { a: 22, b: return };
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_struct.rs:29:29
-   |
-LL |     let x = Foo { a: 22, b: return };
-   |                             ^^^^^^
+   |             ^^^^^^^^^^^^^^^^------^^
+   |             |               |
+   |             |               any code following this expression is unreachable
+   |             unreachable expression
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/reachable/expr_tup.stderr b/src/test/ui/reachable/expr_tup.stderr
index 788499533db33..aaaf6462da895 100644
--- a/src/test/ui/reachable/expr_tup.stderr
+++ b/src/test/ui/reachable/expr_tup.stderr
@@ -2,30 +2,24 @@ error: unreachable expression
   --> $DIR/expr_tup.rs:9:38
    |
 LL |     let x: (usize, usize) = (return, 2);
-   |                                      ^
+   |                              ------  ^ unreachable expression
+   |                              |
+   |                              any code following this expression is unreachable
    |
 note: lint level defined here
   --> $DIR/expr_tup.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_tup.rs:9:30
-   |
-LL |     let x: (usize, usize) = (return, 2);
-   |                              ^^^^^^
 
 error: unreachable expression
   --> $DIR/expr_tup.rs:14:29
    |
 LL |     let x: (usize, usize) = (2, return);
-   |                             ^^^^^^^^^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_tup.rs:14:33
-   |
-LL |     let x: (usize, usize) = (2, return);
-   |                                 ^^^^^^
+   |                             ^^^^------^
+   |                             |   |
+   |                             |   any code following this expression is unreachable
+   |                             unreachable expression
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/reachable/expr_type.stderr b/src/test/ui/reachable/expr_type.stderr
index 15eb735da75d8..cb6e8d7039f2c 100644
--- a/src/test/ui/reachable/expr_type.stderr
+++ b/src/test/ui/reachable/expr_type.stderr
@@ -2,18 +2,16 @@ error: unreachable expression
   --> $DIR/expr_type.rs:9:13
    |
 LL |     let x = {return}: !;
-   |             ^^^^^^^^^^^
+   |             ^------^^^^
+   |             ||
+   |             |any code following this expression is unreachable
+   |             unreachable expression
    |
 note: lint level defined here
   --> $DIR/expr_type.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_type.rs:9:14
-   |
-LL |     let x = {return}: !;
-   |              ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/reachable/expr_unary.stderr b/src/test/ui/reachable/expr_unary.stderr
index 7f86519616639..f5c3564217bba 100644
--- a/src/test/ui/reachable/expr_unary.stderr
+++ b/src/test/ui/reachable/expr_unary.stderr
@@ -8,18 +8,16 @@ error: unreachable expression
   --> $DIR/expr_unary.rs:8:16
    |
 LL |     let x: ! = ! { return; };
-   |                ^^^^^^^^^^^^^
+   |                ^^^^------^^^
+   |                |   |
+   |                |   any code following this expression is unreachable
+   |                unreachable expression
    |
 note: lint level defined here
   --> $DIR/expr_unary.rs:5:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_unary.rs:8:20
-   |
-LL |     let x: ! = ! { return; };
-   |                    ^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/reachable/expr_while.stderr b/src/test/ui/reachable/expr_while.stderr
index b6d6d11ac691e..edb1dd2b9bc70 100644
--- a/src/test/ui/reachable/expr_while.stderr
+++ b/src/test/ui/reachable/expr_while.stderr
@@ -2,38 +2,31 @@ error: unreachable block in `while` expression
   --> $DIR/expr_while.rs:7:20
    |
 LL |       while {return} {
-   |  ____________________^
+   |  ____________------__^
+   | |            |
+   | |            any code following this expression is unreachable
 LL | |
 LL | |         println!("Hello, world!");
 LL | |     }
-   | |_____^
+   | |_____^ unreachable block in `while` expression
    |
 note: lint level defined here
   --> $DIR/expr_while.rs:4:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/expr_while.rs:7:12
-   |
-LL |     while {return} {
-   |            ^^^^^^
 
 error: unreachable block in `while` expression
   --> $DIR/expr_while.rs:22:20
    |
 LL |       while {return} {
-   |  ____________________^
+   |  ____________------__^
+   | |            |
+   | |            any code following this expression is unreachable
 LL | |
 LL | |         println!("I am dead.");
 LL | |     }
-   | |_____^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/expr_while.rs:22:12
-   |
-LL |     while {return} {
-   |            ^^^^^^
+   | |_____^ unreachable block in `while` expression
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr
index ca98a3947146e..cf8f0e98305ea 100644
--- a/src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/protect-precedences.stderr
@@ -2,12 +2,9 @@ warning: unreachable block in `if` expression
   --> $DIR/protect-precedences.rs:13:41
    |
 LL |         if let _ = return true && false {};
-   |                                         ^^
+   |                    -------------------- ^^ unreachable block in `if` expression
+   |                    |
+   |                    any code following this expression is unreachable
    |
    = note: `#[warn(unreachable_code)]` on by default
-note: any code following this expression is unreachable
-  --> $DIR/protect-precedences.rs:13:20
-   |
-LL |         if let _ = return true && false {};
-   |                    ^^^^^^^^^^^^^^^^^^^^
 
diff --git a/src/test/ui/unreachable/unreachable-code.stderr b/src/test/ui/unreachable/unreachable-code.stderr
index 226f088c63a5e..184440db5df48 100644
--- a/src/test/ui/unreachable/unreachable-code.stderr
+++ b/src/test/ui/unreachable/unreachable-code.stderr
@@ -1,19 +1,17 @@
 error: unreachable statement
   --> $DIR/unreachable-code.rs:7:3
    |
+LL |   loop{}
+   |   ------ any code following this expression is unreachable
+LL | 
 LL |   let a = 3;
-   |   ^^^^^^^^^^
+   |   ^^^^^^^^^^ unreachable statement
    |
 note: lint level defined here
   --> $DIR/unreachable-code.rs:1:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/unreachable-code.rs:5:3
-   |
-LL |   loop{}
-   |   ^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unreachable/unreachable-in-call.stderr b/src/test/ui/unreachable/unreachable-in-call.stderr
index 928f5634a1248..1d081d1c76228 100644
--- a/src/test/ui/unreachable/unreachable-in-call.stderr
+++ b/src/test/ui/unreachable/unreachable-in-call.stderr
@@ -1,31 +1,25 @@
 error: unreachable expression
   --> $DIR/unreachable-in-call.rs:14:10
    |
+LL |     call(diverge(),
+   |          --------- any code following this expression is unreachable
 LL |          get_u8());
-   |          ^^^^^^^^
+   |          ^^^^^^^^ unreachable expression
    |
 note: lint level defined here
   --> $DIR/unreachable-in-call.rs:2:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/unreachable-in-call.rs:13:10
-   |
-LL |     call(diverge(),
-   |          ^^^^^^^^^
 
 error: unreachable call
   --> $DIR/unreachable-in-call.rs:17:5
    |
 LL |     call(
-   |     ^^^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/unreachable-in-call.rs:19:9
-   |
+   |     ^^^^ unreachable call
+LL |         get_u8(),
 LL |         diverge());
-   |         ^^^^^^^^^
+   |         --------- any code following this expression is unreachable
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unreachable/unreachable-try-pattern.stderr b/src/test/ui/unreachable/unreachable-try-pattern.stderr
index 889df790124da..707038442a2b6 100644
--- a/src/test/ui/unreachable/unreachable-try-pattern.stderr
+++ b/src/test/ui/unreachable/unreachable-try-pattern.stderr
@@ -2,18 +2,16 @@ warning: unreachable expression
   --> $DIR/unreachable-try-pattern.rs:19:36
    |
 LL |     let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
-   |                                    ^^^^^^^^
+   |                                    -^^^^^^^
+   |                                    |
+   |                                    unreachable expression
+   |                                    any code following this expression is unreachable
    |
 note: lint level defined here
   --> $DIR/unreachable-try-pattern.rs:3:9
    |
 LL | #![warn(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/unreachable-try-pattern.rs:19:36
-   |
-LL |     let y = (match x { Ok(n) => Ok(n as u32), Err(e) => Err(e) })?;
-   |                                    ^
 
 warning: unreachable pattern
   --> $DIR/unreachable-try-pattern.rs:19:24
diff --git a/src/test/ui/unreachable/unwarned-match-on-never.stderr b/src/test/ui/unreachable/unwarned-match-on-never.stderr
index 9ce6e3df8046e..6b2fb4a33c1e8 100644
--- a/src/test/ui/unreachable/unwarned-match-on-never.stderr
+++ b/src/test/ui/unreachable/unwarned-match-on-never.stderr
@@ -2,44 +2,34 @@ error: unreachable expression
   --> $DIR/unwarned-match-on-never.rs:10:5
    |
 LL |     match x {}
-   |     ^^^^^^^^^^
+   |           - any code following this expression is unreachable
+LL |     // But matches in unreachable code are warned.
+LL |     match x {}
+   |     ^^^^^^^^^^ unreachable expression
    |
 note: lint level defined here
   --> $DIR/unwarned-match-on-never.rs:1:9
    |
 LL | #![deny(unreachable_code)]
    |         ^^^^^^^^^^^^^^^^
-note: any code following this expression is unreachable
-  --> $DIR/unwarned-match-on-never.rs:8:11
-   |
-LL |     match x {}
-   |           ^
 
 error: unreachable arm
   --> $DIR/unwarned-match-on-never.rs:15:15
    |
-LL |         () => ()
-   |               ^^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/unwarned-match-on-never.rs:14:11
-   |
 LL |     match (return) {
-   |           ^^^^^^^^
+   |           -------- any code following this expression is unreachable
+LL |         () => ()
+   |               ^^ unreachable arm
 
 error: unreachable expression
   --> $DIR/unwarned-match-on-never.rs:21:5
    |
+LL |       return;
+   |       ------ any code following this expression is unreachable
 LL | /     match () {
 LL | |         () => (),
 LL | |     }
-   | |_____^
-   |
-note: any code following this expression is unreachable
-  --> $DIR/unwarned-match-on-never.rs:20:5
-   |
-LL |     return;
-   |     ^^^^^^
+   | |_____^ unreachable expression
 
 error: aborting due to 3 previous errors
 

From 2aa9d29c6a054d0aca249eb2f9a002acea4ba175 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 21 Sep 2019 15:07:28 -0400
Subject: [PATCH 921/943] Remove unused code

---
 src/libsyntax/ext/build.rs | 294 +------------------------------------
 1 file changed, 3 insertions(+), 291 deletions(-)

diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 84a27fcb7dd94..70f915bf8c4db 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -1,12 +1,11 @@
-use crate::ast::{self, Ident, Generics, Expr, BlockCheckMode, UnOp, PatKind};
+use crate::ast::{self, Ident, Expr, BlockCheckMode, UnOp, PatKind};
 use crate::attr;
-use crate::source_map::{dummy_spanned, respan, Spanned};
+use crate::source_map::{respan, Spanned};
 use crate::ext::base::ExtCtxt;
 use crate::ptr::P;
 use crate::symbol::{kw, sym, Symbol};
 use crate::ThinVec;
 
-use rustc_target::spec::abi::Abi;
 use syntax_pos::{Pos, Span};
 
 // Left so that Cargo tests don't break, this can be removed once those no longer use it
@@ -51,42 +50,6 @@ impl<'a> ExtCtxt<'a> {
         ast::Path { span, segments }
     }
 
-    /// Constructs a qualified path.
-    ///
-    /// Constructs a path like `<self_type as trait_path>::ident`.
-    pub fn qpath(&self,
-             self_type: P<ast::Ty>,
-             trait_path: ast::Path,
-             ident: ast::Ident)
-             -> (ast::QSelf, ast::Path) {
-        self.qpath_all(self_type, trait_path, ident, vec![], vec![])
-    }
-
-    /// Constructs a qualified path.
-    ///
-    /// Constructs a path like `<self_type as trait_path>::ident<'a, T, A = Bar>`.
-    pub fn qpath_all(&self,
-                 self_type: P<ast::Ty>,
-                 trait_path: ast::Path,
-                 ident: ast::Ident,
-                 args: Vec<ast::GenericArg>,
-                 constraints: Vec<ast::AssocTyConstraint>)
-                 -> (ast::QSelf, ast::Path) {
-        let mut path = trait_path;
-        let args = if !args.is_empty() || !constraints.is_empty() {
-            ast::AngleBracketedArgs { args, constraints, span: ident.span }.into()
-        } else {
-            None
-        };
-        path.segments.push(ast::PathSegment { ident, id: ast::DUMMY_NODE_ID, args });
-
-        (ast::QSelf {
-            ty: self_type,
-            path_span: path.span,
-            position: path.segments.len() - 1
-        }, path)
-    }
-
     pub fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
         ast::MutTy {
             ty,
@@ -219,14 +182,6 @@ impl<'a> ExtCtxt<'a> {
         }
     }
 
-    pub fn stmt_semi(&self, expr: P<ast::Expr>) -> ast::Stmt {
-        ast::Stmt {
-            id: ast::DUMMY_NODE_ID,
-            span: expr.span,
-            node: ast::StmtKind::Semi(expr),
-        }
-    }
-
     pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident,
                 ex: P<ast::Expr>) -> ast::Stmt {
         let pat = if mutbl {
@@ -250,34 +205,6 @@ impl<'a> ExtCtxt<'a> {
         }
     }
 
-    pub fn stmt_let_typed(&self,
-                      sp: Span,
-                      mutbl: bool,
-                      ident: ast::Ident,
-                      typ: P<ast::Ty>,
-                      ex: P<ast::Expr>)
-                      -> ast::Stmt {
-        let pat = if mutbl {
-            let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mutable);
-            self.pat_ident_binding_mode(sp, ident, binding_mode)
-        } else {
-            self.pat_ident(sp, ident)
-        };
-        let local = P(ast::Local {
-            pat,
-            ty: Some(typ),
-            init: Some(ex),
-            id: ast::DUMMY_NODE_ID,
-            span: sp,
-            attrs: ThinVec::new(),
-        });
-        ast::Stmt {
-            id: ast::DUMMY_NODE_ID,
-            node: ast::StmtKind::Local(local),
-            span: sp,
-        }
-    }
-
     // Generates `let _: Type;`, which is usually used for type assertions.
     pub fn stmt_let_type_only(&self, span: Span, ty: P<ast::Ty>) -> ast::Stmt {
         let local = P(ast::Local {
@@ -332,11 +259,6 @@ impl<'a> ExtCtxt<'a> {
         self.expr(path.span, ast::ExprKind::Path(None, path))
     }
 
-    /// Constructs a `QPath` expression.
-    pub fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P<ast::Expr> {
-        self.expr(span, ast::ExprKind::Path(Some(qself), path))
-    }
-
     pub fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr> {
         self.expr_path(self.path_ident(span, id))
     }
@@ -350,27 +272,12 @@ impl<'a> ExtCtxt<'a> {
     }
 
     pub fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
-        self.expr_unary(sp, UnOp::Deref, e)
-    }
-    pub fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P<ast::Expr>) -> P<ast::Expr> {
-        self.expr(sp, ast::ExprKind::Unary(op, e))
+        self.expr(sp, ast::ExprKind::Unary(UnOp::Deref, e))
     }
 
-    pub fn expr_field_access(
-        &self, sp: Span, expr: P<ast::Expr>, ident: ast::Ident,
-    ) -> P<ast::Expr> {
-        self.expr(sp, ast::ExprKind::Field(expr, ident.with_span_pos(sp)))
-    }
-    pub fn expr_tup_field_access(&self, sp: Span, expr: P<ast::Expr>, idx: usize) -> P<ast::Expr> {
-        let ident = Ident::new(sym::integer(idx), sp);
-        self.expr(sp, ast::ExprKind::Field(expr, ident))
-    }
     pub fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
         self.expr(sp, ast::ExprKind::AddrOf(ast::Mutability::Immutable, e))
     }
-    pub fn expr_mut_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
-        self.expr(sp, ast::ExprKind::AddrOf(ast::Mutability::Mutable, e))
-    }
 
     pub fn expr_call(
         &self, span: Span, expr: P<ast::Expr>, args: Vec<P<ast::Expr>>,
@@ -426,28 +333,10 @@ impl<'a> ExtCtxt<'a> {
         self.expr_lit(span, ast::LitKind::Int(i as u128,
                                               ast::LitIntType::Unsigned(ast::UintTy::Usize)))
     }
-    pub fn expr_isize(&self, sp: Span, i: isize) -> P<ast::Expr> {
-        if i < 0 {
-            let i = (-i) as u128;
-            let lit_ty = ast::LitIntType::Signed(ast::IntTy::Isize);
-            let lit = self.expr_lit(sp, ast::LitKind::Int(i, lit_ty));
-            self.expr_unary(sp, ast::UnOp::Neg, lit)
-        } else {
-            self.expr_lit(sp, ast::LitKind::Int(i as u128,
-                                                ast::LitIntType::Signed(ast::IntTy::Isize)))
-        }
-    }
     pub fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr> {
         self.expr_lit(sp, ast::LitKind::Int(u as u128,
                                             ast::LitIntType::Unsigned(ast::UintTy::U32)))
     }
-    pub fn expr_u16(&self, sp: Span, u: u16) -> P<ast::Expr> {
-        self.expr_lit(sp, ast::LitKind::Int(u as u128,
-                                            ast::LitIntType::Unsigned(ast::UintTy::U16)))
-    }
-    pub fn expr_u8(&self, sp: Span, u: u8) -> P<ast::Expr> {
-        self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U8)))
-    }
     pub fn expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr> {
         self.expr_lit(sp, ast::LitKind::Bool(value))
     }
@@ -455,10 +344,6 @@ impl<'a> ExtCtxt<'a> {
     pub fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
         self.expr(sp, ast::ExprKind::Array(exprs))
     }
-    pub fn expr_vec_ng(&self, sp: Span) -> P<ast::Expr> {
-        self.expr_call_global(sp, self.std_path(&[sym::vec, sym::Vec, sym::new]),
-                              Vec::new())
-    }
     pub fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
         self.expr_addr_of(sp, self.expr_vec(sp, exprs))
     }
@@ -475,16 +360,6 @@ impl<'a> ExtCtxt<'a> {
         self.expr_call_global(sp, some, vec![expr])
     }
 
-    pub fn expr_none(&self, sp: Span) -> P<ast::Expr> {
-        let none = self.std_path(&[sym::option, sym::Option, sym::None]);
-        let none = self.path_global(sp, none);
-        self.expr_path(none)
-    }
-
-    pub fn expr_break(&self, sp: Span) -> P<ast::Expr> {
-        self.expr(sp, ast::ExprKind::Break(None, None))
-    }
-
     pub fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
         self.expr(sp, ast::ExprKind::Tup(exprs))
     }
@@ -513,11 +388,6 @@ impl<'a> ExtCtxt<'a> {
         self.expr_call_global(sp, ok, vec![expr])
     }
 
-    pub fn expr_err(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
-        self.expr_call_global(sp, err, vec![expr])
-    }
-
     pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
         let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]);
         let ok_path = self.path_global(sp, ok);
@@ -634,10 +504,6 @@ impl<'a> ExtCtxt<'a> {
         self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els))
     }
 
-    pub fn expr_loop(&self, span: Span, block: P<ast::Block>) -> P<ast::Expr> {
-        self.expr(span, ast::ExprKind::Loop(block, None))
-    }
-
     pub fn lambda_fn_decl(&self,
                       span: Span,
                       fn_decl: P<ast::FnDecl>,
@@ -681,16 +547,6 @@ impl<'a> ExtCtxt<'a> {
         self.lambda(span, vec![ident], body)
     }
 
-    pub fn lambda_stmts(&self,
-                    span: Span,
-                    ids: Vec<ast::Ident>,
-                    stmts: Vec<ast::Stmt>)
-                    -> P<ast::Expr> {
-        self.lambda(span, ids, self.expr_block(self.block(span, stmts)))
-    }
-    pub fn lambda_stmts_0(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Expr> {
-        self.lambda0(span, self.expr_block(self.block(span, stmts)))
-    }
     pub fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>,
                       ident: ast::Ident) -> P<ast::Expr> {
         self.lambda1(span, self.expr_block(self.block(span, stmts)), ident)
@@ -732,43 +588,6 @@ impl<'a> ExtCtxt<'a> {
         })
     }
 
-    pub fn item_fn_poly(&self,
-                    span: Span,
-                    name: Ident,
-                    inputs: Vec<ast::Param> ,
-                    output: P<ast::Ty>,
-                    generics: Generics,
-                    body: P<ast::Block>) -> P<ast::Item> {
-        self.item(span,
-                  name,
-                  Vec::new(),
-                  ast::ItemKind::Fn(self.fn_decl(inputs, ast::FunctionRetTy::Ty(output)),
-                              ast::FnHeader {
-                                  unsafety: ast::Unsafety::Normal,
-                                  asyncness: dummy_spanned(ast::IsAsync::NotAsync),
-                                  constness: dummy_spanned(ast::Constness::NotConst),
-                                  abi: Abi::Rust,
-                              },
-                              generics,
-                              body))
-    }
-
-    pub fn item_fn(&self,
-               span: Span,
-               name: Ident,
-               inputs: Vec<ast::Param> ,
-               output: P<ast::Ty>,
-               body: P<ast::Block>
-              ) -> P<ast::Item> {
-        self.item_fn_poly(
-            span,
-            name,
-            inputs,
-            output,
-            Generics::default(),
-            body)
-    }
-
     pub fn variant(&self, span: Span, ident: Ident, tys: Vec<P<ast::Ty>> ) -> ast::Variant {
         let fields: Vec<_> = tys.into_iter().map(|ty| {
             ast::StructField {
@@ -799,52 +618,6 @@ impl<'a> ExtCtxt<'a> {
         }
     }
 
-    pub fn item_enum_poly(&self, span: Span, name: Ident,
-                      enum_definition: ast::EnumDef,
-                      generics: Generics) -> P<ast::Item> {
-        self.item(span, name, Vec::new(), ast::ItemKind::Enum(enum_definition, generics))
-    }
-
-    pub fn item_enum(&self, span: Span, name: Ident,
-                 enum_definition: ast::EnumDef) -> P<ast::Item> {
-        self.item_enum_poly(span, name, enum_definition,
-                            Generics::default())
-    }
-
-    pub fn item_struct(&self, span: Span, name: Ident,
-                   struct_def: ast::VariantData) -> P<ast::Item> {
-        self.item_struct_poly(
-            span,
-            name,
-            struct_def,
-            Generics::default()
-        )
-    }
-
-    pub fn item_struct_poly(&self, span: Span, name: Ident,
-        struct_def: ast::VariantData, generics: Generics) -> P<ast::Item> {
-        self.item(span, name, Vec::new(), ast::ItemKind::Struct(struct_def, generics))
-    }
-
-    pub fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
-                attrs: Vec<ast::Attribute>,
-                items: Vec<P<ast::Item>>) -> P<ast::Item> {
-        self.item(
-            span,
-            name,
-            attrs,
-            ast::ItemKind::Mod(ast::Mod {
-                inner: inner_span,
-                items,
-                inline: true
-            })
-        )
-    }
-
-    pub fn item_extern_crate(&self, span: Span, name: Ident) -> P<ast::Item> {
-        self.item(span, name, Vec::new(), ast::ItemKind::ExternCrate(None))
-    }
-
     pub fn item_static(&self,
                    span: Span,
                    name: Ident,
@@ -864,15 +637,6 @@ impl<'a> ExtCtxt<'a> {
         self.item(span, name, Vec::new(), ast::ItemKind::Const(ty, expr))
     }
 
-    pub fn item_ty_poly(&self, span: Span, name: Ident, ty: P<ast::Ty>,
-                    generics: Generics) -> P<ast::Item> {
-        self.item(span, name, Vec::new(), ast::ItemKind::TyAlias(ty, generics))
-    }
-
-    pub fn item_ty(&self, span: Span, name: Ident, ty: P<ast::Ty>) -> P<ast::Item> {
-        self.item_ty_poly(span, name, ty, Generics::default())
-    }
-
     pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute {
         attr::mk_attr_outer(mi)
     }
@@ -894,56 +658,4 @@ impl<'a> ExtCtxt<'a> {
                        -> ast::MetaItem {
         attr::mk_name_value_item(Ident::new(name, span), lit_kind, span)
     }
-
-    pub fn item_use(&self, sp: Span,
-                vis: ast::Visibility, vp: P<ast::UseTree>) -> P<ast::Item> {
-        P(ast::Item {
-            id: ast::DUMMY_NODE_ID,
-            ident: Ident::invalid(),
-            attrs: vec![],
-            node: ast::ItemKind::Use(vp),
-            vis,
-            span: sp,
-            tokens: None,
-        })
-    }
-
-    pub fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item> {
-        self.item_use_simple_(sp, vis, None, path)
-    }
-
-    pub fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
-                        rename: Option<ast::Ident>, path: ast::Path) -> P<ast::Item> {
-        self.item_use(sp, vis, P(ast::UseTree {
-            span: sp,
-            prefix: path,
-            kind: ast::UseTreeKind::Simple(rename, ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID),
-        }))
-    }
-
-    pub fn item_use_list(&self, sp: Span, vis: ast::Visibility,
-                     path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item> {
-        let imports = imports.iter().map(|id| {
-            (ast::UseTree {
-                span: sp,
-                prefix: self.path(sp, vec![*id]),
-                kind: ast::UseTreeKind::Simple(None, ast::DUMMY_NODE_ID, ast::DUMMY_NODE_ID),
-            }, ast::DUMMY_NODE_ID)
-        }).collect();
-
-        self.item_use(sp, vis, P(ast::UseTree {
-            span: sp,
-            prefix: self.path(sp, path),
-            kind: ast::UseTreeKind::Nested(imports),
-        }))
-    }
-
-    pub fn item_use_glob(&self, sp: Span,
-                     vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item> {
-        self.item_use(sp, vis, P(ast::UseTree {
-            span: sp,
-            prefix: self.path(sp, path),
-            kind: ast::UseTreeKind::Glob,
-        }))
-    }
 }

From e41aa8c0d04d9a663638e66a82868f0fbeb83bd8 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 21 Sep 2019 15:05:31 -0400
Subject: [PATCH 922/943] Inline ty_infer

---
 src/libsyntax/ext/build.rs | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 70f915bf8c4db..cadd7d563dab2 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -111,10 +111,6 @@ impl<'a> ExtCtxt<'a> {
                 ast::TyKind::Ptr(self.ty_mt(ty, mutbl)))
     }
 
-    pub fn ty_infer(&self, span: Span) -> P<ast::Ty> {
-        self.ty(span, ast::TyKind::Infer)
-    }
-
     pub fn typaram(&self,
                span: Span,
                ident: ast::Ident,
@@ -524,7 +520,7 @@ impl<'a> ExtCtxt<'a> {
               body: P<ast::Expr>)
               -> P<ast::Expr> {
         let fn_decl = self.fn_decl(
-            ids.iter().map(|id| self.param(span, *id, self.ty_infer(span))).collect(),
+            ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(),
             ast::FunctionRetTy::Default(span));
 
         // FIXME -- We are using `span` as the span of the `|...|`

From 8417ac67c3fe979098facad586438ea5244617b3 Mon Sep 17 00:00:00 2001
From: Mark Rousskov <mark.simulacrum@gmail.com>
Date: Sat, 21 Sep 2019 15:26:15 -0400
Subject: [PATCH 923/943] Inline attribute constructors

---
 src/libsyntax/ext/build.rs                | 14 --------------
 src/libsyntax_ext/deriving/cmp/eq.rs      |  6 +++---
 src/libsyntax_ext/deriving/generic/mod.rs |  7 +++++--
 src/libsyntax_ext/test.rs                 |  4 ++--
 4 files changed, 10 insertions(+), 21 deletions(-)

diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index cadd7d563dab2..ccd73bb66c677 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -640,18 +640,4 @@ impl<'a> ExtCtxt<'a> {
     pub fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem {
         attr::mk_word_item(Ident::new(w, sp))
     }
-
-    pub fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem {
-        attr::mk_nested_word_item(Ident::new(w, sp))
-    }
-
-    pub fn meta_list(&self, sp: Span, name: ast::Name, mis: Vec<ast::NestedMetaItem>)
-                 -> ast::MetaItem {
-        attr::mk_list_item(Ident::new(name, sp), mis)
-    }
-
-    pub fn meta_name_value(&self, span: Span, name: ast::Name, lit_kind: ast::LitKind)
-                       -> ast::MetaItem {
-        attr::mk_name_value_item(Ident::new(name, span), lit_kind, span)
-    }
 }
diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs
index 471c92dd99949..c92339dd2fbd5 100644
--- a/src/libsyntax_ext/deriving/cmp/eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/eq.rs
@@ -2,7 +2,7 @@ use crate::deriving::path_std;
 use crate::deriving::generic::*;
 use crate::deriving::generic::ty::*;
 
-use syntax::ast::{self, Expr, MetaItem, GenericArg};
+use syntax::ast::{self, Ident, Expr, MetaItem, GenericArg};
 use syntax::ext::base::{Annotatable, ExtCtxt, SpecialDerives};
 use syntax::ptr::P;
 use syntax::symbol::{sym, Symbol};
@@ -16,8 +16,8 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>,
     cx.resolver.add_derives(cx.current_expansion.id.expn_data().parent, SpecialDerives::EQ);
 
     let inline = cx.meta_word(span, sym::inline);
-    let hidden = cx.meta_list_item_word(span, sym::hidden);
-    let doc = cx.meta_list(span, sym::doc, vec![hidden]);
+    let hidden = syntax::attr::mk_nested_word_item(Ident::new(sym::hidden, span));
+    let doc = syntax::attr::mk_list_item(Ident::new(sym::doc, span), vec![hidden]);
     let attrs = vec![cx.attribute(inline), cx.attribute(doc)];
     let trait_def = TraitDef {
         span,
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 5c332eccb62cc..fec035d331dc5 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -672,8 +672,11 @@ impl<'a> TraitDef<'a> {
         attr::mark_used(&attr);
         let opt_trait_ref = Some(trait_ref);
         let unused_qual = {
-            let word = cx.meta_list_item_word(self.span, Symbol::intern("unused_qualifications"));
-            cx.attribute(cx.meta_list(self.span, sym::allow, vec![word]))
+            let word = syntax::attr::mk_nested_word_item(
+                Ident::new(Symbol::intern("unused_qualifications"), self.span));
+            let list = syntax::attr::mk_list_item(
+                Ident::new(sym::allow, self.span), vec![word]);
+            cx.attribute(list)
         };
 
         let mut a = vec![attr, unused_qual];
diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs
index 0910c00a8a2a9..6c7e3e3eb9875 100644
--- a/src/libsyntax_ext/test.rs
+++ b/src/libsyntax_ext/test.rs
@@ -145,8 +145,8 @@ pub fn expand_test_or_bench(
     let mut test_const = cx.item(sp, ast::Ident::new(item.ident.name, sp),
         vec![
             // #[cfg(test)]
-            cx.attribute(cx.meta_list(attr_sp, sym::cfg, vec![
-                cx.meta_list_item_word(attr_sp, sym::test)
+            cx.attribute(attr::mk_list_item(ast::Ident::new(sym::cfg, attr_sp), vec![
+                attr::mk_nested_word_item(ast::Ident::new(sym::test, attr_sp))
             ])),
             // #[rustc_test_marker]
             cx.attribute(cx.meta_word(attr_sp, sym::rustc_test_marker)),

From 3e6b84474d7cd813bda0956568966024915d0ea8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 21 Sep 2019 16:31:27 -0700
Subject: [PATCH 924/943] Propagate `types.err` in locals further to avoid
 spurious knock-down errors

---
 src/librustc_typeck/check/coercion.rs |  8 ++++++--
 src/librustc_typeck/check/mod.rs      | 23 ++++++++++++++++++++++-
 src/test/ui/issues/issue-33575.rs     |  4 ++++
 src/test/ui/issues/issue-33575.stderr |  9 +++++++++
 4 files changed, 41 insertions(+), 3 deletions(-)
 create mode 100644 src/test/ui/issues/issue-33575.rs
 create mode 100644 src/test/ui/issues/issue-33575.stderr

diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index ee4f0a868c10a..ac1bf8e91a149 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -163,7 +163,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
         // Just ignore error types.
         if a.references_error() || b.references_error() {
-            return success(vec![], b, vec![]);
+            return success(vec![], self.fcx.tcx.types.err, vec![]);
         }
 
         if a.is_never() {
@@ -821,7 +821,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let (adjustments, _) = self.register_infer_ok_obligations(ok);
         self.apply_adjustments(expr, adjustments);
-        Ok(target)
+        if expr_ty.references_error() {
+            Ok(self.tcx.types.err)
+        } else {
+            Ok(target)
+        }
     }
 
     /// Same as `try_coerce()`, but without side-effects.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 0eeeee01c82f1..75942731d8790 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -153,7 +153,7 @@ use self::method::{MethodCallee, SelfSource};
 use self::TupleArgumentsFlag::*;
 
 /// The type of a local binding, including the revealed type for anon types.
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 pub struct LocalTy<'tcx> {
     decl_ty: Ty<'tcx>,
     revealed_ty: Ty<'tcx>
@@ -3752,14 +3752,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if let Some(ref init) = local.init {
             let init_ty = self.check_decl_initializer(local, &init);
             if init_ty.references_error() {
+                // Override the types everywhere with `types.err` to avoid knock down errors.
                 self.write_ty(local.hir_id, init_ty);
+                self.write_ty(local.pat.hir_id, init_ty);
+                self.locals.borrow_mut().insert(local.hir_id, LocalTy {
+                    decl_ty: t,
+                    revealed_ty: init_ty,
+                });
+                self.locals.borrow_mut().insert(local.pat.hir_id, LocalTy {
+                    decl_ty: t,
+                    revealed_ty: init_ty,
+                });
             }
         }
 
         self.check_pat_top(&local.pat, t, None);
         let pat_ty = self.node_ty(local.pat.hir_id);
+        debug!("check_decl_local pat_ty {:?}", pat_ty);
         if pat_ty.references_error() {
+            // Override the types everywhere with `types.err` to avoid knock down errors.
             self.write_ty(local.hir_id, pat_ty);
+            self.write_ty(local.pat.hir_id, pat_ty);
+            self.locals.borrow_mut().insert(local.hir_id, LocalTy {
+                decl_ty: t,
+                revealed_ty: pat_ty,
+            });
+            self.locals.borrow_mut().insert(local.pat.hir_id, LocalTy {
+                decl_ty: t,
+                revealed_ty: pat_ty,
+            });
         }
     }
 
diff --git a/src/test/ui/issues/issue-33575.rs b/src/test/ui/issues/issue-33575.rs
new file mode 100644
index 0000000000000..d97afc3d31d5c
--- /dev/null
+++ b/src/test/ui/issues/issue-33575.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let baz = ().foo(); //~ ERROR no method named `foo` found for type `()` in the current scope
+    <i32 as std::str::FromStr>::from_str(&baz); // No complains about `str` being unsized
+}
diff --git a/src/test/ui/issues/issue-33575.stderr b/src/test/ui/issues/issue-33575.stderr
new file mode 100644
index 0000000000000..e6b74d262c340
--- /dev/null
+++ b/src/test/ui/issues/issue-33575.stderr
@@ -0,0 +1,9 @@
+error[E0599]: no method named `foo` found for type `()` in the current scope
+  --> $DIR/issue-33575.rs:2:18
+   |
+LL |     let baz = ().foo();
+   |                  ^^^ method not found in `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.

From 9991d548c72529a7475d33c6925ee23601568aec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 21 Sep 2019 16:34:16 -0700
Subject: [PATCH 925/943] review comments

---
 src/test/ui/lint/unreachable-async-fn.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/test/ui/lint/unreachable-async-fn.rs b/src/test/ui/lint/unreachable-async-fn.rs
index 6e09c3136b5a0..eedd877fe7841 100644
--- a/src/test/ui/lint/unreachable-async-fn.rs
+++ b/src/test/ui/lint/unreachable-async-fn.rs
@@ -1,7 +1,7 @@
-// run-pass
+// check-pass
 // edition:2018
-#[allow(dead_code)]
 
+#[allow(dead_code)]
 async fn foo () { // unreachable lint doesn't trigger
    unimplemented!()
 }

From 60560bc2a2c149e179cd7e58a8b48e06c2c4e3f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 21 Sep 2019 17:11:09 -0700
Subject: [PATCH 926/943] Parse assoc type bounds in generic params and provide
 custom diagnostic

---
 src/libsyntax/parse/parser/generics.rs        | 99 ++++++++++++-------
 src/test/ui/parser/assoc-type-in-type-arg.rs  | 11 +++
 .../ui/parser/assoc-type-in-type-arg.stderr   |  8 ++
 3 files changed, 80 insertions(+), 38 deletions(-)
 create mode 100644 src/test/ui/parser/assoc-type-in-type-arg.rs
 create mode 100644 src/test/ui/parser/assoc-type-in-type-arg.stderr

diff --git a/src/libsyntax/parse/parser/generics.rs b/src/libsyntax/parse/parser/generics.rs
index 3e6118ad86f47..1ffdda19c80b5 100644
--- a/src/libsyntax/parse/parser/generics.rs
+++ b/src/libsyntax/parse/parser/generics.rs
@@ -100,13 +100,31 @@ impl<'a> Parser<'a> {
             } else if self.check_ident() {
                 // Parse type parameter.
                 params.push(self.parse_ty_param(attrs)?);
+            } else if self.token.can_begin_type() {
+                // Trying to write an associated type bound? (#26271)
+                let snapshot = self.clone();
+                match self.parse_ty_where_predicate() {
+                    Ok(where_predicate) => {
+                        self.struct_span_err(
+                            where_predicate.span(),
+                            "associated type bounds do not belong here",
+                        )
+                        .span_label(where_predicate.span(), "belongs in `where` clause")
+                        .emit();
+                    }
+                    Err(mut err) => {
+                        err.cancel();
+                        std::mem::replace(self, snapshot);
+                        break
+                    }
+                }
             } else {
                 // Check for trailing attributes and stop parsing.
                 if !attrs.is_empty() {
                     if !params.is_empty() {
                         self.struct_span_err(
                             attrs[0].span,
-                            &format!("trailing attribute after generic parameter"),
+                            "trailing attribute after generic parameter",
                         )
                         .span_label(attrs[0].span, "attributes must go before parameters")
                         .emit();
@@ -202,43 +220,7 @@ impl<'a> Parser<'a> {
                     }
                 ));
             } else if self.check_type() {
-                // Parse optional `for<'a, 'b>`.
-                // This `for` is parsed greedily and applies to the whole predicate,
-                // the bounded type can have its own `for` applying only to it.
-                // Examples:
-                // * `for<'a> Trait1<'a>: Trait2<'a /* ok */>`
-                // * `(for<'a> Trait1<'a>): Trait2<'a /* not ok */>`
-                // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>`
-                let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
-
-                // Parse type with mandatory colon and (possibly empty) bounds,
-                // or with mandatory equality sign and the second type.
-                let ty = self.parse_ty()?;
-                if self.eat(&token::Colon) {
-                    let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
-                    where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
-                        ast::WhereBoundPredicate {
-                            span: lo.to(self.prev_span),
-                            bound_generic_params: lifetime_defs,
-                            bounded_ty: ty,
-                            bounds,
-                        }
-                    ));
-                // FIXME: Decide what should be used here, `=` or `==`.
-                // FIXME: We are just dropping the binders in lifetime_defs on the floor here.
-                } else if self.eat(&token::Eq) || self.eat(&token::EqEq) {
-                    let rhs_ty = self.parse_ty()?;
-                    where_clause.predicates.push(ast::WherePredicate::EqPredicate(
-                        ast::WhereEqPredicate {
-                            span: lo.to(self.prev_span),
-                            lhs_ty: ty,
-                            rhs_ty,
-                            id: ast::DUMMY_NODE_ID,
-                        }
-                    ));
-                } else {
-                    return self.unexpected();
-                }
+                where_clause.predicates.push(self.parse_ty_where_predicate()?);
             } else {
                 break
             }
@@ -252,6 +234,47 @@ impl<'a> Parser<'a> {
         Ok(where_clause)
     }
 
+    fn parse_ty_where_predicate(&mut self) -> PResult<'a, ast::WherePredicate> {
+        let lo = self.token.span;
+        // Parse optional `for<'a, 'b>`.
+        // This `for` is parsed greedily and applies to the whole predicate,
+        // the bounded type can have its own `for` applying only to it.
+        // Examples:
+        // * `for<'a> Trait1<'a>: Trait2<'a /* ok */>`
+        // * `(for<'a> Trait1<'a>): Trait2<'a /* not ok */>`
+        // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>`
+        let lifetime_defs = self.parse_late_bound_lifetime_defs()?;
+
+        // Parse type with mandatory colon and (possibly empty) bounds,
+        // or with mandatory equality sign and the second type.
+        let ty = self.parse_ty()?;
+        if self.eat(&token::Colon) {
+            let bounds = self.parse_generic_bounds(Some(self.prev_span))?;
+            Ok(ast::WherePredicate::BoundPredicate(
+                ast::WhereBoundPredicate {
+                    span: lo.to(self.prev_span),
+                    bound_generic_params: lifetime_defs,
+                    bounded_ty: ty,
+                    bounds,
+                }
+            ))
+        // FIXME: Decide what should be used here, `=` or `==`.
+        // FIXME: We are just dropping the binders in lifetime_defs on the floor here.
+        } else if self.eat(&token::Eq) || self.eat(&token::EqEq) {
+            let rhs_ty = self.parse_ty()?;
+            Ok(ast::WherePredicate::EqPredicate(
+                ast::WhereEqPredicate {
+                    span: lo.to(self.prev_span),
+                    lhs_ty: ty,
+                    rhs_ty,
+                    id: ast::DUMMY_NODE_ID,
+                }
+            ))
+        } else {
+            self.unexpected()
+        }
+    }
+
     pub(super) fn choose_generics_over_qpath(&self) -> bool {
         // There's an ambiguity between generic parameters and qualified paths in impls.
         // If we see `<` it may start both, so we have to inspect some following tokens.
diff --git a/src/test/ui/parser/assoc-type-in-type-arg.rs b/src/test/ui/parser/assoc-type-in-type-arg.rs
new file mode 100644
index 0000000000000..09765f01371aa
--- /dev/null
+++ b/src/test/ui/parser/assoc-type-in-type-arg.rs
@@ -0,0 +1,11 @@
+trait Tr {
+    type TrSubtype;
+}
+
+struct Bar<'a, Item: Tr, <Item as Tr>::TrSubtype: 'a> {
+    //~^ ERROR associated type bounds do not belong here
+    item: Item,
+    item_sub: &'a <Item as Tr>::TrSubtype,
+}
+
+fn main() {}
diff --git a/src/test/ui/parser/assoc-type-in-type-arg.stderr b/src/test/ui/parser/assoc-type-in-type-arg.stderr
new file mode 100644
index 0000000000000..06addb0241725
--- /dev/null
+++ b/src/test/ui/parser/assoc-type-in-type-arg.stderr
@@ -0,0 +1,8 @@
+error: associated type bounds do not belong here
+  --> $DIR/assoc-type-in-type-arg.rs:5:26
+   |
+LL | struct Bar<'a, Item: Tr, <Item as Tr>::TrSubtype: 'a> {
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ belongs in `where` clause
+
+error: aborting due to previous error
+

From c3d791740f7bc5f85d24e30c835f23cc1423797c Mon Sep 17 00:00:00 2001
From: Tshepang Lekhonkhobe <tshepang@gmail.com>
Date: Sun, 22 Sep 2019 02:23:41 +0200
Subject: [PATCH 927/943] remove outdated comment

---
 src/librustc_mir/borrow_check/flows.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs
index 4400e0c8395a2..1f17ab69f6660 100644
--- a/src/librustc_mir/borrow_check/flows.rs
+++ b/src/librustc_mir/borrow_check/flows.rs
@@ -23,7 +23,6 @@ use std::rc::Rc;
 
 crate type PoloniusOutput = Output<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>;
 
-// (forced to be `pub` due to its use as an associated type below.)
 crate struct Flows<'b, 'tcx> {
     borrows: FlowAtLocation<'tcx, Borrows<'b, 'tcx>>,
     pub uninits: FlowAtLocation<'tcx, MaybeUninitializedPlaces<'b, 'tcx>>,

From daed67481511b65475069214cd8325ca9d018509 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 21 Sep 2019 17:28:07 -0700
Subject: [PATCH 928/943] review comments

---
 src/librustc_typeck/check/coercion.rs |  8 +++---
 src/librustc_typeck/check/mod.rs      | 39 ++++++++++-----------------
 src/test/ui/issues/issue-33575.rs     |  2 +-
 3 files changed, 19 insertions(+), 30 deletions(-)

diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index ac1bf8e91a149..d98e1f3e1283f 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -821,11 +821,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let (adjustments, _) = self.register_infer_ok_obligations(ok);
         self.apply_adjustments(expr, adjustments);
-        if expr_ty.references_error() {
-            Ok(self.tcx.types.err)
+        Ok(if expr_ty.references_error() {
+            self.tcx.types.err
         } else {
-            Ok(target)
-        }
+            target
+        })
     }
 
     /// Same as `try_coerce()`, but without side-effects.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 75942731d8790..07eb034054c95 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3751,36 +3751,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if let Some(ref init) = local.init {
             let init_ty = self.check_decl_initializer(local, &init);
-            if init_ty.references_error() {
-                // Override the types everywhere with `types.err` to avoid knock down errors.
-                self.write_ty(local.hir_id, init_ty);
-                self.write_ty(local.pat.hir_id, init_ty);
-                self.locals.borrow_mut().insert(local.hir_id, LocalTy {
-                    decl_ty: t,
-                    revealed_ty: init_ty,
-                });
-                self.locals.borrow_mut().insert(local.pat.hir_id, LocalTy {
-                    decl_ty: t,
-                    revealed_ty: init_ty,
-                });
-            }
+            self.overwrite_local_ty_if_err(local, t, init_ty);
         }
 
         self.check_pat_top(&local.pat, t, None);
         let pat_ty = self.node_ty(local.pat.hir_id);
-        debug!("check_decl_local pat_ty {:?}", pat_ty);
-        if pat_ty.references_error() {
+        self.overwrite_local_ty_if_err(local, t, pat_ty);
+    }
+
+    fn overwrite_local_ty_if_err(&self, local: &'tcx hir::Local, decl_ty: Ty<'tcx>, ty: Ty<'tcx>) {
+        if ty.references_error() {
             // Override the types everywhere with `types.err` to avoid knock down errors.
-            self.write_ty(local.hir_id, pat_ty);
-            self.write_ty(local.pat.hir_id, pat_ty);
-            self.locals.borrow_mut().insert(local.hir_id, LocalTy {
-                decl_ty: t,
-                revealed_ty: pat_ty,
-            });
-            self.locals.borrow_mut().insert(local.pat.hir_id, LocalTy {
-                decl_ty: t,
-                revealed_ty: pat_ty,
-            });
+            self.write_ty(local.hir_id, ty);
+            self.write_ty(local.pat.hir_id, ty);
+            let local_ty = LocalTy {
+                decl_ty,
+                revealed_ty: ty,
+            };
+            self.locals.borrow_mut().insert(local.hir_id, local_ty);
+            self.locals.borrow_mut().insert(local.pat.hir_id, local_ty);
         }
     }
 
diff --git a/src/test/ui/issues/issue-33575.rs b/src/test/ui/issues/issue-33575.rs
index d97afc3d31d5c..09c499452adb6 100644
--- a/src/test/ui/issues/issue-33575.rs
+++ b/src/test/ui/issues/issue-33575.rs
@@ -1,4 +1,4 @@
 fn main() {
     let baz = ().foo(); //~ ERROR no method named `foo` found for type `()` in the current scope
-    <i32 as std::str::FromStr>::from_str(&baz); // No complains about `str` being unsized
+    <i32 as std::str::FromStr>::from_str(&baz); // No complaints about `str` being unsized
 }

From 0f2f16db5364663b4a2f092bba61dc3b056902e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 21 Sep 2019 18:57:37 -0700
Subject: [PATCH 929/943] review comments: wording

---
 src/libsyntax/parse/parser/generics.rs           | 2 +-
 src/test/ui/parser/assoc-type-in-type-arg.rs     | 2 +-
 src/test/ui/parser/assoc-type-in-type-arg.stderr | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/libsyntax/parse/parser/generics.rs b/src/libsyntax/parse/parser/generics.rs
index 1ffdda19c80b5..2ecd9cca3c64b 100644
--- a/src/libsyntax/parse/parser/generics.rs
+++ b/src/libsyntax/parse/parser/generics.rs
@@ -107,7 +107,7 @@ impl<'a> Parser<'a> {
                     Ok(where_predicate) => {
                         self.struct_span_err(
                             where_predicate.span(),
-                            "associated type bounds do not belong here",
+                            "bounds on associated types do not belong here",
                         )
                         .span_label(where_predicate.span(), "belongs in `where` clause")
                         .emit();
diff --git a/src/test/ui/parser/assoc-type-in-type-arg.rs b/src/test/ui/parser/assoc-type-in-type-arg.rs
index 09765f01371aa..000956ea24fad 100644
--- a/src/test/ui/parser/assoc-type-in-type-arg.rs
+++ b/src/test/ui/parser/assoc-type-in-type-arg.rs
@@ -3,7 +3,7 @@ trait Tr {
 }
 
 struct Bar<'a, Item: Tr, <Item as Tr>::TrSubtype: 'a> {
-    //~^ ERROR associated type bounds do not belong here
+    //~^ ERROR bounds on associated types do not belong here
     item: Item,
     item_sub: &'a <Item as Tr>::TrSubtype,
 }
diff --git a/src/test/ui/parser/assoc-type-in-type-arg.stderr b/src/test/ui/parser/assoc-type-in-type-arg.stderr
index 06addb0241725..b637702f21e90 100644
--- a/src/test/ui/parser/assoc-type-in-type-arg.stderr
+++ b/src/test/ui/parser/assoc-type-in-type-arg.stderr
@@ -1,4 +1,4 @@
-error: associated type bounds do not belong here
+error: bounds on associated types do not belong here
   --> $DIR/assoc-type-in-type-arg.rs:5:26
    |
 LL | struct Bar<'a, Item: Tr, <Item as Tr>::TrSubtype: 'a> {

From 3f2855e4a6003f7e4d5736843d9ca5f327bef9d7 Mon Sep 17 00:00:00 2001
From: ben <benlewisj@gmail.com>
Date: Sun, 22 Sep 2019 17:24:09 +1200
Subject: [PATCH 930/943] Infer consts consistently. Moved some logic into
 super_combined_consts, also removed some duplicated logic from TypeRelation
 methods.

---
 src/librustc/infer/combine.rs                 |  7 ++++
 src/librustc/infer/equate.rs                  | 40 ++----------------
 src/librustc/infer/glb.rs                     |  5 ---
 src/librustc/infer/lub.rs                     |  5 ---
 src/librustc/infer/sub.rs                     | 42 ++-----------------
 src/test/ui/const-generics/issue-64519.rs     | 21 ++++++++++
 src/test/ui/const-generics/issue-64519.stderr |  8 ++++
 7 files changed, 42 insertions(+), 86 deletions(-)
 create mode 100644 src/test/ui/const-generics/issue-64519.rs
 create mode 100644 src/test/ui/const-generics/issue-64519.stderr

diff --git a/src/librustc/infer/combine.rs b/src/librustc/infer/combine.rs
index 4a9b68f24371d..966c5810171af 100644
--- a/src/librustc/infer/combine.rs
+++ b/src/librustc/infer/combine.rs
@@ -30,6 +30,7 @@ use super::sub::Sub;
 use super::type_variable::TypeVariableValue;
 use super::unify_key::{ConstVarValue, ConstVariableValue};
 use super::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
+use super::unify_key::replace_if_possible;
 
 use crate::hir::def_id::DefId;
 use crate::mir::interpret::ConstValue;
@@ -127,6 +128,12 @@ impl<'infcx, 'tcx> InferCtxt<'infcx, 'tcx> {
     where
         R: TypeRelation<'tcx>,
     {
+        debug!("{}.consts({:?}, {:?})", relation.tag(), a, b);
+        if a == b { return Ok(a); }
+
+        let a = replace_if_possible(self.const_unification_table.borrow_mut(), a);
+        let b = replace_if_possible(self.const_unification_table.borrow_mut(), b);
+
         let a_is_expected = relation.a_is_expected();
 
         match (a.val, b.val) {
diff --git a/src/librustc/infer/equate.rs b/src/librustc/infer/equate.rs
index 96d40bc81add2..6065387647fa7 100644
--- a/src/librustc/infer/equate.rs
+++ b/src/librustc/infer/equate.rs
@@ -1,14 +1,12 @@
-use super::combine::{CombineFields, RelationDir, const_unification_error};
+use super::combine::{CombineFields, RelationDir};
 use super::Subtype;
 
 use crate::hir::def_id::DefId;
 
-use crate::ty::{self, Ty, TyCtxt, InferConst};
+use crate::ty::{self, Ty, TyCtxt};
 use crate::ty::TyVar;
 use crate::ty::subst::SubstsRef;
 use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
-use crate::mir::interpret::ConstValue;
-use crate::infer::unify_key::replace_if_possible;
 
 /// Ensures `a` is made equal to `b`. Returns `a` on success.
 pub struct Equate<'combine, 'infcx, 'tcx> {
@@ -108,39 +106,7 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
         a: &'tcx ty::Const<'tcx>,
         b: &'tcx ty::Const<'tcx>,
     ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
-        debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
-        if a == b { return Ok(a); }
-
-        let infcx = self.fields.infcx;
-        let a = replace_if_possible(infcx.const_unification_table.borrow_mut(), a);
-        let b = replace_if_possible(infcx.const_unification_table.borrow_mut(), b);
-        let a_is_expected = self.a_is_expected();
-
-        match (a.val, b.val) {
-            (ConstValue::Infer(InferConst::Var(a_vid)),
-                ConstValue::Infer(InferConst::Var(b_vid))) => {
-                infcx.const_unification_table
-                    .borrow_mut()
-                    .unify_var_var(a_vid, b_vid)
-                    .map_err(|e| const_unification_error(a_is_expected, e))?;
-                return Ok(a);
-            }
-
-            (ConstValue::Infer(InferConst::Var(a_id)), _) => {
-                self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
-                return Ok(a);
-            }
-
-            (_, ConstValue::Infer(InferConst::Var(b_id))) => {
-                self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
-                return Ok(a);
-            }
-
-            _ => {}
-        }
-
-        self.fields.infcx.super_combine_consts(self, a, b)?;
-        Ok(a)
+        self.fields.infcx.super_combine_consts(self, a, b)
     }
 
     fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
diff --git a/src/librustc/infer/glb.rs b/src/librustc/infer/glb.rs
index 10e45321a6d6a..37de54a7e8558 100644
--- a/src/librustc/infer/glb.rs
+++ b/src/librustc/infer/glb.rs
@@ -66,11 +66,6 @@ impl TypeRelation<'tcx> for Glb<'combine, 'infcx, 'tcx> {
         a: &'tcx ty::Const<'tcx>,
         b: &'tcx ty::Const<'tcx>,
     ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
-        debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
-        if a == b {
-            return Ok(a);
-        }
-
         self.fields.infcx.super_combine_consts(self, a, b)
     }
 
diff --git a/src/librustc/infer/lub.rs b/src/librustc/infer/lub.rs
index 8b64cda7bd26d..a1a94865e74e3 100644
--- a/src/librustc/infer/lub.rs
+++ b/src/librustc/infer/lub.rs
@@ -66,11 +66,6 @@ impl TypeRelation<'tcx> for Lub<'combine, 'infcx, 'tcx> {
         a: &'tcx ty::Const<'tcx>,
         b: &'tcx ty::Const<'tcx>,
     ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
-        debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
-        if a == b {
-            return Ok(a);
-        }
-
         self.fields.infcx.super_combine_consts(self, a, b)
     }
 
diff --git a/src/librustc/infer/sub.rs b/src/librustc/infer/sub.rs
index 76db55ecfa8ef..67c97ef5d8b29 100644
--- a/src/librustc/infer/sub.rs
+++ b/src/librustc/infer/sub.rs
@@ -1,13 +1,11 @@
 use super::SubregionOrigin;
-use super::combine::{CombineFields, RelationDir, const_unification_error};
+use super::combine::{CombineFields, RelationDir};
 
 use crate::traits::Obligation;
-use crate::ty::{self, Ty, TyCtxt, InferConst};
+use crate::ty::{self, Ty, TyCtxt};
 use crate::ty::TyVar;
 use crate::ty::fold::TypeFoldable;
 use crate::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
-use crate::infer::unify_key::replace_if_possible;
-use crate::mir::interpret::ConstValue;
 use std::mem;
 
 /// Ensures `a` is made a subtype of `b`. Returns `a` on success.
@@ -142,41 +140,7 @@ impl TypeRelation<'tcx> for Sub<'combine, 'infcx, 'tcx> {
         a: &'tcx ty::Const<'tcx>,
         b: &'tcx ty::Const<'tcx>,
     ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
-        debug!("{}.consts({:?}, {:?})", self.tag(), a, b);
-        if a == b { return Ok(a); }
-
-        let infcx = self.fields.infcx;
-        let a = replace_if_possible(infcx.const_unification_table.borrow_mut(), a);
-        let b = replace_if_possible(infcx.const_unification_table.borrow_mut(), b);
-
-        // Consts can only be equal or unequal to each other: there's no subtyping
-        // relation, so we're just going to perform equating here instead.
-        let a_is_expected = self.a_is_expected();
-        match (a.val, b.val) {
-            (ConstValue::Infer(InferConst::Var(a_vid)),
-                ConstValue::Infer(InferConst::Var(b_vid))) => {
-                infcx.const_unification_table
-                    .borrow_mut()
-                    .unify_var_var(a_vid, b_vid)
-                    .map_err(|e| const_unification_error(a_is_expected, e))?;
-                return Ok(a);
-            }
-
-            (ConstValue::Infer(InferConst::Var(a_id)), _) => {
-                self.fields.infcx.unify_const_variable(a_is_expected, a_id, b)?;
-                return Ok(a);
-            }
-
-            (_, ConstValue::Infer(InferConst::Var(b_id))) => {
-                self.fields.infcx.unify_const_variable(!a_is_expected, b_id, a)?;
-                return Ok(a);
-            }
-
-            _ => {}
-        }
-
-        self.fields.infcx.super_combine_consts(self, a, b)?;
-        Ok(a)
+        self.fields.infcx.super_combine_consts(self, a, b)
     }
 
     fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
diff --git a/src/test/ui/const-generics/issue-64519.rs b/src/test/ui/const-generics/issue-64519.rs
new file mode 100644
index 0000000000000..72cce9b4843d7
--- /dev/null
+++ b/src/test/ui/const-generics/issue-64519.rs
@@ -0,0 +1,21 @@
+// check-pass
+
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+struct Foo<const D: usize> {
+    state: Option<[u8; D]>,
+}
+
+impl<const D: usize> Iterator for Foo<{D}> {
+    type Item = [u8; D];
+    fn next(&mut self) -> Option<Self::Item> {
+        if true {
+            return Some(self.state.unwrap().clone());
+        } else {
+            return Some(self.state.unwrap().clone());
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/const-generics/issue-64519.stderr b/src/test/ui/const-generics/issue-64519.stderr
new file mode 100644
index 0000000000000..d368f39d903a0
--- /dev/null
+++ b/src/test/ui/const-generics/issue-64519.stderr
@@ -0,0 +1,8 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+  --> $DIR/issue-64519.rs:3:12
+   |
+LL | #![feature(const_generics)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+

From bbce971bf7cc37f5f02b759b7e4235ec591a5a4b Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Thu, 19 Sep 2019 08:32:31 +0000
Subject: [PATCH 931/943] Update clippy

---
 Cargo.lock       | 30 +++++++++++++++++++++---------
 src/tools/clippy |  2 +-
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index f52e9738da8f9..fa749e5e3aebe 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -455,7 +455,7 @@ dependencies = [
  "itertools 0.8.0",
  "lazy_static 1.3.0",
  "matches",
- "pulldown-cmark",
+ "pulldown-cmark 0.6.0",
  "quine-mc_cluskey",
  "regex-syntax",
  "semver",
@@ -1637,7 +1637,7 @@ dependencies = [
  "num_cpus",
  "tokio",
  "tokio-codec",
- "unicase 2.4.0",
+ "unicase 2.5.1",
 ]
 
 [[package]]
@@ -1875,7 +1875,7 @@ dependencies = [
  "log",
  "memchr",
  "open",
- "pulldown-cmark",
+ "pulldown-cmark 0.5.3",
  "regex",
  "serde",
  "serde_derive",
@@ -1897,7 +1897,7 @@ dependencies = [
  "log",
  "mdbook",
  "memchr",
- "pulldown-cmark",
+ "pulldown-cmark 0.5.3",
  "rayon",
  "regex",
  "reqwest",
@@ -1957,7 +1957,7 @@ version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425"
 dependencies = [
- "unicase 2.4.0",
+ "unicase 2.5.1",
 ]
 
 [[package]]
@@ -2561,7 +2561,19 @@ dependencies = [
  "bitflags",
  "getopts",
  "memchr",
- "unicase 2.4.0",
+ "unicase 2.5.1",
+]
+
+[[package]]
+name = "pulldown-cmark"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85b0ad0d4c1702965ee6bb5b4ff5e71f83850b497d497e9444302987bf9e26a4"
+dependencies = [
+ "bitflags",
+ "getopts",
+ "memchr",
+ "unicase 2.5.1",
 ]
 
 [[package]]
@@ -3732,7 +3744,7 @@ name = "rustdoc"
 version = "0.0.0"
 dependencies = [
  "minifier",
- "pulldown-cmark",
+ "pulldown-cmark 0.5.3",
  "rustc-rayon",
  "tempfile",
 ]
@@ -4739,9 +4751,9 @@ dependencies = [
 
 [[package]]
 name = "unicase"
-version = "2.4.0"
+version = "2.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6"
+checksum = "2e2e6bd1e59e56598518beb94fd6db628ded570326f0a98c679a304bd9f00150"
 dependencies = [
  "version_check",
 ]
diff --git a/src/tools/clippy b/src/tools/clippy
index 58e01ea4d7df6..157edad6205fd 160000
--- a/src/tools/clippy
+++ b/src/tools/clippy
@@ -1 +1 @@
-Subproject commit 58e01ea4d7df69e658c034afbfa6d0abd90808ed
+Subproject commit 157edad6205fdd6a4f5932fba2675c6190746358

From d06de5d8503c46938e3fa52bfde75c3ea6f98f14 Mon Sep 17 00:00:00 2001
From: Lzu Tao <taolzu@gmail.com>
Date: Sat, 21 Sep 2019 05:28:47 +0000
Subject: [PATCH 932/943] Update rls to fix build error

---
 src/tools/rls | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/rls b/src/tools/rls
index d9aa23a43ad29..80a1d340f7d65 160000
--- a/src/tools/rls
+++ b/src/tools/rls
@@ -1 +1 @@
-Subproject commit d9aa23a43ad29e3a10551a1425ef5d5baef28d70
+Subproject commit 80a1d340f7d65b466bd3e0513c6b4b53498de2ff

From ad4787a992774bc91d257ffab129e6d66dd451ed Mon Sep 17 00:00:00 2001
From: Mazdak Farrokhzad <twingoow@gmail.com>
Date: Sun, 22 Sep 2019 17:18:45 +0200
Subject: [PATCH 933/943] Clarify the "since" tidy check

---
 src/tools/tidy/src/features.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 50e9116c778ea..6d38cfc8630d1 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -307,7 +307,7 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features
                 if prev_since > since {
                     tidy_error!(
                         bad,
-                        "{}:{}: feature {} is not sorted by since",
+                        "{}:{}: feature {} is not sorted by \"since\" (version number)",
                         path.display(),
                         line_number,
                         name,

From b370c111fdb2bc6c6a67bc0ebb7bc4946344a15a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 4 Sep 2019 10:17:59 -0700
Subject: [PATCH 934/943] On obligation errors point at the unfulfilled binding
 when possible

---
 src/librustc/hir/mod.rs                       | 13 +++
 src/librustc/traits/error_reporting.rs        | 22 ++++-
 src/librustc/traits/mod.rs                    |  3 +
 src/librustc/traits/structural_impls.rs       |  1 +
 src/librustc/ty/mod.rs                        |  4 +
 src/librustc_typeck/check/mod.rs              | 44 ++++++---
 .../anonymous-higher-ranked-lifetime.stderr   | 44 ++++-----
 ...nding-to-type-defined-in-supertrait.stderr |  4 +-
 .../associated-types-eq-3.stderr              |  2 +-
 .../associated-types-eq-hr.stderr             | 98 ++++++++-----------
 .../associated-types-issue-20346.stderr       |  2 +-
 ...ated-types-multiple-types-one-trait.stderr |  4 +-
 .../associated-types-path-2.stderr            |  4 +-
 .../higher-ranked-projection.bad.stderr       | 12 +--
 .../ui/async-await/async-fn-nonsend.stderr    |  8 +-
 .../async-await/issues/issue-62009-1.stderr   |  5 +-
 src/test/ui/chalkify/type_inference.stderr    |  2 +-
 .../expect-fn-supply-fn.stderr                | 51 +++++-----
 .../expect-infer-var-appearing-twice.stderr   | 17 ++--
 .../ui/closures/closure-bounds-subtype.stderr |  2 +-
 src/test/ui/closures/closure-move-sync.stderr | 12 ++-
 src/test/ui/defaulted-never-note.rs           |  3 +-
 src/test/ui/defaulted-never-note.stderr       |  4 +-
 ...rives-span-Hash-enum-struct-variant.stderr |  5 +-
 .../ui/derives/derives-span-Hash-enum.stderr  |  5 +-
 .../derives/derives-span-Hash-struct.stderr   |  5 +-
 .../derives-span-Hash-tuple-struct.stderr     |  5 +-
 src/test/ui/derives/deriving-copyclone.stderr |  6 +-
 .../ui/did_you_mean/recursion_limit.stderr    |  2 +-
 src/test/ui/error-codes/E0271.stderr          |  2 +-
 src/test/ui/error-codes/E0277-2.stderr        |  2 +-
 src/test/ui/error-codes/E0277.stderr          |  2 +-
 .../ui/error-should-say-copy-not-pod.stderr   |  2 +-
 .../extern/extern-types-not-sync-send.stderr  |  4 +-
 .../ui/extern/extern-types-unsized.stderr     |  8 +-
 .../ui/extern/extern-wrong-value-type.stderr  |  2 +-
 src/test/ui/fmt/send-sync.stderr              |  4 +-
 src/test/ui/fn/fn-trait-formatting.stderr     |  2 +-
 ...erator-yielding-or-returning-itself.stderr | 13 ++-
 src/test/ui/generator/not-send-sync.stderr    |  4 +-
 src/test/ui/generator/static-not-unpin.stderr |  2 +-
 src/test/ui/hrtb/hrtb-conflate-regions.stderr | 13 ++-
 ...b-exists-forall-trait-contravariant.stderr | 15 ++-
 .../hrtb-exists-forall-trait-covariant.stderr | 15 ++-
 .../hrtb-exists-forall-trait-invariant.stderr | 15 ++-
 ...igher-ranker-supertraits-transitive.stderr | 13 ++-
 .../hrtb-higher-ranker-supertraits.stderr     | 31 +++---
 src/test/ui/hrtb/hrtb-just-for-static.stderr  | 26 +++--
 src/test/ui/hrtb/issue-46989.stderr           |  2 +-
 src/test/ui/impl-trait/auto-trait-leak.stderr |  2 +-
 .../ui/impl-trait/auto-trait-leak2.stderr     |  4 +-
 .../interior-mutability.stderr                |  6 +-
 src/test/ui/issues/issue-1920-1.stderr        |  2 +-
 src/test/ui/issues/issue-1920-2.stderr        |  2 +-
 src/test/ui/issues/issue-1920-3.stderr        |  2 +-
 src/test/ui/issues/issue-21160.stderr         |  5 +-
 src/test/ui/issues/issue-21763.stderr         |  2 +-
 src/test/ui/issues/issue-25076.stderr         |  2 +-
 src/test/ui/issues/issue-32963.stderr         |  2 +-
 src/test/ui/issues/issue-40827.stderr         |  4 +-
 src/test/ui/issues/issue-43623.stderr         | 38 ++++---
 src/test/ui/issues/issue-47706.stderr         | 19 ++--
 src/test/ui/issues/issue-60283.stderr         | 32 +++---
 src/test/ui/kindck/kindck-copy.stderr         | 22 ++---
 .../kindck/kindck-impl-type-params-2.stderr   |  2 +-
 .../kindck/kindck-inherited-copy-bound.stderr |  2 +-
 .../ui/kindck/kindck-nonsendable-1.stderr     |  2 +-
 src/test/ui/kindck/kindck-send-object.stderr  |  4 +-
 src/test/ui/kindck/kindck-send-object1.stderr |  4 +-
 src/test/ui/kindck/kindck-send-object2.stderr |  4 +-
 src/test/ui/kindck/kindck-send-owned.stderr   |  2 +-
 src/test/ui/kindck/kindck-send-unsafe.stderr  |  2 +-
 .../overlap-marker-trait.stderr               |  2 +-
 src/test/ui/mismatched_types/E0631.stderr     |  8 +-
 .../mismatched_types/closure-arg-count.stderr |  6 +-
 .../closure-arg-type-mismatch.stderr          |  4 +-
 .../mismatched_types/closure-mismatch.stderr  |  4 +-
 .../ui/mismatched_types/fn-variance-1.stderr  |  4 +-
 .../unboxed-closures-vtable-mismatch.rs       |  3 +-
 .../unboxed-closures-vtable-mismatch.stderr   |  4 +-
 src/test/ui/mut/mutable-enum-indirect.stderr  |  2 +-
 src/test/ui/mutexguard-sync.stderr            |  2 +-
 src/test/ui/namespace/namespace-mix.stderr    | 88 ++++++++---------
 src/test/ui/no-send-res-ports.stderr          |  6 +-
 src/test/ui/no_send-enum.stderr               |  2 +-
 src/test/ui/no_send-rc.stderr                 |  2 +-
 src/test/ui/no_send-struct.stderr             |  2 +-
 src/test/ui/no_share-enum.stderr              |  2 +-
 src/test/ui/no_share-struct.stderr            |  2 +-
 src/test/ui/not-panic/not-panic-safe-2.stderr |  4 +-
 src/test/ui/not-panic/not-panic-safe-3.stderr |  4 +-
 src/test/ui/not-panic/not-panic-safe-4.stderr |  4 +-
 src/test/ui/not-panic/not-panic-safe-5.stderr |  2 +-
 src/test/ui/not-panic/not-panic-safe-6.stderr |  4 +-
 src/test/ui/not-panic/not-panic-safe.stderr   |  2 +-
 src/test/ui/not-sync.stderr                   | 12 +--
 src/test/ui/object-does-not-impl-trait.stderr |  2 +-
 src/test/ui/on-unimplemented/on-trait.stderr  |  4 +-
 src/test/ui/overlap-marker-trait.stderr       |  2 +-
 src/test/ui/phantom-oibit.stderr              |  4 +-
 .../regions-close-object-into-object-5.stderr | 12 +--
 .../termination-trait-test-wrong-type.stderr  |  6 +-
 src/test/ui/str/str-mut-idx.stderr            |  2 +-
 src/test/ui/substs-ppaux.normal.stderr        |  2 +-
 src/test/ui/substs-ppaux.verbose.stderr       |  2 +-
 ...rg-where-it-should-have-been-called.stderr |  2 +-
 ...rg-where-it-should-have-been-called.stderr |  2 +-
 src/test/ui/suggestions/into-str.stderr       |  2 +-
 .../trait-alias-cross-crate.stderr            |  4 +-
 .../traits/trait-suggest-where-clause.stderr  | 24 ++++-
 ...its-inductive-overflow-simultaneous.stderr |  2 +-
 ...inductive-overflow-supertrait-oibit.stderr |  2 +-
 ...raits-inductive-overflow-supertrait.stderr |  2 +-
 ...raits-inductive-overflow-two-traits.stderr |  2 +-
 .../ui/traits/traits-negative-impls.stderr    | 10 +-
 .../trivial-bounds/trivial-bounds-leak.stderr |  2 +-
 src/test/ui/try-operator-on-main.stderr       |  2 +-
 src/test/ui/type/type-annotation-needed.rs    |  1 +
 .../ui/type/type-annotation-needed.stderr     |  4 +-
 ...ypeck-default-trait-impl-assoc-type.stderr |  2 +-
 ...ault-trait-impl-constituent-types-2.stderr |  2 +-
 ...efault-trait-impl-constituent-types.stderr |  2 +-
 ...ck-default-trait-impl-negation-send.stderr |  2 +-
 ...ck-default-trait-impl-negation-sync.stderr |  6 +-
 .../typeck-default-trait-impl-negation.stderr |  4 +-
 ...ypeck-default-trait-impl-precedence.stderr |  2 +-
 ...ypeck-default-trait-impl-send-param.stderr |  2 +-
 .../typeck/typeck-unsafe-always-share.stderr  |  8 +-
 .../unboxed-closure-sugar-default.stderr      |  2 +-
 .../unboxed-closure-sugar-equiv.stderr        |  2 +-
 .../unboxed-closures-fnmut-as-fn.stderr       |  2 +-
 .../unboxed-closures-unsafe-extern-fn.stderr  | 10 +-
 .../unboxed-closures-wrong-abi.stderr         | 10 +-
 ...d-closures-wrong-arg-type-extern-fn.stderr | 10 +-
 .../ui/unsized/unsized-bare-typaram.stderr    |  2 +-
 src/test/ui/unsized/unsized-struct.stderr     |  2 +-
 src/test/ui/unsized3.stderr                   |  8 +-
 ...traints-are-local-for-inherent-impl.stderr |  2 +-
 ...onstraints-are-local-for-trait-impl.stderr |  2 +-
 .../where-clauses-unsatisfied.stderr          |  2 +-
 .../ui/where-clauses/where-for-self-2.stderr  | 12 +--
 141 files changed, 588 insertions(+), 512 deletions(-)

diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 2c8590aa4e3fa..4f942a22cb8ae 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -2750,3 +2750,16 @@ pub enum Node<'hir> {
 
     Crate,
 }
+
+impl<'hir> Node<'hir> {
+    pub fn ident(&self) -> Option<Ident> {
+
+        match self {
+            Node::TraitItem(TraitItem { ident, .. }) |
+            Node::ImplItem(ImplItem { ident, .. }) |
+            Node::ForeignItem(ForeignItem { ident, .. }) |
+            Node::Item(Item { ident, .. }) => Some(*ident),
+            _ => None,
+        }
+    }
+}
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index c9018f1c290d2..03f8ac250e925 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -40,10 +40,12 @@ use syntax::symbol::{sym, kw};
 use syntax_pos::{DUMMY_SP, Span, ExpnKind};
 
 impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
-    pub fn report_fulfillment_errors(&self,
-                                     errors: &[FulfillmentError<'tcx>],
-                                     body_id: Option<hir::BodyId>,
-                                     fallback_has_occurred: bool) {
+    pub fn report_fulfillment_errors(
+        &self,
+        errors: &[FulfillmentError<'tcx>],
+        body_id: Option<hir::BodyId>,
+        fallback_has_occurred: bool,
+    ) {
         #[derive(Debug)]
         struct ErrorDescriptor<'tcx> {
             predicate: ty::Predicate<'tcx>,
@@ -1651,6 +1653,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     err.note(&msg);
                 }
             }
+            ObligationCauseCode::BindingObligation(item_def_id, span) => {
+                let item_name = tcx.def_path_str(item_def_id);
+                let msg = format!("required by this bound in `{}`", item_name);
+                if let Some(ident) = tcx.opt_item_name(item_def_id) {
+                    err.span_label(ident.span, "");
+                }
+                if span != DUMMY_SP {
+                    err.span_label(span, &msg);
+                } else {
+                    err.note(&msg);
+                }
+            }
             ObligationCauseCode::ObjectCastObligation(object_ty) => {
                 err.note(&format!("required for the cast to the object type `{}`",
                                   self.ty_to_string(object_ty)));
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 27e4d1237c252..1123422ad6008 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -176,6 +176,9 @@ pub enum ObligationCauseCode<'tcx> {
     /// also implement all supertraits of `X`.
     ItemObligation(DefId),
 
+    /// Like `ItemObligation`, but with extra detail on the source of the obligation.
+    BindingObligation(DefId, Span),
+
     /// A type like `&'a T` is WF only if `T: 'a`.
     ReferenceOutlivesReferent(Ty<'tcx>),
 
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 6930c9368282b..68c97226f89cf 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -472,6 +472,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
             super::TupleElem => Some(super::TupleElem),
             super::ProjectionWf(proj) => tcx.lift(&proj).map(super::ProjectionWf),
             super::ItemObligation(def_id) => Some(super::ItemObligation(def_id)),
+            super::BindingObligation(def_id, span) => Some(super::BindingObligation(def_id, span)),
             super::ReferenceOutlivesReferent(ty) => {
                 tcx.lift(&ty).map(super::ReferenceOutlivesReferent)
             }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 5ca819e12f232..8bb9648e031ef 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2797,6 +2797,10 @@ impl<'tcx> TyCtxt<'tcx> {
         })
     }
 
+    pub fn opt_item_name(self, def_id: DefId) -> Option<Ident> {
+        self.hir().as_local_hir_id(def_id).and_then(|hir_id| self.hir().get(hir_id).ident())
+    }
+
     pub fn opt_associated_item(self, def_id: DefId) -> Option<AssocItem> {
         let is_associated_item = if let Some(hir_id) = self.hir().as_local_hir_id(def_id) {
             match self.hir().get(hir_id) {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index c96eab8629889..743e6661247b6 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2617,16 +2617,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// As `instantiate_type_scheme`, but for the bounds found in a
     /// generic type scheme.
-    fn instantiate_bounds(&self, span: Span, def_id: DefId, substs: SubstsRef<'tcx>)
-                          -> ty::InstantiatedPredicates<'tcx> {
+    fn instantiate_bounds(
+        &self,
+        span: Span,
+        def_id: DefId,
+        substs: SubstsRef<'tcx>,
+    ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
         let bounds = self.tcx.predicates_of(def_id);
+        let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
         let result = bounds.instantiate(self.tcx, substs);
         let result = self.normalize_associated_types_in(span, &result);
-        debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
+        debug!(
+            "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
                bounds,
                substs,
-               result);
-        result
+            result,
+            spans,
+        );
+        (result, spans)
     }
 
     /// Replaces the opaque types from the given value with type variables,
@@ -3194,8 +3202,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // All the input types from the fn signature must outlive the call
         // so as to validate implied bounds.
-        for &fn_input_ty in fn_inputs {
-            self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
+        for (fn_input_ty, arg_expr) in fn_inputs.iter().zip(args.iter()) {
+            self.register_wf_obligation(fn_input_ty, arg_expr.span, traits::MiscObligation);
         }
 
         let expected_arg_count = fn_inputs.len();
@@ -3604,7 +3612,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.write_user_type_annotation_from_substs(hir_id, did, substs, None);
 
             // Check bounds on type arguments used in the path.
-            let bounds = self.instantiate_bounds(path_span, did, substs);
+            let (bounds, _) = self.instantiate_bounds(path_span, did, substs);
             let cause = traits::ObligationCause::new(
                 path_span,
                 self.body_id,
@@ -4730,11 +4738,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Add all the obligations that are required, substituting and
         // normalized appropriately.
-        let bounds = self.instantiate_bounds(span, def_id, &substs);
-        self.add_obligations_for_parameters(
-            traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
+        let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
+
+        for (i, mut obligation) in traits::predicates_for_generics(
+            traits::ObligationCause::new(
+                span,
+                self.body_id,
+                traits::ItemObligation(def_id),
+            ),
+            self.param_env,
             &bounds,
-        );
+        ).into_iter().enumerate() {
+            // This makes the error point at the bound, but we want to point at the argument
+            if let Some(span) = spans.get(i) {
+                obligation.cause.code = traits::BindingObligation(def_id, *span);
+            }
+            self.register_predicate(obligation);
+        }
 
         // Substitute the values for the type parameters into the type of
         // the referenced item.
diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
index c65a44bfbccfe..51550e1471e72 100644
--- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr
+++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
@@ -7,7 +7,7 @@ LL |     f1(|_: (), _: ()| {});
    |     expected signature of `for<'r, 's> fn(&'r (), &'s ()) -> _`
 ...
 LL | fn f1<F>(_: F) where F: Fn(&(), &()) {}
-   | ------------------------------------ required by `f1`
+   |    --                   ------------ required by this bound in `f1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:2:5
@@ -18,7 +18,7 @@ LL |     f1(|_: (), _: ()| {});
    |     expected signature of `fn(&(), &()) -> _`
 ...
 LL | fn f1<F>(_: F) where F: Fn(&(), &()) {}
-   | ------------------------------------ required by `f1`
+   |    --                     ---------- required by this bound in `f1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
@@ -29,7 +29,7 @@ LL |     f2(|_: (), _: ()| {});
    |     expected signature of `for<'a, 'r> fn(&'a (), &'r ()) -> _`
 ...
 LL | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
-   | ----------------------------------------------- required by `f2`
+   |    --                   ----------------------- required by this bound in `f2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
@@ -40,7 +40,7 @@ LL |     f2(|_: (), _: ()| {});
    |     expected signature of `fn(&'a (), &()) -> _`
 ...
 LL | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
-   | ----------------------------------------------- required by `f2`
+   |    --                             ------------- required by this bound in `f2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
@@ -51,7 +51,7 @@ LL |     f3(|_: (), _: ()| {});
    |     expected signature of `for<'r> fn(&(), &'r ()) -> _`
 ...
 LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
-   | ------------------------------------------- required by `f3`
+   |    --                       --------------- required by this bound in `f3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
@@ -62,7 +62,7 @@ LL |     f3(|_: (), _: ()| {});
    |     expected signature of `fn(&(), &()) -> _`
 ...
 LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
-   | ------------------------------------------- required by `f3`
+   |    --                         ------------- required by this bound in `f3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
@@ -73,7 +73,7 @@ LL |     f4(|_: (), _: ()| {});
    |     expected signature of `for<'s, 'r> fn(&'s (), &'r ()) -> _`
 ...
 LL | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
-   | ----------------------------------------------- required by `f4`
+   |    --                   ----------------------- required by this bound in `f4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
@@ -84,7 +84,7 @@ LL |     f4(|_: (), _: ()| {});
    |     expected signature of `fn(&(), &'r ()) -> _`
 ...
 LL | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
-   | ----------------------------------------------- required by `f4`
+   |    --                             ------------- required by this bound in `f4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
@@ -95,7 +95,7 @@ LL |     f5(|_: (), _: ()| {});
    |     expected signature of `for<'r> fn(&'r (), &'r ()) -> _`
 ...
 LL | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
-   | -------------------------------------------------- required by `f5`
+   |    --                   -------------------------- required by this bound in `f5`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
@@ -106,7 +106,7 @@ LL |     f5(|_: (), _: ()| {});
    |     expected signature of `fn(&'r (), &'r ()) -> _`
 ...
 LL | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
-   | -------------------------------------------------- required by `f5`
+   |    --                             ---------------- required by this bound in `f5`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
@@ -117,7 +117,7 @@ LL |     g1(|_: (), _: ()| {});
    |     expected signature of `for<'r> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>) -> _`
 ...
 LL | fn g1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>) {}
-   | ------------------------------------------------- required by `g1`
+   |    --                   ------------------------- required by this bound in `g1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
@@ -128,7 +128,7 @@ LL |     g1(|_: (), _: ()| {});
    |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
 ...
 LL | fn g1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>) {}
-   | ------------------------------------------------- required by `g1`
+   |    --                     ----------------------- required by this bound in `g1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
@@ -139,7 +139,7 @@ LL |     g2(|_: (), _: ()| {});
    |     expected signature of `for<'r> fn(&'r (), for<'s> fn(&'s ())) -> _`
 ...
 LL | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
-   | ---------------------------------------- required by `g2`
+   |    --                   ---------------- required by this bound in `g2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
@@ -150,7 +150,7 @@ LL |     g2(|_: (), _: ()| {});
    |     expected signature of `fn(&(), for<'r> fn(&'r ())) -> _`
 ...
 LL | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
-   | ---------------------------------------- required by `g2`
+   |    --                     -------------- required by this bound in `g2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
@@ -161,7 +161,7 @@ LL |     g3(|_: (), _: ()| {});
    |     expected signature of `for<'s> fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
 ...
 LL | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<dyn Fn(&())>) {}
-   | ------------------------------------------------------------ required by `g3`
+   |    --                   ------------------------------------ required by this bound in `g3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
@@ -172,7 +172,7 @@ LL |     g3(|_: (), _: ()| {});
    |     expected signature of `fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
 ...
 LL | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<dyn Fn(&())>) {}
-   | ------------------------------------------------------------ required by `g3`
+   |    --                             -------------------------- required by this bound in `g3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
@@ -183,7 +183,7 @@ LL |     g4(|_: (), _: ()| {});
    |     expected signature of `for<'s> fn(&'s (), for<'r> fn(&'r ())) -> _`
 ...
 LL | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
-   | --------------------------------------------------- required by `g4`
+   |    --                   --------------------------- required by this bound in `g4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
@@ -194,7 +194,7 @@ LL |     g4(|_: (), _: ()| {});
    |     expected signature of `fn(&(), for<'r> fn(&'r ())) -> _`
 ...
 LL | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
-   | --------------------------------------------------- required by `g4`
+   |    --                     ------------------------- required by this bound in `g4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
@@ -205,7 +205,7 @@ LL |     h1(|_: (), _: (), _: (), _: ()| {});
    |     expected signature of `for<'r, 's> fn(&'r (), std::boxed::Box<(dyn for<'t0> std::ops::Fn(&'t0 ()) + 'static)>, &'s (), for<'t0, 't1> fn(&'t0 (), &'t1 ())) -> _`
 ...
 LL | fn h1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>, &(), fn(&(), &())) {}
-   | -------------------------------------------------------------------- required by `h1`
+   |    --                   -------------------------------------------- required by this bound in `h1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
@@ -216,7 +216,7 @@ LL |     h1(|_: (), _: (), _: (), _: ()| {});
    |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &(), for<'r, 's> fn(&'r (), &'s ())) -> _`
 ...
 LL | fn h1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>, &(), fn(&(), &())) {}
-   | -------------------------------------------------------------------- required by `h1`
+   |    --                     ------------------------------------------ required by this bound in `h1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
@@ -227,7 +227,7 @@ LL |     h2(|_: (), _: (), _: (), _: ()| {});
    |     expected signature of `for<'r, 't0> fn(&'r (), std::boxed::Box<(dyn for<'s> std::ops::Fn(&'s ()) + 'static)>, &'t0 (), for<'s, 't1> fn(&'s (), &'t1 ())) -> _`
 ...
 LL | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<dyn Fn(&())>, &'t0 (), fn(&(), &())) {}
-   | --------------------------------------------------------------------------------- required by `h2`
+   |    --                   --------------------------------------------------------- required by this bound in `h2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
@@ -238,7 +238,7 @@ LL |     h2(|_: (), _: (), _: (), _: ()| {});
    |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &'t0 (), for<'r, 's> fn(&'r (), &'s ())) -> _`
 ...
 LL | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<dyn Fn(&())>, &'t0 (), fn(&(), &())) {}
-   | --------------------------------------------------------------------------------- required by `h2`
+   |    --                              ---------------------------------------------- required by this bound in `h2`
 
 error: aborting due to 22 previous errors
 
diff --git a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
index a3049892abc39..6a2135ca46445 100644
--- a/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
+++ b/src/test/ui/associated-types/associated-types-binding-to-type-defined-in-supertrait.stderr
@@ -2,7 +2,7 @@ error[E0271]: type mismatch resolving `<ModelT as Vehicle>::Color == Blue`
   --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:31:10
    |
 LL | fn blue_car<C:Car<Color=Blue>>(c: C) {
-   | ------------------------------------ required by `blue_car`
+   |    --------       ---------- required by this bound in `blue_car`
 ...
 LL | fn b() { blue_car(ModelT); }
    |          ^^^^^^^^ expected struct `Black`, found struct `Blue`
@@ -14,7 +14,7 @@ error[E0271]: type mismatch resolving `<ModelU as Vehicle>::Color == Black`
   --> $DIR/associated-types-binding-to-type-defined-in-supertrait.rs:32:10
    |
 LL | fn black_car<C:Car<Color=Black>>(c: C) {
-   | -------------------------------------- required by `black_car`
+   |    ---------       ----------- required by this bound in `black_car`
 ...
 LL | fn c() { black_car(ModelU); }
    |          ^^^^^^^^^ expected struct `Blue`, found struct `Black`
diff --git a/src/test/ui/associated-types/associated-types-eq-3.stderr b/src/test/ui/associated-types/associated-types-eq-3.stderr
index c9d88b7af0753..83d89924944ab 100644
--- a/src/test/ui/associated-types/associated-types-eq-3.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-3.stderr
@@ -13,7 +13,7 @@ error[E0271]: type mismatch resolving `<isize as Foo>::A == Bar`
   --> $DIR/associated-types-eq-3.rs:38:5
    |
 LL | fn foo1<I: Foo<A=Bar>>(x: I) {
-   | ---------------------------- required by `foo1`
+   |    ----        ----- required by this bound in `foo1`
 ...
 LL |     foo1(a);
    |     ^^^^ expected usize, found struct `Bar`
diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr
index 05e6ed69812ad..f560aefd637c0 100644
--- a/src/test/ui/associated-types/associated-types-eq-hr.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr
@@ -1,15 +1,13 @@
 error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
   --> $DIR/associated-types-eq-hr.rs:82:5
    |
-LL | / fn foo<T>()
-LL | |     where T : for<'x> TheTrait<&'x isize, A = &'x isize>
-LL | | {
-LL | |     // ok for IntStruct, but not UintStruct
-LL | | }
-   | |_- required by `foo`
+LL | fn foo<T>()
+   |    ---
+LL |     where T : for<'x> TheTrait<&'x isize, A = &'x isize>
+   |                                           ------------- required by this bound in `foo`
 ...
-LL |       foo::<UintStruct>();
-   |       ^^^^^^^^^^^^^^^^^ expected usize, found isize
+LL |     foo::<UintStruct>();
+   |     ^^^^^^^^^^^^^^^^^ expected usize, found isize
    |
    = note: expected type `&usize`
               found type `&isize`
@@ -17,15 +15,13 @@ LL |       foo::<UintStruct>();
 error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
   --> $DIR/associated-types-eq-hr.rs:86:5
    |
-LL | / fn bar<T>()
-LL | |     where T : for<'x> TheTrait<&'x isize, A = &'x usize>
-LL | | {
-LL | |     // ok for UintStruct, but not IntStruct
-LL | | }
-   | |_- required by `bar`
+LL | fn bar<T>()
+   |    ---
+LL |     where T : for<'x> TheTrait<&'x isize, A = &'x usize>
+   |                                           ------------- required by this bound in `bar`
 ...
-LL |       bar::<IntStruct>();
-   |       ^^^^^^^^^^^^^^^^ expected isize, found usize
+LL |     bar::<IntStruct>();
+   |     ^^^^^^^^^^^^^^^^ expected isize, found usize
    |
    = note: expected type `&isize`
               found type `&usize`
@@ -33,15 +29,13 @@ LL |       bar::<IntStruct>();
 error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
   --> $DIR/associated-types-eq-hr.rs:91:5
    |
-LL | / fn tuple_one<T>()
-LL | |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
-LL | | {
-LL | |     // not ok for tuple, two lifetimes and we pick first
-LL | | }
-   | |_- required by `tuple_one`
+LL | fn tuple_one<T>()
+   |    ---------
+LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
+   |               ---------------------------------------------------------- required by this bound in `tuple_one`
 ...
-LL |       tuple_one::<Tuple>();
-   |       ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
+LL |     tuple_one::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
    |
    = help: the following implementations were found:
              <Tuple as TheTrait<(&'a isize, &'a isize)>>
@@ -49,28 +43,24 @@ LL |       tuple_one::<Tuple>();
 error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'x isize`
   --> $DIR/associated-types-eq-hr.rs:91:5
    |
-LL | / fn tuple_one<T>()
-LL | |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
-LL | | {
-LL | |     // not ok for tuple, two lifetimes and we pick first
-LL | | }
-   | |_- required by `tuple_one`
+LL | fn tuple_one<T>()
+   |    ---------
+LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
+   |                                                           ------------- required by this bound in `tuple_one`
 ...
-LL |       tuple_one::<Tuple>();
-   |       ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
+LL |     tuple_one::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
 
 error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
   --> $DIR/associated-types-eq-hr.rs:97:5
    |
-LL | / fn tuple_two<T>()
-LL | |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
-LL | | {
-LL | |     // not ok for tuple, two lifetimes and we pick second
-LL | | }
-   | |_- required by `tuple_two`
+LL | fn tuple_two<T>()
+   |    ---------
+LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
+   |               ---------------------------------------------------------- required by this bound in `tuple_two`
 ...
-LL |       tuple_two::<Tuple>();
-   |       ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
+LL |     tuple_two::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
    |
    = help: the following implementations were found:
              <Tuple as TheTrait<(&'a isize, &'a isize)>>
@@ -78,28 +68,24 @@ LL |       tuple_two::<Tuple>();
 error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'y isize`
   --> $DIR/associated-types-eq-hr.rs:97:5
    |
-LL | / fn tuple_two<T>()
-LL | |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
-LL | | {
-LL | |     // not ok for tuple, two lifetimes and we pick second
-LL | | }
-   | |_- required by `tuple_two`
+LL | fn tuple_two<T>()
+   |    ---------
+LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
+   |                                                           ------------- required by this bound in `tuple_two`
 ...
-LL |       tuple_two::<Tuple>();
-   |       ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
+LL |     tuple_two::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
 
 error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
   --> $DIR/associated-types-eq-hr.rs:107:5
    |
-LL | / fn tuple_four<T>()
-LL | |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)>
-LL | | {
-LL | |     // not ok for tuple, two lifetimes, and lifetime matching is invariant
-LL | | }
-   | |_- required by `tuple_four`
+LL | fn tuple_four<T>()
+   |    ----------
+LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)>
+   |               ------------------------------------------- required by this bound in `tuple_four`
 ...
-LL |       tuple_four::<Tuple>();
-   |       ^^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
+LL |     tuple_four::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
    |
    = help: the following implementations were found:
              <Tuple as TheTrait<(&'a isize, &'a isize)>>
diff --git a/src/test/ui/associated-types/associated-types-issue-20346.stderr b/src/test/ui/associated-types/associated-types-issue-20346.stderr
index e037bd851ca21..c8f8725afc45c 100644
--- a/src/test/ui/associated-types/associated-types-issue-20346.stderr
+++ b/src/test/ui/associated-types/associated-types-issue-20346.stderr
@@ -2,7 +2,7 @@ error[E0271]: type mismatch resolving `<Adapter<I> as Iterator>::Item == std::op
   --> $DIR/associated-types-issue-20346.rs:34:5
    |
 LL | fn is_iterator_of<A, I: Iterator<Item=A>>(_: &I) {}
-   | ------------------------------------------------ required by `is_iterator_of`
+   |    --------------                ------ required by this bound in `is_iterator_of`
 ...
 LL |     is_iterator_of::<Option<T>, _>(&adapter);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter, found enum `std::option::Option`
diff --git a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
index d6328a64c7c74..c7de186c1d3e0 100644
--- a/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
+++ b/src/test/ui/associated-types/associated-types-multiple-types-one-trait.stderr
@@ -5,7 +5,7 @@ LL |     want_y(t);
    |     ^^^^^^ expected associated type, found i32
 ...
 LL | fn want_y<T:Foo<Y=i32>>(t: &T) { }
-   | ------------------------------ required by `want_y`
+   |    ------       ----- required by this bound in `want_y`
    |
    = note: expected type `<T as Foo>::Y`
               found type `i32`
@@ -19,7 +19,7 @@ LL |     want_x(t);
    |     ^^^^^^ expected associated type, found u32
 ...
 LL | fn want_x<T:Foo<X=u32>>(t: &T) { }
-   | ------------------------------ required by `want_x`
+   |    ------       ----- required by this bound in `want_x`
    |
    = note: expected type `<T as Foo>::X`
               found type `u32`
diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr
index a8fcaeac95d5f..bb2e7251849d3 100644
--- a/src/test/ui/associated-types/associated-types-path-2.stderr
+++ b/src/test/ui/associated-types/associated-types-path-2.stderr
@@ -12,7 +12,7 @@ error[E0277]: the trait bound `u32: Foo` is not satisfied
   --> $DIR/associated-types-path-2.rs:29:5
    |
 LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
-   | -------------------------------- required by `f1`
+   |        --    --- required by this bound in `f1`
 ...
 LL |     f1(2u32, 4u32);
    |     ^^ the trait `Foo` is not implemented for `u32`
@@ -27,7 +27,7 @@ error[E0277]: the trait bound `u32: Foo` is not satisfied
   --> $DIR/associated-types-path-2.rs:35:5
    |
 LL | pub fn f1<T: Foo>(a: T, x: T::A) {}
-   | -------------------------------- required by `f1`
+   |        --    --- required by this bound in `f1`
 ...
 LL |     f1(2u32, 4i32);
    |     ^^ the trait `Foo` is not implemented for `u32`
diff --git a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr
index 22d44888e951b..74c9ad2c39e67 100644
--- a/src/test/ui/associated-types/higher-ranked-projection.bad.stderr
+++ b/src/test/ui/associated-types/higher-ranked-projection.bad.stderr
@@ -1,13 +1,13 @@
 error[E0271]: type mismatch resolving `for<'a> <&'a _ as Mirror>::Image == _`
   --> $DIR/higher-ranked-projection.rs:25:5
    |
-LL | / fn foo<U, T>(_t: T)
-LL | |     where for<'a> &'a T: Mirror<Image=U>
-LL | | {}
-   | |__- required by `foo`
+LL | fn foo<U, T>(_t: T)
+   |    ---
+LL |     where for<'a> &'a T: Mirror<Image=U>
+   |                                 ------- required by this bound in `foo`
 ...
-LL |       foo(());
-   |       ^^^ expected bound lifetime parameter 'a, found concrete lifetime
+LL |     foo(());
+   |     ^^^ expected bound lifetime parameter 'a, found concrete lifetime
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr
index d2f92f04f40a7..001e0b1cad305 100644
--- a/src/test/ui/async-await/async-fn-nonsend.stderr
+++ b/src/test/ui/async-await/async-fn-nonsend.stderr
@@ -2,7 +2,7 @@ error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
   --> $DIR/async-fn-nonsend.rs:50:5
    |
 LL | fn assert_send(_: impl Send) {}
-   | ---------------------------- required by `assert_send`
+   |    -----------         ---- required by this bound in `assert_send`
 ...
 LL |     assert_send(local_dropped_before_await());
    |     ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
@@ -19,7 +19,7 @@ error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
   --> $DIR/async-fn-nonsend.rs:52:5
    |
 LL | fn assert_send(_: impl Send) {}
-   | ---------------------------- required by `assert_send`
+   |    -----------         ---- required by this bound in `assert_send`
 ...
 LL |     assert_send(non_send_temporary_in_match());
    |     ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
@@ -36,7 +36,7 @@ error[E0277]: `dyn std::fmt::Write` cannot be sent between threads safely
   --> $DIR/async-fn-nonsend.rs:54:5
    |
 LL | fn assert_send(_: impl Send) {}
-   | ---------------------------- required by `assert_send`
+   |    -----------         ---- required by this bound in `assert_send`
 ...
 LL |     assert_send(non_sync_with_method_call());
    |     ^^^^^^^^^^^ `dyn std::fmt::Write` cannot be sent between threads safely
@@ -55,7 +55,7 @@ error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between thr
   --> $DIR/async-fn-nonsend.rs:54:5
    |
 LL | fn assert_send(_: impl Send) {}
-   | ---------------------------- required by `assert_send`
+   |    -----------         ---- required by this bound in `assert_send`
 ...
 LL |     assert_send(non_sync_with_method_call());
    |     ^^^^^^^^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr
index cd155f0fc32b6..3d8028635f5a5 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.stderr
+++ b/src/test/ui/async-await/issues/issue-62009-1.stderr
@@ -32,8 +32,11 @@ error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]: std:
    |
 LL |     (|_| 2333).await;
    |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
+   | 
+  ::: $SRC_DIR/libstd/future.rs:LL:COL
    |
-   = note: required by `std::future::poll_with_tls_context`
+LL |     F: Future
+   |        ------ required by this bound in `std::future::poll_with_tls_context`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/chalkify/type_inference.stderr b/src/test/ui/chalkify/type_inference.stderr
index 15c52f461c183..c6bc306e45a1c 100644
--- a/src/test/ui/chalkify/type_inference.stderr
+++ b/src/test/ui/chalkify/type_inference.stderr
@@ -11,7 +11,7 @@ error[E0277]: the trait bound `{float}: Bar` is not satisfied
   --> $DIR/type_inference.rs:25:5
    |
 LL | fn only_bar<T: Bar>(_x: T) { }
-   | -------------------------- required by `only_bar`
+   |    --------    --- required by this bound in `only_bar`
 ...
 LL |     only_bar(x);
    |     ^^^^^^^^ the trait `Bar` is not implemented for `{float}`
diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
index c618c2c550ba1..6fadea31f7e69 100644
--- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
@@ -39,44 +39,41 @@ LL |     with_closure_expecting_fn_with_free_region(|x: fn(&'x u32), y| {});
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:30:5
    |
-LL | / fn with_closure_expecting_fn_with_free_region<F>(_: F)
-LL | |     where F: for<'a> FnOnce(fn(&'a u32), &i32)
-LL | | {
-LL | | }
-   | |_- required by `with_closure_expecting_fn_with_free_region`
+LL | fn with_closure_expecting_fn_with_free_region<F>(_: F)
+   |    ------------------------------------------
+LL |     where F: for<'a> FnOnce(fn(&'a u32), &i32)
+   |                            ------------------- required by this bound in `with_closure_expecting_fn_with_free_region`
 ...
-LL |       with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
-   |       |
-   |       expected signature of `fn(fn(&'a u32), &i32) -> _`
+LL |     with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
+   |     |
+   |     expected signature of `fn(fn(&'a u32), &i32) -> _`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:37:5
    |
-LL | / fn with_closure_expecting_fn_with_bound_region<F>(_: F)
-LL | |     where F: FnOnce(fn(&u32), &i32)
-LL | | {
-LL | | }
-   | |_- required by `with_closure_expecting_fn_with_bound_region`
+LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
+   |    -------------------------------------------
+LL |     where F: FnOnce(fn(&u32), &i32)
+   |                    ---------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
 ...
-LL |       with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
-   |       |
-   |       expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
+LL |     with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
+   |     |
+   |     expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:46:5
    |
-LL | / fn with_closure_expecting_fn_with_bound_region<F>(_: F)
-LL | |     where F: FnOnce(fn(&u32), &i32)
-LL | | {
-LL | | }
-   | |_- required by `with_closure_expecting_fn_with_bound_region`
+LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
+   |    -------------------------------------------
+LL |     where F: FnOnce(fn(&u32), &i32)
+   |                    ---------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
 ...
-LL |       with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
-   |       |
-   |       expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
+LL |     with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
+   |     |
+   |     expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
index a2b3a66dc4d23..9fbe95a9c3945 100644
--- a/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
+++ b/src/test/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr
@@ -1,16 +1,15 @@
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-infer-var-appearing-twice.rs:14:5
    |
-LL | / fn with_closure<F, A>(_: F)
-LL | |     where F: FnOnce(A, A)
-LL | | {
-LL | | }
-   | |_- required by `with_closure`
+LL | fn with_closure<F, A>(_: F)
+   |    ------------
+LL |     where F: FnOnce(A, A)
+   |              ------------ required by this bound in `with_closure`
 ...
-LL |       with_closure(|x: u32, y: i32| {
-   |       ^^^^^^^^^^^^ ---------------- found signature of `fn(u32, i32) -> _`
-   |       |
-   |       expected signature of `fn(_, _) -> _`
+LL |     with_closure(|x: u32, y: i32| {
+   |     ^^^^^^^^^^^^ ---------------- found signature of `fn(u32, i32) -> _`
+   |     |
+   |     expected signature of `fn(_, _) -> _`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/closure-bounds-subtype.stderr b/src/test/ui/closures/closure-bounds-subtype.stderr
index e9b34e05ac2e2..4b703eded69c3 100644
--- a/src/test/ui/closures/closure-bounds-subtype.stderr
+++ b/src/test/ui/closures/closure-bounds-subtype.stderr
@@ -2,7 +2,7 @@ error[E0277]: `F` cannot be shared between threads safely
   --> $DIR/closure-bounds-subtype.rs:13:22
    |
 LL | fn take_const_owned<F>(_: F) where F: FnOnce() + Sync + Send {
-   | ------------------------------------------------------------ required by `take_const_owned`
+   |    ----------------                              ---- required by this bound in `take_const_owned`
 ...
 LL |     take_const_owned(f);
    |                      ^ `F` cannot be shared between threads safely
diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr
index 8afebc7c74816..aaa5f76233f91 100644
--- a/src/test/ui/closures/closure-move-sync.stderr
+++ b/src/test/ui/closures/closure-move-sync.stderr
@@ -3,22 +3,30 @@ error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads s
    |
 LL |     let t = thread::spawn(|| {
    |             ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
+   | 
+  ::: $SRC_DIR/libstd/thread/mod.rs:LL:COL
+   |
+LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
+   |                          ---- required by this bound in `std::thread::spawn`
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Receiver<()>`
    = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:6:27: 9:6 recv:&std::sync::mpsc::Receiver<()>]`
-   = note: required by `std::thread::spawn`
 
 error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
   --> $DIR/closure-move-sync.rs:18:5
    |
 LL |     thread::spawn(|| tx.send(()).unwrap());
    |     ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
+   | 
+  ::: $SRC_DIR/libstd/thread/mod.rs:LL:COL
+   |
+LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
+   |                          ---- required by this bound in `std::thread::spawn`
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<()>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Sender<()>`
    = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:18:19: 18:42 tx:&std::sync::mpsc::Sender<()>]`
-   = note: required by `std::thread::spawn`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/defaulted-never-note.rs b/src/test/ui/defaulted-never-note.rs
index cf1922ecc789f..d3fb8a09414ce 100644
--- a/src/test/ui/defaulted-never-note.rs
+++ b/src/test/ui/defaulted-never-note.rs
@@ -19,7 +19,8 @@ trait ImplementedForUnitButNotNever {}
 impl ImplementedForUnitButNotNever for () {}
 
 fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
-//~^ NOTE required by `foo`
+//~^ NOTE required by this bound in `foo`
+//~| NOTE
 
 fn smeg() {
     let _x = return;
diff --git a/src/test/ui/defaulted-never-note.stderr b/src/test/ui/defaulted-never-note.stderr
index 277477a0b0acd..28c9da059edaa 100644
--- a/src/test/ui/defaulted-never-note.stderr
+++ b/src/test/ui/defaulted-never-note.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the trait bound `!: ImplementedForUnitButNotNever` is not satisfied
-  --> $DIR/defaulted-never-note.rs:26:5
+  --> $DIR/defaulted-never-note.rs:27:5
    |
 LL | fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
-   | ----------------------------------------------- required by `foo`
+   |    ---    ----------------------------- required by this bound in `foo`
 ...
 LL |     foo(_x);
    |     ^^^ the trait `ImplementedForUnitButNotNever` is not implemented for `!`
diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
index 417c720c63e99..4752ef3713d42 100644
--- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
@@ -3,8 +3,11 @@ error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
+   | 
+  ::: $SRC_DIR/libcore/hash/mod.rs:LL:COL
    |
-   = note: required by `std::hash::Hash::hash`
+LL |     fn hash<H: Hasher>(&self, state: &mut H);
+   |             - required by this bound in `std::hash::Hash::hash`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/derives/derives-span-Hash-enum.stderr b/src/test/ui/derives/derives-span-Hash-enum.stderr
index 25be8794889fc..efaa679c410be 100644
--- a/src/test/ui/derives/derives-span-Hash-enum.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum.stderr
@@ -3,8 +3,11 @@ error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
    |
 LL |      Error
    |      ^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
+   | 
+  ::: $SRC_DIR/libcore/hash/mod.rs:LL:COL
    |
-   = note: required by `std::hash::Hash::hash`
+LL |     fn hash<H: Hasher>(&self, state: &mut H);
+   |             - required by this bound in `std::hash::Hash::hash`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/derives/derives-span-Hash-struct.stderr b/src/test/ui/derives/derives-span-Hash-struct.stderr
index c0574453a7a6b..a92103032ee1f 100644
--- a/src/test/ui/derives/derives-span-Hash-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-struct.stderr
@@ -3,8 +3,11 @@ error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
+   | 
+  ::: $SRC_DIR/libcore/hash/mod.rs:LL:COL
    |
-   = note: required by `std::hash::Hash::hash`
+LL |     fn hash<H: Hasher>(&self, state: &mut H);
+   |             - required by this bound in `std::hash::Hash::hash`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
index 6339c38578eb8..4af96ada66c28 100644
--- a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
@@ -3,8 +3,11 @@ error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
    |
 LL |     Error
    |     ^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
+   | 
+  ::: $SRC_DIR/libcore/hash/mod.rs:LL:COL
    |
-   = note: required by `std::hash::Hash::hash`
+LL |     fn hash<H: Hasher>(&self, state: &mut H);
+   |             - required by this bound in `std::hash::Hash::hash`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/derives/deriving-copyclone.stderr b/src/test/ui/derives/deriving-copyclone.stderr
index f142257604cc8..4cca14ae089e9 100644
--- a/src/test/ui/derives/deriving-copyclone.stderr
+++ b/src/test/ui/derives/deriving-copyclone.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `C: std::marker::Copy` is not satisfied
   --> $DIR/deriving-copyclone.rs:31:13
    |
 LL | fn is_copy<T: Copy>(_: T) {}
-   | ------------------------- required by `is_copy`
+   |    -------    ---- required by this bound in `is_copy`
 ...
 LL |     is_copy(B { a: 1, b: C });
    |             ^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `C`
@@ -13,7 +13,7 @@ error[E0277]: the trait bound `C: std::clone::Clone` is not satisfied
   --> $DIR/deriving-copyclone.rs:32:14
    |
 LL | fn is_clone<T: Clone>(_: T) {}
-   | --------------------------- required by `is_clone`
+   |    --------    ----- required by this bound in `is_clone`
 ...
 LL |     is_clone(B { a: 1, b: C });
    |              ^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `C`
@@ -24,7 +24,7 @@ error[E0277]: the trait bound `D: std::marker::Copy` is not satisfied
   --> $DIR/deriving-copyclone.rs:35:13
    |
 LL | fn is_copy<T: Copy>(_: T) {}
-   | ------------------------- required by `is_copy`
+   |    -------    ---- required by this bound in `is_copy`
 ...
 LL |     is_copy(B { a: 1, b: D });
    |             ^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `D`
diff --git a/src/test/ui/did_you_mean/recursion_limit.stderr b/src/test/ui/did_you_mean/recursion_limit.stderr
index 745d90a5d4cbf..b05b92bf1e94b 100644
--- a/src/test/ui/did_you_mean/recursion_limit.stderr
+++ b/src/test/ui/did_you_mean/recursion_limit.stderr
@@ -2,7 +2,7 @@ error[E0275]: overflow evaluating the requirement `J: std::marker::Send`
   --> $DIR/recursion_limit.rs:34:5
    |
 LL | fn is_send<T:Send>() { }
-   | -------------------- required by `is_send`
+   |    -------   ---- required by this bound in `is_send`
 ...
 LL |     is_send::<A>();
    |     ^^^^^^^^^^^^
diff --git a/src/test/ui/error-codes/E0271.stderr b/src/test/ui/error-codes/E0271.stderr
index 0afcbcc79eee9..c56853f45a0b0 100644
--- a/src/test/ui/error-codes/E0271.stderr
+++ b/src/test/ui/error-codes/E0271.stderr
@@ -2,7 +2,7 @@ error[E0271]: type mismatch resolving `<i8 as Trait>::AssociatedType == u32`
   --> $DIR/E0271.rs:10:5
    |
 LL | fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
-   | -------------------------------------------------- required by `foo`
+   |    ---                         ------------------ required by this bound in `foo`
 ...
 LL |     foo(3_i8);
    |     ^^^ expected reference, found u32
diff --git a/src/test/ui/error-codes/E0277-2.stderr b/src/test/ui/error-codes/E0277-2.stderr
index b42849cd84201..407e51e4f5f9c 100644
--- a/src/test/ui/error-codes/E0277-2.stderr
+++ b/src/test/ui/error-codes/E0277-2.stderr
@@ -2,7 +2,7 @@ error[E0277]: `*const u8` cannot be sent between threads safely
   --> $DIR/E0277-2.rs:16:5
    |
 LL | fn is_send<T: Send>() { }
-   | --------------------- required by `is_send`
+   |    -------    ---- required by this bound in `is_send`
 ...
 LL |     is_send::<Foo>();
    |     ^^^^^^^^^^^^^^ `*const u8` cannot be sent between threads safely
diff --git a/src/test/ui/error-codes/E0277.stderr b/src/test/ui/error-codes/E0277.stderr
index 9cd0dc7a68e7c..a069d048c8862 100644
--- a/src/test/ui/error-codes/E0277.stderr
+++ b/src/test/ui/error-codes/E0277.stderr
@@ -14,7 +14,7 @@ error[E0277]: the trait bound `i32: Foo` is not satisfied
   --> $DIR/E0277.rs:17:15
    |
 LL | fn some_func<T: Foo>(foo: T) {
-   | ---------------------------- required by `some_func`
+   |    ---------    --- required by this bound in `some_func`
 ...
 LL |     some_func(5i32);
    |               ^^^^ the trait `Foo` is not implemented for `i32`
diff --git a/src/test/ui/error-should-say-copy-not-pod.stderr b/src/test/ui/error-should-say-copy-not-pod.stderr
index df79aeea054ca..d0148f418e33b 100644
--- a/src/test/ui/error-should-say-copy-not-pod.stderr
+++ b/src/test/ui/error-should-say-copy-not-pod.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not sa
   --> $DIR/error-should-say-copy-not-pod.rs:6:17
    |
 LL | fn check_bound<T:Copy>(_: T) {}
-   | ---------------------------- required by `check_bound`
+   |    -----------   ---- required by this bound in `check_bound`
 ...
 LL |     check_bound("nocopy".to_string());
    |                 ^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
diff --git a/src/test/ui/extern/extern-types-not-sync-send.stderr b/src/test/ui/extern/extern-types-not-sync-send.stderr
index 0f32d4489dece..803bd9dbac62c 100644
--- a/src/test/ui/extern/extern-types-not-sync-send.stderr
+++ b/src/test/ui/extern/extern-types-not-sync-send.stderr
@@ -2,7 +2,7 @@ error[E0277]: `A` cannot be shared between threads safely
   --> $DIR/extern-types-not-sync-send.rs:13:5
    |
 LL | fn assert_sync<T: ?Sized + Sync>() { }
-   | ---------------------------------- required by `assert_sync`
+   |    -----------             ---- required by this bound in `assert_sync`
 ...
 LL |     assert_sync::<A>();
    |     ^^^^^^^^^^^^^^^^ `A` cannot be shared between threads safely
@@ -13,7 +13,7 @@ error[E0277]: `A` cannot be sent between threads safely
   --> $DIR/extern-types-not-sync-send.rs:16:5
    |
 LL | fn assert_send<T: ?Sized + Send>() { }
-   | ---------------------------------- required by `assert_send`
+   |    -----------             ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<A>();
    |     ^^^^^^^^^^^^^^^^ `A` cannot be sent between threads safely
diff --git a/src/test/ui/extern/extern-types-unsized.stderr b/src/test/ui/extern/extern-types-unsized.stderr
index 06527d973e2ab..1f69a4e154eb3 100644
--- a/src/test/ui/extern/extern-types-unsized.stderr
+++ b/src/test/ui/extern/extern-types-unsized.stderr
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim
   --> $DIR/extern-types-unsized.rs:22:5
    |
 LL | fn assert_sized<T>() { }
-   | -------------------- required by `assert_sized`
+   |    ------------ - required by this bound in `assert_sized`
 ...
 LL |     assert_sized::<A>();
    |     ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -14,7 +14,7 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim
   --> $DIR/extern-types-unsized.rs:25:5
    |
 LL | fn assert_sized<T>() { }
-   | -------------------- required by `assert_sized`
+   |    ------------ - required by this bound in `assert_sized`
 ...
 LL |     assert_sized::<Foo>();
    |     ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -27,7 +27,7 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim
   --> $DIR/extern-types-unsized.rs:28:5
    |
 LL | fn assert_sized<T>() { }
-   | -------------------- required by `assert_sized`
+   |    ------------ - required by this bound in `assert_sized`
 ...
 LL |     assert_sized::<Bar<A>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -40,7 +40,7 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim
   --> $DIR/extern-types-unsized.rs:31:5
    |
 LL | fn assert_sized<T>() { }
-   | -------------------- required by `assert_sized`
+   |    ------------ - required by this bound in `assert_sized`
 ...
 LL |     assert_sized::<Bar<Bar<A>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
diff --git a/src/test/ui/extern/extern-wrong-value-type.stderr b/src/test/ui/extern/extern-wrong-value-type.stderr
index f2468895d21d1..9a6af8119a8c5 100644
--- a/src/test/ui/extern/extern-wrong-value-type.stderr
+++ b/src/test/ui/extern/extern-wrong-value-type.stderr
@@ -2,7 +2,7 @@ error[E0277]: expected a `std::ops::Fn<()>` closure, found `extern "C" fn() {f}`
   --> $DIR/extern-wrong-value-type.rs:9:11
    |
 LL | fn is_fn<F>(_: F) where F: Fn() {}
-   | ------------------------------- required by `is_fn`
+   |    -----                   ---- required by this bound in `is_fn`
 ...
 LL |     is_fn(f);
    |           ^ expected an `Fn<()>` closure, found `extern "C" fn() {f}`
diff --git a/src/test/ui/fmt/send-sync.stderr b/src/test/ui/fmt/send-sync.stderr
index 599dcfaa72617..be6e41afaf811 100644
--- a/src/test/ui/fmt/send-sync.stderr
+++ b/src/test/ui/fmt/send-sync.stderr
@@ -2,7 +2,7 @@ error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between thr
   --> $DIR/send-sync.rs:8:5
    |
 LL | fn send<T: Send>(_: T) {}
-   | ---------------------- required by `send`
+   |    ----    ---- required by this bound in `send`
 ...
 LL |     send(format_args!("{:?}", c));
    |     ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
@@ -20,7 +20,7 @@ error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between thr
   --> $DIR/send-sync.rs:9:5
    |
 LL | fn sync<T: Sync>(_: T) {}
-   | ---------------------- required by `sync`
+   |    ----    ---- required by this bound in `sync`
 ...
 LL |     sync(format_args!("{:?}", c));
    |     ^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
diff --git a/src/test/ui/fn/fn-trait-formatting.stderr b/src/test/ui/fn/fn-trait-formatting.stderr
index 4d610b49dff8e..f891b9c6439be 100644
--- a/src/test/ui/fn/fn-trait-formatting.stderr
+++ b/src/test/ui/fn/fn-trait-formatting.stderr
@@ -29,7 +29,7 @@ error[E0277]: expected a `std::ops::Fn<(isize,)>` closure, found `{integer}`
   --> $DIR/fn-trait-formatting.rs:19:14
    |
 LL | fn needs_fn<F>(x: F) where F: Fn(isize) -> isize {}
-   | ------------------------------------------------ required by `needs_fn`
+   |    --------                   ------------------ required by this bound in `needs_fn`
 ...
 LL |     needs_fn(1);
    |              ^ expected an `Fn<(isize,)>` closure, found `{integer}`
diff --git a/src/test/ui/generator-yielding-or-returning-itself.stderr b/src/test/ui/generator-yielding-or-returning-itself.stderr
index 1049bb6240a24..c9a71e03858f1 100644
--- a/src/test/ui/generator-yielding-or-returning-itself.stderr
+++ b/src/test/ui/generator-yielding-or-returning-itself.stderr
@@ -16,14 +16,13 @@ LL | |     })
 error[E0271]: type mismatch resolving `<[generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 32:6 _] as std::ops::Generator>::Yield == [generator@$DIR/generator-yielding-or-returning-itself.rs:28:33: 32:6 _]`
   --> $DIR/generator-yielding-or-returning-itself.rs:28:5
    |
-LL | / pub fn want_cyclic_generator_yield<T>(_: T)
-LL | |     where T: Generator<Yield = T, Return = ()>
-LL | | {
-LL | | }
-   | |_- required by `want_cyclic_generator_yield`
+LL | pub fn want_cyclic_generator_yield<T>(_: T)
+   |        ---------------------------
+LL |     where T: Generator<Yield = T, Return = ()>
+   |                        --------- required by this bound in `want_cyclic_generator_yield`
 ...
-LL |       want_cyclic_generator_yield(|| {
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
+LL |     want_cyclic_generator_yield(|| {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
    |
    = note: closures cannot capture themselves or take themselves as argument;
            this error may be the result of a recent compiler bug-fix,
diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr
index 51416ce0d2f7a..620db245d3e57 100644
--- a/src/test/ui/generator/not-send-sync.stderr
+++ b/src/test/ui/generator/not-send-sync.stderr
@@ -2,7 +2,7 @@ error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
   --> $DIR/not-send-sync.rs:16:5
    |
 LL |     fn assert_send<T: Send>(_: T) {}
-   |     ----------------------------- required by `main::assert_send`
+   |        -----------    ---- required by this bound in `main::assert_send`
 ...
 LL |     assert_send(|| {
    |     ^^^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
@@ -15,7 +15,7 @@ error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
   --> $DIR/not-send-sync.rs:9:5
    |
 LL |     fn assert_sync<T: Sync>(_: T) {}
-   |     ----------------------------- required by `main::assert_sync`
+   |        -----------    ---- required by this bound in `main::assert_sync`
 ...
 LL |     assert_sync(|| {
    |     ^^^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
diff --git a/src/test/ui/generator/static-not-unpin.stderr b/src/test/ui/generator/static-not-unpin.stderr
index b7871ee3478a4..f2b1078e2b532 100644
--- a/src/test/ui/generator/static-not-unpin.stderr
+++ b/src/test/ui/generator/static-not-unpin.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `[static generator@$DIR/static-not-unpin.rs:11:25:
   --> $DIR/static-not-unpin.rs:14:18
    |
 LL | fn assert_unpin<T: Unpin>(_: T) {
-   | ------------------------------- required by `assert_unpin`
+   |    ------------    ----- required by this bound in `assert_unpin`
 ...
 LL |     assert_unpin(generator);
    |                  ^^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `[static generator@$DIR/static-not-unpin.rs:11:25: 13:6 _]`
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
index e0b968b67645e..205fa2b5bc81f 100644
--- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr
+++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
@@ -1,14 +1,13 @@
 error[E0277]: the trait bound `for<'a, 'b> SomeStruct: Foo<(&'a isize, &'b isize)>` is not satisfied
   --> $DIR/hrtb-conflate-regions.rs:27:10
    |
-LL | / fn want_foo2<T>()
-LL | |     where T : for<'a,'b> Foo<(&'a isize, &'b isize)>
-LL | | {
-LL | | }
-   | |_- required by `want_foo2`
+LL | fn want_foo2<T>()
+   |    ---------
+LL |     where T : for<'a,'b> Foo<(&'a isize, &'b isize)>
+   |               -------------------------------------- required by this bound in `want_foo2`
 ...
-LL |   fn b() { want_foo2::<SomeStruct>(); }
-   |            ^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct`
+LL | fn b() { want_foo2::<SomeStruct>(); }
+   |          ^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct`
    |
    = help: the following implementations were found:
              <SomeStruct as Foo<(&'a isize, &'a isize)>>
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
index bc58b8e16aaf2..ceba22234be6a 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
@@ -1,15 +1,14 @@
 error[E0277]: the trait bound `(): Trait<for<'b> fn(&'b u32)>` is not satisfied
   --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
    |
-LL | / fn foo<T>()
-LL | | where
-LL | |     T: Trait<for<'b> fn(&'b u32)>,
-LL | | {
-LL | | }
-   | |_- required by `foo`
+LL | fn foo<T>()
+   |    ---
+LL | where
+LL |     T: Trait<for<'b> fn(&'b u32)>,
+   |        -------------------------- required by this bound in `foo`
 ...
-LL |       foo::<()>();
-   |       ^^^^^^^^^ the trait `Trait<for<'b> fn(&'b u32)>` is not implemented for `()`
+LL |     foo::<()>();
+   |     ^^^^^^^^^ the trait `Trait<for<'b> fn(&'b u32)>` is not implemented for `()`
    |
    = help: the following implementations were found:
              <() as Trait<fn(&'a u32)>>
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr
index 441f75135f3a4..a1cb3b230fea2 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr
@@ -1,15 +1,14 @@
 error[E0277]: the trait bound `(): Trait<for<'b> fn(fn(&'b u32))>` is not satisfied
   --> $DIR/hrtb-exists-forall-trait-covariant.rs:36:5
    |
-LL | / fn foo<T>()
-LL | | where
-LL | |     T: Trait<for<'b> fn(fn(&'b u32))>,
-LL | | {
-LL | | }
-   | |_- required by `foo`
+LL | fn foo<T>()
+   |    ---
+LL | where
+LL |     T: Trait<for<'b> fn(fn(&'b u32))>,
+   |        ------------------------------ required by this bound in `foo`
 ...
-LL |       foo::<()>();
-   |       ^^^^^^^^^ the trait `Trait<for<'b> fn(fn(&'b u32))>` is not implemented for `()`
+LL |     foo::<()>();
+   |     ^^^^^^^^^ the trait `Trait<for<'b> fn(fn(&'b u32))>` is not implemented for `()`
    |
    = help: the following implementations were found:
              <() as Trait<fn(fn(&'a u32))>>
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
index a11949735b9d2..093bee375bb0b 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
@@ -1,15 +1,14 @@
 error[E0277]: the trait bound `(): Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not satisfied
   --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5
    |
-LL | / fn foo<T>()
-LL | | where
-LL | |     T: Trait<for<'b> fn(Cell<&'b u32>)>,
-LL | | {
-LL | | }
-   | |_- required by `foo`
+LL | fn foo<T>()
+   |    ---
+LL | where
+LL |     T: Trait<for<'b> fn(Cell<&'b u32>)>,
+   |        -------------------------------- required by this bound in `foo`
 ...
-LL |       foo::<()>();
-   |       ^^^^^^^^^ the trait `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not implemented for `()`
+LL |     foo::<()>();
+   |     ^^^^^^^^^ the trait `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not implemented for `()`
    |
    = help: the following implementations were found:
              <() as Trait<fn(std::cell::Cell<&'a u32>)>>
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
index 18f49089302e5..c2cc8ebad2726 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
+++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits-transitive.stderr
@@ -1,14 +1,13 @@
 error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
   --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26
    |
-LL | / fn want_bar_for_any_ccx<B>(b: &B)
-LL | |     where B : for<'ccx> Bar<'ccx>
-LL | | {
-LL | | }
-   | |_- required by `want_bar_for_any_ccx`
+LL | fn want_bar_for_any_ccx<B>(b: &B)
+   |    --------------------
+LL |     where B : for<'ccx> Bar<'ccx>
+   |               ------------------- required by this bound in `want_bar_for_any_ccx`
 ...
-LL |       want_bar_for_any_ccx(b);
-   |                            ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+LL |     want_bar_for_any_ccx(b);
+   |                          ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
    |
    = help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound
 
diff --git a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
index 7857ab6e86a20..a93814ad4c25e 100644
--- a/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
+++ b/src/test/ui/hrtb/hrtb-higher-ranker-supertraits.stderr
@@ -1,33 +1,26 @@
 error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
   --> $DIR/hrtb-higher-ranker-supertraits.rs:18:26
    |
-LL |       want_foo_for_any_tcx(f);
-   |                            ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
+LL |     want_foo_for_any_tcx(f);
+   |                          ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
 ...
-LL | / fn want_foo_for_any_tcx<F>(f: &F)
-LL | |     where F : for<'tcx> Foo<'tcx>
-LL | | {
-LL | |     want_foo_for_some_tcx(f);
-LL | |     want_foo_for_any_tcx(f);
-LL | | }
-   | |_- required by `want_foo_for_any_tcx`
+LL | fn want_foo_for_any_tcx<F>(f: &F)
+   |    --------------------
+LL |     where F : for<'tcx> Foo<'tcx>
+   |               ------------------- required by this bound in `want_foo_for_any_tcx`
    |
    = help: consider adding a `where for<'tcx> F: Foo<'tcx>` bound
 
 error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
   --> $DIR/hrtb-higher-ranker-supertraits.rs:35:26
    |
-LL |       want_bar_for_any_ccx(b);
-   |                            ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
+LL |     want_bar_for_any_ccx(b);
+   |                          ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
 ...
-LL | / fn want_bar_for_any_ccx<B>(b: &B)
-LL | |     where B : for<'ccx> Bar<'ccx>
-LL | | {
-LL | |     want_foo_for_some_tcx(b);
-...  |
-LL | |     want_bar_for_any_ccx(b);
-LL | | }
-   | |_- required by `want_bar_for_any_ccx`
+LL | fn want_bar_for_any_ccx<B>(b: &B)
+   |    --------------------
+LL |     where B : for<'ccx> Bar<'ccx>
+   |               ------------------- required by this bound in `want_bar_for_any_ccx`
    |
    = help: consider adding a `where for<'ccx> B: Bar<'ccx>` bound
 
diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr
index b2938e541fdd8..f4cf3555868f2 100644
--- a/src/test/ui/hrtb/hrtb-just-for-static.stderr
+++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr
@@ -1,14 +1,13 @@
 error[E0277]: the trait bound `for<'a> StaticInt: Foo<&'a isize>` is not satisfied
   --> $DIR/hrtb-just-for-static.rs:24:5
    |
-LL | / fn want_hrtb<T>()
-LL | |     where T : for<'a> Foo<&'a isize>
-LL | | {
-LL | | }
-   | |_- required by `want_hrtb`
+LL | fn want_hrtb<T>()
+   |    ---------
+LL |     where T : for<'a> Foo<&'a isize>
+   |               ---------------------- required by this bound in `want_hrtb`
 ...
-LL |       want_hrtb::<StaticInt>()
-   |       ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt`
+LL |     want_hrtb::<StaticInt>()
+   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt`
    |
    = help: the following implementations were found:
              <StaticInt as Foo<&'static isize>>
@@ -16,14 +15,13 @@ LL |       want_hrtb::<StaticInt>()
 error[E0277]: the trait bound `for<'a> &'a u32: Foo<&'a isize>` is not satisfied
   --> $DIR/hrtb-just-for-static.rs:30:5
    |
-LL | / fn want_hrtb<T>()
-LL | |     where T : for<'a> Foo<&'a isize>
-LL | | {
-LL | | }
-   | |_- required by `want_hrtb`
+LL | fn want_hrtb<T>()
+   |    ---------
+LL |     where T : for<'a> Foo<&'a isize>
+   |               ---------------------- required by this bound in `want_hrtb`
 ...
-LL |       want_hrtb::<&'a u32>()
-   |       ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `&'a u32`
+LL |     want_hrtb::<&'a u32>()
+   |     ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `&'a u32`
    |
    = help: the following implementations were found:
              <&'a u32 as Foo<&'a isize>>
diff --git a/src/test/ui/hrtb/issue-46989.stderr b/src/test/ui/hrtb/issue-46989.stderr
index 57eaf2aad2bc5..4da3e3ddb7ebd 100644
--- a/src/test/ui/hrtb/issue-46989.stderr
+++ b/src/test/ui/hrtb/issue-46989.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied
   --> $DIR/issue-46989.rs:40:5
    |
 LL | fn assert_foo<T: Foo>() {}
-   | ----------------------- required by `assert_foo`
+   |    ----------    --- required by this bound in `assert_foo`
 ...
 LL |     assert_foo::<fn(&i32)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `for<'r> fn(&'r i32)`
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr
index af641a89e7f9c..d11941fee1824 100644
--- a/src/test/ui/impl-trait/auto-trait-leak.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak.stderr
@@ -73,7 +73,7 @@ error[E0277]: `std::rc::Rc<std::string::String>` cannot be sent between threads
   --> $DIR/auto-trait-leak.rs:15:5
    |
 LL | fn send<T: Send>(_: T) {}
-   | ---------------------- required by `send`
+   |    ----    ---- required by this bound in `send`
 ...
 LL |     send(cycle2().clone());
    |     ^^^^ `std::rc::Rc<std::string::String>` cannot be sent between threads safely
diff --git a/src/test/ui/impl-trait/auto-trait-leak2.stderr b/src/test/ui/impl-trait/auto-trait-leak2.stderr
index 460af7dedbea8..d163e1dff7ac9 100644
--- a/src/test/ui/impl-trait/auto-trait-leak2.stderr
+++ b/src/test/ui/impl-trait/auto-trait-leak2.stderr
@@ -2,7 +2,7 @@ error[E0277]: `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads
   --> $DIR/auto-trait-leak2.rs:13:5
    |
 LL | fn send<T: Send>(_: T) {}
-   | ---------------------- required by `send`
+   |    ----    ---- required by this bound in `send`
 ...
 LL |     send(before());
    |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
@@ -15,7 +15,7 @@ error[E0277]: `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads
   --> $DIR/auto-trait-leak2.rs:16:5
    |
 LL | fn send<T: Send>(_: T) {}
-   | ---------------------- required by `send`
+   |    ----    ---- required by this bound in `send`
 ...
 LL |     send(after());
    |     ^^^^ `std::rc::Rc<std::cell::Cell<i32>>` cannot be sent between threads safely
diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr
index 31390bc6ccefd..1a726be4aa6f4 100644
--- a/src/test/ui/interior-mutability/interior-mutability.stderr
+++ b/src/test/ui/interior-mutability/interior-mutability.stderr
@@ -3,12 +3,16 @@ error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutabil
    |
 LL |     catch_unwind(|| { x.set(23); });
    |     ^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
+   | 
+  ::: $SRC_DIR/libstd/panic.rs:LL:COL
+   |
+LL | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
+   |                                        ---------- required by this bound in `std::panic::catch_unwind`
    |
    = help: within `std::cell::Cell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
    = note: required because it appears within the type `std::cell::Cell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&std::cell::Cell<i32>`
    = note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:5:18: 5:35 x:&std::cell::Cell<i32>]`
-   = note: required by `std::panic::catch_unwind`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-1920-1.stderr b/src/test/ui/issues/issue-1920-1.stderr
index c62cbb0cf8b96..56f70aa296cb9 100644
--- a/src/test/ui/issues/issue-1920-1.stderr
+++ b/src/test/ui/issues/issue-1920-1.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `foo::issue_1920::S: std::clone::Clone` is not sat
   --> $DIR/issue-1920-1.rs:12:5
    |
 LL | fn assert_clone<T>() where T : Clone { }
-   | ------------------------------------ required by `assert_clone`
+   |    ------------                ----- required by this bound in `assert_clone`
 ...
 LL |     assert_clone::<foo::issue_1920::S>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `foo::issue_1920::S`
diff --git a/src/test/ui/issues/issue-1920-2.stderr b/src/test/ui/issues/issue-1920-2.stderr
index aad076244699a..37027b0579265 100644
--- a/src/test/ui/issues/issue-1920-2.stderr
+++ b/src/test/ui/issues/issue-1920-2.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `bar::S: std::clone::Clone` is not satisfied
   --> $DIR/issue-1920-2.rs:10:5
    |
 LL | fn assert_clone<T>() where T : Clone { }
-   | ------------------------------------ required by `assert_clone`
+   |    ------------                ----- required by this bound in `assert_clone`
 ...
 LL |     assert_clone::<bar::S>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `bar::S`
diff --git a/src/test/ui/issues/issue-1920-3.stderr b/src/test/ui/issues/issue-1920-3.stderr
index 4378ea49755a7..dbcb3aee11703 100644
--- a/src/test/ui/issues/issue-1920-3.stderr
+++ b/src/test/ui/issues/issue-1920-3.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `issue_1920::S: std::clone::Clone` is not satisfie
   --> $DIR/issue-1920-3.rs:14:5
    |
 LL | fn assert_clone<T>() where T : Clone { }
-   | ------------------------------------ required by `assert_clone`
+   |    ------------                ----- required by this bound in `assert_clone`
 ...
 LL |     assert_clone::<foo::issue_1920::S>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `issue_1920::S`
diff --git a/src/test/ui/issues/issue-21160.stderr b/src/test/ui/issues/issue-21160.stderr
index e32343e9682db..577baa97d8f9d 100644
--- a/src/test/ui/issues/issue-21160.stderr
+++ b/src/test/ui/issues/issue-21160.stderr
@@ -3,8 +3,11 @@ error[E0277]: the trait bound `Bar: std::hash::Hash` is not satisfied
    |
 LL | struct Foo(Bar);
    |            ^^^ the trait `std::hash::Hash` is not implemented for `Bar`
+   | 
+  ::: $SRC_DIR/libcore/hash/mod.rs:LL:COL
    |
-   = note: required by `std::hash::Hash::hash`
+LL |     fn hash<H: Hasher>(&self, state: &mut H);
+   |             - required by this bound in `std::hash::Hash::hash`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-21763.stderr b/src/test/ui/issues/issue-21763.stderr
index 99d004a973a26..2bede9120cf1d 100644
--- a/src/test/ui/issues/issue-21763.stderr
+++ b/src/test/ui/issues/issue-21763.stderr
@@ -2,7 +2,7 @@ error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
   --> $DIR/issue-21763.rs:9:5
    |
 LL | fn foo<T: Send>() {}
-   | ----------------- required by `foo`
+   |    ---    ---- required by this bound in `foo`
 ...
 LL |     foo::<HashMap<Rc<()>, Rc<()>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
diff --git a/src/test/ui/issues/issue-25076.stderr b/src/test/ui/issues/issue-25076.stderr
index a7b6626b16a1c..0a13a2bc33023 100644
--- a/src/test/ui/issues/issue-25076.stderr
+++ b/src/test/ui/issues/issue-25076.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `(): InOut<_>` is not satisfied
   --> $DIR/issue-25076.rs:10:20
    |
 LL | fn do_fold<B, F: InOut<B, Out=B>>(init: B, f: F) {}
-   | ------------------------------------------------ required by `do_fold`
+   |    -------       --------------- required by this bound in `do_fold`
 ...
 LL |     do_fold(bot(), ());
    |                    ^^ the trait `InOut<_>` is not implemented for `()`
diff --git a/src/test/ui/issues/issue-32963.stderr b/src/test/ui/issues/issue-32963.stderr
index 2960f4e598997..e3564e8670174 100644
--- a/src/test/ui/issues/issue-32963.stderr
+++ b/src/test/ui/issues/issue-32963.stderr
@@ -13,7 +13,7 @@ error[E0277]: the trait bound `dyn Misc: std::marker::Copy` is not satisfied
   --> $DIR/issue-32963.rs:8:5
    |
 LL | fn size_of_copy<T: Copy+?Sized>() -> usize { mem::size_of::<T>() }
-   | ------------------------------------------ required by `size_of_copy`
+   |    ------------    ---- required by this bound in `size_of_copy`
 ...
 LL |     size_of_copy::<dyn Misc + Copy>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `dyn Misc`
diff --git a/src/test/ui/issues/issue-40827.stderr b/src/test/ui/issues/issue-40827.stderr
index 9131120671f4c..3fe47e249f10c 100644
--- a/src/test/ui/issues/issue-40827.stderr
+++ b/src/test/ui/issues/issue-40827.stderr
@@ -2,7 +2,7 @@ error[E0277]: `std::rc::Rc<Foo>` cannot be sent between threads safely
   --> $DIR/issue-40827.rs:14:5
    |
 LL | fn f<T: Send>(_: T) {}
-   | ------------------- required by `f`
+   |    -    ---- required by this bound in `f`
 ...
 LL |     f(Foo(Arc::new(Bar::B(None))));
    |     ^ `std::rc::Rc<Foo>` cannot be sent between threads safely
@@ -16,7 +16,7 @@ error[E0277]: `std::rc::Rc<Foo>` cannot be shared between threads safely
   --> $DIR/issue-40827.rs:14:5
    |
 LL | fn f<T: Send>(_: T) {}
-   | ------------------- required by `f`
+   |    -    ---- required by this bound in `f`
 ...
 LL |     f(Foo(Arc::new(Bar::B(None))));
    |     ^ `std::rc::Rc<Foo>` cannot be shared between threads safely
diff --git a/src/test/ui/issues/issue-43623.stderr b/src/test/ui/issues/issue-43623.stderr
index d843629e8a26f..210d831abf0de 100644
--- a/src/test/ui/issues/issue-43623.stderr
+++ b/src/test/ui/issues/issue-43623.stderr
@@ -1,31 +1,27 @@
 error[E0631]: type mismatch in function arguments
   --> $DIR/issue-43623.rs:14:5
    |
-LL | / pub fn break_me<T, F>(f: F)
-LL | | where T: for<'b> Trait<'b>,
-LL | |       F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
-LL | |     break_me::<Type, fn(_)>;
-   | |     ^^^^^^^^^^^^^^^^^^^^^^^
-   | |     |
-   | |     expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
-   | |     found signature of `fn(_) -> _`
-LL | |
-LL | |
-LL | | }
-   | |_- required by `break_me`
+LL | pub fn break_me<T, F>(f: F)
+   |        --------
+LL | where T: for<'b> Trait<'b>,
+LL |       F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
+   |          -------------------------------------- required by this bound in `break_me`
+LL |     break_me::<Type, fn(_)>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     expected signature of `for<'b> fn(<Type as Trait<'b>>::Assoc) -> _`
+   |     found signature of `fn(_) -> _`
 
 error[E0271]: type mismatch resolving `for<'b> <fn(_) as std::ops::FnOnce<(<Type as Trait<'b>>::Assoc,)>>::Output == ()`
   --> $DIR/issue-43623.rs:14:5
    |
-LL | / pub fn break_me<T, F>(f: F)
-LL | | where T: for<'b> Trait<'b>,
-LL | |       F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
-LL | |     break_me::<Type, fn(_)>;
-   | |     ^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'b, found concrete lifetime
-LL | |
-LL | |
-LL | | }
-   | |_- required by `break_me`
+LL | pub fn break_me<T, F>(f: F)
+   |        --------
+LL | where T: for<'b> Trait<'b>,
+LL |       F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
+   |                       ------------------------- required by this bound in `break_me`
+LL |     break_me::<Type, fn(_)>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'b, found concrete lifetime
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-47706.stderr b/src/test/ui/issues/issue-47706.stderr
index 4f64a643fe57d..6cde93734667f 100644
--- a/src/test/ui/issues/issue-47706.stderr
+++ b/src/test/ui/issues/issue-47706.stderr
@@ -10,18 +10,17 @@ LL |         self.foo.map(Foo::new)
 error[E0593]: function is expected to take 0 arguments, but it takes 1 argument
   --> $DIR/issue-47706.rs:27:9
    |
-LL |       Bar(i32),
-   |       -------- takes 1 argument
+LL |     Bar(i32),
+   |     -------- takes 1 argument
 ...
-LL | / fn foo<F>(f: F)
-LL | | where
-LL | |     F: Fn(),
-LL | | {
-LL | | }
-   | |_- required by `foo`
+LL | fn foo<F>(f: F)
+   |    ---
+LL | where
+LL |     F: Fn(),
+   |        ---- required by this bound in `foo`
 ...
-LL |       foo(Qux::Bar);
-   |           ^^^^^^^^ expected function that takes 0 arguments
+LL |     foo(Qux::Bar);
+   |         ^^^^^^^^ expected function that takes 0 arguments
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-60283.stderr b/src/test/ui/issues/issue-60283.stderr
index 2b01a64d39a9b..dc7952200b18e 100644
--- a/src/test/ui/issues/issue-60283.stderr
+++ b/src/test/ui/issues/issue-60283.stderr
@@ -1,27 +1,29 @@
 error[E0631]: type mismatch in function arguments
   --> $DIR/issue-60283.rs:14:13
    |
-LL | / pub fn foo<T, F>(_: T, _: F)
-LL | | where T: for<'a> Trait<'a>,
-LL | |       F: for<'a> FnMut(<T as Trait<'a>>::Item) {}
-   | |_________________________________________________- required by `foo`
+LL | pub fn foo<T, F>(_: T, _: F)
+   |        ---
+LL | where T: for<'a> Trait<'a>,
+LL |       F: for<'a> FnMut(<T as Trait<'a>>::Item) {}
+   |          ------------------------------------- required by this bound in `foo`
 ...
-LL |       foo((), drop)
-   |               ^^^^
-   |               |
-   |               expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
-   |               found signature of `fn(_) -> _`
+LL |     foo((), drop)
+   |             ^^^^
+   |             |
+   |             expected signature of `for<'a> fn(<() as Trait<'a>>::Item) -> _`
+   |             found signature of `fn(_) -> _`
 
 error[E0271]: type mismatch resolving `for<'a> <fn(_) {std::mem::drop::<_>} as std::ops::FnOnce<(<() as Trait<'a>>::Item,)>>::Output == ()`
   --> $DIR/issue-60283.rs:14:5
    |
-LL | / pub fn foo<T, F>(_: T, _: F)
-LL | | where T: for<'a> Trait<'a>,
-LL | |       F: for<'a> FnMut(<T as Trait<'a>>::Item) {}
-   | |_________________________________________________- required by `foo`
+LL | pub fn foo<T, F>(_: T, _: F)
+   |        ---
+LL | where T: for<'a> Trait<'a>,
+LL |       F: for<'a> FnMut(<T as Trait<'a>>::Item) {}
+   |                       ------------------------ required by this bound in `foo`
 ...
-LL |       foo((), drop)
-   |       ^^^ expected bound lifetime parameter 'a, found concrete lifetime
+LL |     foo((), drop)
+   |     ^^^ expected bound lifetime parameter 'a, found concrete lifetime
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/kindck/kindck-copy.stderr b/src/test/ui/kindck/kindck-copy.stderr
index 1fe59460e057f..53b4448a7574f 100644
--- a/src/test/ui/kindck/kindck-copy.stderr
+++ b/src/test/ui/kindck/kindck-copy.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `&'static mut isize: std::marker::Copy` is not sat
   --> $DIR/kindck-copy.rs:27:5
    |
 LL | fn assert_copy<T:Copy>() { }
-   | ------------------------ required by `assert_copy`
+   |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<&'static mut isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'static mut isize`
@@ -14,7 +14,7 @@ error[E0277]: the trait bound `&'a mut isize: std::marker::Copy` is not satisfie
   --> $DIR/kindck-copy.rs:28:5
    |
 LL | fn assert_copy<T:Copy>() { }
-   | ------------------------ required by `assert_copy`
+   |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<&'a mut isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'a mut isize`
@@ -26,7 +26,7 @@ error[E0277]: the trait bound `std::boxed::Box<isize>: std::marker::Copy` is not
   --> $DIR/kindck-copy.rs:31:5
    |
 LL | fn assert_copy<T:Copy>() { }
-   | ------------------------ required by `assert_copy`
+   |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<Box<isize>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<isize>`
@@ -35,7 +35,7 @@ error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not sa
   --> $DIR/kindck-copy.rs:32:5
    |
 LL | fn assert_copy<T:Copy>() { }
-   | ------------------------ required by `assert_copy`
+   |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<String>();
    |     ^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
@@ -44,7 +44,7 @@ error[E0277]: the trait bound `std::vec::Vec<isize>: std::marker::Copy` is not s
   --> $DIR/kindck-copy.rs:33:5
    |
 LL | fn assert_copy<T:Copy>() { }
-   | ------------------------ required by `assert_copy`
+   |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<Vec<isize> >();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::vec::Vec<isize>`
@@ -53,7 +53,7 @@ error[E0277]: the trait bound `std::boxed::Box<&'a mut isize>: std::marker::Copy
   --> $DIR/kindck-copy.rs:34:5
    |
 LL | fn assert_copy<T:Copy>() { }
-   | ------------------------ required by `assert_copy`
+   |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<Box<&'a mut isize>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<&'a mut isize>`
@@ -62,7 +62,7 @@ error[E0277]: the trait bound `std::boxed::Box<dyn Dummy>: std::marker::Copy` is
   --> $DIR/kindck-copy.rs:42:5
    |
 LL | fn assert_copy<T:Copy>() { }
-   | ------------------------ required by `assert_copy`
+   |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<Box<dyn Dummy>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<dyn Dummy>`
@@ -71,7 +71,7 @@ error[E0277]: the trait bound `std::boxed::Box<dyn Dummy + std::marker::Send>: s
   --> $DIR/kindck-copy.rs:43:5
    |
 LL | fn assert_copy<T:Copy>() { }
-   | ------------------------ required by `assert_copy`
+   |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<Box<dyn Dummy + Send>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<dyn Dummy + std::marker::Send>`
@@ -80,7 +80,7 @@ error[E0277]: the trait bound `&'a mut (dyn Dummy + std::marker::Send + 'a): std
   --> $DIR/kindck-copy.rs:46:5
    |
 LL | fn assert_copy<T:Copy>() { }
-   | ------------------------ required by `assert_copy`
+   |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<&'a mut (dyn Dummy + Send)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'a mut (dyn Dummy + std::marker::Send + 'a)`
@@ -89,7 +89,7 @@ error[E0277]: the trait bound `MyNoncopyStruct: std::marker::Copy` is not satisf
   --> $DIR/kindck-copy.rs:64:5
    |
 LL | fn assert_copy<T:Copy>() { }
-   | ------------------------ required by `assert_copy`
+   |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<MyNoncopyStruct>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `MyNoncopyStruct`
@@ -98,7 +98,7 @@ error[E0277]: the trait bound `std::rc::Rc<isize>: std::marker::Copy` is not sat
   --> $DIR/kindck-copy.rs:67:5
    |
 LL | fn assert_copy<T:Copy>() { }
-   | ------------------------ required by `assert_copy`
+   |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<Rc<isize>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::rc::Rc<isize>`
diff --git a/src/test/ui/kindck/kindck-impl-type-params-2.stderr b/src/test/ui/kindck/kindck-impl-type-params-2.stderr
index 5e6eca6f0571b..8e98911324411 100644
--- a/src/test/ui/kindck/kindck-impl-type-params-2.stderr
+++ b/src/test/ui/kindck/kindck-impl-type-params-2.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `std::boxed::Box<{integer}>: std::marker::Copy` is
   --> $DIR/kindck-impl-type-params-2.rs:13:16
    |
 LL | fn take_param<T:Foo>(foo: &T) { }
-   | ----------------------------- required by `take_param`
+   |    ----------   --- required by this bound in `take_param`
 ...
 LL |     take_param(&x);
    |                ^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<{integer}>`
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.stderr
index 9f548083e73d1..27901d0692799 100644
--- a/src/test/ui/kindck/kindck-inherited-copy-bound.stderr
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `std::boxed::Box<{integer}>: std::marker::Copy` is
   --> $DIR/kindck-inherited-copy-bound.rs:18:16
    |
 LL | fn take_param<T:Foo>(foo: &T) { }
-   | ----------------------------- required by `take_param`
+   |    ----------   --- required by this bound in `take_param`
 ...
 LL |     take_param(&x);
    |                ^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<{integer}>`
diff --git a/src/test/ui/kindck/kindck-nonsendable-1.stderr b/src/test/ui/kindck/kindck-nonsendable-1.stderr
index 6d60de888c98d..40b67f8fe8cd7 100644
--- a/src/test/ui/kindck/kindck-nonsendable-1.stderr
+++ b/src/test/ui/kindck/kindck-nonsendable-1.stderr
@@ -2,7 +2,7 @@ error[E0277]: `std::rc::Rc<usize>` cannot be sent between threads safely
   --> $DIR/kindck-nonsendable-1.rs:9:5
    |
 LL | fn bar<F:FnOnce() + Send>(_: F) { }
-   | ------------------------------- required by `bar`
+   |    ---              ---- required by this bound in `bar`
 ...
 LL |     bar(move|| foo(x));
    |     ^^^ `std::rc::Rc<usize>` cannot be sent between threads safely
diff --git a/src/test/ui/kindck/kindck-send-object.stderr b/src/test/ui/kindck/kindck-send-object.stderr
index 3ca2d730cbae9..8708537f8630f 100644
--- a/src/test/ui/kindck/kindck-send-object.stderr
+++ b/src/test/ui/kindck/kindck-send-object.stderr
@@ -2,7 +2,7 @@ error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely
   --> $DIR/kindck-send-object.rs:12:5
    |
 LL | fn assert_send<T:Send>() { }
-   | ------------------------ required by `assert_send`
+   |    -----------   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<&'static (dyn Dummy + 'static)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
@@ -14,7 +14,7 @@ error[E0277]: `dyn Dummy` cannot be sent between threads safely
   --> $DIR/kindck-send-object.rs:17:5
    |
 LL | fn assert_send<T:Send>() { }
-   | ------------------------ required by `assert_send`
+   |    -----------   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<Box<dyn Dummy>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
diff --git a/src/test/ui/kindck/kindck-send-object1.stderr b/src/test/ui/kindck/kindck-send-object1.stderr
index 0f5f7e0890b23..436b92637aaad 100644
--- a/src/test/ui/kindck/kindck-send-object1.stderr
+++ b/src/test/ui/kindck/kindck-send-object1.stderr
@@ -2,7 +2,7 @@ error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely
   --> $DIR/kindck-send-object1.rs:10:5
    |
 LL | fn assert_send<T:Send+'static>() { }
-   | -------------------------------- required by `assert_send`
+   |    -----------   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<&'a dyn Dummy>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely
@@ -22,7 +22,7 @@ error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely
   --> $DIR/kindck-send-object1.rs:29:5
    |
 LL | fn assert_send<T:Send+'static>() { }
-   | -------------------------------- required by `assert_send`
+   |    -----------   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<Box<dyn Dummy + 'a>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely
diff --git a/src/test/ui/kindck/kindck-send-object2.stderr b/src/test/ui/kindck/kindck-send-object2.stderr
index 72cd985cc8639..6cb82edf263b1 100644
--- a/src/test/ui/kindck/kindck-send-object2.stderr
+++ b/src/test/ui/kindck/kindck-send-object2.stderr
@@ -2,7 +2,7 @@ error[E0277]: `(dyn Dummy + 'static)` cannot be shared between threads safely
   --> $DIR/kindck-send-object2.rs:7:5
    |
 LL | fn assert_send<T:Send>() { }
-   | ------------------------ required by `assert_send`
+   |    -----------   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<&'static dyn Dummy>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'static)` cannot be shared between threads safely
@@ -14,7 +14,7 @@ error[E0277]: `dyn Dummy` cannot be sent between threads safely
   --> $DIR/kindck-send-object2.rs:12:5
    |
 LL | fn assert_send<T:Send>() { }
-   | ------------------------ required by `assert_send`
+   |    -----------   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<Box<dyn Dummy>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `dyn Dummy` cannot be sent between threads safely
diff --git a/src/test/ui/kindck/kindck-send-owned.stderr b/src/test/ui/kindck/kindck-send-owned.stderr
index ee919f02d6537..c740349542458 100644
--- a/src/test/ui/kindck/kindck-send-owned.stderr
+++ b/src/test/ui/kindck/kindck-send-owned.stderr
@@ -2,7 +2,7 @@ error[E0277]: `*mut u8` cannot be sent between threads safely
   --> $DIR/kindck-send-owned.rs:12:5
    |
 LL | fn assert_send<T:Send>() { }
-   | ------------------------ required by `assert_send`
+   |    -----------   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<Box<*mut u8>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut u8` cannot be sent between threads safely
diff --git a/src/test/ui/kindck/kindck-send-unsafe.stderr b/src/test/ui/kindck/kindck-send-unsafe.stderr
index a87e1c7db2a2e..a46705ab1755d 100644
--- a/src/test/ui/kindck/kindck-send-unsafe.stderr
+++ b/src/test/ui/kindck/kindck-send-unsafe.stderr
@@ -2,7 +2,7 @@ error[E0277]: `*mut &'a isize` cannot be sent between threads safely
   --> $DIR/kindck-send-unsafe.rs:6:5
    |
 LL | fn assert_send<T:Send>() { }
-   | ------------------------ required by `assert_send`
+   |    -----------   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<*mut &'a isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely
diff --git a/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr b/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr
index 4e79fbdeadc5c..be5e649ef8340 100644
--- a/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr
+++ b/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `NotDebugOrDisplay: Marker` is not satisfied
   --> $DIR/overlap-marker-trait.rs:27:5
    |
 LL | fn is_marker<T: Marker>() { }
-   | ------------------------- required by `is_marker`
+   |    ---------    ------ required by this bound in `is_marker`
 ...
 LL |     is_marker::<NotDebugOrDisplay>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Marker` is not implemented for `NotDebugOrDisplay`
diff --git a/src/test/ui/mismatched_types/E0631.stderr b/src/test/ui/mismatched_types/E0631.stderr
index 64ddf1deb0639..88c1efdbb90f4 100644
--- a/src/test/ui/mismatched_types/E0631.stderr
+++ b/src/test/ui/mismatched_types/E0631.stderr
@@ -2,7 +2,7 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/E0631.rs:7:5
    |
 LL | fn foo<F: Fn(usize)>(_: F) {}
-   | -------------------------- required by `foo`
+   |    ---    --------- required by this bound in `foo`
 ...
 LL |     foo(|_: isize| {});
    |     ^^^ ---------- found signature of `fn(isize) -> _`
@@ -13,7 +13,7 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/E0631.rs:8:5
    |
 LL | fn bar<F: Fn<usize>>(_: F) {}
-   | -------------------------- required by `bar`
+   |    ---    --------- required by this bound in `bar`
 ...
 LL |     bar(|_: isize| {});
    |     ^^^ ---------- found signature of `fn(isize) -> _`
@@ -24,7 +24,7 @@ error[E0631]: type mismatch in function arguments
   --> $DIR/E0631.rs:9:9
    |
 LL | fn foo<F: Fn(usize)>(_: F) {}
-   | -------------------------- required by `foo`
+   |    ---    --------- required by this bound in `foo`
 ...
 LL |     fn f(_: u64) {}
    |     ------------ found signature of `fn(u64) -> _`
@@ -36,7 +36,7 @@ error[E0631]: type mismatch in function arguments
   --> $DIR/E0631.rs:10:9
    |
 LL | fn bar<F: Fn<usize>>(_: F) {}
-   | -------------------------- required by `bar`
+   |    ---    --------- required by this bound in `bar`
 LL | fn main() {
 LL |     fn f(_: u64) {}
    |     ------------ found signature of `fn(u64) -> _`
diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr
index 12ae8acaee5cf..ed2b3f0c3ce6c 100644
--- a/src/test/ui/mismatched_types/closure-arg-count.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-count.stderr
@@ -46,7 +46,7 @@ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
   --> $DIR/closure-arg-count.rs:13:5
    |
 LL | fn f<F: Fn<usize>>(_: F) {}
-   | ------------------------ required by `f`
+   |    -    --------- required by this bound in `f`
 ...
 LL |     f(|| panic!());
    |     ^ -- takes 0 arguments
@@ -61,7 +61,7 @@ error[E0593]: closure is expected to take 1 argument, but it takes 0 arguments
   --> $DIR/closure-arg-count.rs:15:5
    |
 LL | fn f<F: Fn<usize>>(_: F) {}
-   | ------------------------ required by `f`
+   |    -    --------- required by this bound in `f`
 ...
 LL |     f(  move    || panic!());
    |     ^   ---------- takes 0 arguments
@@ -143,7 +143,7 @@ LL |     call(Foo);
    |          ^^^ expected function that takes 0 arguments
 ...
 LL | fn call<F, R>(_: F) where F: FnOnce() -> R {}
-   | ------------------------------------------ required by `call`
+   |    ----                      ------------- required by this bound in `call`
 LL | struct Foo(u8);
    | --------------- takes 1 argument
 
diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
index 68bc17b4966f1..a731891bf764e 100644
--- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
@@ -26,7 +26,7 @@ error[E0631]: type mismatch in function arguments
   --> $DIR/closure-arg-type-mismatch.rs:10:9
    |
 LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
-   | ------------------------------ required by `baz`
+   |    ---    ------------- required by this bound in `baz`
 LL | fn _test<'a>(f: fn(*mut &'a u32)) {
 LL |     baz(f);
    |         ^
@@ -38,7 +38,7 @@ error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::Fn
   --> $DIR/closure-arg-type-mismatch.rs:10:5
    |
 LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
-   | ------------------------------ required by `baz`
+   |    ---      ----------- required by this bound in `baz`
 LL | fn _test<'a>(f: fn(*mut &'a u32)) {
 LL |     baz(f);
    |     ^^^ expected bound lifetime parameter, found concrete lifetime
diff --git a/src/test/ui/mismatched_types/closure-mismatch.stderr b/src/test/ui/mismatched_types/closure-mismatch.stderr
index 0fe4909eaa778..fd2b9f3c66b04 100644
--- a/src/test/ui/mismatched_types/closure-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-mismatch.stderr
@@ -2,7 +2,7 @@ error[E0271]: type mismatch resolving `for<'r> <[closure@$DIR/closure-mismatch.r
   --> $DIR/closure-mismatch.rs:8:5
    |
 LL | fn baz<T: Foo>(_: T) {}
-   | -------------------- required by `baz`
+   |    ---    --- required by this bound in `baz`
 ...
 LL |     baz(|_| ());
    |     ^^^ expected bound lifetime parameter, found concrete lifetime
@@ -13,7 +13,7 @@ error[E0631]: type mismatch in closure arguments
   --> $DIR/closure-mismatch.rs:8:5
    |
 LL | fn baz<T: Foo>(_: T) {}
-   | -------------------- required by `baz`
+   |    ---    --- required by this bound in `baz`
 ...
 LL |     baz(|_| ());
    |     ^^^ ------ found signature of `fn(_) -> _`
diff --git a/src/test/ui/mismatched_types/fn-variance-1.stderr b/src/test/ui/mismatched_types/fn-variance-1.stderr
index 6342ee770ddaf..1a82dd53edc70 100644
--- a/src/test/ui/mismatched_types/fn-variance-1.stderr
+++ b/src/test/ui/mismatched_types/fn-variance-1.stderr
@@ -5,7 +5,7 @@ LL | fn takes_mut(x: &mut isize) { }
    | --------------------------- found signature of `for<'r> fn(&'r mut isize) -> _`
 LL | 
 LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
-   | --------------------------------------------- required by `apply`
+   |    -----                            --------- required by this bound in `apply`
 ...
 LL |     apply(&3, takes_mut);
    |               ^^^^^^^^^ expected signature of `fn(&{integer}) -> _`
@@ -17,7 +17,7 @@ LL | fn takes_imm(x: &isize) { }
    | ----------------------- found signature of `for<'r> fn(&'r isize) -> _`
 ...
 LL | fn apply<T, F>(t: T, f: F) where F: FnOnce(T) {
-   | --------------------------------------------- required by `apply`
+   |    -----                            --------- required by this bound in `apply`
 ...
 LL |     apply(&mut 3, takes_imm);
    |                   ^^^^^^^^^ expected signature of `fn(&mut {integer}) -> _`
diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
index 88bea979b97fe..2bd4d3384469f 100644
--- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
+++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.rs
@@ -5,7 +5,8 @@ use std::ops::FnMut;
 fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
 
 fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize {
-//~^ NOTE required by `call_it`
+//~^ NOTE required by this bound in `call_it`
+//~| NOTE
     f(2, y)
 }
 
diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
index 139d87d58b640..6c249f6275181 100644
--- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
+++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
@@ -1,8 +1,8 @@
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/unboxed-closures-vtable-mismatch.rs:15:24
+  --> $DIR/unboxed-closures-vtable-mismatch.rs:16:13
    |
 LL | fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize {
-   | -------------------------------------------------------------------- required by `call_it`
+   |    -------   ------------------------- required by this bound in `call_it`
 ...
 LL |     let f = to_fn_mut(|x: usize, y: isize| -> isize { (x as isize) + y });
    |                       ----------------------------- found signature of `fn(usize, isize) -> _`
diff --git a/src/test/ui/mut/mutable-enum-indirect.stderr b/src/test/ui/mut/mutable-enum-indirect.stderr
index 4efb10b56290e..0290efc3d9679 100644
--- a/src/test/ui/mut/mutable-enum-indirect.stderr
+++ b/src/test/ui/mut/mutable-enum-indirect.stderr
@@ -2,7 +2,7 @@ error[E0277]: `NoSync` cannot be shared between threads safely
   --> $DIR/mutable-enum-indirect.rs:17:5
    |
 LL | fn bar<T: Sync>(_: T) {}
-   | --------------------- required by `bar`
+   |    ---    ---- required by this bound in `bar`
 ...
 LL |     bar(&x);
    |     ^^^ `NoSync` cannot be shared between threads safely
diff --git a/src/test/ui/mutexguard-sync.stderr b/src/test/ui/mutexguard-sync.stderr
index 1cda2da5061a5..71a06fce4b9e1 100644
--- a/src/test/ui/mutexguard-sync.stderr
+++ b/src/test/ui/mutexguard-sync.stderr
@@ -2,7 +2,7 @@ error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
   --> $DIR/mutexguard-sync.rs:11:15
    |
 LL | fn test_sync<T: Sync>(_t: T) {}
-   | ---------------------------- required by `test_sync`
+   |    ---------    ---- required by this bound in `test_sync`
 ...
 LL |     test_sync(guard);
    |               ^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr
index 249ad1c584421..aa21928aaeff2 100644
--- a/src/test/ui/namespace/namespace-mix.stderr
+++ b/src/test/ui/namespace/namespace-mix.stderr
@@ -70,7 +70,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:33:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m1::S{});
    |           ^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -79,7 +79,7 @@ error[E0277]: the trait bound `c::S: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:35:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m2::S{});
    |           ^^^^^^^ the trait `Impossible` is not implemented for `c::S`
@@ -88,7 +88,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:36:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m2::S);
    |           ^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -97,7 +97,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:39:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm1::S{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
@@ -106,7 +106,7 @@ error[E0277]: the trait bound `namespace_mix::c::S: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:41:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm2::S{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::S`
@@ -115,7 +115,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:42:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm2::S);
    |           ^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
@@ -124,7 +124,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:55:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m3::TS{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -133,7 +133,7 @@ error[E0277]: the trait bound `fn() -> c::TS {c::TS}: Impossible` is not satisfi
   --> $DIR/namespace-mix.rs:56:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m3::TS);
    |           ^^^^^^ the trait `Impossible` is not implemented for `fn() -> c::TS {c::TS}`
@@ -142,7 +142,7 @@ error[E0277]: the trait bound `c::TS: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:57:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m4::TS{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::TS`
@@ -151,7 +151,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:58:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m4::TS);
    |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -160,7 +160,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:61:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm3::TS{});
    |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
@@ -169,7 +169,7 @@ error[E0277]: the trait bound `fn() -> namespace_mix::c::TS {namespace_mix::c::T
   --> $DIR/namespace-mix.rs:62:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm3::TS);
    |           ^^^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::TS {namespace_mix::c::TS}`
@@ -178,7 +178,7 @@ error[E0277]: the trait bound `namespace_mix::c::TS: Impossible` is not satisfie
   --> $DIR/namespace-mix.rs:63:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm4::TS{});
    |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::TS`
@@ -187,7 +187,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:64:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm4::TS);
    |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
@@ -196,7 +196,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:77:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m5::US{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -205,7 +205,7 @@ error[E0277]: the trait bound `c::US: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:78:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m5::US);
    |           ^^^^^^ the trait `Impossible` is not implemented for `c::US`
@@ -214,7 +214,7 @@ error[E0277]: the trait bound `c::US: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:79:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m6::US{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::US`
@@ -223,7 +223,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:80:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m6::US);
    |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -232,7 +232,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:83:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm5::US{});
    |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
@@ -241,7 +241,7 @@ error[E0277]: the trait bound `namespace_mix::c::US: Impossible` is not satisfie
   --> $DIR/namespace-mix.rs:84:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm5::US);
    |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
@@ -250,7 +250,7 @@ error[E0277]: the trait bound `namespace_mix::c::US: Impossible` is not satisfie
   --> $DIR/namespace-mix.rs:85:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm6::US{});
    |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::US`
@@ -259,7 +259,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:86:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm6::US);
    |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
@@ -268,7 +268,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:99:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m7::V{});
    |           ^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -277,7 +277,7 @@ error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:101:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m8::V{});
    |           ^^^^^^^ the trait `Impossible` is not implemented for `c::E`
@@ -286,7 +286,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:102:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m8::V);
    |           ^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -295,7 +295,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:105:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm7::V{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
@@ -304,7 +304,7 @@ error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:107:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm8::V{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
@@ -313,7 +313,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:108:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm8::V);
    |           ^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
@@ -322,7 +322,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:121:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m9::TV{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -331,7 +331,7 @@ error[E0277]: the trait bound `fn() -> c::E {c::E::TV}: Impossible` is not satis
   --> $DIR/namespace-mix.rs:122:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(m9::TV);
    |           ^^^^^^ the trait `Impossible` is not implemented for `fn() -> c::E {c::E::TV}`
@@ -340,7 +340,7 @@ error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:123:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(mA::TV{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::E`
@@ -349,7 +349,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:124:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(mA::TV);
    |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -358,7 +358,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:127:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm9::TV{});
    |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
@@ -367,7 +367,7 @@ error[E0277]: the trait bound `fn() -> namespace_mix::c::E {namespace_mix::xm7::
   --> $DIR/namespace-mix.rs:128:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xm9::TV);
    |           ^^^^^^^ the trait `Impossible` is not implemented for `fn() -> namespace_mix::c::E {namespace_mix::xm7::TV}`
@@ -376,7 +376,7 @@ error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:129:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xmA::TV{});
    |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
@@ -385,7 +385,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:130:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xmA::TV);
    |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
@@ -394,7 +394,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:143:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(mB::UV{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -403,7 +403,7 @@ error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:144:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(mB::UV);
    |           ^^^^^^ the trait `Impossible` is not implemented for `c::E`
@@ -412,7 +412,7 @@ error[E0277]: the trait bound `c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:145:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(mC::UV{});
    |           ^^^^^^^^ the trait `Impossible` is not implemented for `c::E`
@@ -421,7 +421,7 @@ error[E0277]: the trait bound `c::Item: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:146:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(mC::UV);
    |           ^^^^^^ the trait `Impossible` is not implemented for `c::Item`
@@ -430,7 +430,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:149:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xmB::UV{});
    |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
@@ -439,7 +439,7 @@ error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:150:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xmB::UV);
    |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
@@ -448,7 +448,7 @@ error[E0277]: the trait bound `namespace_mix::c::E: Impossible` is not satisfied
   --> $DIR/namespace-mix.rs:151:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xmC::UV{});
    |           ^^^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::E`
@@ -457,7 +457,7 @@ error[E0277]: the trait bound `namespace_mix::c::Item: Impossible` is not satisf
   --> $DIR/namespace-mix.rs:152:11
    |
 LL | fn check<T: Impossible>(_: T) {}
-   | ----------------------------- required by `check`
+   |    -----    ---------- required by this bound in `check`
 ...
 LL |     check(xmC::UV);
    |           ^^^^^^^ the trait `Impossible` is not implemented for `namespace_mix::c::Item`
diff --git a/src/test/ui/no-send-res-ports.stderr b/src/test/ui/no-send-res-ports.stderr
index 515b948cc7eb2..20f88badbefd4 100644
--- a/src/test/ui/no-send-res-ports.stderr
+++ b/src/test/ui/no-send-res-ports.stderr
@@ -3,12 +3,16 @@ error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
    |
 LL |     thread::spawn(move|| {
    |     ^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
+   | 
+  ::: $SRC_DIR/libstd/thread/mod.rs:LL:COL
+   |
+LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
+   |                          ---- required by this bound in `std::thread::spawn`
    |
    = help: within `[closure@$DIR/no-send-res-ports.rs:25:19: 29:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
    = note: required because it appears within the type `Port<()>`
    = note: required because it appears within the type `main::Foo`
    = note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:25:19: 29:6 x:main::Foo]`
-   = note: required by `std::thread::spawn`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/no_send-enum.stderr b/src/test/ui/no_send-enum.stderr
index d1f3398ff9027..8a4b2e9c7a7c1 100644
--- a/src/test/ui/no_send-enum.stderr
+++ b/src/test/ui/no_send-enum.stderr
@@ -2,7 +2,7 @@ error[E0277]: `NoSend` cannot be sent between threads safely
   --> $DIR/no_send-enum.rs:16:5
    |
 LL | fn bar<T: Send>(_: T) {}
-   | --------------------- required by `bar`
+   |    ---    ---- required by this bound in `bar`
 ...
 LL |     bar(x);
    |     ^^^ `NoSend` cannot be sent between threads safely
diff --git a/src/test/ui/no_send-rc.stderr b/src/test/ui/no_send-rc.stderr
index de08634e16ac4..bd646d0509daf 100644
--- a/src/test/ui/no_send-rc.stderr
+++ b/src/test/ui/no_send-rc.stderr
@@ -2,7 +2,7 @@ error[E0277]: `std::rc::Rc<{integer}>` cannot be sent between threads safely
   --> $DIR/no_send-rc.rs:7:9
    |
 LL | fn bar<T: Send>(_: T) {}
-   | --------------------- required by `bar`
+   |    ---    ---- required by this bound in `bar`
 ...
 LL |     bar(x);
    |         ^ `std::rc::Rc<{integer}>` cannot be sent between threads safely
diff --git a/src/test/ui/no_send-struct.stderr b/src/test/ui/no_send-struct.stderr
index 3865971fcfdd1..4823852c2ff80 100644
--- a/src/test/ui/no_send-struct.stderr
+++ b/src/test/ui/no_send-struct.stderr
@@ -2,7 +2,7 @@ error[E0277]: `Foo` cannot be sent between threads safely
   --> $DIR/no_send-struct.rs:15:9
    |
 LL | fn bar<T: Send>(_: T) {}
-   | --------------------- required by `bar`
+   |    ---    ---- required by this bound in `bar`
 ...
 LL |     bar(x);
    |         ^ `Foo` cannot be sent between threads safely
diff --git a/src/test/ui/no_share-enum.stderr b/src/test/ui/no_share-enum.stderr
index 5a9b7cae0b9f6..f42228ef6ab42 100644
--- a/src/test/ui/no_share-enum.stderr
+++ b/src/test/ui/no_share-enum.stderr
@@ -2,7 +2,7 @@ error[E0277]: `NoSync` cannot be shared between threads safely
   --> $DIR/no_share-enum.rs:14:5
    |
 LL | fn bar<T: Sync>(_: T) {}
-   | --------------------- required by `bar`
+   |    ---    ---- required by this bound in `bar`
 ...
 LL |     bar(x);
    |     ^^^ `NoSync` cannot be shared between threads safely
diff --git a/src/test/ui/no_share-struct.stderr b/src/test/ui/no_share-struct.stderr
index 13de5bd6fe84b..620b5427b9aec 100644
--- a/src/test/ui/no_share-struct.stderr
+++ b/src/test/ui/no_share-struct.stderr
@@ -2,7 +2,7 @@ error[E0277]: `Foo` cannot be shared between threads safely
   --> $DIR/no_share-struct.rs:12:9
    |
 LL | fn bar<T: Sync>(_: T) {}
-   | --------------------- required by `bar`
+   |    ---    ---- required by this bound in `bar`
 ...
 LL |     bar(x);
    |         ^ `Foo` cannot be shared between threads safely
diff --git a/src/test/ui/not-panic/not-panic-safe-2.stderr b/src/test/ui/not-panic/not-panic-safe-2.stderr
index 5bacf0bbc6b45..6668d2d0db191 100644
--- a/src/test/ui/not-panic/not-panic-safe-2.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-2.stderr
@@ -2,7 +2,7 @@ error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutabil
   --> $DIR/not-panic-safe-2.rs:10:5
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ----------------------------------- required by `assert`
+   |    ------    ---------- required by this bound in `assert`
 ...
 LL |     assert::<Rc<RefCell<i32>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
@@ -15,7 +15,7 @@ error[E0277]: the type `std::cell::UnsafeCell<isize>` may contain interior mutab
   --> $DIR/not-panic-safe-2.rs:10:5
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ----------------------------------- required by `assert`
+   |    ------    ---------- required by this bound in `assert`
 ...
 LL |     assert::<Rc<RefCell<i32>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
diff --git a/src/test/ui/not-panic/not-panic-safe-3.stderr b/src/test/ui/not-panic/not-panic-safe-3.stderr
index 6d2a450115dff..c23b08fc9eda9 100644
--- a/src/test/ui/not-panic/not-panic-safe-3.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-3.stderr
@@ -2,7 +2,7 @@ error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutabil
   --> $DIR/not-panic-safe-3.rs:10:5
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ----------------------------------- required by `assert`
+   |    ------    ---------- required by this bound in `assert`
 ...
 LL |     assert::<Arc<RefCell<i32>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
@@ -15,7 +15,7 @@ error[E0277]: the type `std::cell::UnsafeCell<isize>` may contain interior mutab
   --> $DIR/not-panic-safe-3.rs:10:5
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ----------------------------------- required by `assert`
+   |    ------    ---------- required by this bound in `assert`
 ...
 LL |     assert::<Arc<RefCell<i32>>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
diff --git a/src/test/ui/not-panic/not-panic-safe-4.stderr b/src/test/ui/not-panic/not-panic-safe-4.stderr
index e28f169b72b6c..916804a834f58 100644
--- a/src/test/ui/not-panic/not-panic-safe-4.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-4.stderr
@@ -2,7 +2,7 @@ error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutabil
   --> $DIR/not-panic-safe-4.rs:9:5
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ----------------------------------- required by `assert`
+   |    ------    ---------- required by this bound in `assert`
 ...
 LL |     assert::<&RefCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
@@ -15,7 +15,7 @@ error[E0277]: the type `std::cell::UnsafeCell<isize>` may contain interior mutab
   --> $DIR/not-panic-safe-4.rs:9:5
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ----------------------------------- required by `assert`
+   |    ------    ---------- required by this bound in `assert`
 ...
 LL |     assert::<&RefCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
diff --git a/src/test/ui/not-panic/not-panic-safe-5.stderr b/src/test/ui/not-panic/not-panic-safe-5.stderr
index f8c4fe68dde7b..d5c189723f402 100644
--- a/src/test/ui/not-panic/not-panic-safe-5.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-5.stderr
@@ -2,7 +2,7 @@ error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutabil
   --> $DIR/not-panic-safe-5.rs:9:5
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ----------------------------------- required by `assert`
+   |    ------    ---------- required by this bound in `assert`
 ...
 LL |     assert::<*const UnsafeCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
diff --git a/src/test/ui/not-panic/not-panic-safe-6.stderr b/src/test/ui/not-panic/not-panic-safe-6.stderr
index 2cd780590729c..c8013a836a177 100644
--- a/src/test/ui/not-panic/not-panic-safe-6.stderr
+++ b/src/test/ui/not-panic/not-panic-safe-6.stderr
@@ -2,7 +2,7 @@ error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutabil
   --> $DIR/not-panic-safe-6.rs:9:5
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ----------------------------------- required by `assert`
+   |    ------    ---------- required by this bound in `assert`
 ...
 LL |     assert::<*mut RefCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
@@ -15,7 +15,7 @@ error[E0277]: the type `std::cell::UnsafeCell<isize>` may contain interior mutab
   --> $DIR/not-panic-safe-6.rs:9:5
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ----------------------------------- required by `assert`
+   |    ------    ---------- required by this bound in `assert`
 ...
 LL |     assert::<*mut RefCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
diff --git a/src/test/ui/not-panic/not-panic-safe.stderr b/src/test/ui/not-panic/not-panic-safe.stderr
index 315ea17971aa9..aa18b923044c6 100644
--- a/src/test/ui/not-panic/not-panic-safe.stderr
+++ b/src/test/ui/not-panic/not-panic-safe.stderr
@@ -2,7 +2,7 @@ error[E0277]: the type `&mut i32` may not be safely transferred across an unwind
   --> $DIR/not-panic-safe.rs:9:5
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
-   | ----------------------------------- required by `assert`
+   |    ------    ---------- required by this bound in `assert`
 ...
 LL |     assert::<&mut i32>();
    |     ^^^^^^^^^^^^^^^^^^ `&mut i32` may not be safely transferred across an unwind boundary
diff --git a/src/test/ui/not-sync.stderr b/src/test/ui/not-sync.stderr
index 57f1122be2b35..8871abedd00dd 100644
--- a/src/test/ui/not-sync.stderr
+++ b/src/test/ui/not-sync.stderr
@@ -2,7 +2,7 @@ error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
   --> $DIR/not-sync.rs:8:5
    |
 LL | fn test<T: Sync>() {}
-   | ------------------ required by `test`
+   |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<Cell<i32>>();
    |     ^^^^^^^^^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
@@ -13,7 +13,7 @@ error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely
   --> $DIR/not-sync.rs:10:5
    |
 LL | fn test<T: Sync>() {}
-   | ------------------ required by `test`
+   |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<RefCell<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely
@@ -24,7 +24,7 @@ error[E0277]: `std::rc::Rc<i32>` cannot be shared between threads safely
   --> $DIR/not-sync.rs:13:5
    |
 LL | fn test<T: Sync>() {}
-   | ------------------ required by `test`
+   |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<Rc<i32>>();
    |     ^^^^^^^^^^^^^^^ `std::rc::Rc<i32>` cannot be shared between threads safely
@@ -35,7 +35,7 @@ error[E0277]: `std::rc::Weak<i32>` cannot be shared between threads safely
   --> $DIR/not-sync.rs:15:5
    |
 LL | fn test<T: Sync>() {}
-   | ------------------ required by `test`
+   |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<Weak<i32>>();
    |     ^^^^^^^^^^^^^^^^^ `std::rc::Weak<i32>` cannot be shared between threads safely
@@ -46,7 +46,7 @@ error[E0277]: `std::sync::mpsc::Receiver<i32>` cannot be shared between threads
   --> $DIR/not-sync.rs:18:5
    |
 LL | fn test<T: Sync>() {}
-   | ------------------ required by `test`
+   |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<Receiver<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
@@ -57,7 +57,7 @@ error[E0277]: `std::sync::mpsc::Sender<i32>` cannot be shared between threads sa
   --> $DIR/not-sync.rs:20:5
    |
 LL | fn test<T: Sync>() {}
-   | ------------------ required by `test`
+   |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<Sender<i32>>();
    |     ^^^^^^^^^^^^^^^^^^^ `std::sync::mpsc::Sender<i32>` cannot be shared between threads safely
diff --git a/src/test/ui/object-does-not-impl-trait.stderr b/src/test/ui/object-does-not-impl-trait.stderr
index 83ca9a7212b22..7ac199d094383 100644
--- a/src/test/ui/object-does-not-impl-trait.stderr
+++ b/src/test/ui/object-does-not-impl-trait.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `std::boxed::Box<dyn Foo>: Foo` is not satisfied
   --> $DIR/object-does-not-impl-trait.rs:6:44
    |
 LL | fn take_foo<F:Foo>(f: F) {}
-   | ------------------------ required by `take_foo`
+   |    --------   --- required by this bound in `take_foo`
 LL | fn take_object(f: Box<dyn Foo>) { take_foo(f); }
    |                                            ^ the trait `Foo` is not implemented for `std::boxed::Box<dyn Foo>`
 
diff --git a/src/test/ui/on-unimplemented/on-trait.stderr b/src/test/ui/on-unimplemented/on-trait.stderr
index 992f53b1da6b6..8fe7ed4a20443 100644
--- a/src/test/ui/on-unimplemented/on-trait.stderr
+++ b/src/test/ui/on-unimplemented/on-trait.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `std::option::Option<std::vec::Vec<u8>>: MyFromIte
   --> $DIR/on-trait.rs:28:30
    |
 LL | fn collect<A, I: Iterator<Item=A>, B: MyFromIterator<A>>(it: I) -> B {
-   | -------------------------------------------------------------------- required by `collect`
+   |    -------                            ----------------- required by this bound in `collect`
 ...
 LL |     let y: Option<Vec<u8>> = collect(x.iter()); // this should give approximately the same error for x.iter().collect()
    |                              ^^^^^^^ a collection of type `std::option::Option<std::vec::Vec<u8>>` cannot be built from an iterator over elements of type `&u8`
@@ -13,7 +13,7 @@ error[E0277]: the trait bound `std::string::String: Bar::Foo<u8, _, u32>` is not
   --> $DIR/on-trait.rs:31:21
    |
 LL | fn foobar<U: Clone, T: Foo<u8, U, u32>>() -> T {
-   | ---------------------------------------------- required by `foobar`
+   |    ------              --------------- required by this bound in `foobar`
 ...
 LL |     let x: String = foobar();
    |                     ^^^^^^ test error `std::string::String` with `u8` `_` `u32` in `Bar::Foo`
diff --git a/src/test/ui/overlap-marker-trait.stderr b/src/test/ui/overlap-marker-trait.stderr
index a66e3990e8bd9..daf4e5e69a29b 100644
--- a/src/test/ui/overlap-marker-trait.stderr
+++ b/src/test/ui/overlap-marker-trait.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `NotDebugOrDisplay: Marker` is not satisfied
   --> $DIR/overlap-marker-trait.rs:30:5
    |
 LL | fn is_marker<T: Marker>() { }
-   | ------------------------- required by `is_marker`
+   |    ---------    ------ required by this bound in `is_marker`
 ...
 LL |     is_marker::<NotDebugOrDisplay>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Marker` is not implemented for `NotDebugOrDisplay`
diff --git a/src/test/ui/phantom-oibit.stderr b/src/test/ui/phantom-oibit.stderr
index c1b60e0823fd4..ac48ee0cb0fe3 100644
--- a/src/test/ui/phantom-oibit.stderr
+++ b/src/test/ui/phantom-oibit.stderr
@@ -2,7 +2,7 @@ error[E0277]: `T` cannot be shared between threads safely
   --> $DIR/phantom-oibit.rs:21:12
    |
 LL | fn is_zen<T: Zen>(_: T) {}
-   | ----------------------- required by `is_zen`
+   |    ------    --- required by this bound in `is_zen`
 ...
 LL |     is_zen(x)
    |            ^ `T` cannot be shared between threads safely
@@ -17,7 +17,7 @@ error[E0277]: `T` cannot be shared between threads safely
   --> $DIR/phantom-oibit.rs:26:12
    |
 LL | fn is_zen<T: Zen>(_: T) {}
-   | ----------------------- required by `is_zen`
+   |    ------    --- required by this bound in `is_zen`
 ...
 LL |     is_zen(x)
    |            ^ `T` cannot be shared between threads safely
diff --git a/src/test/ui/regions/regions-close-object-into-object-5.stderr b/src/test/ui/regions/regions-close-object-into-object-5.stderr
index 390f8e7baa34a..01975d40fdf1f 100644
--- a/src/test/ui/regions/regions-close-object-into-object-5.stderr
+++ b/src/test/ui/regions/regions-close-object-into-object-5.stderr
@@ -52,26 +52,26 @@ LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
    |         ^^^^^^
    |
-note: ...so that the reference type `&dyn A<T>` does not outlive the data it points at
+note: ...so that the type `T` will meet its required lifetime bounds
   --> $DIR/regions-close-object-into-object-5.rs:17:9
    |
 LL |     box B(&*v) as Box<X>
    |         ^^^^^^
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/regions-close-object-into-object-5.rs:17:9
+  --> $DIR/regions-close-object-into-object-5.rs:17:11
    |
 LL | fn f<'a, T, U>(v: Box<A<T>+'static>) -> Box<X+'static> {
    |          - help: consider adding an explicit lifetime bound `T: 'static`...
 LL |     // oh dear!
 LL |     box B(&*v) as Box<X>
-   |         ^^^^^^
+   |           ^^^
    |
-note: ...so that the type `T` will meet its required lifetime bounds
-  --> $DIR/regions-close-object-into-object-5.rs:17:9
+note: ...so that the reference type `&dyn A<T>` does not outlive the data it points at
+  --> $DIR/regions-close-object-into-object-5.rs:17:11
    |
 LL |     box B(&*v) as Box<X>
-   |         ^^^^^^
+   |           ^^^
 
 error[E0310]: the parameter type `T` may not live long enough
   --> $DIR/regions-close-object-into-object-5.rs:17:11
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index f253b67a01914..983063d19711f 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -5,9 +5,13 @@ LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
 LL | |     "0".parse()
 LL | | }
    | |_^ `main` can only return types that implement `std::process::Termination`
+   | 
+  ::: $SRC_DIR/libtest/lib.rs:LL:COL
+   |
+LL |   pub fn assert_test_result<T: Termination>(result: T) {
+   |                                ----------- required by this bound in `test::assert_test_result`
    |
    = help: the trait `std::process::Termination` is not implemented for `std::result::Result<f32, std::num::ParseFloatError>`
-   = note: required by `test::assert_test_result`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr
index 372077a465e4a..3c957970e51c2 100644
--- a/src/test/ui/str/str-mut-idx.stderr
+++ b/src/test/ui/str/str-mut-idx.stderr
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
   --> $DIR/str-mut-idx.rs:4:15
    |
 LL | fn bot<T>() -> T { loop {} }
-   | ---------------- required by `bot`
+   |    --- - required by this bound in `bot`
 ...
 LL |     s[1..2] = bot();
    |               ^^^ doesn't have a size known at compile-time
diff --git a/src/test/ui/substs-ppaux.normal.stderr b/src/test/ui/substs-ppaux.normal.stderr
index 4a8c99cdef3f5..cb55203c88e31 100644
--- a/src/test/ui/substs-ppaux.normal.stderr
+++ b/src/test/ui/substs-ppaux.normal.stderr
@@ -62,7 +62,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
   --> $DIR/substs-ppaux.rs:49:5
    |
 LL |     fn bar<'a, T>() where T: 'a {}
-   |     --------------------------- required by `Foo::bar`
+   |        ---                   -- required by this bound in `Foo::bar`
 ...
 LL |     <str as Foo<u8>>::bar;
    |     ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
diff --git a/src/test/ui/substs-ppaux.verbose.stderr b/src/test/ui/substs-ppaux.verbose.stderr
index 3314eb60cdea6..cafcba97b92c8 100644
--- a/src/test/ui/substs-ppaux.verbose.stderr
+++ b/src/test/ui/substs-ppaux.verbose.stderr
@@ -62,7 +62,7 @@ error[E0277]: the size for values of type `str` cannot be known at compilation t
   --> $DIR/substs-ppaux.rs:49:5
    |
 LL |     fn bar<'a, T>() where T: 'a {}
-   |     --------------------------- required by `Foo::bar`
+   |        ---                   -- required by this bound in `Foo::bar`
 ...
 LL |     <str as Foo<u8>>::bar;
    |     ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
diff --git a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index 6bb6533899669..1cc704b443366 100644
--- a/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `fn() -> impl std::future::Future {foo}: std::futu
   --> $DIR/async-fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:9:9
    |
 LL | fn bar(f: impl Future<Output=()>) {}
-   | --------------------------------- required by `bar`
+   |    ---         ----------------- required by this bound in `bar`
 ...
 LL |     bar(foo);
    |         ^^^
diff --git a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
index 59726c82c2377..7a49031bde7c2 100644
--- a/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
+++ b/src/test/ui/suggestions/fn-ctor-passed-as-arg-where-it-should-have-been-called.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `fn() -> impl T {foo}: T` is not satisfied
   --> $DIR/fn-ctor-passed-as-arg-where-it-should-have-been-called.rs:17:9
    |
 LL | fn bar(f: impl T<O=()>) {}
-   | ----------------------- required by `bar`
+   |    ---         ------- required by this bound in `bar`
 ...
 LL |     bar(foo);
    |         ^^^
diff --git a/src/test/ui/suggestions/into-str.stderr b/src/test/ui/suggestions/into-str.stderr
index da5aeb63b909a..fb3e1096ad54c 100644
--- a/src/test/ui/suggestions/into-str.stderr
+++ b/src/test/ui/suggestions/into-str.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `&str: std::convert::From<std::string::String>` is
   --> $DIR/into-str.rs:4:5
    |
 LL | fn foo<'a, T>(_t: T) where T: Into<&'a str> {}
-   | ------------------------------------------- required by `foo`
+   |    ---                        ------------- required by this bound in `foo`
 ...
 LL |     foo(String::new());
    |     ^^^ the trait `std::convert::From<std::string::String>` is not implemented for `&str`
diff --git a/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr b/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr
index 8403b2ebaca10..10a9506bd0639 100644
--- a/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr
+++ b/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr
@@ -2,7 +2,7 @@ error[E0277]: `std::rc::Rc<u32>` cannot be sent between threads safely
   --> $DIR/trait-alias-cross-crate.rs:14:5
    |
 LL | fn use_alias<T: SendSync>() {}
-   | --------------------------- required by `use_alias`
+   |    ---------    -------- required by this bound in `use_alias`
 ...
 LL |     use_alias::<Rc<u32>>();
    |     ^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc<u32>` cannot be sent between threads safely
@@ -13,7 +13,7 @@ error[E0277]: `std::rc::Rc<u32>` cannot be shared between threads safely
   --> $DIR/trait-alias-cross-crate.rs:14:5
    |
 LL | fn use_alias<T: SendSync>() {}
-   | --------------------------- required by `use_alias`
+   |    ---------    -------- required by this bound in `use_alias`
 ...
 LL |     use_alias::<Rc<u32>>();
    |     ^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc<u32>` cannot be shared between threads safely
diff --git a/src/test/ui/traits/trait-suggest-where-clause.stderr b/src/test/ui/traits/trait-suggest-where-clause.stderr
index f88dae37e48e5..0aa5f429334ef 100644
--- a/src/test/ui/traits/trait-suggest-where-clause.stderr
+++ b/src/test/ui/traits/trait-suggest-where-clause.stderr
@@ -3,23 +3,31 @@ error[E0277]: the size for values of type `U` cannot be known at compilation tim
    |
 LL |     mem::size_of::<U>();
    |     ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   | 
+  ::: $SRC_DIR/libcore/mem/mod.rs:LL:COL
+   |
+LL | pub const fn size_of<T>() -> usize {
+   |                      - required by this bound in `std::mem::size_of`
    |
    = help: the trait `std::marker::Sized` is not implemented for `U`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where U: std::marker::Sized` bound
-   = note: required by `std::mem::size_of`
 
 error[E0277]: the size for values of type `U` cannot be known at compilation time
   --> $DIR/trait-suggest-where-clause.rs:10:5
    |
 LL |     mem::size_of::<Misc<U>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   | 
+  ::: $SRC_DIR/libcore/mem/mod.rs:LL:COL
+   |
+LL | pub const fn size_of<T>() -> usize {
+   |                      - required by this bound in `std::mem::size_of`
    |
    = help: within `Misc<U>`, the trait `std::marker::Sized` is not implemented for `U`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
    = help: consider adding a `where U: std::marker::Sized` bound
    = note: required because it appears within the type `Misc<U>`
-   = note: required by `std::mem::size_of`
 
 error[E0277]: the trait bound `u64: std::convert::From<T>` is not satisfied
   --> $DIR/trait-suggest-where-clause.rs:15:5
@@ -52,20 +60,28 @@ error[E0277]: the size for values of type `[T]` cannot be known at compilation t
    |
 LL |     mem::size_of::<[T]>();
    |     ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   | 
+  ::: $SRC_DIR/libcore/mem/mod.rs:LL:COL
+   |
+LL | pub const fn size_of<T>() -> usize {
+   |                      - required by this bound in `std::mem::size_of`
    |
    = help: the trait `std::marker::Sized` is not implemented for `[T]`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
-   = note: required by `std::mem::size_of`
 
 error[E0277]: the size for values of type `[&U]` cannot be known at compilation time
   --> $DIR/trait-suggest-where-clause.rs:31:5
    |
 LL |     mem::size_of::<[&U]>();
    |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   | 
+  ::: $SRC_DIR/libcore/mem/mod.rs:LL:COL
+   |
+LL | pub const fn size_of<T>() -> usize {
+   |                      - required by this bound in `std::mem::size_of`
    |
    = help: the trait `std::marker::Sized` is not implemented for `[&U]`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
-   = note: required by `std::mem::size_of`
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/traits/traits-inductive-overflow-simultaneous.stderr b/src/test/ui/traits/traits-inductive-overflow-simultaneous.stderr
index b29d726fbba94..6fd6a37b22dfe 100644
--- a/src/test/ui/traits/traits-inductive-overflow-simultaneous.stderr
+++ b/src/test/ui/traits/traits-inductive-overflow-simultaneous.stderr
@@ -2,7 +2,7 @@ error[E0275]: overflow evaluating the requirement `{integer}: Tweedledum`
   --> $DIR/traits-inductive-overflow-simultaneous.rs:18:5
    |
 LL | fn is_ee<T: Combo>(t: T) {
-   | ------------------------ required by `is_ee`
+   |    -----    ----- required by this bound in `is_ee`
 ...
 LL |     is_ee(4);
    |     ^^^^^
diff --git a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr
index 76d486a51e5cc..40c2c2e4c9d10 100644
--- a/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr
+++ b/src/test/ui/traits/traits-inductive-overflow-supertrait-oibit.stderr
@@ -8,7 +8,7 @@ error[E0277]: the trait bound `NoClone: std::marker::Copy` is not satisfied
   --> $DIR/traits-inductive-overflow-supertrait-oibit.rs:15:23
    |
 LL | fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
-   | --------------------------------- required by `copy`
+   |    ----    ----- required by this bound in `copy`
 ...
 LL |     let (a, b) = copy(NoClone);
    |                       ^^^^^^^ the trait `std::marker::Copy` is not implemented for `NoClone`
diff --git a/src/test/ui/traits/traits-inductive-overflow-supertrait.stderr b/src/test/ui/traits/traits-inductive-overflow-supertrait.stderr
index 92747be7d2c6b..96a9343d4ebfb 100644
--- a/src/test/ui/traits/traits-inductive-overflow-supertrait.stderr
+++ b/src/test/ui/traits/traits-inductive-overflow-supertrait.stderr
@@ -2,7 +2,7 @@ error[E0275]: overflow evaluating the requirement `NoClone: Magic`
   --> $DIR/traits-inductive-overflow-supertrait.rs:13:18
    |
 LL | fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
-   | --------------------------------- required by `copy`
+   |    ----    ----- required by this bound in `copy`
 ...
 LL |     let (a, b) = copy(NoClone);
    |                  ^^^^
diff --git a/src/test/ui/traits/traits-inductive-overflow-two-traits.stderr b/src/test/ui/traits/traits-inductive-overflow-two-traits.stderr
index 58d7fcd56c71e..447fc56434831 100644
--- a/src/test/ui/traits/traits-inductive-overflow-two-traits.stderr
+++ b/src/test/ui/traits/traits-inductive-overflow-two-traits.stderr
@@ -2,7 +2,7 @@ error[E0275]: overflow evaluating the requirement `*mut (): Magic`
   --> $DIR/traits-inductive-overflow-two-traits.rs:19:5
    |
 LL | fn wizard<T: Magic>() { check::<<T as Magic>::X>(); }
-   | --------------------- required by `wizard`
+   |    ------    ----- required by this bound in `wizard`
 ...
 LL |     wizard::<*mut ()>();
    |     ^^^^^^^^^^^^^^^^^
diff --git a/src/test/ui/traits/traits-negative-impls.stderr b/src/test/ui/traits/traits-negative-impls.stderr
index 022b12d256cc3..22b6d2a0c4e98 100644
--- a/src/test/ui/traits/traits-negative-impls.stderr
+++ b/src/test/ui/traits/traits-negative-impls.stderr
@@ -24,7 +24,7 @@ error[E0277]: `dummy1b::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:32:13
    |
 LL | fn is_send<T: Send>(_: T) {}
-   | ------------------------- required by `is_send`
+   |    -------    ---- required by this bound in `is_send`
 ...
 LL |     is_send(TestType);
    |             ^^^^^^^^ `dummy1b::TestType` cannot be sent between threads safely
@@ -35,7 +35,7 @@ error[E0277]: `dummy1c::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:40:13
    |
 LL | fn is_send<T: Send>(_: T) {}
-   | ------------------------- required by `is_send`
+   |    -------    ---- required by this bound in `is_send`
 ...
 LL |     is_send((8, TestType));
    |             ^^^^^^^^^^^^^ `dummy1c::TestType` cannot be sent between threads safely
@@ -47,7 +47,7 @@ error[E0277]: `dummy2::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:48:13
    |
 LL | fn is_send<T: Send>(_: T) {}
-   | ------------------------- required by `is_send`
+   |    -------    ---- required by this bound in `is_send`
 ...
 LL |     is_send(Box::new(TestType));
    |             ^^^^^^^^^^^^^^^^^^ `dummy2::TestType` cannot be sent between threads safely
@@ -60,7 +60,7 @@ error[E0277]: `dummy3::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:56:13
    |
 LL | fn is_send<T: Send>(_: T) {}
-   | ------------------------- required by `is_send`
+   |    -------    ---- required by this bound in `is_send`
 ...
 LL |     is_send(Box::new(Outer2(TestType)));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ `dummy3::TestType` cannot be sent between threads safely
@@ -74,7 +74,7 @@ error[E0277]: `main::TestType` cannot be sent between threads safely
   --> $DIR/traits-negative-impls.rs:66:13
    |
 LL | fn is_sync<T: Sync>(_: T) {}
-   | ------------------------- required by `is_sync`
+   |    -------    ---- required by this bound in `is_sync`
 ...
 LL |     is_sync(Outer2(TestType));
    |             ^^^^^^^^^^^^^^^^ `main::TestType` cannot be sent between threads safely
diff --git a/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
index 49393a8678ef8..acf309ac60872 100644
--- a/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
+++ b/src/test/ui/trivial-bounds/trivial-bounds-leak.stderr
@@ -34,7 +34,7 @@ LL |     generic_function(5i32);
    |                      ^^^^ the trait `Foo` is not implemented for `i32`
 ...
 LL | fn generic_function<T: Foo>(t: T) {}
-   | --------------------------------- required by `generic_function`
+   |    ----------------    --- required by this bound in `generic_function`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/try-operator-on-main.stderr b/src/test/ui/try-operator-on-main.stderr
index 6878cd80629bc..de75d3e313d9e 100644
--- a/src/test/ui/try-operator-on-main.stderr
+++ b/src/test/ui/try-operator-on-main.stderr
@@ -23,7 +23,7 @@ LL |     try_trait_generic::<()>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()`
 ...
 LL | fn try_trait_generic<T: Try>() -> T {
-   | ----------------------------------- required by `try_trait_generic`
+   |    -----------------    --- required by this bound in `try_trait_generic`
 
 error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
   --> $DIR/try-operator-on-main.rs:22:5
diff --git a/src/test/ui/type/type-annotation-needed.rs b/src/test/ui/type/type-annotation-needed.rs
index ff2342c4455c5..ddf16f7699517 100644
--- a/src/test/ui/type/type-annotation-needed.rs
+++ b/src/test/ui/type/type-annotation-needed.rs
@@ -1,5 +1,6 @@
 fn foo<T: Into<String>>(x: i32) {}
 //~^ NOTE required by
+//~| NOTE
 
 fn main() {
     foo(42);
diff --git a/src/test/ui/type/type-annotation-needed.stderr b/src/test/ui/type/type-annotation-needed.stderr
index 1dd2aafeb62fa..01287b727d2f8 100644
--- a/src/test/ui/type/type-annotation-needed.stderr
+++ b/src/test/ui/type/type-annotation-needed.stderr
@@ -1,8 +1,8 @@
 error[E0283]: type annotations required: cannot resolve `_: std::convert::Into<std::string::String>`
-  --> $DIR/type-annotation-needed.rs:5:5
+  --> $DIR/type-annotation-needed.rs:6:5
    |
 LL | fn foo<T: Into<String>>(x: i32) {}
-   | ------------------------------- required by `foo`
+   |    ---    ------------ required by this bound in `foo`
 ...
 LL |     foo(42);
    |     ^^^
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr
index 7fb3731be23e6..b842d0ae1a248 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-assoc-type.stderr
@@ -5,7 +5,7 @@ LL |     is_send::<T::AssocType>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ `<T as Trait>::AssocType` cannot be sent between threads safely
 ...
 LL | fn is_send<T:Send>() {
-   | -------------------- required by `is_send`
+   |    -------   ---- required by this bound in `is_send`
    |
    = help: the trait `std::marker::Send` is not implemented for `<T as Trait>::AssocType`
    = help: consider adding a `where <T as Trait>::AssocType: std::marker::Send` bound
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr
index 8389356fdd6f6..f060afea24e7f 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types-2.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied in `(MyS2, MyS)`
   --> $DIR/typeck-default-trait-impl-constituent-types-2.rs:16:5
    |
 LL | fn is_mytrait<T: MyTrait>() {}
-   | --------------------------- required by `is_mytrait`
+   |    ----------    ------- required by this bound in `is_mytrait`
 ...
 LL |     is_mytrait::<(MyS2, MyS)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ within `(MyS2, MyS)`, the trait `MyTrait` is not implemented for `MyS2`
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr
index eee186feea67d..e5d275083dfe0 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied
   --> $DIR/typeck-default-trait-impl-constituent-types.rs:20:5
    |
 LL | fn is_mytrait<T: MyTrait>() {}
-   | --------------------------- required by `is_mytrait`
+   |    ----------    ------- required by this bound in `is_mytrait`
 ...
 LL |     is_mytrait::<MyS2>();
    |     ^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `MyS2`
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr
index 1e6adeb430998..2f5be975c6dd7 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr
@@ -2,7 +2,7 @@ error[E0277]: `MyNotSendable` cannot be sent between threads safely
   --> $DIR/typeck-default-trait-impl-negation-send.rs:19:5
    |
 LL | fn is_send<T: Send>() {}
-   | --------------------- required by `is_send`
+   |    -------    ---- required by this bound in `is_send`
 ...
 LL |     is_send::<MyNotSendable>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ `MyNotSendable` cannot be sent between threads safely
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
index d4f8f5ad82c9e..77e04a75a25c1 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
@@ -2,7 +2,7 @@ error[E0277]: `MyNotSync` cannot be shared between threads safely
   --> $DIR/typeck-default-trait-impl-negation-sync.rs:33:5
    |
 LL | fn is_sync<T: Sync>() {}
-   | --------------------- required by `is_sync`
+   |    -------    ---- required by this bound in `is_sync`
 ...
 LL |     is_sync::<MyNotSync>();
    |     ^^^^^^^^^^^^^^^^^^^^ `MyNotSync` cannot be shared between threads safely
@@ -13,7 +13,7 @@ error[E0277]: `std::cell::UnsafeCell<u8>` cannot be shared between threads safel
   --> $DIR/typeck-default-trait-impl-negation-sync.rs:36:5
    |
 LL | fn is_sync<T: Sync>() {}
-   | --------------------- required by `is_sync`
+   |    -------    ---- required by this bound in `is_sync`
 ...
 LL |     is_sync::<MyTypeWUnsafe>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ `std::cell::UnsafeCell<u8>` cannot be shared between threads safely
@@ -25,7 +25,7 @@ error[E0277]: `Managed` cannot be shared between threads safely
   --> $DIR/typeck-default-trait-impl-negation-sync.rs:39:5
    |
 LL | fn is_sync<T: Sync>() {}
-   | --------------------- required by `is_sync`
+   |    -------    ---- required by this bound in `is_sync`
 ...
 LL |     is_sync::<MyTypeManaged>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ `Managed` cannot be shared between threads safely
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr
index e993098b2deed..09c05825190e7 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `ThisImplsUnsafeTrait: MyTrait` is not satisfied
   --> $DIR/typeck-default-trait-impl-negation.rs:21:5
    |
 LL | fn is_my_trait<T: MyTrait>() {}
-   | ---------------------------- required by `is_my_trait`
+   |    -----------    ------- required by this bound in `is_my_trait`
 ...
 LL |     is_my_trait::<ThisImplsUnsafeTrait>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `ThisImplsUnsafeTrait`
@@ -14,7 +14,7 @@ error[E0277]: the trait bound `ThisImplsTrait: MyUnsafeTrait` is not satisfied
   --> $DIR/typeck-default-trait-impl-negation.rs:24:5
    |
 LL | fn is_my_unsafe_trait<T: MyUnsafeTrait>() {}
-   | ----------------------------------------- required by `is_my_unsafe_trait`
+   |    ------------------    ------------- required by this bound in `is_my_unsafe_trait`
 ...
 LL |     is_my_unsafe_trait::<ThisImplsTrait>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyUnsafeTrait` is not implemented for `ThisImplsTrait`
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr b/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr
index d87a6384e5c01..1587730441820 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-precedence.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `u32: Signed` is not satisfied
   --> $DIR/typeck-default-trait-impl-precedence.rs:18:5
    |
 LL | fn is_defaulted<T:Defaulted>() { }
-   | ------------------------------ required by `is_defaulted`
+   |    ------------   --------- required by this bound in `is_defaulted`
 ...
 LL |     is_defaulted::<&'static u32>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
index 5f3a5bc6e0054..46731c0fbb014 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
@@ -5,7 +5,7 @@ LL |     is_send::<T>()
    |     ^^^^^^^^^^^^ `T` cannot be sent between threads safely
 ...
 LL | fn is_send<T:Send>() {
-   | -------------------- required by `is_send`
+   |    -------   ---- required by this bound in `is_send`
    |
    = help: the trait `std::marker::Send` is not implemented for `T`
    = help: consider adding a `where T: std::marker::Send` bound
diff --git a/src/test/ui/typeck/typeck-unsafe-always-share.stderr b/src/test/ui/typeck/typeck-unsafe-always-share.stderr
index 8b3032b088d0e..d08613238f866 100644
--- a/src/test/ui/typeck/typeck-unsafe-always-share.stderr
+++ b/src/test/ui/typeck/typeck-unsafe-always-share.stderr
@@ -2,7 +2,7 @@ error[E0277]: `std::cell::UnsafeCell<MySync<{integer}>>` cannot be shared betwee
   --> $DIR/typeck-unsafe-always-share.rs:19:10
    |
 LL | fn test<T: Sync>(s: T) {}
-   | ---------------------- required by `test`
+   |    ----    ---- required by this bound in `test`
 ...
 LL |     test(us);
    |          ^^ `std::cell::UnsafeCell<MySync<{integer}>>` cannot be shared between threads safely
@@ -13,7 +13,7 @@ error[E0277]: `std::cell::UnsafeCell<NoSync>` cannot be shared between threads s
   --> $DIR/typeck-unsafe-always-share.rs:23:10
    |
 LL | fn test<T: Sync>(s: T) {}
-   | ---------------------- required by `test`
+   |    ----    ---- required by this bound in `test`
 ...
 LL |     test(uns);
    |          ^^^ `std::cell::UnsafeCell<NoSync>` cannot be shared between threads safely
@@ -24,7 +24,7 @@ error[E0277]: `std::cell::UnsafeCell<NoSync>` cannot be shared between threads s
   --> $DIR/typeck-unsafe-always-share.rs:27:5
    |
 LL | fn test<T: Sync>(s: T) {}
-   | ---------------------- required by `test`
+   |    ----    ---- required by this bound in `test`
 ...
 LL |     test(ms);
    |     ^^^^ `std::cell::UnsafeCell<NoSync>` cannot be shared between threads safely
@@ -36,7 +36,7 @@ error[E0277]: `NoSync` cannot be shared between threads safely
   --> $DIR/typeck-unsafe-always-share.rs:30:10
    |
 LL | fn test<T: Sync>(s: T) {}
-   | ---------------------- required by `test`
+   |    ----    ---- required by this bound in `test`
 ...
 LL |     test(NoSync);
    |          ^^^^^^ `NoSync` cannot be shared between threads safely
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr
index dd024b76c3ba7..6ec4063828917 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-default.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `dyn Foo<(isize,), isize, Output = ()>: Eq<dyn Foo
   --> $DIR/unboxed-closure-sugar-default.rs:21:5
    |
 LL | fn eq<A: ?Sized,B: ?Sized>() where A : Eq<B> { }
-   | -------------------------------------------- required by `eq`
+   |    --                                  ----- required by this bound in `eq`
 ...
 LL |     eq::<dyn Foo<(isize,), isize, Output=()>, dyn Foo(isize)>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq<dyn Foo<(isize,), Output = ()>>` is not implemented for `dyn Foo<(isize,), isize, Output = ()>`
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr
index 83754bd36ef2a..8dd32ee7f104a 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-equiv.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `dyn Foo<(char,), Output = ()>: Eq<dyn Foo<(), Out
   --> $DIR/unboxed-closure-sugar-equiv.rs:43:5
    |
 LL |   fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
-   |   ----------------------------------- required by `eq`
+   |      --                      ----- required by this bound in `eq`
 ...
 LL | /     eq::< dyn Foo<(),Output=()>,
 LL | |           dyn Foo(char)                                               >();
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr
index d03397e42445c..dc7661815310d 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-fnmut-as-fn.stderr
@@ -2,7 +2,7 @@ error[E0277]: expected a `std::ops::Fn<(isize,)>` closure, found `S`
   --> $DIR/unboxed-closures-fnmut-as-fn.rs:28:21
    |
 LL | fn call_it<F:Fn(isize)->isize>(f: &F, x: isize) -> isize {
-   | -------------------------------------------------------- required by `call_it`
+   |    -------   ---------------- required by this bound in `call_it`
 ...
 LL |     let x = call_it(&S, 22);
    |                     ^^ expected an `Fn<(isize,)>` closure, found `S`
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
index bde30729a3ca3..0b86719df848a 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-unsafe-extern-fn.stderr
@@ -2,7 +2,7 @@ error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `for<'r> unsaf
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | --------------------------------------------------------- required by `call_it`
+   |    -------   ----------------- required by this bound in `call_it`
 ...
 LL |     let x = call_it(&square, 22);
    |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
@@ -13,7 +13,7 @@ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> u
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:12:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | --------------------------------------------------------- required by `call_it`
+   |    -------               ----- required by this bound in `call_it`
 ...
 LL |     let x = call_it(&square, 22);
    |                     ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
@@ -24,7 +24,7 @@ error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> un
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | -------------------------------------------------------------------- required by `call_it_mut`
+   |    -----------   -------------------- required by this bound in `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
    |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
@@ -35,7 +35,7 @@ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> u
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:18:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | -------------------------------------------------------------------- required by `call_it_mut`
+   |    -----------                  ----- required by this bound in `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
    |                         ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
@@ -46,7 +46,7 @@ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> u
   --> $DIR/unboxed-closures-unsafe-extern-fn.rs:24:26
    |
 LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
-   | ----------------------------------------------------------------- required by `call_it_once`
+   |    ------------                   ----- required by this bound in `call_it_once`
 ...
 LL |     let z = call_it_once(square, 22);
    |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> unsafe fn(&'r isize) -> isize {square}`
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
index 7b393b35f298d..17faf047c14e3 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-abi.stderr
@@ -2,7 +2,7 @@ error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `for<'r> exter
   --> $DIR/unboxed-closures-wrong-abi.rs:12:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | --------------------------------------------------------- required by `call_it`
+   |    -------   ----------------- required by this bound in `call_it`
 ...
 LL |     let x = call_it(&square, 22);
    |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
@@ -13,7 +13,7 @@ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> e
   --> $DIR/unboxed-closures-wrong-abi.rs:12:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | --------------------------------------------------------- required by `call_it`
+   |    -------               ----- required by this bound in `call_it`
 ...
 LL |     let x = call_it(&square, 22);
    |                     ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
@@ -24,7 +24,7 @@ error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `for<'r> ex
   --> $DIR/unboxed-closures-wrong-abi.rs:18:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | -------------------------------------------------------------------- required by `call_it_mut`
+   |    -----------   -------------------- required by this bound in `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
    |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
@@ -35,7 +35,7 @@ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> e
   --> $DIR/unboxed-closures-wrong-abi.rs:18:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | -------------------------------------------------------------------- required by `call_it_mut`
+   |    -----------                  ----- required by this bound in `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
    |                         ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
@@ -46,7 +46,7 @@ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `for<'r> e
   --> $DIR/unboxed-closures-wrong-abi.rs:24:26
    |
 LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
-   | ----------------------------------------------------------------- required by `call_it_once`
+   |    ------------                   ----- required by this bound in `call_it_once`
 ...
 LL |     let z = call_it_once(square, 22);
    |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `for<'r> extern "C" fn(&'r isize) -> isize {square}`
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
index 68fc0d45b9a8c..5b1d6eb5b681b 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-wrong-arg-type-extern-fn.stderr
@@ -2,7 +2,7 @@ error[E0277]: expected a `std::ops::Fn<(&isize,)>` closure, found `unsafe fn(isi
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | --------------------------------------------------------- required by `call_it`
+   |    -------   ----------------- required by this bound in `call_it`
 ...
 LL |     let x = call_it(&square, 22);
    |                     ^^^^^^^ expected an `Fn<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
@@ -13,7 +13,7 @@ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:13:21
    |
 LL | fn call_it<F:Fn(&isize)->isize>(_: &F, _: isize) -> isize { 0 }
-   | --------------------------------------------------------- required by `call_it`
+   |    -------               ----- required by this bound in `call_it`
 ...
 LL |     let x = call_it(&square, 22);
    |                     ^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
@@ -24,7 +24,7 @@ error[E0277]: expected a `std::ops::FnMut<(&isize,)>` closure, found `unsafe fn(
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | -------------------------------------------------------------------- required by `call_it_mut`
+   |    -----------   -------------------- required by this bound in `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
    |                         ^^^^^^^^^^^ expected an `FnMut<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
@@ -35,7 +35,7 @@ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:19:25
    |
 LL | fn call_it_mut<F:FnMut(&isize)->isize>(_: &mut F, _: isize) -> isize { 0 }
-   | -------------------------------------------------------------------- required by `call_it_mut`
+   |    -----------                  ----- required by this bound in `call_it_mut`
 ...
 LL |     let y = call_it_mut(&mut square, 22);
    |                         ^^^^^^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
@@ -46,7 +46,7 @@ error[E0277]: expected a `std::ops::FnOnce<(&isize,)>` closure, found `unsafe fn
   --> $DIR/unboxed-closures-wrong-arg-type-extern-fn.rs:25:26
    |
 LL | fn call_it_once<F:FnOnce(&isize)->isize>(_: F, _: isize) -> isize { 0 }
-   | ----------------------------------------------------------------- required by `call_it_once`
+   |    ------------                   ----- required by this bound in `call_it_once`
 ...
 LL |     let z = call_it_once(square, 22);
    |                          ^^^^^^ expected an `FnOnce<(&isize,)>` closure, found `unsafe fn(isize) -> isize {square}`
diff --git a/src/test/ui/unsized/unsized-bare-typaram.stderr b/src/test/ui/unsized/unsized-bare-typaram.stderr
index c39c648f661c6..565d561033722 100644
--- a/src/test/ui/unsized/unsized-bare-typaram.stderr
+++ b/src/test/ui/unsized/unsized-bare-typaram.stderr
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
   --> $DIR/unsized-bare-typaram.rs:2:23
    |
 LL | fn bar<T: Sized>() { }
-   | ------------------ required by `bar`
+   |    --- - required by this bound in `bar`
 LL | fn foo<T: ?Sized>() { bar::<T>() }
    |                       ^^^^^^^^ doesn't have a size known at compile-time
    |
diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr
index 795115154e72b..0d4776ff6c25b 100644
--- a/src/test/ui/unsized/unsized-struct.stderr
+++ b/src/test/ui/unsized/unsized-struct.stderr
@@ -15,7 +15,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
   --> $DIR/unsized-struct.rs:13:24
    |
 LL | fn is_sized<T:Sized>() { }
-   | ---------------------- required by `is_sized`
+   |    -------- - required by this bound in `is_sized`
 ...
 LL | fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
    |                        ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
diff --git a/src/test/ui/unsized3.stderr b/src/test/ui/unsized3.stderr
index f381cacadf9c0..c821a08f6b585 100644
--- a/src/test/ui/unsized3.stderr
+++ b/src/test/ui/unsized3.stderr
@@ -5,7 +5,7 @@ LL |     f2::<X>(x);
    |             ^ doesn't have a size known at compile-time
 ...
 LL | fn f2<X>(x: &X) {
-   | --------------- required by `f2`
+   |    -- - required by this bound in `f2`
    |
    = help: the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
@@ -18,7 +18,7 @@ LL |     f4::<X>(x);
    |             ^ doesn't have a size known at compile-time
 ...
 LL | fn f4<X: T>(x: &X) {
-   | ------------------ required by `f4`
+   |    -- - required by this bound in `f4`
    |
    = help: the trait `std::marker::Sized` is not implemented for `X`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
@@ -28,7 +28,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
   --> $DIR/unsized3.rs:33:8
    |
 LL | fn f5<Y>(x: &Y) {}
-   | --------------- required by `f5`
+   |    -- - required by this bound in `f5`
 ...
 LL |     f5(x1);
    |        ^^ doesn't have a size known at compile-time
@@ -67,7 +67,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
   --> $DIR/unsized3.rs:45:8
    |
 LL | fn f5<Y>(x: &Y) {}
-   | --------------- required by `f5`
+   |    -- - required by this bound in `f5`
 ...
 LL |     f5(&(32, *x1));
    |        ^^^^^^^^^^ doesn't have a size known at compile-time
diff --git a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
index 118caf8cccec7..727c9b8e06721 100644
--- a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
+++ b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-inherent-impl.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/where-clause-constraints-are-local-for-inherent-impl.rs:13:22
    |
 LL | fn require_copy<T: Copy>(x: T) {}
-   | ------------------------------ required by `require_copy`
+   |    ------------    ---- required by this bound in `require_copy`
 ...
 LL |         require_copy(self.x);
    |                      ^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
diff --git a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
index d1cb4e1cc7d1d..1c1937c3074db 100644
--- a/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
+++ b/src/test/ui/where-clauses/where-clause-constraints-are-local-for-trait-impl.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
   --> $DIR/where-clause-constraints-are-local-for-trait-impl.rs:18:22
    |
 LL | fn require_copy<T: Copy>(x: T) {}
-   | ------------------------------ required by `require_copy`
+   |    ------------    ---- required by this bound in `require_copy`
 ...
 LL |         require_copy(self.x);
    |                      ^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
diff --git a/src/test/ui/where-clauses/where-clauses-unsatisfied.stderr b/src/test/ui/where-clauses/where-clauses-unsatisfied.stderr
index e59d6089ea539..1c859ac648c3b 100644
--- a/src/test/ui/where-clauses/where-clauses-unsatisfied.stderr
+++ b/src/test/ui/where-clauses/where-clauses-unsatisfied.stderr
@@ -2,7 +2,7 @@ error[E0277]: the trait bound `Struct: std::cmp::Eq` is not satisfied
   --> $DIR/where-clauses-unsatisfied.rs:6:10
    |
 LL | fn equal<T>(a: &T, b: &T) -> bool where T : Eq { a == b }
-   | ---------------------------------------------- required by `equal`
+   |    -----                                    -- required by this bound in `equal`
 ...
 LL |     drop(equal(&Struct, &Struct))
    |          ^^^^^ the trait `std::cmp::Eq` is not implemented for `Struct`
diff --git a/src/test/ui/where-clauses/where-for-self-2.stderr b/src/test/ui/where-clauses/where-for-self-2.stderr
index 32dc0e7359cbe..b18b36d029d70 100644
--- a/src/test/ui/where-clauses/where-for-self-2.stderr
+++ b/src/test/ui/where-clauses/where-for-self-2.stderr
@@ -1,13 +1,13 @@
 error[E0277]: the trait bound `for<'a> &'a _: Bar` is not satisfied
   --> $DIR/where-for-self-2.rs:21:5
    |
-LL | / fn foo<T>(x: &T)
-LL | |     where for<'a> &'a T: Bar
-LL | | {}
-   | |__- required by `foo`
+LL | fn foo<T>(x: &T)
+   |    ---
+LL |     where for<'a> &'a T: Bar
+   |                          --- required by this bound in `foo`
 ...
-LL |       foo(&X);
-   |       ^^^ the trait `for<'a> Bar` is not implemented for `&'a _`
+LL |     foo(&X);
+   |     ^^^ the trait `for<'a> Bar` is not implemented for `&'a _`
    |
    = help: the following implementations were found:
              <&'static u32 as Bar>

From c9d05aa9ceb82f31a86a548eaaffab8bdb229d76 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 4 Sep 2019 17:36:01 -0700
Subject: [PATCH 935/943] Point at correct span for parenthesized types

---
 src/librustc/hir/lowering.rs                  |  5 +++-
 src/libsyntax/parse/parser/path.rs            | 13 +++++----
 .../anonymous-higher-ranked-lifetime.stderr   | 22 +++++++--------
 .../expect-fn-supply-fn.stderr                |  6 ++--
 src/test/ui/error-codes/E0214.stderr          | 10 +++----
 ...-gate-unboxed-closures-manual-impls.stderr |  4 +--
 src/test/ui/issues/issue-23589.stderr         | 10 +++----
 src/test/ui/issues/issue-32995-2.stderr       | 12 ++++----
 src/test/ui/issues/issue-32995.stderr         | 28 +++++++++----------
 src/test/ui/issues/issue-39687.stderr         |  4 +--
 src/test/ui/issues/issue-43623.stderr         |  2 +-
 src/test/ui/issues/issue-60283.stderr         |  2 +-
 .../closure-arg-type-mismatch.stderr          |  2 +-
 .../type-parameters-in-field-exprs.stderr     | 12 ++++----
 src/test/ui/span/macro-ty-params.stderr       | 12 ++++----
 .../ui/type/ascription/issue-34255-1.stderr   |  4 +--
 ...oxed-closure-sugar-used-on-struct-1.stderr |  4 +--
 ...oxed-closure-sugar-used-on-struct-3.stderr | 10 +++----
 ...nboxed-closure-sugar-used-on-struct.stderr |  4 +--
 ...ong-number-number-type-parameters-1.stderr |  4 +--
 ...ong-number-number-type-parameters-3.stderr |  4 +--
 ...wrong-number-number-type-parameters.stderr |  8 +++---
 .../unboxed-closure-sugar-wrong-trait.stderr  |  4 +--
 23 files changed, 95 insertions(+), 91 deletions(-)

diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 48f7fc4446505..f6b872623d789 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -1893,10 +1893,13 @@ impl<'a> LoweringContext<'a> {
                         if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
                             // Do not suggest going from `Trait()` to `Trait<>`
                             if data.inputs.len() > 0 {
+                                let split = snippet.find('(').unwrap();
+                                let trait_name = &snippet[0..split];
+                                let args = &snippet[split + 1 .. snippet.len() - 1];
                                 err.span_suggestion(
                                     data.span,
                                     "use angle brackets instead",
-                                    format!("<{}>", &snippet[1..snippet.len() - 1]),
+                                    format!("{}<{}>", trait_name, args),
                                     Applicability::MaybeIncorrect,
                                 );
                             }
diff --git a/src/libsyntax/parse/parser/path.rs b/src/libsyntax/parse/parser/path.rs
index dcd3c64801742..f6df24c05684a 100644
--- a/src/libsyntax/parse/parser/path.rs
+++ b/src/libsyntax/parse/parser/path.rs
@@ -129,10 +129,11 @@ impl<'a> Parser<'a> {
         self.parse_path(style)
     }
 
-    crate fn parse_path_segments(&mut self,
-                           segments: &mut Vec<PathSegment>,
-                           style: PathStyle)
-                           -> PResult<'a, ()> {
+    crate fn parse_path_segments(
+        &mut self,
+        segments: &mut Vec<PathSegment>,
+        style: PathStyle,
+    ) -> PResult<'a, ()> {
         loop {
             let segment = self.parse_path_segment(style)?;
             if style == PathStyle::Expr {
@@ -196,12 +197,12 @@ impl<'a> Parser<'a> {
                 let (args, constraints) =
                     self.parse_generic_args_with_leaning_angle_bracket_recovery(style, lo)?;
                 self.expect_gt()?;
-                let span = lo.to(self.prev_span);
+                let span = ident.span.to(self.prev_span);
                 AngleBracketedArgs { args, constraints, span }.into()
             } else {
                 // `(T, U) -> R`
                 let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?;
-                let span = lo.to(self.prev_span);
+                let span = ident.span.to(self.prev_span);
                 let output = if self.eat(&token::RArrow) {
                     Some(self.parse_ty_common(false, false, false)?)
                 } else {
diff --git a/src/test/ui/anonymous-higher-ranked-lifetime.stderr b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
index 51550e1471e72..fbe2d192d0cce 100644
--- a/src/test/ui/anonymous-higher-ranked-lifetime.stderr
+++ b/src/test/ui/anonymous-higher-ranked-lifetime.stderr
@@ -18,7 +18,7 @@ LL |     f1(|_: (), _: ()| {});
    |     expected signature of `fn(&(), &()) -> _`
 ...
 LL | fn f1<F>(_: F) where F: Fn(&(), &()) {}
-   |    --                     ---------- required by this bound in `f1`
+   |    --                   ------------ required by this bound in `f1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:4:5
@@ -40,7 +40,7 @@ LL |     f2(|_: (), _: ()| {});
    |     expected signature of `fn(&'a (), &()) -> _`
 ...
 LL | fn f2<F>(_: F) where F: for<'a> Fn(&'a (), &()) {}
-   |    --                             ------------- required by this bound in `f2`
+   |    --                           --------------- required by this bound in `f2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:6:5
@@ -62,7 +62,7 @@ LL |     f3(|_: (), _: ()| {});
    |     expected signature of `fn(&(), &()) -> _`
 ...
 LL | fn f3<'a, F>(_: F) where F: Fn(&'a (), &()) {}
-   |    --                         ------------- required by this bound in `f3`
+   |    --                       --------------- required by this bound in `f3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:8:5
@@ -84,7 +84,7 @@ LL |     f4(|_: (), _: ()| {});
    |     expected signature of `fn(&(), &'r ()) -> _`
 ...
 LL | fn f4<F>(_: F) where F: for<'r> Fn(&(), &'r ()) {}
-   |    --                             ------------- required by this bound in `f4`
+   |    --                           --------------- required by this bound in `f4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:10:5
@@ -106,7 +106,7 @@ LL |     f5(|_: (), _: ()| {});
    |     expected signature of `fn(&'r (), &'r ()) -> _`
 ...
 LL | fn f5<F>(_: F) where F: for<'r> Fn(&'r (), &'r ()) {}
-   |    --                             ---------------- required by this bound in `f5`
+   |    --                           ------------------ required by this bound in `f5`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:12:5
@@ -128,7 +128,7 @@ LL |     g1(|_: (), _: ()| {});
    |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
 ...
 LL | fn g1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>) {}
-   |    --                     ----------------------- required by this bound in `g1`
+   |    --                   ------------------------- required by this bound in `g1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:14:5
@@ -150,7 +150,7 @@ LL |     g2(|_: (), _: ()| {});
    |     expected signature of `fn(&(), for<'r> fn(&'r ())) -> _`
 ...
 LL | fn g2<F>(_: F) where F: Fn(&(), fn(&())) {}
-   |    --                     -------------- required by this bound in `g2`
+   |    --                   ---------------- required by this bound in `g2`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:16:5
@@ -172,7 +172,7 @@ LL |     g3(|_: (), _: ()| {});
    |     expected signature of `fn(&'s (), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>) -> _`
 ...
 LL | fn g3<F>(_: F) where F: for<'s> Fn(&'s (), Box<dyn Fn(&())>) {}
-   |    --                             -------------------------- required by this bound in `g3`
+   |    --                           ---------------------------- required by this bound in `g3`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:18:5
@@ -194,7 +194,7 @@ LL |     g4(|_: (), _: ()| {});
    |     expected signature of `fn(&(), for<'r> fn(&'r ())) -> _`
 ...
 LL | fn g4<F>(_: F) where F: Fn(&(), for<'r> fn(&'r ())) {}
-   |    --                     ------------------------- required by this bound in `g4`
+   |    --                   --------------------------- required by this bound in `g4`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:20:5
@@ -216,7 +216,7 @@ LL |     h1(|_: (), _: (), _: (), _: ()| {});
    |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &(), for<'r, 's> fn(&'r (), &'s ())) -> _`
 ...
 LL | fn h1<F>(_: F) where F: Fn(&(), Box<dyn Fn(&())>, &(), fn(&(), &())) {}
-   |    --                     ------------------------------------------ required by this bound in `h1`
+   |    --                   -------------------------------------------- required by this bound in `h1`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/anonymous-higher-ranked-lifetime.rs:22:5
@@ -238,7 +238,7 @@ LL |     h2(|_: (), _: (), _: (), _: ()| {});
    |     expected signature of `fn(&(), std::boxed::Box<(dyn for<'r> std::ops::Fn(&'r ()) + 'static)>, &'t0 (), for<'r, 's> fn(&'r (), &'s ())) -> _`
 ...
 LL | fn h2<F>(_: F) where F: for<'t0> Fn(&(), Box<dyn Fn(&())>, &'t0 (), fn(&(), &())) {}
-   |    --                              ---------------------------------------------- required by this bound in `h2`
+   |    --                            ------------------------------------------------ required by this bound in `h2`
 
 error: aborting due to 22 previous errors
 
diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
index 6fadea31f7e69..ac4666fe36de6 100644
--- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.stderr
@@ -42,7 +42,7 @@ error[E0631]: type mismatch in closure arguments
 LL | fn with_closure_expecting_fn_with_free_region<F>(_: F)
    |    ------------------------------------------
 LL |     where F: for<'a> FnOnce(fn(&'a u32), &i32)
-   |                            ------------------- required by this bound in `with_closure_expecting_fn_with_free_region`
+   |                      ------------------------- required by this bound in `with_closure_expecting_fn_with_free_region`
 ...
 LL |     with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
@@ -55,7 +55,7 @@ error[E0631]: type mismatch in closure arguments
 LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
    |    -------------------------------------------
 LL |     where F: FnOnce(fn(&u32), &i32)
-   |                    ---------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
+   |              ---------------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
 ...
 LL |     with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
@@ -68,7 +68,7 @@ error[E0631]: type mismatch in closure arguments
 LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
    |    -------------------------------------------
 LL |     where F: FnOnce(fn(&u32), &i32)
-   |                    ---------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
+   |              ---------------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
 ...
 LL |     with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
diff --git a/src/test/ui/error-codes/E0214.stderr b/src/test/ui/error-codes/E0214.stderr
index a10f2c00578c6..bcbd3a91cb951 100644
--- a/src/test/ui/error-codes/E0214.stderr
+++ b/src/test/ui/error-codes/E0214.stderr
@@ -1,11 +1,11 @@
 error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/E0214.rs:2:15
+  --> $DIR/E0214.rs:2:12
    |
 LL |     let v: Vec(&str) = vec!["foo"];
-   |               ^^^^^^
-   |               |
-   |               only `Fn` traits may use parentheses
-   |               help: use angle brackets instead: `<&str>`
+   |            ^^^^^^^^^
+   |            |
+   |            only `Fn` traits may use parentheses
+   |            help: use angle brackets instead: `Vec<&str>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
index fc4317b316a37..c05379c71eeaf 100644
--- a/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
+++ b/src/test/ui/feature-gates/feature-gate-unboxed-closures-manual-impls.stderr
@@ -44,10 +44,10 @@ LL | impl Fn<()> for Foo {
    = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
 error[E0229]: associated type bindings are not allowed here
-  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:15:12
+  --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:15:6
    |
 LL | impl FnOnce() for Foo1 {
-   |            ^^ associated type not allowed here
+   |      ^^^^^^^^ associated type not allowed here
 
 error[E0658]: the precise format of `Fn`-family traits' type parameters is subject to change. Use parenthetical notation (Fn(Foo, Bar) -> Baz) instead
   --> $DIR/feature-gate-unboxed-closures-manual-impls.rs:21:6
diff --git a/src/test/ui/issues/issue-23589.stderr b/src/test/ui/issues/issue-23589.stderr
index d169fdfe2dddd..c3b419fe939cb 100644
--- a/src/test/ui/issues/issue-23589.stderr
+++ b/src/test/ui/issues/issue-23589.stderr
@@ -1,11 +1,11 @@
 error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-23589.rs:2:15
+  --> $DIR/issue-23589.rs:2:12
    |
 LL |     let v: Vec(&str) = vec!['1', '2'];
-   |               ^^^^^^
-   |               |
-   |               only `Fn` traits may use parentheses
-   |               help: use angle brackets instead: `<&str>`
+   |            ^^^^^^^^^
+   |            |
+   |            only `Fn` traits may use parentheses
+   |            help: use angle brackets instead: `Vec<&str>`
 
 error[E0308]: mismatched types
   --> $DIR/issue-23589.rs:2:29
diff --git a/src/test/ui/issues/issue-32995-2.stderr b/src/test/ui/issues/issue-32995-2.stderr
index 4a580b09bf372..976e3064db64b 100644
--- a/src/test/ui/issues/issue-32995-2.stderr
+++ b/src/test/ui/issues/issue-32995-2.stderr
@@ -1,27 +1,27 @@
 error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995-2.rs:4:28
+  --> $DIR/issue-32995-2.rs:4:22
    |
 LL |     { fn f<X: ::std::marker()::Send>() {} }
-   |                            ^^
+   |                      ^^^^^^^^
    |
    = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
 
 error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995-2.rs:8:35
+  --> $DIR/issue-32995-2.rs:8:29
    |
 LL |     { fn f() -> impl ::std::marker()::Send { } }
-   |                                   ^^
+   |                             ^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
 
 error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995-2.rs:16:19
+  --> $DIR/issue-32995-2.rs:16:13
    |
 LL | impl ::std::marker()::Copy for X {}
-   |                   ^^
+   |             ^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
diff --git a/src/test/ui/issues/issue-32995.stderr b/src/test/ui/issues/issue-32995.stderr
index 59d93ece06742..724e82a59dc35 100644
--- a/src/test/ui/issues/issue-32995.stderr
+++ b/src/test/ui/issues/issue-32995.stderr
@@ -1,63 +1,63 @@
 error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:4:17
+  --> $DIR/issue-32995.rs:4:12
    |
 LL |     let x: usize() = 1;
-   |                 ^^
+   |            ^^^^^^^
    |
    = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
 
 error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:8:24
+  --> $DIR/issue-32995.rs:8:19
    |
 LL |     let b: ::std::boxed()::Box<_> = Box::new(1);
-   |                        ^^
+   |                   ^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
 
 error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:12:25
+  --> $DIR/issue-32995.rs:12:20
    |
 LL |     let p = ::std::str::()::from_utf8(b"foo").unwrap();
-   |                         ^^
+   |                    ^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
 
 error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:16:36
+  --> $DIR/issue-32995.rs:16:25
    |
 LL |     let p = ::std::str::from_utf8::()(b"foo").unwrap();
-   |                                    ^^
+   |                         ^^^^^^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
 
 error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:20:35
+  --> $DIR/issue-32995.rs:20:29
    |
 LL |     let o : Box<dyn (::std::marker()::Send)> = Box::new(1);
-   |                                   ^^
+   |                             ^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
 
 error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:24:41
+  --> $DIR/issue-32995.rs:24:35
    |
 LL |     let o : Box<dyn Send + ::std::marker()::Sync> = Box::new(1);
-   |                                         ^^
+   |                                   ^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
 
 error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-32995.rs:30:14
+  --> $DIR/issue-32995.rs:30:13
    |
 LL |     let d : X() = Default::default();
-   |              ^^
+   |             ^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238>
diff --git a/src/test/ui/issues/issue-39687.stderr b/src/test/ui/issues/issue-39687.stderr
index 886de1d6faffc..b1b3041ea0275 100644
--- a/src/test/ui/issues/issue-39687.stderr
+++ b/src/test/ui/issues/issue-39687.stderr
@@ -1,8 +1,8 @@
 error[E0229]: associated type bindings are not allowed here
-  --> $DIR/issue-39687.rs:4:16
+  --> $DIR/issue-39687.rs:4:14
    |
 LL |     <fn() as Fn()>::call;
-   |                ^^ associated type not allowed here
+   |              ^^^^ associated type not allowed here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-43623.stderr b/src/test/ui/issues/issue-43623.stderr
index 210d831abf0de..2c57b8585d924 100644
--- a/src/test/ui/issues/issue-43623.stderr
+++ b/src/test/ui/issues/issue-43623.stderr
@@ -19,7 +19,7 @@ LL | pub fn break_me<T, F>(f: F)
    |        --------
 LL | where T: for<'b> Trait<'b>,
 LL |       F: for<'b> FnMut(<T as Trait<'b>>::Assoc) {
-   |                       ------------------------- required by this bound in `break_me`
+   |                  ------------------------------ required by this bound in `break_me`
 LL |     break_me::<Type, fn(_)>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'b, found concrete lifetime
 
diff --git a/src/test/ui/issues/issue-60283.stderr b/src/test/ui/issues/issue-60283.stderr
index dc7952200b18e..69c1d85e4e12d 100644
--- a/src/test/ui/issues/issue-60283.stderr
+++ b/src/test/ui/issues/issue-60283.stderr
@@ -20,7 +20,7 @@ LL | pub fn foo<T, F>(_: T, _: F)
    |        ---
 LL | where T: for<'a> Trait<'a>,
 LL |       F: for<'a> FnMut(<T as Trait<'a>>::Item) {}
-   |                       ------------------------ required by this bound in `foo`
+   |                  ----------------------------- required by this bound in `foo`
 ...
 LL |     foo((), drop)
    |     ^^^ expected bound lifetime parameter 'a, found concrete lifetime
diff --git a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
index a731891bf764e..85cad61210ebf 100644
--- a/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
+++ b/src/test/ui/mismatched_types/closure-arg-type-mismatch.stderr
@@ -38,7 +38,7 @@ error[E0271]: type mismatch resolving `for<'r> <fn(*mut &'a u32) as std::ops::Fn
   --> $DIR/closure-arg-type-mismatch.rs:10:5
    |
 LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
-   |    ---      ----------- required by this bound in `baz`
+   |    ---    ------------- required by this bound in `baz`
 LL | fn _test<'a>(f: fn(*mut &'a u32)) {
 LL |     baz(f);
    |     ^^^ expected bound lifetime parameter, found concrete lifetime
diff --git a/src/test/ui/parser/type-parameters-in-field-exprs.stderr b/src/test/ui/parser/type-parameters-in-field-exprs.stderr
index 2183c74da0acb..dd8a3feb04954 100644
--- a/src/test/ui/parser/type-parameters-in-field-exprs.stderr
+++ b/src/test/ui/parser/type-parameters-in-field-exprs.stderr
@@ -1,20 +1,20 @@
 error: field expressions may not have generic arguments
-  --> $DIR/type-parameters-in-field-exprs.rs:13:10
+  --> $DIR/type-parameters-in-field-exprs.rs:13:7
    |
 LL |     f.x::<isize>;
-   |          ^^^^^^^
+   |       ^^^^^^^^^^
 
 error: field expressions may not have generic arguments
-  --> $DIR/type-parameters-in-field-exprs.rs:15:10
+  --> $DIR/type-parameters-in-field-exprs.rs:15:7
    |
 LL |     f.x::<>;
-   |          ^^
+   |       ^^^^^
 
 error: field expressions may not have generic arguments
-  --> $DIR/type-parameters-in-field-exprs.rs:17:10
+  --> $DIR/type-parameters-in-field-exprs.rs:17:7
    |
 LL |     f.x::();
-   |          ^^
+   |       ^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr
index 39b3edc67033d..139247c0388a9 100644
--- a/src/test/ui/span/macro-ty-params.stderr
+++ b/src/test/ui/span/macro-ty-params.stderr
@@ -1,14 +1,14 @@
 error: generic arguments in macro path
-  --> $DIR/macro-ty-params.rs:10:10
+  --> $DIR/macro-ty-params.rs:10:5
    |
 LL |     foo::<T>!();
-   |          ^^^
+   |     ^^^^^^^^
 
 error: generic arguments in macro path
-  --> $DIR/macro-ty-params.rs:11:10
+  --> $DIR/macro-ty-params.rs:11:5
    |
 LL |     foo::<>!();
-   |          ^^
+   |     ^^^^^^^
 
 error: unexpected generic arguments in path
   --> $DIR/macro-ty-params.rs:12:8
@@ -17,10 +17,10 @@ LL |     m!(Default<>);
    |        ^^^^^^^^^
 
 error: generic arguments in macro path
-  --> $DIR/macro-ty-params.rs:12:15
+  --> $DIR/macro-ty-params.rs:12:8
    |
 LL |     m!(Default<>);
-   |               ^^
+   |        ^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/type/ascription/issue-34255-1.stderr b/src/test/ui/type/ascription/issue-34255-1.stderr
index 195b393b2f609..0d0acfde88605 100644
--- a/src/test/ui/type/ascription/issue-34255-1.stderr
+++ b/src/test/ui/type/ascription/issue-34255-1.stderr
@@ -5,10 +5,10 @@ LL |         input_cells: Vec::new()
    |         ^^^^^^^^^^^ a field by this name exists in `Self`
 
 error: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-34255-1.rs:7:30
+  --> $DIR/issue-34255-1.rs:7:27
    |
 LL |         input_cells: Vec::new()
-   |                              ^^
+   |                           ^^^^^
    |
    = note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
index 81095826f38ae..32619420f6d53 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr
@@ -1,8 +1,8 @@
 error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:19
+  --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16
    |
 LL |     let x: Box<Bar()> = panic!();
-   |                   ^^ only `Fn` traits may use parentheses
+   |                ^^^^^ only `Fn` traits may use parentheses
 
 error[E0107]: wrong number of type arguments: expected 1, found 0
   --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
index 7d05ca55ffdb0..f5cf6db30f99c 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
@@ -1,11 +1,11 @@
 error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:18
+  --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:13
    |
 LL |     let b = Bar::(isize, usize)::new(); // OK too (for the parser)
-   |                  ^^^^^^^^^^^^^^
-   |                  |
-   |                  only `Fn` traits may use parentheses
-   |                  help: use angle brackets instead: `<isize, usize>`
+   |             ^^^^^^^^^^^^^^^^^^^
+   |             |
+   |             only `Fn` traits may use parentheses
+   |             help: use angle brackets instead: `Bar::<isize, usize>`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
index 3c78d9f9135cf..ba93b60dad878 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr
@@ -1,8 +1,8 @@
 error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:18
+  --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:15
    |
 LL | fn foo(b: Box<Bar()>) {
-   |                  ^^ only `Fn` traits may use parentheses
+   |               ^^^^^ only `Fn` traits may use parentheses
 
 error[E0107]: wrong number of type arguments: expected 1, found 0
   --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:15
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-1.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-1.stderr
index c59082932ddfe..59e7bc8c832d6 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-1.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-1.stderr
@@ -1,8 +1,8 @@
 error[E0220]: associated type `Output` not found for `One<()>`
-  --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs:5:19
+  --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-1.rs:5:16
    |
 LL | fn foo(_: &dyn One())
-   |                   ^^ associated type `Output` not found
+   |                ^^^^^ associated type `Output` not found
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
index 6c61e74584a50..f42ac38d370d5 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr
@@ -5,10 +5,10 @@ LL | fn foo(_: &dyn Three())
    |                ^^^^^^^ expected 3 type arguments
 
 error[E0220]: associated type `Output` not found for `Three<(), [type error], [type error]>`
-  --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs:5:21
+  --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs:5:16
    |
 LL | fn foo(_: &dyn Three())
-   |                     ^^ associated type `Output` not found
+   |                ^^^^^^^ associated type `Output` not found
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr
index b96e2cbc36bb4..8185a798e7b65 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr
@@ -1,14 +1,14 @@
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:5:19
+  --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:5:15
    |
 LL | fn foo(_: dyn Zero())
-   |                   ^^ unexpected type argument
+   |               ^^^^^^ unexpected type argument
 
 error[E0220]: associated type `Output` not found for `Zero`
-  --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:5:19
+  --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:5:15
    |
 LL | fn foo(_: dyn Zero())
-   |                   ^^ associated type `Output` not found
+   |               ^^^^^^ associated type `Output` not found
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr
index bd707a8508a7d..c81402a3dcc00 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr
@@ -1,8 +1,8 @@
 error[E0107]: wrong number of type arguments: expected 0, found 1
-  --> $DIR/unboxed-closure-sugar-wrong-trait.rs:5:13
+  --> $DIR/unboxed-closure-sugar-wrong-trait.rs:5:8
    |
 LL | fn f<F:Trait(isize) -> isize>(x: F) {}
-   |             ^^^^^^^ unexpected type argument
+   |        ^^^^^^^^^^^^ unexpected type argument
 
 error[E0220]: associated type `Output` not found for `Trait`
   --> $DIR/unboxed-closure-sugar-wrong-trait.rs:5:24

From b21408527a77136af7aed22ffbe256a6116ddc4e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 4 Sep 2019 23:41:51 -0700
Subject: [PATCH 936/943] review comments

---
 src/librustc/hir/mod.rs                       |  3 +-
 src/librustc_typeck/check/mod.rs              | 41 ++++++++++---------
 src/libsyntax/parse/parser/path.rs            |  2 +-
 .../type-parameters-in-field-exprs.stderr     |  8 ++--
 src/test/ui/span/macro-ty-params.stderr       | 12 +++---
 5 files changed, 34 insertions(+), 32 deletions(-)

diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 4f942a22cb8ae..92a8c00804733 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -2751,9 +2751,8 @@ pub enum Node<'hir> {
     Crate,
 }
 
-impl<'hir> Node<'hir> {
+impl Node<'_> {
     pub fn ident(&self) -> Option<Ident> {
-
         match self {
             Node::TraitItem(TraitItem { ident, .. }) |
             Node::ImplItem(ImplItem { ident, .. }) |
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 743e6661247b6..edea91c717ef7 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4736,25 +4736,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // First, store the "user substs" for later.
         self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
 
-        // Add all the obligations that are required, substituting and
-        // normalized appropriately.
-        let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
-
-        for (i, mut obligation) in traits::predicates_for_generics(
-            traits::ObligationCause::new(
-                span,
-                self.body_id,
-                traits::ItemObligation(def_id),
-            ),
-            self.param_env,
-            &bounds,
-        ).into_iter().enumerate() {
-            // This makes the error point at the bound, but we want to point at the argument
-            if let Some(span) = spans.get(i) {
-                obligation.cause.code = traits::BindingObligation(def_id, *span);
-            }
-            self.register_predicate(obligation);
-        }
+        self.add_required_obligations(span, def_id, &substs);
 
         // Substitute the values for the type parameters into the type of
         // the referenced item.
@@ -4791,6 +4773,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         (ty_substituted, res)
     }
 
+    /// Add all the obligations that are required, substituting and normalized appropriately.
+    fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
+        let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
+
+        for (i, mut obligation) in traits::predicates_for_generics(
+            traits::ObligationCause::new(
+                span,
+                self.body_id,
+                traits::ItemObligation(def_id),
+            ),
+            self.param_env,
+            &bounds,
+        ).into_iter().enumerate() {
+            // This makes the error point at the bound, but we want to point at the argument
+            if let Some(span) = spans.get(i) {
+                obligation.cause.code = traits::BindingObligation(def_id, *span);
+            }
+            self.register_predicate(obligation);
+        }
+    }
+
     fn check_rustc_args_require_const(&self,
                                       def_id: DefId,
                                       hir_id: hir::HirId,
diff --git a/src/libsyntax/parse/parser/path.rs b/src/libsyntax/parse/parser/path.rs
index f6df24c05684a..87839f8c70ee8 100644
--- a/src/libsyntax/parse/parser/path.rs
+++ b/src/libsyntax/parse/parser/path.rs
@@ -197,7 +197,7 @@ impl<'a> Parser<'a> {
                 let (args, constraints) =
                     self.parse_generic_args_with_leaning_angle_bracket_recovery(style, lo)?;
                 self.expect_gt()?;
-                let span = ident.span.to(self.prev_span);
+                let span = lo.to(self.prev_span);
                 AngleBracketedArgs { args, constraints, span }.into()
             } else {
                 // `(T, U) -> R`
diff --git a/src/test/ui/parser/type-parameters-in-field-exprs.stderr b/src/test/ui/parser/type-parameters-in-field-exprs.stderr
index dd8a3feb04954..8f32fb0eca106 100644
--- a/src/test/ui/parser/type-parameters-in-field-exprs.stderr
+++ b/src/test/ui/parser/type-parameters-in-field-exprs.stderr
@@ -1,14 +1,14 @@
 error: field expressions may not have generic arguments
-  --> $DIR/type-parameters-in-field-exprs.rs:13:7
+  --> $DIR/type-parameters-in-field-exprs.rs:13:10
    |
 LL |     f.x::<isize>;
-   |       ^^^^^^^^^^
+   |          ^^^^^^^
 
 error: field expressions may not have generic arguments
-  --> $DIR/type-parameters-in-field-exprs.rs:15:7
+  --> $DIR/type-parameters-in-field-exprs.rs:15:10
    |
 LL |     f.x::<>;
-   |       ^^^^^
+   |          ^^
 
 error: field expressions may not have generic arguments
   --> $DIR/type-parameters-in-field-exprs.rs:17:7
diff --git a/src/test/ui/span/macro-ty-params.stderr b/src/test/ui/span/macro-ty-params.stderr
index 139247c0388a9..39b3edc67033d 100644
--- a/src/test/ui/span/macro-ty-params.stderr
+++ b/src/test/ui/span/macro-ty-params.stderr
@@ -1,14 +1,14 @@
 error: generic arguments in macro path
-  --> $DIR/macro-ty-params.rs:10:5
+  --> $DIR/macro-ty-params.rs:10:10
    |
 LL |     foo::<T>!();
-   |     ^^^^^^^^
+   |          ^^^
 
 error: generic arguments in macro path
-  --> $DIR/macro-ty-params.rs:11:5
+  --> $DIR/macro-ty-params.rs:11:10
    |
 LL |     foo::<>!();
-   |     ^^^^^^^
+   |          ^^
 
 error: unexpected generic arguments in path
   --> $DIR/macro-ty-params.rs:12:8
@@ -17,10 +17,10 @@ LL |     m!(Default<>);
    |        ^^^^^^^^^
 
 error: generic arguments in macro path
-  --> $DIR/macro-ty-params.rs:12:8
+  --> $DIR/macro-ty-params.rs:12:15
    |
 LL |     m!(Default<>);
-   |        ^^^^^^^^^
+   |               ^^
 
 error: aborting due to 4 previous errors
 

From f81734bcaa9688bef78b5ef35c7d134edc0b41f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Mon, 16 Sep 2019 11:25:32 -0700
Subject: [PATCH 937/943] ignore musl target in tests to avoid issues with
 output differences

---
 src/etc/generate-deriving-span-tests.py            |  2 ++
 src/test/ui/async-await/issues/issue-62009-1.rs    |  2 ++
 .../ui/async-await/issues/issue-62009-1.stderr     | 12 ++++++------
 src/test/ui/closures/closure-move-sync.rs          |  2 ++
 src/test/ui/closures/closure-move-sync.stderr      |  8 ++++----
 .../derives-span-Hash-enum-struct-variant.rs       |  2 ++
 .../derives-span-Hash-enum-struct-variant.stderr   |  2 +-
 src/test/ui/derives/derives-span-Hash-enum.rs      |  2 ++
 src/test/ui/derives/derives-span-Hash-enum.stderr  |  2 +-
 src/test/ui/derives/derives-span-Hash-struct.rs    |  2 ++
 .../ui/derives/derives-span-Hash-struct.stderr     |  2 +-
 .../ui/derives/derives-span-Hash-tuple-struct.rs   |  2 ++
 .../derives/derives-span-Hash-tuple-struct.stderr  |  2 +-
 .../ui/interior-mutability/interior-mutability.rs  |  2 ++
 .../interior-mutability/interior-mutability.stderr |  4 ++--
 src/test/ui/issues/issue-21160.rs                  |  2 ++
 src/test/ui/issues/issue-21160.stderr              |  2 +-
 src/test/ui/no-send-res-ports.rs                   |  2 ++
 src/test/ui/no-send-res-ports.stderr               |  6 +++---
 .../termination-trait-test-wrong-type.rs           |  2 ++
 .../termination-trait-test-wrong-type.stderr       |  2 +-
 src/test/ui/traits/trait-suggest-where-clause.rs   |  2 ++
 .../ui/traits/trait-suggest-where-clause.stderr    | 14 +++++++-------
 23 files changed, 52 insertions(+), 28 deletions(-)

diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py
index 1c525101c76f6..4af67039fd877 100755
--- a/src/etc/generate-deriving-span-tests.py
+++ b/src/etc/generate-deriving-span-tests.py
@@ -14,6 +14,8 @@
     os.path.join(os.path.dirname(__file__), '../test/ui/derives/'))
 
 TEMPLATE = """\
+// ignore-musl
+// ^ due to stderr output differences
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 {error_deriving}
diff --git a/src/test/ui/async-await/issues/issue-62009-1.rs b/src/test/ui/async-await/issues/issue-62009-1.rs
index 3ee7ab2e9d12f..007ed4efa6981 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.rs
+++ b/src/test/ui/async-await/issues/issue-62009-1.rs
@@ -1,4 +1,6 @@
 // edition:2018
+// ignore-musl
+// ^ due to stderr output differences
 
 async fn print_dur() {}
 
diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr
index 3d8028635f5a5..f63eaa4c48a97 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.stderr
+++ b/src/test/ui/async-await/issues/issue-62009-1.stderr
@@ -1,5 +1,5 @@
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:6:5
+  --> $DIR/issue-62009-1.rs:8:5
    |
 LL | fn main() {
    |    ---- this is not `async`
@@ -7,7 +7,7 @@ LL |     async { let (); }.await;
    |     ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:8:5
+  --> $DIR/issue-62009-1.rs:10:5
    |
 LL |   fn main() {
    |      ---- this is not `async`
@@ -19,7 +19,7 @@ LL | |     }.await;
    | |___________^ only allowed inside `async` functions and blocks
 
 error[E0728]: `await` is only allowed inside `async` functions and blocks
-  --> $DIR/issue-62009-1.rs:12:5
+  --> $DIR/issue-62009-1.rs:14:5
    |
 LL | fn main() {
    |    ---- this is not `async`
@@ -27,11 +27,11 @@ LL | fn main() {
 LL |     (|_| 2333).await;
    |     ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks
 
-error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]: std::future::Future` is not satisfied
-  --> $DIR/issue-62009-1.rs:12:5
+error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]: std::future::Future` is not satisfied
+  --> $DIR/issue-62009-1.rs:14:5
    |
 LL |     (|_| 2333).await;
-   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]`
+   |     ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]`
    | 
   ::: $SRC_DIR/libstd/future.rs:LL:COL
    |
diff --git a/src/test/ui/closures/closure-move-sync.rs b/src/test/ui/closures/closure-move-sync.rs
index 580cd1af4f303..4cb6358864fca 100644
--- a/src/test/ui/closures/closure-move-sync.rs
+++ b/src/test/ui/closures/closure-move-sync.rs
@@ -1,3 +1,5 @@
+// ignore-musl
+// ^ due to stderr output differences
 use std::thread;
 use std::sync::mpsc::channel;
 
diff --git a/src/test/ui/closures/closure-move-sync.stderr b/src/test/ui/closures/closure-move-sync.stderr
index aaa5f76233f91..f676df9c559eb 100644
--- a/src/test/ui/closures/closure-move-sync.stderr
+++ b/src/test/ui/closures/closure-move-sync.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
-  --> $DIR/closure-move-sync.rs:6:13
+  --> $DIR/closure-move-sync.rs:8:13
    |
 LL |     let t = thread::spawn(|| {
    |             ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<()>` cannot be shared between threads safely
@@ -11,10 +11,10 @@ LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<()>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Receiver<()>`
-   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:6:27: 9:6 recv:&std::sync::mpsc::Receiver<()>]`
+   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:8:27: 11:6 recv:&std::sync::mpsc::Receiver<()>]`
 
 error[E0277]: `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
-  --> $DIR/closure-move-sync.rs:18:5
+  --> $DIR/closure-move-sync.rs:20:5
    |
 LL |     thread::spawn(|| tx.send(()).unwrap());
    |     ^^^^^^^^^^^^^ `std::sync::mpsc::Sender<()>` cannot be shared between threads safely
@@ -26,7 +26,7 @@ LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<()>`
    = note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Sender<()>`
-   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:18:19: 18:42 tx:&std::sync::mpsc::Sender<()>]`
+   = note: required because it appears within the type `[closure@$DIR/closure-move-sync.rs:20:19: 20:42 tx:&std::sync::mpsc::Sender<()>]`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
index 3018a7b6d03ee..516a15b55bf1d 100644
--- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
@@ -1,3 +1,5 @@
+// ignore-musl
+// ^ due to stderr output differences
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
index 4752ef3713d42..708ebca9fb153 100644
--- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-enum-struct-variant.rs:9:6
+  --> $DIR/derives-span-Hash-enum-struct-variant.rs:11:6
    |
 LL |      x: Error
    |      ^^^^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-enum.rs b/src/test/ui/derives/derives-span-Hash-enum.rs
index bb656e5c2fe3c..ba12deaf98137 100644
--- a/src/test/ui/derives/derives-span-Hash-enum.rs
+++ b/src/test/ui/derives/derives-span-Hash-enum.rs
@@ -1,3 +1,5 @@
+// ignore-musl
+// ^ due to stderr output differences
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-enum.stderr b/src/test/ui/derives/derives-span-Hash-enum.stderr
index efaa679c410be..dc171cbe5dd13 100644
--- a/src/test/ui/derives/derives-span-Hash-enum.stderr
+++ b/src/test/ui/derives/derives-span-Hash-enum.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-enum.rs:9:6
+  --> $DIR/derives-span-Hash-enum.rs:11:6
    |
 LL |      Error
    |      ^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-struct.rs b/src/test/ui/derives/derives-span-Hash-struct.rs
index fa5e2af6be870..b9e7e04f4cfed 100644
--- a/src/test/ui/derives/derives-span-Hash-struct.rs
+++ b/src/test/ui/derives/derives-span-Hash-struct.rs
@@ -1,3 +1,5 @@
+// ignore-musl
+// ^ due to stderr output differences
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-struct.stderr b/src/test/ui/derives/derives-span-Hash-struct.stderr
index a92103032ee1f..429449b82bf64 100644
--- a/src/test/ui/derives/derives-span-Hash-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-struct.rs:8:5
+  --> $DIR/derives-span-Hash-struct.rs:10:5
    |
 LL |     x: Error
    |     ^^^^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.rs b/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
index 3822bce1466ea..bb271e60745a5 100644
--- a/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
@@ -1,3 +1,5 @@
+// ignore-musl
+// ^ due to stderr output differences
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
 
diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
index 4af96ada66c28..a6c4c479b24d7 100644
--- a/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
+++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Error: std::hash::Hash` is not satisfied
-  --> $DIR/derives-span-Hash-tuple-struct.rs:8:5
+  --> $DIR/derives-span-Hash-tuple-struct.rs:10:5
    |
 LL |     Error
    |     ^^^^^ the trait `std::hash::Hash` is not implemented for `Error`
diff --git a/src/test/ui/interior-mutability/interior-mutability.rs b/src/test/ui/interior-mutability/interior-mutability.rs
index ddc882cccf390..d75c149a7b682 100644
--- a/src/test/ui/interior-mutability/interior-mutability.rs
+++ b/src/test/ui/interior-mutability/interior-mutability.rs
@@ -1,3 +1,5 @@
+// ignore-musl
+// ^ due to stderr output differences
 use std::cell::Cell;
 use std::panic::catch_unwind;
 fn main() {
diff --git a/src/test/ui/interior-mutability/interior-mutability.stderr b/src/test/ui/interior-mutability/interior-mutability.stderr
index 1a726be4aa6f4..b76fce2880552 100644
--- a/src/test/ui/interior-mutability/interior-mutability.stderr
+++ b/src/test/ui/interior-mutability/interior-mutability.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the type `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
-  --> $DIR/interior-mutability.rs:5:5
+  --> $DIR/interior-mutability.rs:7:5
    |
 LL |     catch_unwind(|| { x.set(23); });
    |     ^^^^^^^^^^^^ `std::cell::UnsafeCell<i32>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
@@ -12,7 +12,7 @@ LL | pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
    = help: within `std::cell::Cell<i32>`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<i32>`
    = note: required because it appears within the type `std::cell::Cell<i32>`
    = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&std::cell::Cell<i32>`
-   = note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:5:18: 5:35 x:&std::cell::Cell<i32>]`
+   = note: required because it appears within the type `[closure@$DIR/interior-mutability.rs:7:18: 7:35 x:&std::cell::Cell<i32>]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-21160.rs b/src/test/ui/issues/issue-21160.rs
index 46733566cf383..1e441a173e4be 100644
--- a/src/test/ui/issues/issue-21160.rs
+++ b/src/test/ui/issues/issue-21160.rs
@@ -1,3 +1,5 @@
+// ignore-musl
+// ^ due to stderr output differences
 struct Bar;
 
 impl Bar {
diff --git a/src/test/ui/issues/issue-21160.stderr b/src/test/ui/issues/issue-21160.stderr
index 577baa97d8f9d..9f88fa2fadd4c 100644
--- a/src/test/ui/issues/issue-21160.stderr
+++ b/src/test/ui/issues/issue-21160.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Bar: std::hash::Hash` is not satisfied
-  --> $DIR/issue-21160.rs:8:12
+  --> $DIR/issue-21160.rs:10:12
    |
 LL | struct Foo(Bar);
    |            ^^^ the trait `std::hash::Hash` is not implemented for `Bar`
diff --git a/src/test/ui/no-send-res-ports.rs b/src/test/ui/no-send-res-ports.rs
index e10f447365ea6..2c8cf0cf4e61c 100644
--- a/src/test/ui/no-send-res-ports.rs
+++ b/src/test/ui/no-send-res-ports.rs
@@ -1,3 +1,5 @@
+// ignore-musl
+// ^ due to stderr output differences
 use std::thread;
 use std::rc::Rc;
 
diff --git a/src/test/ui/no-send-res-ports.stderr b/src/test/ui/no-send-res-ports.stderr
index 20f88badbefd4..dc186f7c85e94 100644
--- a/src/test/ui/no-send-res-ports.stderr
+++ b/src/test/ui/no-send-res-ports.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely
-  --> $DIR/no-send-res-ports.rs:25:5
+  --> $DIR/no-send-res-ports.rs:27:5
    |
 LL |     thread::spawn(move|| {
    |     ^^^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely
@@ -9,10 +9,10 @@ LL |     thread::spawn(move|| {
 LL |     F: FnOnce() -> T, F: Send + 'static, T: Send + 'static
    |                          ---- required by this bound in `std::thread::spawn`
    |
-   = help: within `[closure@$DIR/no-send-res-ports.rs:25:19: 29:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
+   = help: within `[closure@$DIR/no-send-res-ports.rs:27:19: 31:6 x:main::Foo]`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>`
    = note: required because it appears within the type `Port<()>`
    = note: required because it appears within the type `main::Foo`
-   = note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:25:19: 29:6 x:main::Foo]`
+   = note: required because it appears within the type `[closure@$DIR/no-send-res-ports.rs:27:19: 31:6 x:main::Foo]`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
index 193a523aed24b..d5105b40d36f5 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
@@ -1,4 +1,6 @@
 // compile-flags: --test
+// ignore-musl
+// ^ due to stderr output differences
 
 use std::num::ParseFloatError;
 
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
index 983063d19711f..6aa95c308f248 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `main` has invalid return type `std::result::Result<f32, std::num::ParseFloatError>`
-  --> $DIR/termination-trait-test-wrong-type.rs:6:1
+  --> $DIR/termination-trait-test-wrong-type.rs:8:1
    |
 LL | / fn can_parse_zero_as_f32() -> Result<f32, ParseFloatError> {
 LL | |     "0".parse()
diff --git a/src/test/ui/traits/trait-suggest-where-clause.rs b/src/test/ui/traits/trait-suggest-where-clause.rs
index 8405e5ff62e8e..822f0c580e651 100644
--- a/src/test/ui/traits/trait-suggest-where-clause.rs
+++ b/src/test/ui/traits/trait-suggest-where-clause.rs
@@ -1,3 +1,5 @@
+// ignore-musl
+// ^ due to stderr output differences
 use std::mem;
 
 struct Misc<T:?Sized>(T);
diff --git a/src/test/ui/traits/trait-suggest-where-clause.stderr b/src/test/ui/traits/trait-suggest-where-clause.stderr
index 0aa5f429334ef..a59306d3cb41f 100644
--- a/src/test/ui/traits/trait-suggest-where-clause.stderr
+++ b/src/test/ui/traits/trait-suggest-where-clause.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the size for values of type `U` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:7:5
+  --> $DIR/trait-suggest-where-clause.rs:9:5
    |
 LL |     mem::size_of::<U>();
    |     ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -14,7 +14,7 @@ LL | pub const fn size_of<T>() -> usize {
    = help: consider adding a `where U: std::marker::Sized` bound
 
 error[E0277]: the size for values of type `U` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:10:5
+  --> $DIR/trait-suggest-where-clause.rs:12:5
    |
 LL |     mem::size_of::<Misc<U>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -30,7 +30,7 @@ LL | pub const fn size_of<T>() -> usize {
    = note: required because it appears within the type `Misc<U>`
 
 error[E0277]: the trait bound `u64: std::convert::From<T>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:15:5
+  --> $DIR/trait-suggest-where-clause.rs:17:5
    |
 LL |     <u64 as From<T>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<T>` is not implemented for `u64`
@@ -39,7 +39,7 @@ LL |     <u64 as From<T>>::from;
    = note: required by `std::convert::From::from`
 
 error[E0277]: the trait bound `u64: std::convert::From<<T as std::iter::Iterator>::Item>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:18:5
+  --> $DIR/trait-suggest-where-clause.rs:20:5
    |
 LL |     <u64 as From<<T as Iterator>::Item>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<<T as std::iter::Iterator>::Item>` is not implemented for `u64`
@@ -48,7 +48,7 @@ LL |     <u64 as From<<T as Iterator>::Item>>::from;
    = note: required by `std::convert::From::from`
 
 error[E0277]: the trait bound `Misc<_>: std::convert::From<T>` is not satisfied
-  --> $DIR/trait-suggest-where-clause.rs:23:5
+  --> $DIR/trait-suggest-where-clause.rs:25:5
    |
 LL |     <Misc<_> as From<T>>::from;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<T>` is not implemented for `Misc<_>`
@@ -56,7 +56,7 @@ LL |     <Misc<_> as From<T>>::from;
    = note: required by `std::convert::From::from`
 
 error[E0277]: the size for values of type `[T]` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:28:5
+  --> $DIR/trait-suggest-where-clause.rs:30:5
    |
 LL |     mem::size_of::<[T]>();
    |     ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -70,7 +70,7 @@ LL | pub const fn size_of<T>() -> usize {
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
 
 error[E0277]: the size for values of type `[&U]` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:31:5
+  --> $DIR/trait-suggest-where-clause.rs:33:5
    |
 LL |     mem::size_of::<[&U]>();
    |     ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time

From 4e0437ee8e51c43b76ff2e1a4ea717f18d279f72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 18 Sep 2019 13:51:36 -0700
Subject: [PATCH 938/943] Fix rebase

---
 src/test/ui/hrtb/due-to-where-clause.stderr | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/src/test/ui/hrtb/due-to-where-clause.stderr b/src/test/ui/hrtb/due-to-where-clause.stderr
index e698584bb716f..9fef1e3354399 100644
--- a/src/test/ui/hrtb/due-to-where-clause.stderr
+++ b/src/test/ui/hrtb/due-to-where-clause.stderr
@@ -2,15 +2,12 @@ error: implementation of `Foo` is not general enough
   --> $DIR/due-to-where-clause.rs:5:5
    |
 LL |     test::<FooS>(&mut 42);
-   |     ^^^^^^^^^^^^ doesn't satisfy where-clause
+   |     ^^^^^^^^^^^^ implementation of `Foo` is not general enough
 ...
 LL | trait Foo<'a> {}
    | ---------------- trait `Foo` defined here
-...
-LL | fn test<'a, F>(data: &'a mut u32) where F: for<'b> Foo<'b> {}
-   | ------------------------------------------------------------- due to a where-clause on `test`...
    |
-   = note: ...`FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`...
+   = note: `FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`...
    = note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1`
 
 error: aborting due to previous error

From 4be51c879e763fefd31f02766ab967d9943f65c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 20 Sep 2019 11:58:20 -0700
Subject: [PATCH 939/943] Point at type param when it's cause of unfulfilled
 obligation

---
 src/librustc_typeck/check/callee.rs           | 12 +--
 src/librustc_typeck/check/expr.rs             |  2 +-
 src/librustc_typeck/check/mod.rs              | 79 ++++++++++++++++---
 .../associated-types-eq-hr.stderr             | 12 +--
 .../extern/extern-types-not-sync-send.stderr  |  8 +-
 .../ui/extern/extern-types-unsized.stderr     |  4 +-
 src/test/ui/hrtb/hrtb-conflate-regions.stderr |  4 +-
 ...b-exists-forall-trait-contravariant.stderr |  4 +-
 .../hrtb-exists-forall-trait-covariant.stderr |  4 +-
 .../hrtb-exists-forall-trait-invariant.stderr |  4 +-
 src/test/ui/hrtb/hrtb-just-for-static.stderr  |  8 +-
 src/test/ui/hrtb/issue-46989.stderr           |  4 +-
 src/test/ui/issues/issue-1920-1.stderr        |  4 +-
 src/test/ui/issues/issue-1920-2.stderr        |  4 +-
 src/test/ui/issues/issue-1920-3.stderr        |  4 +-
 src/test/ui/kindck/kindck-copy.stderr         | 42 +++++-----
 src/test/ui/kindck/kindck-send-unsafe.stderr  |  4 +-
 .../overlap-marker-trait.stderr               |  4 +-
 .../unboxed-closures-vtable-mismatch.stderr   |  2 +-
 src/test/ui/not-sync.stderr                   | 24 +++---
 src/test/ui/overlap-marker-trait.stderr       |  4 +-
 .../trait-alias-cross-crate.stderr            |  8 +-
 .../traits/trait-suggest-where-clause.stderr  |  8 +-
 src/test/ui/try-operator-on-main.stderr       |  4 +-
 ...efault-trait-impl-constituent-types.stderr |  4 +-
 ...ck-default-trait-impl-negation-send.stderr |  4 +-
 ...ck-default-trait-impl-negation-sync.stderr |  4 +-
 .../typeck-default-trait-impl-negation.stderr |  8 +-
 ...ypeck-default-trait-impl-send-param.stderr |  4 +-
 .../ui/unsized/unsized-bare-typaram.stderr    |  4 +-
 30 files changed, 176 insertions(+), 109 deletions(-)

diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs
index e6999f9e3ac8a..710d847384e6c 100644
--- a/src/librustc_typeck/check/callee.rs
+++ b/src/librustc_typeck/check/callee.rs
@@ -263,7 +263,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn confirm_builtin_call(
         &self,
-        call_expr: &hir::Expr,
+        call_expr: &'tcx hir::Expr,
         callee_ty: Ty<'tcx>,
         arg_exprs: &'tcx [hir::Expr],
         expected: Expectation<'tcx>,
@@ -425,7 +425,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         );
         self.check_argument_types(
             call_expr.span,
-            call_expr.span,
+            call_expr,
             inputs,
             &expected_arg_tys[..],
             arg_exprs,
@@ -439,7 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn confirm_deferred_closure_call(
         &self,
-        call_expr: &hir::Expr,
+        call_expr: &'tcx hir::Expr,
         arg_exprs: &'tcx [hir::Expr],
         expected: Expectation<'tcx>,
         fn_sig: ty::FnSig<'tcx>,
@@ -458,7 +458,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         self.check_argument_types(
             call_expr.span,
-            call_expr.span,
+            call_expr,
             fn_sig.inputs(),
             &expected_arg_tys,
             arg_exprs,
@@ -472,14 +472,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     fn confirm_overloaded_call(
         &self,
-        call_expr: &hir::Expr,
+        call_expr: &'tcx hir::Expr,
         arg_exprs: &'tcx [hir::Expr],
         expected: Expectation<'tcx>,
         method_callee: MethodCallee<'tcx>,
     ) -> Ty<'tcx> {
         let output_type = self.check_method_argument_types(
             call_expr.span,
-            call_expr.span,
+            call_expr,
             Ok(method_callee),
             arg_exprs,
             TupleArgumentsFlag::TupleArguments,
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 1ae50b8cb2883..e34a2c6f61c24 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -796,7 +796,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Call the generic checker.
         self.check_method_argument_types(
             span,
-            expr.span,
+            expr,
             method,
             &args[1..],
             DontTupleArguments,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index edea91c717ef7..5fe554de2586f 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3070,12 +3070,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_method_argument_types(
         &self,
         sp: Span,
-        expr_sp: Span,
+        expr: &'tcx hir::Expr,
         method: Result<MethodCallee<'tcx>, ()>,
         args_no_rcvr: &'tcx [hir::Expr],
         tuple_arguments: TupleArgumentsFlag,
         expected: Expectation<'tcx>,
     ) -> Ty<'tcx> {
+
         let has_error = match method {
             Ok(method) => {
                 method.substs.references_error() || method.sig.references_error()
@@ -3090,8 +3091,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
             };
 
-            self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
-                                      false, tuple_arguments, None);
+            self.check_argument_types(
+                sp,
+                expr,
+                &err_inputs[..],
+                &[],
+                args_no_rcvr,
+                false,
+                tuple_arguments,
+                None,
+            );
             return self.tcx.types.err;
         }
 
@@ -3103,9 +3112,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             method.sig.output(),
             &method.sig.inputs()[1..]
         );
-        self.check_argument_types(sp, expr_sp, &method.sig.inputs()[1..], &expected_arg_tys[..],
-                                  args_no_rcvr, method.sig.c_variadic, tuple_arguments,
-                                  self.tcx.hir().span_if_local(method.def_id));
+        self.check_argument_types(
+            sp,
+            expr,
+            &method.sig.inputs()[1..],
+            &expected_arg_tys[..],
+            args_no_rcvr,
+            method.sig.c_variadic,
+            tuple_arguments,
+            self.tcx.hir().span_if_local(method.def_id),
+        );
         method.sig.output()
     }
 
@@ -3182,7 +3198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn check_argument_types(
         &self,
         sp: Span,
-        expr_sp: Span,
+        expr: &'tcx hir::Expr,
         fn_inputs: &[Ty<'tcx>],
         expected_arg_tys: &[Ty<'tcx>],
         args: &'tcx [hir::Expr],
@@ -3191,7 +3207,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         def_span: Option<Span>,
     ) {
         let tcx = self.tcx;
-
         // Grab the argument types, supplying fresh type variables
         // if the wrong number of arguments were supplied
         let supplied_arg_count = if tuple_arguments == DontTupleArguments {
@@ -3225,7 +3240,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 err.span_label(def_s, "defined here");
             }
             if sugg_unit {
-                let sugg_span = tcx.sess.source_map().end_point(expr_sp);
+                let sugg_span = tcx.sess.source_map().end_point(expr.span);
                 // remove closing `)` from the span
                 let sugg_span = sugg_span.shrink_to_lo();
                 err.span_suggestion(
@@ -3319,6 +3334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // the call. This helps coercions.
             if check_closures {
                 self.select_obligations_where_possible(false, |errors| {
+                    self.point_at_type_arg_instead_of_call_if_possible(errors, expr);
                     self.point_at_arg_instead_of_call_if_possible(
                         errors,
                         &final_arg_types[..],
@@ -3456,6 +3472,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    /// Given a vec of evaluated `FullfillmentError`s and an `fn` call expression, we walk the
+    /// `PathSegment`s and resolve their type parameters to see if any of the `FullfillmentError`s
+    /// were caused by them. If they were, we point at the corresponding type argument's span
+    /// instead of the `fn` call path span.
+    fn point_at_type_arg_instead_of_call_if_possible(
+        &self,
+        errors: &mut Vec<traits::FulfillmentError<'_>>,
+        call_expr: &'tcx hir::Expr,
+    ) {
+        if let hir::ExprKind::Call(path, _args) = &call_expr.node {
+            if let hir::ExprKind::Path(qpath) = &path.node {
+                if let hir::QPath::Resolved(_self, path) = &qpath {
+                    for error in errors {
+                        if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
+                            // If any of the type arguments in this path segment caused the
+                            // `FullfillmentError`, point at its span (#61860).
+                            for segment in &path.segments {
+                                if let Some(args) = &segment.args {
+                                    for arg in &args.args {
+                                        if let hir::GenericArg::Type(hir_ty) = &arg {
+                                            if let hir::TyKind::Path(
+                                                hir::QPath::TypeRelative(..),
+                                            ) = &hir_ty.node {
+                                                // Avoid ICE with associated types. As this is best
+                                                // effort only, it's ok to ignore the case. It
+                                                // would trigger in `is_send::<T::AssocType>();`
+                                                // from `typeck-default-trait-impl-assoc-type.rs`.
+                                            } else {
+                                                let ty = AstConv::ast_ty_to_ty(self, hir_ty);
+                                                let ty = self.resolve_vars_if_possible(&ty);
+                                                if ty == predicate.skip_binder().self_ty() {
+                                                    error.obligation.cause.span = hir_ty.span;
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     // AST fragment checking
     fn check_lit(&self,
                  lit: &hir::Lit,
diff --git a/src/test/ui/associated-types/associated-types-eq-hr.stderr b/src/test/ui/associated-types/associated-types-eq-hr.stderr
index f560aefd637c0..45b6cc9ba5f98 100644
--- a/src/test/ui/associated-types/associated-types-eq-hr.stderr
+++ b/src/test/ui/associated-types/associated-types-eq-hr.stderr
@@ -27,7 +27,7 @@ LL |     bar::<IntStruct>();
               found type `&usize`
 
 error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
-  --> $DIR/associated-types-eq-hr.rs:91:5
+  --> $DIR/associated-types-eq-hr.rs:91:17
    |
 LL | fn tuple_one<T>()
    |    ---------
@@ -35,7 +35,7 @@ LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
    |               ---------------------------------------------------------- required by this bound in `tuple_one`
 ...
 LL |     tuple_one::<Tuple>();
-   |     ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
+   |                 ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
    |
    = help: the following implementations were found:
              <Tuple as TheTrait<(&'a isize, &'a isize)>>
@@ -52,7 +52,7 @@ LL |     tuple_one::<Tuple>();
    |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
 
 error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
-  --> $DIR/associated-types-eq-hr.rs:97:5
+  --> $DIR/associated-types-eq-hr.rs:97:17
    |
 LL | fn tuple_two<T>()
    |    ---------
@@ -60,7 +60,7 @@ LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
    |               ---------------------------------------------------------- required by this bound in `tuple_two`
 ...
 LL |     tuple_two::<Tuple>();
-   |     ^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
+   |                 ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
    |
    = help: the following implementations were found:
              <Tuple as TheTrait<(&'a isize, &'a isize)>>
@@ -77,7 +77,7 @@ LL |     tuple_two::<Tuple>();
    |     ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
 
 error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
-  --> $DIR/associated-types-eq-hr.rs:107:5
+  --> $DIR/associated-types-eq-hr.rs:107:18
    |
 LL | fn tuple_four<T>()
    |    ----------
@@ -85,7 +85,7 @@ LL |     where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)>
    |               ------------------------------------------- required by this bound in `tuple_four`
 ...
 LL |     tuple_four::<Tuple>();
-   |     ^^^^^^^^^^^^^^^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
+   |                  ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
    |
    = help: the following implementations were found:
              <Tuple as TheTrait<(&'a isize, &'a isize)>>
diff --git a/src/test/ui/extern/extern-types-not-sync-send.stderr b/src/test/ui/extern/extern-types-not-sync-send.stderr
index 803bd9dbac62c..c395f3875ea0e 100644
--- a/src/test/ui/extern/extern-types-not-sync-send.stderr
+++ b/src/test/ui/extern/extern-types-not-sync-send.stderr
@@ -1,22 +1,22 @@
 error[E0277]: `A` cannot be shared between threads safely
-  --> $DIR/extern-types-not-sync-send.rs:13:5
+  --> $DIR/extern-types-not-sync-send.rs:13:19
    |
 LL | fn assert_sync<T: ?Sized + Sync>() { }
    |    -----------             ---- required by this bound in `assert_sync`
 ...
 LL |     assert_sync::<A>();
-   |     ^^^^^^^^^^^^^^^^ `A` cannot be shared between threads safely
+   |                   ^ `A` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `A`
 
 error[E0277]: `A` cannot be sent between threads safely
-  --> $DIR/extern-types-not-sync-send.rs:16:5
+  --> $DIR/extern-types-not-sync-send.rs:16:19
    |
 LL | fn assert_send<T: ?Sized + Send>() { }
    |    -----------             ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<A>();
-   |     ^^^^^^^^^^^^^^^^ `A` cannot be sent between threads safely
+   |                   ^ `A` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `A`
 
diff --git a/src/test/ui/extern/extern-types-unsized.stderr b/src/test/ui/extern/extern-types-unsized.stderr
index 1f69a4e154eb3..0417186eed346 100644
--- a/src/test/ui/extern/extern-types-unsized.stderr
+++ b/src/test/ui/extern/extern-types-unsized.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the size for values of type `A` cannot be known at compilation time
-  --> $DIR/extern-types-unsized.rs:22:5
+  --> $DIR/extern-types-unsized.rs:22:20
    |
 LL | fn assert_sized<T>() { }
    |    ------------ - required by this bound in `assert_sized`
 ...
 LL |     assert_sized::<A>();
-   |     ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |                    ^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `A`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
diff --git a/src/test/ui/hrtb/hrtb-conflate-regions.stderr b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
index 205fa2b5bc81f..9822b48f4f48f 100644
--- a/src/test/ui/hrtb/hrtb-conflate-regions.stderr
+++ b/src/test/ui/hrtb/hrtb-conflate-regions.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `for<'a, 'b> SomeStruct: Foo<(&'a isize, &'b isize)>` is not satisfied
-  --> $DIR/hrtb-conflate-regions.rs:27:10
+  --> $DIR/hrtb-conflate-regions.rs:27:22
    |
 LL | fn want_foo2<T>()
    |    ---------
@@ -7,7 +7,7 @@ LL |     where T : for<'a,'b> Foo<(&'a isize, &'b isize)>
    |               -------------------------------------- required by this bound in `want_foo2`
 ...
 LL | fn b() { want_foo2::<SomeStruct>(); }
-   |          ^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct`
+   |                      ^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct`
    |
    = help: the following implementations were found:
              <SomeStruct as Foo<(&'a isize, &'a isize)>>
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
index ceba22234be6a..969d9eda73519 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-contravariant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `(): Trait<for<'b> fn(&'b u32)>` is not satisfied
-  --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
+  --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:11
    |
 LL | fn foo<T>()
    |    ---
@@ -8,7 +8,7 @@ LL |     T: Trait<for<'b> fn(&'b u32)>,
    |        -------------------------- required by this bound in `foo`
 ...
 LL |     foo::<()>();
-   |     ^^^^^^^^^ the trait `Trait<for<'b> fn(&'b u32)>` is not implemented for `()`
+   |           ^^ the trait `Trait<for<'b> fn(&'b u32)>` is not implemented for `()`
    |
    = help: the following implementations were found:
              <() as Trait<fn(&'a u32)>>
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr
index a1cb3b230fea2..dddc2bcce49e5 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-covariant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `(): Trait<for<'b> fn(fn(&'b u32))>` is not satisfied
-  --> $DIR/hrtb-exists-forall-trait-covariant.rs:36:5
+  --> $DIR/hrtb-exists-forall-trait-covariant.rs:36:11
    |
 LL | fn foo<T>()
    |    ---
@@ -8,7 +8,7 @@ LL |     T: Trait<for<'b> fn(fn(&'b u32))>,
    |        ------------------------------ required by this bound in `foo`
 ...
 LL |     foo::<()>();
-   |     ^^^^^^^^^ the trait `Trait<for<'b> fn(fn(&'b u32))>` is not implemented for `()`
+   |           ^^ the trait `Trait<for<'b> fn(fn(&'b u32))>` is not implemented for `()`
    |
    = help: the following implementations were found:
              <() as Trait<fn(fn(&'a u32))>>
diff --git a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
index 093bee375bb0b..23ef75944d317 100644
--- a/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
+++ b/src/test/ui/hrtb/hrtb-exists-forall-trait-invariant.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `(): Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not satisfied
-  --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5
+  --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:11
    |
 LL | fn foo<T>()
    |    ---
@@ -8,7 +8,7 @@ LL |     T: Trait<for<'b> fn(Cell<&'b u32>)>,
    |        -------------------------------- required by this bound in `foo`
 ...
 LL |     foo::<()>();
-   |     ^^^^^^^^^ the trait `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not implemented for `()`
+   |           ^^ the trait `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not implemented for `()`
    |
    = help: the following implementations were found:
              <() as Trait<fn(std::cell::Cell<&'a u32>)>>
diff --git a/src/test/ui/hrtb/hrtb-just-for-static.stderr b/src/test/ui/hrtb/hrtb-just-for-static.stderr
index f4cf3555868f2..6ec0beefd60e3 100644
--- a/src/test/ui/hrtb/hrtb-just-for-static.stderr
+++ b/src/test/ui/hrtb/hrtb-just-for-static.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `for<'a> StaticInt: Foo<&'a isize>` is not satisfied
-  --> $DIR/hrtb-just-for-static.rs:24:5
+  --> $DIR/hrtb-just-for-static.rs:24:17
    |
 LL | fn want_hrtb<T>()
    |    ---------
@@ -7,13 +7,13 @@ LL |     where T : for<'a> Foo<&'a isize>
    |               ---------------------- required by this bound in `want_hrtb`
 ...
 LL |     want_hrtb::<StaticInt>()
-   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt`
+   |                 ^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt`
    |
    = help: the following implementations were found:
              <StaticInt as Foo<&'static isize>>
 
 error[E0277]: the trait bound `for<'a> &'a u32: Foo<&'a isize>` is not satisfied
-  --> $DIR/hrtb-just-for-static.rs:30:5
+  --> $DIR/hrtb-just-for-static.rs:30:17
    |
 LL | fn want_hrtb<T>()
    |    ---------
@@ -21,7 +21,7 @@ LL |     where T : for<'a> Foo<&'a isize>
    |               ---------------------- required by this bound in `want_hrtb`
 ...
 LL |     want_hrtb::<&'a u32>()
-   |     ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `&'a u32`
+   |                 ^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `&'a u32`
    |
    = help: the following implementations were found:
              <&'a u32 as Foo<&'a isize>>
diff --git a/src/test/ui/hrtb/issue-46989.stderr b/src/test/ui/hrtb/issue-46989.stderr
index 4da3e3ddb7ebd..c818041e59632 100644
--- a/src/test/ui/hrtb/issue-46989.stderr
+++ b/src/test/ui/hrtb/issue-46989.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied
-  --> $DIR/issue-46989.rs:40:5
+  --> $DIR/issue-46989.rs:40:18
    |
 LL | fn assert_foo<T: Foo>() {}
    |    ----------    --- required by this bound in `assert_foo`
 ...
 LL |     assert_foo::<fn(&i32)>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `for<'r> fn(&'r i32)`
+   |                  ^^^^^^^^ the trait `Foo` is not implemented for `for<'r> fn(&'r i32)`
    |
    = help: the following implementations were found:
              <fn(A) as Foo>
diff --git a/src/test/ui/issues/issue-1920-1.stderr b/src/test/ui/issues/issue-1920-1.stderr
index 56f70aa296cb9..089968ede7d0f 100644
--- a/src/test/ui/issues/issue-1920-1.stderr
+++ b/src/test/ui/issues/issue-1920-1.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `foo::issue_1920::S: std::clone::Clone` is not satisfied
-  --> $DIR/issue-1920-1.rs:12:5
+  --> $DIR/issue-1920-1.rs:12:20
    |
 LL | fn assert_clone<T>() where T : Clone { }
    |    ------------                ----- required by this bound in `assert_clone`
 ...
 LL |     assert_clone::<foo::issue_1920::S>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `foo::issue_1920::S`
+   |                    ^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `foo::issue_1920::S`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-1920-2.stderr b/src/test/ui/issues/issue-1920-2.stderr
index 37027b0579265..eaf34e076c088 100644
--- a/src/test/ui/issues/issue-1920-2.stderr
+++ b/src/test/ui/issues/issue-1920-2.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `bar::S: std::clone::Clone` is not satisfied
-  --> $DIR/issue-1920-2.rs:10:5
+  --> $DIR/issue-1920-2.rs:10:20
    |
 LL | fn assert_clone<T>() where T : Clone { }
    |    ------------                ----- required by this bound in `assert_clone`
 ...
 LL |     assert_clone::<bar::S>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `bar::S`
+   |                    ^^^^^^ the trait `std::clone::Clone` is not implemented for `bar::S`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-1920-3.stderr b/src/test/ui/issues/issue-1920-3.stderr
index dbcb3aee11703..0550f5feba5be 100644
--- a/src/test/ui/issues/issue-1920-3.stderr
+++ b/src/test/ui/issues/issue-1920-3.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `issue_1920::S: std::clone::Clone` is not satisfied
-  --> $DIR/issue-1920-3.rs:14:5
+  --> $DIR/issue-1920-3.rs:14:20
    |
 LL | fn assert_clone<T>() where T : Clone { }
    |    ------------                ----- required by this bound in `assert_clone`
 ...
 LL |     assert_clone::<foo::issue_1920::S>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `issue_1920::S`
+   |                    ^^^^^^^^^^^^^^^^^^ the trait `std::clone::Clone` is not implemented for `issue_1920::S`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/kindck/kindck-copy.stderr b/src/test/ui/kindck/kindck-copy.stderr
index 53b4448a7574f..fee9e2802a6c3 100644
--- a/src/test/ui/kindck/kindck-copy.stderr
+++ b/src/test/ui/kindck/kindck-copy.stderr
@@ -1,62 +1,68 @@
 error[E0277]: the trait bound `&'static mut isize: std::marker::Copy` is not satisfied
-  --> $DIR/kindck-copy.rs:27:5
+  --> $DIR/kindck-copy.rs:27:19
    |
 LL | fn assert_copy<T:Copy>() { }
    |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<&'static mut isize>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'static mut isize`
+   |                   -^^^^^^^^^^^^^^^^^
+   |                   |
+   |                   the trait `std::marker::Copy` is not implemented for `&'static mut isize`
+   |                   help: consider removing 1 leading `&`-references
    |
    = help: the following implementations were found:
              <isize as std::marker::Copy>
 
 error[E0277]: the trait bound `&'a mut isize: std::marker::Copy` is not satisfied
-  --> $DIR/kindck-copy.rs:28:5
+  --> $DIR/kindck-copy.rs:28:19
    |
 LL | fn assert_copy<T:Copy>() { }
    |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<&'a mut isize>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'a mut isize`
+   |                   -^^^^^^^^^^^^
+   |                   |
+   |                   the trait `std::marker::Copy` is not implemented for `&'a mut isize`
+   |                   help: consider removing 1 leading `&`-references
    |
    = help: the following implementations were found:
              <isize as std::marker::Copy>
 
 error[E0277]: the trait bound `std::boxed::Box<isize>: std::marker::Copy` is not satisfied
-  --> $DIR/kindck-copy.rs:31:5
+  --> $DIR/kindck-copy.rs:31:19
    |
 LL | fn assert_copy<T:Copy>() { }
    |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<Box<isize>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<isize>`
+   |                   ^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<isize>`
 
 error[E0277]: the trait bound `std::string::String: std::marker::Copy` is not satisfied
-  --> $DIR/kindck-copy.rs:32:5
+  --> $DIR/kindck-copy.rs:32:19
    |
 LL | fn assert_copy<T:Copy>() { }
    |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<String>();
-   |     ^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
+   |                   ^^^^^^ the trait `std::marker::Copy` is not implemented for `std::string::String`
 
 error[E0277]: the trait bound `std::vec::Vec<isize>: std::marker::Copy` is not satisfied
-  --> $DIR/kindck-copy.rs:33:5
+  --> $DIR/kindck-copy.rs:33:19
    |
 LL | fn assert_copy<T:Copy>() { }
    |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<Vec<isize> >();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::vec::Vec<isize>`
+   |                   ^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::vec::Vec<isize>`
 
 error[E0277]: the trait bound `std::boxed::Box<&'a mut isize>: std::marker::Copy` is not satisfied
-  --> $DIR/kindck-copy.rs:34:5
+  --> $DIR/kindck-copy.rs:34:19
    |
 LL | fn assert_copy<T:Copy>() { }
    |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<Box<&'a mut isize>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<&'a mut isize>`
+   |                   ^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<&'a mut isize>`
 
 error[E0277]: the trait bound `std::boxed::Box<dyn Dummy>: std::marker::Copy` is not satisfied
   --> $DIR/kindck-copy.rs:42:5
@@ -77,31 +83,31 @@ LL |     assert_copy::<Box<dyn Dummy + Send>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<dyn Dummy + std::marker::Send>`
 
 error[E0277]: the trait bound `&'a mut (dyn Dummy + std::marker::Send + 'a): std::marker::Copy` is not satisfied
-  --> $DIR/kindck-copy.rs:46:5
+  --> $DIR/kindck-copy.rs:46:19
    |
 LL | fn assert_copy<T:Copy>() { }
    |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<&'a mut (dyn Dummy + Send)>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'a mut (dyn Dummy + std::marker::Send + 'a)`
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'a mut (dyn Dummy + std::marker::Send + 'a)`
 
 error[E0277]: the trait bound `MyNoncopyStruct: std::marker::Copy` is not satisfied
-  --> $DIR/kindck-copy.rs:64:5
+  --> $DIR/kindck-copy.rs:64:19
    |
 LL | fn assert_copy<T:Copy>() { }
    |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<MyNoncopyStruct>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `MyNoncopyStruct`
+   |                   ^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `MyNoncopyStruct`
 
 error[E0277]: the trait bound `std::rc::Rc<isize>: std::marker::Copy` is not satisfied
-  --> $DIR/kindck-copy.rs:67:5
+  --> $DIR/kindck-copy.rs:67:19
    |
 LL | fn assert_copy<T:Copy>() { }
    |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<Rc<isize>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::rc::Rc<isize>`
+   |                   ^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `std::rc::Rc<isize>`
 
 error: aborting due to 11 previous errors
 
diff --git a/src/test/ui/kindck/kindck-send-unsafe.stderr b/src/test/ui/kindck/kindck-send-unsafe.stderr
index a46705ab1755d..05ed51d0f1175 100644
--- a/src/test/ui/kindck/kindck-send-unsafe.stderr
+++ b/src/test/ui/kindck/kindck-send-unsafe.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `*mut &'a isize` cannot be sent between threads safely
-  --> $DIR/kindck-send-unsafe.rs:6:5
+  --> $DIR/kindck-send-unsafe.rs:6:19
    |
 LL | fn assert_send<T:Send>() { }
    |    -----------   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<*mut &'a isize>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely
+   |                   ^^^^^^^^^^^^^^ `*mut &'a isize` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `*mut &'a isize`
 
diff --git a/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr b/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr
index be5e649ef8340..4508870746bcb 100644
--- a/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr
+++ b/src/test/ui/marker_trait_attr/overlap-marker-trait.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `NotDebugOrDisplay: Marker` is not satisfied
-  --> $DIR/overlap-marker-trait.rs:27:5
+  --> $DIR/overlap-marker-trait.rs:27:17
    |
 LL | fn is_marker<T: Marker>() { }
    |    ---------    ------ required by this bound in `is_marker`
 ...
 LL |     is_marker::<NotDebugOrDisplay>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Marker` is not implemented for `NotDebugOrDisplay`
+   |                 ^^^^^^^^^^^^^^^^^ the trait `Marker` is not implemented for `NotDebugOrDisplay`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
index 6c249f6275181..2daf4781c7e6f 100644
--- a/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
+++ b/src/test/ui/mismatched_types/unboxed-closures-vtable-mismatch.stderr
@@ -1,5 +1,5 @@
 error[E0631]: type mismatch in closure arguments
-  --> $DIR/unboxed-closures-vtable-mismatch.rs:16:13
+  --> $DIR/unboxed-closures-vtable-mismatch.rs:16:24
    |
 LL | fn call_it<F:FnMut(isize,isize)->isize>(y: isize, mut f: F) -> isize {
    |    -------   ------------------------- required by this bound in `call_it`
diff --git a/src/test/ui/not-sync.stderr b/src/test/ui/not-sync.stderr
index 8871abedd00dd..8bb4ce2e2c773 100644
--- a/src/test/ui/not-sync.stderr
+++ b/src/test/ui/not-sync.stderr
@@ -1,66 +1,66 @@
 error[E0277]: `std::cell::Cell<i32>` cannot be shared between threads safely
-  --> $DIR/not-sync.rs:8:5
+  --> $DIR/not-sync.rs:8:12
    |
 LL | fn test<T: Sync>() {}
    |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<Cell<i32>>();
-   |     ^^^^^^^^^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
+   |            ^^^^^^^^^ `std::cell::Cell<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
 
 error[E0277]: `std::cell::RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/not-sync.rs:10:5
+  --> $DIR/not-sync.rs:10:12
    |
 LL | fn test<T: Sync>() {}
    |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<RefCell<i32>>();
-   |     ^^^^^^^^^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely
+   |            ^^^^^^^^^^^^ `std::cell::RefCell<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<i32>`
 
 error[E0277]: `std::rc::Rc<i32>` cannot be shared between threads safely
-  --> $DIR/not-sync.rs:13:5
+  --> $DIR/not-sync.rs:13:12
    |
 LL | fn test<T: Sync>() {}
    |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<Rc<i32>>();
-   |     ^^^^^^^^^^^^^^^ `std::rc::Rc<i32>` cannot be shared between threads safely
+   |            ^^^^^^^ `std::rc::Rc<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::rc::Rc<i32>`
 
 error[E0277]: `std::rc::Weak<i32>` cannot be shared between threads safely
-  --> $DIR/not-sync.rs:15:5
+  --> $DIR/not-sync.rs:15:12
    |
 LL | fn test<T: Sync>() {}
    |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<Weak<i32>>();
-   |     ^^^^^^^^^^^^^^^^^ `std::rc::Weak<i32>` cannot be shared between threads safely
+   |            ^^^^^^^^^ `std::rc::Weak<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::rc::Weak<i32>`
 
 error[E0277]: `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
-  --> $DIR/not-sync.rs:18:5
+  --> $DIR/not-sync.rs:18:12
    |
 LL | fn test<T: Sync>() {}
    |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<Receiver<i32>>();
-   |     ^^^^^^^^^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
+   |            ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<i32>`
 
 error[E0277]: `std::sync::mpsc::Sender<i32>` cannot be shared between threads safely
-  --> $DIR/not-sync.rs:20:5
+  --> $DIR/not-sync.rs:20:12
    |
 LL | fn test<T: Sync>() {}
    |    ----    ---- required by this bound in `test`
 ...
 LL |     test::<Sender<i32>>();
-   |     ^^^^^^^^^^^^^^^^^^^ `std::sync::mpsc::Sender<i32>` cannot be shared between threads safely
+   |            ^^^^^^^^^^^ `std::sync::mpsc::Sender<i32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Sender<i32>`
 
diff --git a/src/test/ui/overlap-marker-trait.stderr b/src/test/ui/overlap-marker-trait.stderr
index daf4e5e69a29b..15ebcd17b0dbc 100644
--- a/src/test/ui/overlap-marker-trait.stderr
+++ b/src/test/ui/overlap-marker-trait.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `NotDebugOrDisplay: Marker` is not satisfied
-  --> $DIR/overlap-marker-trait.rs:30:5
+  --> $DIR/overlap-marker-trait.rs:30:17
    |
 LL | fn is_marker<T: Marker>() { }
    |    ---------    ------ required by this bound in `is_marker`
 ...
 LL |     is_marker::<NotDebugOrDisplay>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Marker` is not implemented for `NotDebugOrDisplay`
+   |                 ^^^^^^^^^^^^^^^^^ the trait `Marker` is not implemented for `NotDebugOrDisplay`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr b/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr
index 10a9506bd0639..cad5c81f5a6ca 100644
--- a/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr
+++ b/src/test/ui/traits/trait-alias/trait-alias-cross-crate.stderr
@@ -1,22 +1,22 @@
 error[E0277]: `std::rc::Rc<u32>` cannot be sent between threads safely
-  --> $DIR/trait-alias-cross-crate.rs:14:5
+  --> $DIR/trait-alias-cross-crate.rs:14:17
    |
 LL | fn use_alias<T: SendSync>() {}
    |    ---------    -------- required by this bound in `use_alias`
 ...
 LL |     use_alias::<Rc<u32>>();
-   |     ^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc<u32>` cannot be sent between threads safely
+   |                 ^^^^^^^ `std::rc::Rc<u32>` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `std::rc::Rc<u32>`
 
 error[E0277]: `std::rc::Rc<u32>` cannot be shared between threads safely
-  --> $DIR/trait-alias-cross-crate.rs:14:5
+  --> $DIR/trait-alias-cross-crate.rs:14:17
    |
 LL | fn use_alias<T: SendSync>() {}
    |    ---------    -------- required by this bound in `use_alias`
 ...
 LL |     use_alias::<Rc<u32>>();
-   |     ^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc<u32>` cannot be shared between threads safely
+   |                 ^^^^^^^ `std::rc::Rc<u32>` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `std::rc::Rc<u32>`
 
diff --git a/src/test/ui/traits/trait-suggest-where-clause.stderr b/src/test/ui/traits/trait-suggest-where-clause.stderr
index a59306d3cb41f..d15edaa9c8146 100644
--- a/src/test/ui/traits/trait-suggest-where-clause.stderr
+++ b/src/test/ui/traits/trait-suggest-where-clause.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the size for values of type `U` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:9:5
+  --> $DIR/trait-suggest-where-clause.rs:9:20
    |
 LL |     mem::size_of::<U>();
-   |     ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |                    ^ doesn't have a size known at compile-time
    | 
   ::: $SRC_DIR/libcore/mem/mod.rs:LL:COL
    |
@@ -56,10 +56,10 @@ LL |     <Misc<_> as From<T>>::from;
    = note: required by `std::convert::From::from`
 
 error[E0277]: the size for values of type `[T]` cannot be known at compilation time
-  --> $DIR/trait-suggest-where-clause.rs:30:5
+  --> $DIR/trait-suggest-where-clause.rs:30:20
    |
 LL |     mem::size_of::<[T]>();
-   |     ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |                    ^^^ doesn't have a size known at compile-time
    | 
   ::: $SRC_DIR/libcore/mem/mod.rs:LL:COL
    |
diff --git a/src/test/ui/try-operator-on-main.stderr b/src/test/ui/try-operator-on-main.stderr
index de75d3e313d9e..d2f1a04837b86 100644
--- a/src/test/ui/try-operator-on-main.stderr
+++ b/src/test/ui/try-operator-on-main.stderr
@@ -17,10 +17,10 @@ LL |     ()?;
    = note: required by `std::ops::Try::into_result`
 
 error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
-  --> $DIR/try-operator-on-main.rs:15:5
+  --> $DIR/try-operator-on-main.rs:15:25
    |
 LL |     try_trait_generic::<()>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Try` is not implemented for `()`
+   |                         ^^ the trait `std::ops::Try` is not implemented for `()`
 ...
 LL | fn try_trait_generic<T: Try>() -> T {
    |    -----------------    --- required by this bound in `try_trait_generic`
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr
index e5d275083dfe0..22a2cb3e0ecb8 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-constituent-types.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `MyS2: MyTrait` is not satisfied
-  --> $DIR/typeck-default-trait-impl-constituent-types.rs:20:5
+  --> $DIR/typeck-default-trait-impl-constituent-types.rs:20:18
    |
 LL | fn is_mytrait<T: MyTrait>() {}
    |    ----------    ------- required by this bound in `is_mytrait`
 ...
 LL |     is_mytrait::<MyS2>();
-   |     ^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `MyS2`
+   |                  ^^^^ the trait `MyTrait` is not implemented for `MyS2`
    |
    = help: the following implementations were found:
              <MyS2 as MyTrait>
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr
index 2f5be975c6dd7..e30d4dfa1b3c4 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-send.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `MyNotSendable` cannot be sent between threads safely
-  --> $DIR/typeck-default-trait-impl-negation-send.rs:19:5
+  --> $DIR/typeck-default-trait-impl-negation-send.rs:19:15
    |
 LL | fn is_send<T: Send>() {}
    |    -------    ---- required by this bound in `is_send`
 ...
 LL |     is_send::<MyNotSendable>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ `MyNotSendable` cannot be sent between threads safely
+   |               ^^^^^^^^^^^^^ `MyNotSendable` cannot be sent between threads safely
    |
    = help: the trait `std::marker::Send` is not implemented for `MyNotSendable`
 
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
index 77e04a75a25c1..4dd8e01cf2d36 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-negation-sync.stderr
@@ -1,11 +1,11 @@
 error[E0277]: `MyNotSync` cannot be shared between threads safely
-  --> $DIR/typeck-default-trait-impl-negation-sync.rs:33:5
+  --> $DIR/typeck-default-trait-impl-negation-sync.rs:33:15
    |
 LL | fn is_sync<T: Sync>() {}
    |    -------    ---- required by this bound in `is_sync`
 ...
 LL |     is_sync::<MyNotSync>();
-   |     ^^^^^^^^^^^^^^^^^^^^ `MyNotSync` cannot be shared between threads safely
+   |               ^^^^^^^^^ `MyNotSync` cannot be shared between threads safely
    |
    = help: the trait `std::marker::Sync` is not implemented for `MyNotSync`
 
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr b/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr
index 09c05825190e7..4b13fcc885a0d 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-negation.stderr
@@ -1,23 +1,23 @@
 error[E0277]: the trait bound `ThisImplsUnsafeTrait: MyTrait` is not satisfied
-  --> $DIR/typeck-default-trait-impl-negation.rs:21:5
+  --> $DIR/typeck-default-trait-impl-negation.rs:21:19
    |
 LL | fn is_my_trait<T: MyTrait>() {}
    |    -----------    ------- required by this bound in `is_my_trait`
 ...
 LL |     is_my_trait::<ThisImplsUnsafeTrait>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `ThisImplsUnsafeTrait`
+   |                   ^^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `ThisImplsUnsafeTrait`
    |
    = help: the following implementations were found:
              <ThisImplsUnsafeTrait as MyTrait>
 
 error[E0277]: the trait bound `ThisImplsTrait: MyUnsafeTrait` is not satisfied
-  --> $DIR/typeck-default-trait-impl-negation.rs:24:5
+  --> $DIR/typeck-default-trait-impl-negation.rs:24:26
    |
 LL | fn is_my_unsafe_trait<T: MyUnsafeTrait>() {}
    |    ------------------    ------------- required by this bound in `is_my_unsafe_trait`
 ...
 LL |     is_my_unsafe_trait::<ThisImplsTrait>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `MyUnsafeTrait` is not implemented for `ThisImplsTrait`
+   |                          ^^^^^^^^^^^^^^ the trait `MyUnsafeTrait` is not implemented for `ThisImplsTrait`
    |
    = help: the following implementations were found:
              <ThisImplsTrait as MyUnsafeTrait>
diff --git a/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
index 46731c0fbb014..b3139083b1ac8 100644
--- a/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
+++ b/src/test/ui/typeck/typeck-default-trait-impl-send-param.stderr
@@ -1,8 +1,8 @@
 error[E0277]: `T` cannot be sent between threads safely
-  --> $DIR/typeck-default-trait-impl-send-param.rs:5:5
+  --> $DIR/typeck-default-trait-impl-send-param.rs:5:15
    |
 LL |     is_send::<T>()
-   |     ^^^^^^^^^^^^ `T` cannot be sent between threads safely
+   |               ^ `T` cannot be sent between threads safely
 ...
 LL | fn is_send<T:Send>() {
    |    -------   ---- required by this bound in `is_send`
diff --git a/src/test/ui/unsized/unsized-bare-typaram.stderr b/src/test/ui/unsized/unsized-bare-typaram.stderr
index 565d561033722..e56176690a113 100644
--- a/src/test/ui/unsized/unsized-bare-typaram.stderr
+++ b/src/test/ui/unsized/unsized-bare-typaram.stderr
@@ -1,10 +1,10 @@
 error[E0277]: the size for values of type `T` cannot be known at compilation time
-  --> $DIR/unsized-bare-typaram.rs:2:23
+  --> $DIR/unsized-bare-typaram.rs:2:29
    |
 LL | fn bar<T: Sized>() { }
    |    --- - required by this bound in `bar`
 LL | fn foo<T: ?Sized>() { bar::<T>() }
-   |                       ^^^^^^^^ doesn't have a size known at compile-time
+   |                             ^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `T`
    = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

From d201e278ba6f9e2f8d9046eb983116b839807c98 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 20 Sep 2019 14:29:39 -0700
Subject: [PATCH 940/943] review comments

---
 src/librustc_typeck/check/mod.rs | 39 ++++++++++++++++----------------
 1 file changed, 19 insertions(+), 20 deletions(-)

diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 5fe554de2586f..38071a9e74da8 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3481,31 +3481,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         errors: &mut Vec<traits::FulfillmentError<'_>>,
         call_expr: &'tcx hir::Expr,
     ) {
-        if let hir::ExprKind::Call(path, _args) = &call_expr.node {
+        if let hir::ExprKind::Call(path, _) = &call_expr.node {
             if let hir::ExprKind::Path(qpath) = &path.node {
-                if let hir::QPath::Resolved(_self, path) = &qpath {
+                if let hir::QPath::Resolved(_, path) = &qpath {
                     for error in errors {
                         if let ty::Predicate::Trait(predicate) = error.obligation.predicate {
                             // If any of the type arguments in this path segment caused the
                             // `FullfillmentError`, point at its span (#61860).
-                            for segment in &path.segments {
-                                if let Some(args) = &segment.args {
-                                    for arg in &args.args {
-                                        if let hir::GenericArg::Type(hir_ty) = &arg {
-                                            if let hir::TyKind::Path(
-                                                hir::QPath::TypeRelative(..),
-                                            ) = &hir_ty.node {
-                                                // Avoid ICE with associated types. As this is best
-                                                // effort only, it's ok to ignore the case. It
-                                                // would trigger in `is_send::<T::AssocType>();`
-                                                // from `typeck-default-trait-impl-assoc-type.rs`.
-                                            } else {
-                                                let ty = AstConv::ast_ty_to_ty(self, hir_ty);
-                                                let ty = self.resolve_vars_if_possible(&ty);
-                                                if ty == predicate.skip_binder().self_ty() {
-                                                    error.obligation.cause.span = hir_ty.span;
-                                                }
-                                            }
+                            for arg in path.segments.iter()
+                                .filter_map(|seg| seg.args.as_ref())
+                                .flat_map(|a| a.args.iter())
+                            {
+                                if let hir::GenericArg::Type(hir_ty) = &arg {
+                                    if let hir::TyKind::Path(
+                                        hir::QPath::TypeRelative(..),
+                                    ) = &hir_ty.node {
+                                        // Avoid ICE with associated types. As this is best
+                                        // effort only, it's ok to ignore the case. It
+                                        // would trigger in `is_send::<T::AssocType>();`
+                                        // from `typeck-default-trait-impl-assoc-type.rs`.
+                                    } else {
+                                        let ty = AstConv::ast_ty_to_ty(self, hir_ty);
+                                        let ty = self.resolve_vars_if_possible(&ty);
+                                        if ty == predicate.skip_binder().self_ty() {
+                                            error.obligation.cause.span = hir_ty.span;
                                         }
                                     }
                                 }

From 3ea0d1097945273d6f9091126e67899a2e7e8fb1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Fri, 20 Sep 2019 15:02:36 -0700
Subject: [PATCH 941/943] hack to avoid incorrect suggestion

---
 src/librustc/traits/error_reporting.rs |  7 +++++++
 src/test/ui/kindck/kindck-copy.stderr  | 10 ++--------
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 03f8ac250e925..aff866fa76d5f 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1055,6 +1055,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 .filter(|c| !c.is_whitespace())
                 .take_while(|c| *c == '&')
                 .count();
+            if let Some('\'') = snippet.chars()
+                .filter(|c| !c.is_whitespace())
+                .skip(refs_number)
+                .next()
+            { // Do not suggest removal of borrow from type arguments.
+                return;
+            }
 
             let mut trait_type = trait_ref.self_ty();
 
diff --git a/src/test/ui/kindck/kindck-copy.stderr b/src/test/ui/kindck/kindck-copy.stderr
index fee9e2802a6c3..3ca9cf7e973db 100644
--- a/src/test/ui/kindck/kindck-copy.stderr
+++ b/src/test/ui/kindck/kindck-copy.stderr
@@ -5,10 +5,7 @@ LL | fn assert_copy<T:Copy>() { }
    |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<&'static mut isize>();
-   |                   -^^^^^^^^^^^^^^^^^
-   |                   |
-   |                   the trait `std::marker::Copy` is not implemented for `&'static mut isize`
-   |                   help: consider removing 1 leading `&`-references
+   |                   ^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'static mut isize`
    |
    = help: the following implementations were found:
              <isize as std::marker::Copy>
@@ -20,10 +17,7 @@ LL | fn assert_copy<T:Copy>() { }
    |    -----------   ---- required by this bound in `assert_copy`
 ...
 LL |     assert_copy::<&'a mut isize>();
-   |                   -^^^^^^^^^^^^
-   |                   |
-   |                   the trait `std::marker::Copy` is not implemented for `&'a mut isize`
-   |                   help: consider removing 1 leading `&`-references
+   |                   ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `&'a mut isize`
    |
    = help: the following implementations were found:
              <isize as std::marker::Copy>

From 7cef8b34959ce5472f1b3d0223ccfc7e8d71df60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sat, 21 Sep 2019 11:39:06 -0700
Subject: [PATCH 942/943] ignore-x86 instead of ignore-musl

---
 src/etc/generate-deriving-span-tests.py                         | 2 +-
 src/test/ui/async-await/issues/issue-62009-1.rs                 | 2 +-
 src/test/ui/closures/closure-move-sync.rs                       | 2 +-
 src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs    | 2 +-
 src/test/ui/derives/derives-span-Hash-enum.rs                   | 2 +-
 src/test/ui/derives/derives-span-Hash-struct.rs                 | 2 +-
 src/test/ui/derives/derives-span-Hash-tuple-struct.rs           | 2 +-
 src/test/ui/interior-mutability/interior-mutability.rs          | 2 +-
 src/test/ui/issues/issue-21160.rs                               | 2 +-
 src/test/ui/no-send-res-ports.rs                                | 2 +-
 .../termination-trait-test-wrong-type.rs                        | 2 +-
 src/test/ui/traits/trait-suggest-where-clause.rs                | 2 +-
 12 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/etc/generate-deriving-span-tests.py b/src/etc/generate-deriving-span-tests.py
index 4af67039fd877..66a3c8e555405 100755
--- a/src/etc/generate-deriving-span-tests.py
+++ b/src/etc/generate-deriving-span-tests.py
@@ -14,7 +14,7 @@
     os.path.join(os.path.dirname(__file__), '../test/ui/derives/'))
 
 TEMPLATE = """\
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
diff --git a/src/test/ui/async-await/issues/issue-62009-1.rs b/src/test/ui/async-await/issues/issue-62009-1.rs
index 007ed4efa6981..788474365c9e5 100644
--- a/src/test/ui/async-await/issues/issue-62009-1.rs
+++ b/src/test/ui/async-await/issues/issue-62009-1.rs
@@ -1,5 +1,5 @@
 // edition:2018
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 
 async fn print_dur() {}
diff --git a/src/test/ui/closures/closure-move-sync.rs b/src/test/ui/closures/closure-move-sync.rs
index 4cb6358864fca..951a3bcb5f423 100644
--- a/src/test/ui/closures/closure-move-sync.rs
+++ b/src/test/ui/closures/closure-move-sync.rs
@@ -1,4 +1,4 @@
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 use std::thread;
 use std::sync::mpsc::channel;
diff --git a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
index 516a15b55bf1d..ed87360a0be9f 100644
--- a/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
+++ b/src/test/ui/derives/derives-span-Hash-enum-struct-variant.rs
@@ -1,4 +1,4 @@
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
diff --git a/src/test/ui/derives/derives-span-Hash-enum.rs b/src/test/ui/derives/derives-span-Hash-enum.rs
index ba12deaf98137..5b3649c9826e6 100644
--- a/src/test/ui/derives/derives-span-Hash-enum.rs
+++ b/src/test/ui/derives/derives-span-Hash-enum.rs
@@ -1,4 +1,4 @@
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
diff --git a/src/test/ui/derives/derives-span-Hash-struct.rs b/src/test/ui/derives/derives-span-Hash-struct.rs
index b9e7e04f4cfed..ead70861a0ad6 100644
--- a/src/test/ui/derives/derives-span-Hash-struct.rs
+++ b/src/test/ui/derives/derives-span-Hash-struct.rs
@@ -1,4 +1,4 @@
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
diff --git a/src/test/ui/derives/derives-span-Hash-tuple-struct.rs b/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
index bb271e60745a5..820f13ed18ef2 100644
--- a/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
+++ b/src/test/ui/derives/derives-span-Hash-tuple-struct.rs
@@ -1,4 +1,4 @@
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 // This file was auto-generated using 'src/etc/generate-deriving-span-tests.py'
 
diff --git a/src/test/ui/interior-mutability/interior-mutability.rs b/src/test/ui/interior-mutability/interior-mutability.rs
index d75c149a7b682..6968e3669caec 100644
--- a/src/test/ui/interior-mutability/interior-mutability.rs
+++ b/src/test/ui/interior-mutability/interior-mutability.rs
@@ -1,4 +1,4 @@
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 use std::cell::Cell;
 use std::panic::catch_unwind;
diff --git a/src/test/ui/issues/issue-21160.rs b/src/test/ui/issues/issue-21160.rs
index 1e441a173e4be..dfb39743352fc 100644
--- a/src/test/ui/issues/issue-21160.rs
+++ b/src/test/ui/issues/issue-21160.rs
@@ -1,4 +1,4 @@
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 struct Bar;
 
diff --git a/src/test/ui/no-send-res-ports.rs b/src/test/ui/no-send-res-ports.rs
index 2c8cf0cf4e61c..01fc29713a45d 100644
--- a/src/test/ui/no-send-res-ports.rs
+++ b/src/test/ui/no-send-res-ports.rs
@@ -1,4 +1,4 @@
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 use std::thread;
 use std::rc::Rc;
diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
index d5105b40d36f5..c27cea302fc40 100644
--- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
+++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.rs
@@ -1,5 +1,5 @@
 // compile-flags: --test
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 
 use std::num::ParseFloatError;
diff --git a/src/test/ui/traits/trait-suggest-where-clause.rs b/src/test/ui/traits/trait-suggest-where-clause.rs
index 822f0c580e651..5ed14a6a86685 100644
--- a/src/test/ui/traits/trait-suggest-where-clause.rs
+++ b/src/test/ui/traits/trait-suggest-where-clause.rs
@@ -1,4 +1,4 @@
-// ignore-musl
+// ignore-x86
 // ^ due to stderr output differences
 use std::mem;
 

From ff75124a377f60ee4bd084ca2569e1530ff52856 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Sun, 22 Sep 2019 11:54:38 -0700
Subject: [PATCH 943/943] fix nll tests

---
 .../expect-fn-supply-fn.nll.stderr            | 51 +++++++++----------
 .../ui/kindck/kindck-send-object1.nll.stderr  |  4 +-
 2 files changed, 26 insertions(+), 29 deletions(-)

diff --git a/src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr b/src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr
index 565c60e5216dd..a6b52b258f005 100644
--- a/src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr
+++ b/src/test/ui/closure-expected-type/expect-fn-supply-fn.nll.stderr
@@ -1,44 +1,41 @@
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:30:5
    |
-LL | / fn with_closure_expecting_fn_with_free_region<F>(_: F)
-LL | |     where F: for<'a> FnOnce(fn(&'a u32), &i32)
-LL | | {
-LL | | }
-   | |_- required by `with_closure_expecting_fn_with_free_region`
+LL | fn with_closure_expecting_fn_with_free_region<F>(_: F)
+   |    ------------------------------------------
+LL |     where F: for<'a> FnOnce(fn(&'a u32), &i32)
+   |                      ------------------------- required by this bound in `with_closure_expecting_fn_with_free_region`
 ...
-LL |       with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
-   |       |
-   |       expected signature of `fn(fn(&'a u32), &i32) -> _`
+LL |     with_closure_expecting_fn_with_free_region(|x: fn(&u32), y| {});
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------------- found signature of `fn(for<'r> fn(&'r u32), _) -> _`
+   |     |
+   |     expected signature of `fn(fn(&'a u32), &i32) -> _`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:37:5
    |
-LL | / fn with_closure_expecting_fn_with_bound_region<F>(_: F)
-LL | |     where F: FnOnce(fn(&u32), &i32)
-LL | | {
-LL | | }
-   | |_- required by `with_closure_expecting_fn_with_bound_region`
+LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
+   |    -------------------------------------------
+LL |     where F: FnOnce(fn(&u32), &i32)
+   |              ---------------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
 ...
-LL |       with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
-   |       |
-   |       expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
+LL |     with_closure_expecting_fn_with_bound_region(|x: fn(&'x u32), y| {});
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------- found signature of `fn(fn(&'x u32), _) -> _`
+   |     |
+   |     expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
 
 error[E0631]: type mismatch in closure arguments
   --> $DIR/expect-fn-supply-fn.rs:46:5
    |
-LL | / fn with_closure_expecting_fn_with_bound_region<F>(_: F)
-LL | |     where F: FnOnce(fn(&u32), &i32)
-LL | | {
-LL | | }
-   | |_- required by `with_closure_expecting_fn_with_bound_region`
+LL | fn with_closure_expecting_fn_with_bound_region<F>(_: F)
+   |    -------------------------------------------
+LL |     where F: FnOnce(fn(&u32), &i32)
+   |              ---------------------- required by this bound in `with_closure_expecting_fn_with_bound_region`
 ...
-LL |       with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
-   |       |
-   |       expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
+LL |     with_closure_expecting_fn_with_bound_region(|x: Foo<'_>, y| {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --------------- found signature of `for<'r> fn(fn(&'r u32), _) -> _`
+   |     |
+   |     expected signature of `fn(for<'r> fn(&'r u32), &i32) -> _`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/kindck/kindck-send-object1.nll.stderr b/src/test/ui/kindck/kindck-send-object1.nll.stderr
index c7d18cd8b8bb1..f882e06ed222a 100644
--- a/src/test/ui/kindck/kindck-send-object1.nll.stderr
+++ b/src/test/ui/kindck/kindck-send-object1.nll.stderr
@@ -2,7 +2,7 @@ error[E0277]: `(dyn Dummy + 'a)` cannot be shared between threads safely
   --> $DIR/kindck-send-object1.rs:10:5
    |
 LL | fn assert_send<T:Send+'static>() { }
-   | -------------------------------- required by `assert_send`
+   |    -----------   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<&'a dyn Dummy>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be shared between threads safely
@@ -14,7 +14,7 @@ error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely
   --> $DIR/kindck-send-object1.rs:29:5
    |
 LL | fn assert_send<T:Send+'static>() { }
-   | -------------------------------- required by `assert_send`
+   |    -----------   ---- required by this bound in `assert_send`
 ...
 LL |     assert_send::<Box<dyn Dummy + 'a>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely